From: Sehong Na Date: Sat, 31 May 2014 03:54:16 +0000 (+0900) Subject: Initialize Tizen 2.3 X-Git-Tag: 2.3a_release X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Ftags%2F2.3a_release;p=external%2Fnettle.git Initialize Tizen 2.3 --- 06f836bd1b8f3bcb635b43d6a922b14569f24da0 diff --git a/.bootstrap b/.bootstrap new file mode 100755 index 0000000..d85e2e2 --- /dev/null +++ b/.bootstrap @@ -0,0 +1,3 @@ +#! /bin/sh + +autoconf && autoheader diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..b021b48 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Please see the Nettle manual. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..623b625 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. + + 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.) + +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. + + 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. + + 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 + + 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. + + + Copyright (C) + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. + + , 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. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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. + + 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. + + + + Copyright (C) + + 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 St, Fifth Floor, Boston, MA 02110-1301 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..7df4d23 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4976 @@ +2010-07-25 Niels Möller + + * Released nettle-2.1. + + * configure.ac: Use camellia-crypt-internal.asm, if available. + Bumped soname to libnettle.so.4, and reset LIBNETTLE_MINOR to + zero. + + * x86/machine.m4 (LREG, HREG): Moved macros here, from... + * x86/aes.m4: ...here. + + * x86/camellia-crypt-internal.asm: New file. + + * nettle.texinfo: Updated and expanded section on DSA. + Document aes_invert_key, and camellia. Added missing functions + rsa_sha512_verify and rsa_sha512_verify_digest. + + * camellia.h (struct camellia_ctx): Eliminate the two unused + subkeys, and renumber the remaining ones. + * camellia-crypt-internal.c (_camellia_crypt): Updated for + renumbered subkeys. + * camellia-set-encrypt-key.c (camellia_set_encrypt_key): Likewise. + * camellia-set-decrypt-key.c (camellia_invert_key): Likewise. + + * camellia-set-encrypt-key.c (camellia_set_encrypt_key): Inline + the expansion of camellia_setup128 and camellia_setup256, keeping + the unexpanded key in scalar variables. + (camellia_setup128): Deleted. + (camellia_setup256): Deleted. + +2010-07-24 Niels Möller + + * camellia-set-encrypt-key.c (camellia_set_encrypt_key): Reduced + code size, no complete loop unroll. Use one loop for each phase of + the post-processing. + + * testsuite/camellia-test.c: New tests for camellia_invert_key. + * testsuite/aes-test.c: New tests for aes_invert_key. + + * aes.h (aes_invert_key): Declare it. + + * aes-set-decrypt-key.c (aes_invert_key): New function, key + inversion code extracted from aes_set_decrypt_key. + (aes_set_decrypt_key): Use aes_invert_key. + + * camellia-set-encrypt-key.c (camellia_setup128): Generate + unmodified subkeys according to the spec. Moved clever combination + of subkeys to camellia_set_encrypt_key. + (camellia_setup256): Likewise. + (camellia_set_encrypt_key): Moved subkey post-processing code + here, and reduce code duplication between 128-bit keys and larger + keys. + + * camellia.c: Deleted file, split into several new files... + * camellia-table.c (_camellia_table): New file with the constant + sbox tables. + * camellia-set-encrypt-key.c: New file. + (camellia_setup128): Generate unmodified subkeys according to the + spec. Moved clever combination of subkeys to camellia_set_encrypt_key. + (camellia_setup256): Likewise. + + * camellia-set-decrypt-key.c: New file. + (camellia_invert_key): Key inversion function. + (camellia_set_decrypt_key): New key setup function. + * camellia-internal.h: New file. + * camellia-crypt.c (camellia_crypt): New file, new wrapper + function passing the sbox table to _camellia_crypt. + * camellia-crypt-internal.c (_camellia_crypt): New file, with main + encrypt/decrypt function. + * Makefile.in (nettle_SOURCES): Updated list of camellia source files. + (DISTFILES): Added camellia-internal.h. + +2010-07-20 Niels Möller + + * camellia-meta.c: Use _NETTLE_CIPHER_SEP_SET_KEY. + + * camellia.h (struct camellia_ctx): Replaced flag camellia128 by + expanded key length nkeys. + + * camellia.c (camellia_set_encrypt_key): Renamed, from... + (camellia_set_key): ... old name. + (camellia_invert_key): New function. + (camellia_set_decrypt_key): New function, using + camellia_invert_key. + (camellia_crypt): Renamed, from... + (camellia_encrypt): ... old name. + (camellia_decrypt): Deleted, no longer needed. camellia_crypt used + for both encryption and decryption. + + * nettle-meta.h (_NETTLE_CIPHER_SEP_SET_KEY): New macro. + + * dsa-keygen.c: Removed unnecessary include of memxor.h. + + * camellia.c: Rewrote to use 64-bit type for subkeys and use + 64-bit operations throughout. Performance on x86_32, when compiled + with gcc-4.4.4, is reduced by roughly 15%, this should be fixed + later. + + * camellia.h (struct camellia_ctx): Use type uint64_t for subkeys. + +2010-07-07 Niels Möller + + * aes.h (aes_encrypt, aes_decrypt): Declare ctx argument as const. + Also updated implementation. + * blowfish.h (blowfish_encrypt, blowfish_decrypt): Likewise. + * cast128.h (cast128_encrypt, cast128_decrypt): Likewise. + * serpent.h (serpent_encrypt, serpent_decrypt): Likewise. + * twofish.h (twofish_encrypt, twofish_decrypt): Likewise. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + camellia-test.c. + + * examples/nettle-benchmark.c: Added camellia ciphers. + + * Makefile.in (nettle_SOURCES): Added camellia.c and + camellia-meta.c. + (HEADERS): Added camellia.h. + + * nettle-meta.h (nettle_camellia128): Declare. + (nettle_camellia192): Likewise. + (nettle_camellia256): Likewise. + + * camellia-meta.c: New file. + + * camellia.h: Rewrote interface to match nettle conventions. + + * camellia.c: Converted to nettle conventions. + (camellia_encrypt128, camellia_encrypt256): Unified to new + function... + (camellia_encrypt): ...New function, with a loop doing 6 + regular rounds, one FL round and one FLINV round per iteration, + with iteration count depending on the key size. + + (camellia_decrypt128, camellia_decrypt256): Similarly unified + as... + (camellia_decrypt): ...New function, analogous to + camellia_encrypt. + +2010-07-06 Niels Möller + + * camellia.c, camellia.h: New files, copied from + http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz. + + * testsuite/camellia-test.c: New file. + +2010-07-05 Niels Möller + + * nettle.texinfo: Document new conventions for weak key and des + parity checks. Document des_check_parity. + + * testsuite/des-test.c (test_weak): Don't check the deleted status + attribute. + + * des-compat.c (des_key_sched): Rewrote error checking logic for + the case of non-zero des_check_key. + + * des3.c (des3_set_key): Changed weak key detection logic. + Complete key setup also for weak keys, and don't set the status + attribute. + + * des.c (des_set_key): New iteration logic, to keep key pointer + unchanged. Moved weak key check to the end, and don't set the + status attribute. + (des_encrypt): Ignore status attribute. + (des_decrypt): Likewise. + + * des.h (enum des_error): Deleted. + (struct des_ctx): Deleted status attribute. + (struct des3_ctx): Likewise. + + * blowfish.c (initial_ctx): Deleted status value. + (blowfish_encrypt): Ignore status attribute. + (blowfish_decrypt): Likewise. + (blowfish_set_key): return result from weak key check, without + setting the status attribute. + + * blowfish.h (enum blowfish_error): Deleted. + (struct blowfish_ctx): Deleted status attribute. + + * Makefile.in (des_headers): Deleted parity.h. + +2010-06-30 Niels Möller + + * testsuite/des-test.c (test_des): New function. + (test_weak): New function. + (test_main): Use test_des and test_weak. Added tests for all the + weak keys. Added some tests with invalid (to be ignored) parity + bits. + + * des.c (parity_16): New smaller parity table. + (des_check_parity): New function. + (des_fix_parity): Use parity_16. + (des_weak_p): New weak-key detection. Ignores parity bits, and + uses a hash table. + (des_set_key): Deleted parity checking code. Replaced old weak-key + detection code by a call to des_weak_p. + +2010-06-04 Niels Möller + + * testsuite/testutils.c (test_dsa_key): Updated for new name + DSA_SHA1_MIN_P_BITS. + + * dsa-keygen.c (dsa_generate_keypair): Use DSA_SHA1_MIN_P_BITS and + DSA_SHA256_MIN_P_BITS. + + * dsa.h (DSA_MIN_P_BITS, DSA_Q_OCTETS, DSA_Q_BITS): Renamed to... + (DSA_SHA1_MIN_P_BITS, DSA_SHA1_Q_OCTETS, DSA_SHA1_Q_BITS): New + names. + + * sexp2dsa.c (dsa_keypair_from_sexp_alist): New argument q_bits. + Renamed parameter limit to p_max_bits. + (dsa_sha1_keypair_from_sexp): Renamed, was dsa_keypair_from_sexp. + Updated to call dsa_keypair_from_sexp_alist with the new argument. + (dsa_sha256_keypair_from_sexp): New function. + (dsa_signature_from_sexp): New argument q_bits. + + * der2dsa.c (dsa_params_from_der_iterator): Enforce 160-bit limit + on q. Renamed parameter limit to p_max_bits. + (dsa_openssl_private_key_from_der_iterator): Enforce 160-bit limit + on q and x. Renamed parameter limit to p_max_bits. + +2010-06-03 Niels Möller + + * testsuite/dsa-test.c (test_main): Added test for dsa-sha256. + +2010-06-02 Niels Möller + + * testsuite/dsa-test.c (test_main): Provide expected value of the + signature. + + * testsuite/testutils.c (test_dsa160): Added argument for expected + signature. + (test_dsa256): Likewise. + +2010-06-01 Niels Möller + + * testsuite/rsa-keygen-test.c (test_main): Updated expected + signatures. + + * examples/random-prime.c (main): Updated for nettle_random_prime + change. + * testsuite/random-prime-test.c (test_main): Likewise. + + * rsa-keygen.c (bignum_random_prime): Deleted function. + (rsa_generate_keypair): Use new nettle_random_prime. Generate + secret factors p and q with the two most significant bits set. + + * dsa-keygen.c (dsa_generate_keypair): Updated for changes in + nettle_random_prime and _nettle_generate_pocklington_prime. Invoke + progress callback. + + * bignum-random-prime.c (_nettle_generate_pocklington_prime): New + argument top_bits_set, to optionally generate primes with the two + most significant bits set. Reordered argument list. + (nettle_random_prime): Likewise, added top_bits_set argument. + Invoke progress callback when a prime is generated. + +2010-05-26 Niels Möller + + * dsa-keygen.c (dsa_generate_keypair): Use + _nettle_generate_pocklington_prime. Deleted old key generation + code. + + * bignum-random-prime.c (_nettle_generate_pocklington_prime): Also + return the used r. Updated caller. + + * examples/random-prime.c (main): Allow sizes down to 3 bits. + + * bignum-random-prime.c (_nettle_generate_pocklington_prime): New + function. Rely on mpz_probab_prime_p (for lack of a trial division + function) for trial division. + (nettle_random_prime): Rewritten. Uses the prime table for the + smallest sizes, then trial division using a new set of tables, and + then Maurer's algorithm, calling the new + _nettle_generate_pocklington_prime for the final search. + +2010-05-25 Niels Möller + + * testsuite/dsa-test.c (test_main): Updated for dsa testing + changes. + + * testsuite/dsa-keygen-test.c (test_main): Test dsa256. + + * testsuite/testutils.h (struct nettle_mac): New struct, currently + unused. + + * testsuite/testutils.c (test_mac): New function (currently not + used). + (test_dsa): Replaced by two new functions... + (test_dsa160): New function. + (test_dsa256): New function. + (test_dsa_key): New argument q_size. + (DSA_VERIFY): Generalized. + + * dsa-keygen.c (dsa_generate_keypair): Rewritten, now generating + primes using Pocklington's theorem. Takes both p_size and q_size + as arguments. + +2010-05-20 Niels Möller + + * bignum-random-prime.c (miller_rabin_pocklington): Fixed broken + logic when Miller-rabin succeeds early. + +2010-04-09 Niels Möller + + * bignum-next-prime.c: Include stdlib.h, needed for alloca on + freebsd. + * hmac.c: Likewise. + + * examples/Makefile.in (SOURCES): Added random-prime.c. + + * examples/random-prime.c: New program. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Moved + knuth-lfib-test.c, cbc-test.c, ctr-test.c, hmac-test.c here, from + TS_HOGWEED_SOURCES. + (TS_HOGWEED_SOURCES): Added random-prime-test.c. + + * testsuite/random-prime-test.c: New test case. + + * examples/next-prime.c (main): With no command line arguments. + exit after dislaying usage message. + + * examples/io.c (simple_random): Free buffer when done. + + * configure.ac: Changed message, say CC is the recommended + way to configure the ABI. + + * bignum-random.c: Deleted test of HAVE_LIBGMP. + * bignum.c: Likewise. + * sexp2bignum.c: Likewise. + + * Makefile.in (hogweed_SOURCES): Added bignum-random-prime.c. + + * bignum-random-prime.c (nettle_random_prime): New file, new + function. + +2010-03-31 Niels Möller + + * examples/nettle-benchmark.c (main): Benchmark sha224. + +2010-03-30 Niels Möller + + * testsuite/testutils.c (DSA_VERIFY): Updated for dsa_sha1_verify + rename. + (test_dsa): Check return value from dsa_sha1_sign. + + * Makefile.in (hogweed_SOURCES): Added dsa-sha1-sign.c, + dsa-sha1-verify.c, dsa-sha256-sign.c, and dsa-sha256-verify.c. + + * dsa.h: Updated and added dsa declarations. + + * dsa-sha256-verify.c (dsa_sha256_verify_digest): New file, new + function. + (dsa_sha256_verify): New function. + * dsa-sha256-sign.c (dsa_sha256_sign_digest): New file, new + function. + (dsa_sha256_sign): New function. + + * dsa-sha1-verify.c (dsa_sha1_verify_digest): New file. Moved and + renamed function, from dsa_verify_digest, rewrote to use + _dsa_verify. + (dsa_sha1_verify): Analogous change, renamed from dsa_verify. + * dsa-sha1-sign.c (dsa_sha1_sign_digest): New file. Moved and + renamed function, from dsa_sign_digest, rewrote to use _dsa_sign, + and added return value. + (dsa_sha1_sign): Analogous change, renamed from dsa_sign. + + * dsa-verify.c (_dsa_verify): New general verification function, + for any hash. + * dsa-sign.c (_dsa_sign): New general signing function, for any + hash. Returns success code, like the rsa signture functions. + +2010-03-29 Niels Möller + + * configure.ac (ABI): Attempt to use a better, ABI-dependant, + default value for libdir. + + * x86/md5-compress.asm: Fixed function name in epilogue. + + * asm.m4 (EPILOGUE): Use . to refer to current address. + + * configure.ac (ABI): Detect which ABI the compiler is using. + On x86_64, also check for __arch64__. + +2010-03-28 Niels Möller + + * configure.ac (asm_path): For x86_64, check if compiler is + generating 32-bit code. + +2010-03-27 Niels Möller + + * testsuite/hmac-test.c (test_main): Rewrote rest of tests to use + HMAC_TEST, and added more tests from Daniel Kahn Gillmor and from + RFC 4231. + + * Makefile.in (nettle_SOURCES): Added hmac-sha224.c and + hmac-sha384.c. + + * hmac.h: Added declarations of hmac-sha224 and hmac-sha384. + + * hmac-sha224.c: New file. + +2010-03-26 Niels Möller + + * testsuite/hmac-test.c (HMAC_TEST): New macro. + (test_main): Use HMAC_TEST for the md5 and sha1 tests, and add + test vectors from Daniel Kahn Gillmor. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added sha224-test.c. + + * Makefile.in (nettle_SOURCES): Added sha224-meta.c and + write-be32.c. + (DISTFILES): Added nettle-write.h. + + * sha.h: Added declarations for sha224. Some are aliases for the + corresponding sha256 definition. + + * sha256.c (sha256_digest): Use _nettle_write_be32. + (sha224_init): New function. + (sha224_digest): New function. + + * sha1.c (sha1_digest): Use _nettle_write_be32. + + * nettle-internal.h (NETTLE_MAX_HASH_BLOCK_SIZE) + (NETTLE_MAX_HASH_DIGEST_SIZE): Increased, to take sha512 into + account. + + * nettle-write.h: New file. + + * write-be32.c (_nettle_write_be32): New file, new function. + + * sha224-meta.c: New file. + +2010-03-25 Niels Möller + + * hmac-sha384.c: New file. + + * testsuite/sha224-test.c: New file. + + * testsuite/md4-test.c (test_main): More test vectors, provided by + Daniel Kahn Gillmor. + * testsuite/md5-test.c (test_main): Likewise. + * testsuite/sha1-test.c (test_main): Likewise. + * testsuite/sha256-test.c (test_main): Likewise. + * testsuite/sha384-test.c (test_main): Likewise. + * testsuite/sha512-test.c (test_main): Likewise. + + * configure.ac: Bumped version numbers. Package version + nettle-2.1, library versions libnettle.so.3.1, libhogweed.so.2.0. + + * examples/nettle-benchmark.c (main): Benchmark sha384. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added sha384-test.c. + + * testsuite/sha384-test.c: New file. + + * Makefile.in (nettle_SOURCES): Added sha384-meta.c. + + * sha384-meta.c: New file. + + * sha.h: Added declarations for sha384. Some are aliases for the + corresponding sha512 definition. + + * sha512.c (sha512_write_digest): New function. + (sha512_digest): Use it. + (sha384_init): New function. + (sha384_digest): New function. + +2010-03-24 Niels Möller + + * sha512.c: (sha512_digest): Simplified handling of any final + partial word of the digest. + + * sha512.c: Reorganized to use _nettle_sha512_compress. + + * sha512-compress.c (_nettle_sha512_compress): Compression + function extracted from sha512.c to a new file. + + * Makefile.in (nettle_SOURCES): Added sha256-compress.c and + sha512-compress.c. + + * sha256.c: Reorganized to use _nettle_sha256_compress. + + * sha256-compress.c (_nettle_sha256_compress): Compression + function extracted from sha256.c to a new file. + + * examples/nettle-benchmark.c (main): Benchmark sha512. + + * rsa-keygen.c (rsa_generate_keypair): Ensure that bit size of e + is less than bit size of n, and check for the unlikely case p = q. + + * rsa.h (RSA_MINIMUM_N_OCTETS, RSA_MINIMUM_N_BITS): Reduced, to + correspond to pkcs#1 encryption of single byte messagees. + + * pgp-encode.c (pgp_put_rsa_sha1_signature): Check return value + from rsa_sha1_sign. + * rsa-compat.c (R_SignFinal): Likewise. + + * rsa-md5-sign.c (rsa_md5_sign): Check and propagate return value + from pkcs1_rsa_md5_encode. + (rsa_md5_sign_digest): Check and propagate return value from + pkcs1_rsa_md5_encode_digest. + * rsa-md5-verify.c (rsa_md5_verify): Check return value from + pkcs1_rsa_md5_encode. + (rsa_md5_verify_digest): Check return value from + pkcs1_rsa_md5_encode_digest. + * rsa-sha1-sign.c: Analogous changes. + * rsa-sha1-verify.c: Analogous changes. + * rsa-sha256-sign.c: Analogous changes. + * rsa-sha256-verify.c: Analogous changes. + * rsa-sha512-sign.c: Analogous changes. + * rsa-sha512-verify.c: Analogous changes. + + * pkcs1-rsa-md5.c (pkcs1_rsa_md5_encode) + (pkcs1_rsa_md5_encode_digest): Added return value. Check and + propagate return value from pkcs1_signature_prefix. + * pkcs1-rsa-sha256.c (pkcs1_rsa_sha256_encode) + (pkcs1_rsa_sha256_encode_digest): Likewise. + * pkcs1-rsa-sha1.c (pkcs1_rsa_sha1_encode) + (pkcs1_rsa_sha1_encode_digest): Likewise. + * pkcs1-rsa-sha512.c (pkcs1_rsa_sha512_encode) + (pkcs1_rsa_sha512_encode_digest): Likewise. + + * pkcs1.c (pkcs1_signature_prefix): Interface change, take both + the total size and digest size as arguments, and return a status + code to say if the size was large enough. + + * testsuite/Makefile.in: Added hogweed dependency for the test + programs. + +2010-03-23 Niels Möller + + * testsuite/rsa-test.c (test_main): Test signing with sha512. + + * testsuite/testutils.c (test_rsa_sha512): New function. + + * Makefile.in (hogweed_SOURCES): Added pkcs1-rsa-sha512.c, + rsa-sha512-sign.c and rsa-sha512-verify.c. + + * rsa.h: Added prototypes for sha512-related functions. + (RSA_MINIMUM_N_OCTETS, RSA_MINIMUM_N_BITS): Increased. + * pkcs1.h: Added prototypes for sha512-related functions. + + * rsa-sha512-verify.c: New file. + * rsa-sha512-sign.c: New file. + * pkcs1-rsa-sha512.c: New file. + +2010-03-22 Niels Möller + + * Makefile.in (nettle_SOURCES): Added hmac-sha512.c. + + * testsuite/hmac-test.c (test_main): Added test cases for + hmac-sha512. + + * hmac.h: Declare functions sha512-related functions. + * hmac-sha512.c (hmac_sha512_set_key): New file. + + Basic sha512 support. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added sha512-test.c. + * testsuite/sha512-test.c: New file. + + * macros.h (READ_UINT64, WRITE_UINT64): New macros. + + * Makefile.in (nettle_SOURCES): Added sha512.c and sha512-meta.c. + * sha.h: Added sha512-related declarations. + * nettle-meta.h: Likewise. + * sha512-meta.c: New file. + * sha512.c: New file. + +2010-03-06 Niels Möller + + * Makefile.in (distdir): Include x86_64 assembler files. + +2010-01-20 Niels Möller + + * configure.ac: Check for mpz_powm_sec. + +2010-01-13 Niels Möller + + * Makefile.in ($(LIBHOGWEED_FORLINK)): Depend on + $(LIBNETTLE_FORLINK). + + * configure.ac (LIBHOGWEED_LIBS): Added -lnettle -lgmp for the + default case. Follows debian, and also makes dlopen of + libhogweed.so work, without having to use RTLD_GLOBAL. + (LIBHOGWEED_LINK): Added -L., to find our libnettle.so. + +2009-10-21 Niels Möller + + * tools/Makefile.in (pkcs1-conv$(EXEEXT)): Added dependency on + ../libhogweed.a. + +2009-10-19 Niels Möller + + * tools/pkcs1-conv.c: Updated for dsa/der interface change. + + * der2dsa.c (dsa_public_key_from_der_iterators): Split into two + new functions... + (dsa_params_from_der_iterator): New function. + (dsa_public_key_from_der_iterator): New function. + (dsa_openssl_private_key_from_der_iterator): Renamed, was + dsa_private_key_from_der_iterator. + (dsa_openssl_private_key_from_der): Likewise. + * dsa.h: Corresponding changees to prototypes and #defines. + +2009-10-12 Niels Möller + + * sexp-format.c: Removed conditioning on HAVE_LIBGMP. + + * tools/pkcs1-conv.c: Support for DSA keys, contributed by Magnus + Holmgren. + + * Makefile.in (hogweed_SOURCES): Added dsa2sexp.c and der2dsa.c. + + * der2dsa.c: New file, contributed by Magnus Holmgren. + * dsa2sexp.c: Likewise. + * dsa.h: Added prototypes. + + * configure.ac (LIBHOGWEED_MINOR): Bumped libhogweed minor + version, now it's 1.1. + + * testsuite/rsa2sexp-test.c (test_main): Updated testcase for + "rsa-pkcs1". + +2009-10-11 Niels Möller + + * rsa2sexp.c (rsa_keypair_to_sexp): Changed default algorithm name + to "rsa-pkcs1". + +2009-09-20 Niels Möller + + * x86/sha1-compress.asm: Improved performance by 17% on AMD K7, + by letting loopmix scramble the instruction order. + +2009-09-15 Niels Möller + + * x86/sha1-compress.asm: Cleanup, removing old cruft. Slight + improvement to ROUND_F1_NOEXP. Slight reduction of + dependency-chains. + +2009-08-25 Niels Möller + + * x86/sha1-compress.asm: Eliminated tmp variable for f3 rounds. + + * examples/nettle-benchmark.c (bench_sha1_compress): New function, + for precise benchmarking of the compression function. + +2009-06-08 Niels Möller + + * Released nettle-2.0. + +2009-06-04 Niels Möller + + * configure.ac: Set version to 2.0 + +2009-05-30 Niels Möller + + * Makefile.in (.texinfo.info): Don't use a temporary output file + $@T, trust makeinfo to remove output file on errors. + +2009-05-19 Niels Möller + + * nettle.texinfo: Changed license to public domain. + +2009-05-11 Niels Möller + + * nettle.texinfo: Fixes from Karl Berry. Added some more index + terms. + +2009-03-06 Niels Möller + + * x86_64/aes-encrypt-internal.asm: Reduced unrolling. Keep state + in %eax--%edx only. + * x86_64/aes-decrypt-internal.asm: Likewise. + + * x86_64/aes.m4 (MOVE_HREG): Deleted, no longer needed. + (AES_STORE): Reduced offsets. + (AES_ROUND): Use HREG directly, not MOVE_HREG. + + * x86_64/aes-decrypt-internal.asm: Rearrange register allocation. + Put SA--SD in %eax--%edx, so the second byte can be accessed as + %ah-%dh. TD is not needed, SD can be reused. Use the register that + is saved for the outer loop counter, getting it off the stack. + * x86_64/aes-encrypt-internal.asm: Likewise. + + * x86_64/aes.m4 (HREG, MOVE_HREG): New macros. + (XREG): Fixed bug in handling of %r8 and %r9. + (AES_ROUND): Use MOVE_HREG. + +2009-02-10 Niels Möller + + * base16-meta.c (base16_encode_update_wrapper): Mark ctx argument + as UNUSED. + + * testsuite/sexp-conv-test: Updated testcases for improved + handling of comments. + + * tools/sexp-conv.c (sexp_convert_item): Use sexp_put_soft_newline + to terminate comments, and modify indentation for the case that a + list starts with a comment. + + * tools/output.c (sexp_output_init): Initialize soft_newline. + (sexp_put_raw_char): Clear soft_newline. + (sexp_put_newline): Check and reset soft_newline. + (sexp_put_soft_newline): New function. + + * tools/output.h (struct sexp_output): Removed union with single + element, and updated all users. New attribute soft_newline. + +2008-12-22 Niels Möller + + * Makefile.in ($(des_headers)): Create files in $(srcdir). + +2008-11-28 Niels Möller + + * testsuite/cxx-test.cxx: Include . + +2008-11-22 Niels Möller + + * yarrow256.c (yarrow256_fast_reseed): Set ctx->seeded = 1, so + that it is set if and only if the aes context has been initialized + with aes_set_encrypt_key. + (yarrow256_seed): No need to set ctx->seeded here. + (yarrow256_update): Likewise. + +2008-11-04 Niels Möller + + * examples/next-prime.c (main): Avoid using gmp_fprintf, to stay + compatible with gmp-3.1. + +2008-11-01 Niels Möller + + * nettle.texinfo: Updated for 2.0. New section on linking. + + * nettle-types.h, nettle-meta.h: Moved all typedefs for function + types to nettle-types.h. Use non-pointer types, so that the types + can be used to declare functions. Updated all users. + +2008-10-31 Niels Möller + + * testsuite/yarrow-test.c (test_main): Updated for seed file + changes. + + * sha-example.c (display_hex): Use %02x, not %2x. + +2008-10-30 Niels Möller + + * tools/sexp-conv.c (main): Fixed file locking. + +2008-10-25 Niels Möller + + * configure.ac: Set version to 2.0rc1. + + * examples/Makefile.in (next-prime$(EXEEXT)): Added -lnettle to + linker. + +2008-10-24 Niels Möller + + * sha256.c (ROUND): Simplified macro. + + * yarrow256.c (yarrow256_fast_reseed): Renamed (was + yarrow_fast_reseed) and made non-static. Don't generate seed file + here, let the application use yarrow256_random instead. + (yarrow256_slow_reseed): Renamed (was yarrow_slow_reseed) and made + non-static. + (yarrow256_force_reseed): Deleted function, use + yarrow256_slow_reseed instead. For backwards compatibility, + yarrow.h defines yarrow256_force_reseed as an alias for that + function. + + * yarrow.h (struct yarrow256_ctx): Deleted seed_file buffer. + +2008-09-17 Niels Möller + + * x86/arcfour-crypt.asm: Improved loop logic, and unrolled + loop twice. Gave a modest speedup. + +2008-09-15 Niels Möller + + * yarrow256.c (yarrow256_seed): Disallow length == 0. + + * base64-decode.c (decode_table): Added vertical tab (VT) and form + feed (FF) as white space characters. + + * x86_64/aes-decrypt-internal.asm: New file. + +2008-09-13 Niels Möller + + * x86/aes-encrypt-internal.asm: Replaced pushl and popl in the + loop with movl. Eliminated redundant movl. + * x86/aes-decrypt-internal.asm: Likewise. + + * x86_64/aes.m4: New file. + + * x86/aes-encrypt-internal.asm: Updated for AES_FINAL_ROUND. Only + three times through the substitution loop. + * x86/aes-decrypt-internal.asm: Likewise. + * x86_64/aes-encrypt-internal.asm: Likewise. + + * x86/aes.m4 (AES_FINAL_ROUND): Do the substitution on the least + significant byte here. + + * x86/aes-encrypt-internal.asm: Updated use of AES_SUBST_BYTE. USe + decl for outer loop. + * x86/aes-decrypt-internal.asm: Likewise. + + * x86/aes.m4 (LREG, HREG): New macros. + (AES_SUBST_BYTE): Take state registers as argument. Use LREG to + get the corresponding byte register. + (AES_ROUND): Use movzbl together with LREG and HREG. + (AES_SUBST_BYTE): Likewise. + +2008-09-10 Niels Möller + + * x86_64/sha1-compress.asm: Avoid using registers %rbx and %rbp, + which must be preserved. + +2008-09-08 Niels Möller + + * Makefile.in (stamp-h.in): Use $(AUTOHEADER). + + * x86_64/sha1-compress.asm: New x86_64 assembler, based on the x86 + version. + + * configure.ac (asm_path): Set up asm_path for x86_64. + + * x86_64/machine.m4: New file, new directory. + +2008-08-28 Niels Möller + + * examples/eratosthenes.c (main): Rewrote block-wise sieving to + use less memory. New options -s and -v. + +2008-08-27 Niels Möller + + * testsuite/sexp-conv-test (print_raw, print_nl): Use printf. + Updated testcases with comments; comments are now preserved. + + * tools/sexp-conv.c (sexp_convert_item): Keep comments in advanced + output. + (parse_options): New --lock option. + (main): Optionally lock output file. + + * tools/parse.c (sexp_check_token): Removed check for "any" token. + All callers specify the token they expect. + (sexp_parse): Pass on comment tokens. + + * tools/output.c (sexp_put_data): Made non-static. + + * tools/input.c (sexp_get_comment): New function. + (sexp_get_token): Use sexp_get_comment. + + * tools/misc.h (enum sexp_token): Start enumeration with zero, zero + is no longer used to mean any type. New type SEXP_COMMENT. + + * configure.ac: Check for fcntl file locking. + +2008-08-26 Niels Möller + + * Makefile.in (tags-here): Put TAGS file in the source directory. + * examples/Makefile.in (tags): Likewise. + * testsuite/Makefile.in (tags): Likewise. + * tools/Makefile.in (tags): Likewise. + +2008-02-29 Niels Möller + + * examples/Makefile.in (SOURCES): Added next-prime.c. + +2008-01-05 Niels Möller + + * examples/Makefile.in (TARGETS): Added eratosthenes and next-prime. + (next-prime, eratosthenes): New rules. + (nettle-benchmark): Don't rely on $@. + + * examples/eratosthenes.c (find_first_one): Optimized, using + slightly larger table. + (main): Use atol, rather than atoi. + + * testsuite/symbols-test: Check symbols also in libhogweed. + + * examples/next-prime.c: New file. + Deleted code for detailed timing. + + * Makefile.in (hogweed_SOURCES): Added bignum-next-prime.c. + (DISTFILES): Added prime-list.h. + (hogweed_OBJS): Removed $(LIBOBJS). + + * bignum-next-prime.c (nettle_next_prime): Renamed function, for + name space reasons. Was bignum_next_prime. Updated call in + rsa-keygen.c. + (primes): Use prime-list.h. + (nettle_next_prime): Skip Fermat test. Use mpz_millerrabin + directly, rather than mpz_probab_prime_p, when the former is + available. + + * bignum.h (nettle_next_prime): New prototype. + + * rsa-keygen.c (bignum_next_prime): Deleted, moved to + bignum-next-prime.c. Call with a larger prime limit, this improves + the running time of lsh-keygen by roughly 25%. + + * prime-list.h: List of odd primes < 2^16. + + * configure.ac: Check for sizeof(long). + +2008-01-03 Niels Möller + + * examples/nettle-benchmark.c (main): Removed incorrect UNUSED + from declaration. + + * bignum-next-prime.c: Moved the bignum_next_prime function to a + separate file. + +2007-09-08 Niels Möller + + * sparc64/aes-encrypt-internal.asm: The directory with the aes.m4 + include file was renamed from "sparc" to "sparc32". Updated include. + * sparc64/aes-decrypt-internal.asm: Likewise. + * sparc32/aes-encrypt-internal.asm: Likewise. + * sparc32/aes-decrypt-internal.asm: Likewise. + +2007-09-07 Niels Möller + + * examples/read_rsa_key.c: Include stdlib.h. + +2007-06-02 Niels Möller + + * Makefile.in: Typo fixes to install targets, spotted by Magnus + Holmgren. + +2007-05-14 Niels Möller + + * configure.ac: Fixed copy-and-paste errors in shared library + name setup. + + * config.make.in (LIBNETTLE_SONAME, LIBHOGWEED_SONAME): Define. + + * Makefile.in (libnettle.so, libhogweed.so): Fixed rules. + + * Makefile.in: Split nettle library into two files, libnettle.a + and libhogweed.a, and similarly for the shared libraries. + + * configure.ac: Bumped nettle so-versions to 3.0. Set hogweed + so-versions to 1.0. New makefile conditionals IF_SHARED and + IF_HOGWEED. Renamed WITH_PUBLIC_KEY to WITH_HOGWEED. Deleted + SHLIBTARGET, SHLIBINSTALL, RSA_EXAMPLES and RSA_TOOLS. + + * config.make.in: Updated for hogweed split. + + * C source files: Don't use WITH_PUBLIC_KEY / WITH_HOGWEED, the + Makefile sorts out which files should be compiled. + + * pgp.h: Include bignum.h, don't pretend to work without bignums. + + * pgp-encode.c (pgp_put_mpi, pgp_put_public_rsa_key) + (pgp_put_rsa_sha1_signature): Define unconditionally. Removed the + checking of HAVE_LIBGMP and WITH_PUBLIC_KEY. + + * examples/io.h: Use WITH_HOGWEED, not WITH_PUBLIC_KEY. + * examples/io.c (read_rsa_key): Deleted, moved to... + * examples/read_rsa_key.c: New file, extracted from io.c. + + * examples/Makefile.in: Use IF_HOGWEED instead of RSA_EXAMPLES. + Link appropriate programs with -lhogweed. + (SOURCES): Added read_rsa_key.c. + + * tools/Makefile.in (pkcs1-conv): Use IF_HOGWEED, not @RSA_TOOLS@, + for configuration. Link with -lhogweed. + + * testsuite/testutils.h: Use WITH_HOGWEED, not WITH_PUBLIC_KEY. + * testsuite/testutils.c: Likewise. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES, TS_HOGWEED_SOURCES): + Separate test cases using nettle and those also using hogweed. + +2007-04-05 Niels Möller + + * Moved in CVS tree. Also renamed directory sparc to sparc32. + +2007-02-24 Niels Möller + + * Makefile.in (clean-here): Remove .lib directory. + (distclean-here): Remove machine.m4. + +2006-12-05 Niels Möller + + * configure.ac: AC_PREREQ 2.61, for AC_PROG_MKDIR_P. + + * config.make.in (datarootdir): New directory variable (for + autoconf-2.61). + +2006-11-28 Niels Möller + + * configure.ac: Bumped version to 1.16. + + * Released nettle-1.15. + +2006-11-27 Niels Möller + + * NEWS: New entry for nettle-1.15. + + * configure.ac (SHLIBMINOR): Bumped version. Library name is now + libnettle.so.2.6. + + * sha256.c: Changed copyright notice to use the LGPL. + + * Makefile.in (DISTFILES): Added COPYING.LIB. + + * COPYING.LIB: New file (previously only the plain GPL was + included in the distribution). + + * nettle.texinfo: Updated vor nettle-1.15. + + * testsuite/rsa-test.c (test_main): Use test_rsa_sha256. + * testsuite/testutils.c (test_rsa_sha256): New function. + + * testsuite/Makefile.in (DISTFILES): Replaces rfc1750.txt by + gold-bug.txt. + + * rsa.h (rsa_sha256_sign, rsa_sha256_verify) + (rsa_sha256_sign_digest, rsa_sha256_verify_digest): New declarations. + (RSA_MINIMUM_N_OCTETS, RSA_MINIMUM_N_BITS): Increased to + 62 octets and 489 bits, respectively, for supporting sha256. + + * pkcs1.h (pkcs1_rsa_sha256_encode) + (pkcs1_rsa_sha256_encode_digest): New declarations and name + mangling symbols. + + * Makefile.in (nettle_SOURCES): Added pkcs1-rsa-sha256.c, + rsa-sha256-sign.c, rsa-sha256-verify.c. + + * pkcs1-rsa-sha256.c, rsa-sha256-sign.c, rsa-sha256-verify.c: New + files. + + * COPYING, INSTALL, install-sh, texinfo.tex: Updated files, from + automake-1.10. + +2006-11-27 Niels Möller + + * tools/Makefile.in (install): Use MKDIR_P to create installation + directory. Install only one file at a time. + + * Makefile.in (MKDIR_P): Use MKDIR_P for creating installation + directories. + + * configure.ac: Use AC_PROG_MKDIR_P. + +2006-11-24 Niels Möller + + * testsuite/yarrow-test.c (test_main): Use gold-bug.txt as input + file, instead of rfc1750.txt. + + * testsuite/gold-bug.txt: New test input file for yarrow-test. + The copyright on this short story by Edgar Allan Poe has expired. + + * testsuite/rfc1750.txt: Deleted file. Debian considers RFC:s + non-free, and it was expired anyway. Replaced by gold-bug.txt. + +2006-11-24 Niels Möller + + * Almost all header files: Added C++ guards. + + * configure.ac: Test if the system has any C++ compiler. + + * config.make.in (CXX, CXXFLAGS, COMPILE_CXX, LINK_CXX): New variables. + + * testsuite/Makefile.in: New variables TS_C and TS_CXX. Setup for + compiling the C++ file cxx-test.cxx. + + * testsuite/cxx-test.cxx: New testcase, trying to use nettle from + a C++ program. + +2006-08-28 Niels Möller + + * index.html: Added section on language bindings. + +2006-06-10 Niels Möller + + * configure.ac: Darwin shared library support, from Grant + Robinsson. + +2006-05-18 Niels Möller + + * src/nettle/x86/aes.asm: Deleted unused file. + + * aes-decrypt.c (_aes_decrypt_table): Deleted the indexing array, + previously commented out. + * aes-encrypt-table.c (_aes_encrypt_table): Likewise. + + * Makefile.in (.texinfo.info, .dvi.ps): Use more quotes with + basename. + (install-here, install-shared, install-info, install-headers): Use + plain mkdir, not $(INSTALL) -d. + +2006-05-16 Niels Möller + Merged from the lsh experimental branch. + +2006-04-26 Niels Möller + + * examples/rsa-decrypt.c: Don't include "getopt.h", since it's not used. + * examples/nettle-benchmark.c: Include "getopt.h". + + * examples/Makefile.in (GETOPT_OBJS): New variable. + (rsa-keygen, rsa-encrypt, nettle-benchmark): Depend on and link + with $(GETOPT_OBJS). + + * x86/aes-decrypt-internal.asm: Use ALIGN. + * x86/aes-encrypt-internal.asm: Likewise. + * x86/arcfour-crypt.asm: Likewise. + * x86/md5-compress.asm: Likewise. + * x86/sha1-compress.asm: Likewise. + + * config.m4.in (ASM_ALIGN_LOG): Substitute. + * configure.ac (ASM_ALIGN_LOG): Check if .align directive is + logarithmic. + * asm.m4 (ALIGN): New macro. Takes a logarithmic argument, and + expands to a .align directive. + +2006-04-21 Niels Möller + + * nettle.texinfo (Public-key algorithms): Say that the public key + operations are undocumented, not unsupported. Reported by Jeronimo + Pellegrini. + +2006-04-08 Niels Möller + + * tools/pkcs1-conv.c (read_pem): Fixed c99-style declaration. + Reported by Henrik Grubbström. + +2006-01-31 Niels Möller + + * examples/rsa-verify.c: Fixed typo in usage message. + +2005-12-05 Niels Möller + + * configure.ac: Bumped version to 1.15, + + * Released nettle-1.14. + + * NEWS: Updated for 1.14. + + * configure.ac (SHLIBMINOR): Increased minor number. Library + version is now libnettle.so.2.5, soname still libnettle.so.2. + +2005-11-28 Niels Möller + + * config.make.in (INSTALL): Don't substitute INSTALL, INSTALL_DATA + and friends here, to get a correct a relative filename for + install-sh when used in tools/Makefile. + + * tools/Makefile.in (INSTALL): Substitute INSTALL, INSTALL_DATA + and friends here. + * Makefile.in (INSTALL): Likewise. + +2005-11-27 Niels Möller + + * Makefile.in (.texinfo.pdf): New rule. Avoid dependency on + intermediate .dvi and .ps files. + + * testsuite/Makefile.in (clean): Delete sha1-huge-test. + + * Makefile.in (install-info, install-headers): Don't use $< and + $?; Solaris make doesn't support them in explicit rules. + +2005-11-26 Niels Möller + + * testsuite/Makefile.in: Include .test-rules.make, which contains + the rules for all the test executables. + (test-rules): New rule, to update this file. + (DISTFILES): Added $(EXTRA_SOURCES). + + * testsuite/.test-rules.make: Automatically generated file for + building the test programs. + +2005-11-25 Niels Möller + + * configure.ac: Disable assembler when compiling with rntcl. + + * tools/Makefile.in (pkcs1_conv_SOURCES): New variable. + (pkcs1-conv): Link with getopt.o and getopt1.o. + + * Makefile.in (aesdata, desdata, shadata): Use explicit rules for + executables. + + * testsuite/Makefile.in: Use %-rules for building the -test + executables, in addition to the suffix rules. Hopefully, this + should make all of GNU make, BSD make and Solaris make happy. + Use $(EXEEXT) and $(OBJEXT) more consistently. + + * examples/Makefile.in: Use explicit rules for all executable + targets. Use $(EXEEXT) and $(OBJEXT) more consistently. + +2005-11-25 Niels Möller + + * testsuite/Makefile.in: Avoid using single-suffix rule to build + executables. + +2005-11-24 Niels Möller + + * Makefile.in (distdir): Use [ -f, not [ -e, since the latter + is less portable, and not supported by Solaris /bin/sh. + +2005-11-23 Niels Möller + + * testsuite/Makefile.in (DISTFILES): Added teardown-env. + * testsuite/teardown-env: New file. Delete files created by the + testsuite. + +2005-11-21 Niels Möller + + * testsuite/testutils.c (main): Fixed check for -v option. Spotted + by Goran K. + +2005-11-21 Niels Möller + + * ctr.h (CTR_CTX, CTR_CRYPT): Fixed bugs, spotted by Goran K. + +2005-11-20 Niels Möller + + * Makefile.in (nettle_SOURCES): Added der2rsa.c. + + * testsuite/Makefile.in (TS_SH): Added pkcs1-conv-test. + + * tools/Makefile.in (TARGETS): Added @RSA_TOOLS@. + (SOURCES): Added pkcs1-conv.c. + (pkcs1-conv): New rule. + + * tools/pkcs1-conv.c: New program. + + * testsuite/pkcs1-conv-test: New file. + + * examples/rsa-verify-test: Use rsa-sign to create signature. + + * examples/io.c (read_file): Fixed spelling in error message. + + * rsa.h (rsa_public_key_from_der_iterator) + (rsa_private_key_from_der_iterator, rsa_keypair_from_der): Declare + functions. + + * der2rsa.c: New file. + + * der-iterator.c (asn1_der_iterator_init): Initialize length and + data. + (asn1_der_iterator_next): Support for lengths >= 0x80. + (asn1_der_decode_constructed_last, asn1_der_decode_bitstring) + (asn1_der_decode_bitstring_last): New functions. + (asn1_der_get_bignum): Check for non-mininal encodings. + + * configure.ac (RSA_TOOLS): New substituted variable. Includes + pkcs1-conv, when public-key support is enabled. + + * bignum.h (nettle_asn1_der_get_bignum): Include nettle_-prefix in + declaration. + + * asn1.h: Added name mangling defines, and a few new declarations. + +2005-11-13 Niels Möller + + * Makefile.in (nettle_SOURCES): Added der-iterator.c. + (HEADERS): Added asn1.h. + + * bignum.h (asn1_der_get_bignum): Declare function. + + * der-iterator.c: New file. + * asn1.h: New file. + +2005-11-07 Niels Möller + + * examples/nettle-benchmark.c: Check HAVE_UNISTD_H. + + * examples/Makefile.in (TARGETS): Use $(EXEEXT). + * tools/Makefile.in (TARGETS, sexp-conv, nettle-lfib-stream): Likewise. + + * configure.ac: Use $host_cpu, not $host, when setting up the + assembler path. Use $host_os, not uname, when setting up shared + library flags. + + * Makefile.in (des.$(OBJEXT)): Use OBJEXT. + + * config.guess, config.sub: In the CVS tree, moved files to the + lsh top-level directory. + +2005-10-23 Niels Möller + + * sparc64/arcfour-crypt.asm: New file, almost the same as + sparc/arcfour-crypt.asm. + + * examples/nettle-benchmark.c (display): Use two decimal places. + + * sparc/arcfour-crypt.asm: Reorganized. Main loop unrolled four + times. Uses aligned 32-bit write accesses at DST. Still uses 8-bit + read accesses at SRC; could be improved int he case that SRC and + DST have compatible alignment. + +2005-10-19 Niels Möller + + * testsuite/arcfour-test.c (test_main): New testcase with 512 + bytes of data. + +2005-10-19 Niels Möller + + * sparc/arcfour-crypt.asm: Fixed bug, spotted by Mikael Kalms. We + must order the store at [CTX+I] before the load of [CTX+SI+SJ]. + +2005-10-18 Niels Möller + + * sparc/arcfour-crypt.asm: Special unrolled code if SRC and DST + have compatible alignment. Improves performance by 20%, but I'm + not sure it's worth the extra complexity. + + * bignum.c (nettle_mpz_from_octets): Removed sign argument. If + mpz_import is available, define nettle_mpz_from_octets as a macro + calling mpz_import. + (nettle_mpz_from_octets): Start by setting x to zero; callers no + longer need to do that. + (nettle_mpz_set_str_256_s): New logic for the handling of negative + numbers. Convert in the same way as for positive numbers, and then + subtract the appropriate power of two. + +2005-10-17 Niels Möller + + * bignum.c (nettle_mpz_from_octets): Improved loop. Removed the + digit temporary (suggested by Torbjörn Granlund). + + * sparc/arcfour-crypt.asm: Improved instruction scheduling. + + * sparc/arcfour-crypt.asm: Bugfix, use lduh and stuh. + + * sparc/arcfour-crypt.asm: New file. + + * sparc64/aes.asm: Deleted unused file. + + * x86/arcfour-crypt.asm: Use ARCFOUR_I and ARCFOUR_J + * asm.m4 (ARCFOUR): New struct. + +2005-10-17 Niels Möller + + * aes-internal.h (struct aes_table): Deleted idx and sparc_idx + arrays. + * aes-encrypt-table.c (_aes_encrypt_table): Likewise. + * aes-decrypt.c (_aes_decrypt_table): Likewise. + * asm.m4 (AES): Likewise + +2005-10-16 Niels Möller + + * tools/input.c (sexp_get_char): Use unsigned for the done flag. + + * sparc64/aes-encrypt-internal.asm: Include sparc/aes.m4. + * sparc64/aes-decrypt-internal.asm: Likewise. + + * sparc64/machine.m4: Use .register pseudo op to say that we use + %g2 and %g3 as scratch registers. + + * sparc/aes-encrypt-internal.asm: Explicitly include sparc/aes.m4. + * sparc/aes-decrypt-internal.asm: Likewise. + + * sparc/aes.m4: New file. Moved aes-related macros here... + * sparc/machine.m4: ... removed aes macros. + + * x86/aes-encrypt-internal.asm: Explicitly include x86/aes.m4. + * x86/aes-decrypt-internal.asm: Likewise. + + * x86/aes.m4: New file. Moved aes-related macros here, from... + * x86/machine.m4: ... removed aes macros. + + * sparc64/aes-encrypt-internal.asm: New file. + * sparc64/aes-decrypt-internal.asm: New file. + + * sparc64/machine.m4: Include the same aes macros used for + sparc32. + (BIAS): Define magic stack bias constant. + + * sparc/aes-encrypt-internal.asm, sparc/aes-decrypt-internal.asm: + Reduced frame size to 104 bytes, since we no longer need wtxt and + tmp on the stack. + + * sparc/aes.asm: Deleted old aes implementation. + + * sparc/aes-decrypt-internal.asm: New file. + + * sparc/machine.m4: Don't use m4 eval, instead rely on the + assembler's arithmetic. + + * sparc/machine.m4 (AES_FINAL_ROUND): Better scheduling, by + interleaving independent operations. + + * sparc/machine.m4 (TMP3): A third temporary register. + (AES_FINAL_ROUND): Prepared for scheduling. + + * sparc/machine.m4 (AES_ROUND): Deleted unused argument T. Updated + all calls in aes-encrypt-internal.asm. + + * sparc/machine.m4 (AES_ROUND): New loop invariants T0-T3, to + avoid the additions of the AES_TABLEx constants in the inner loop. + + * sparc/machine.m4 (AES_ROUND): Better scheduling, by + interleaving independent operations. + + * sparc/machine.m4 (AES_ROUND): Alternate between using TMP1 and + TMP2, to prepare for scheduling. + + * sparc/aes-encrypt-internal.asm: Renamed Ti -> Xi. + + * sparc/aes-encrypt-internal.asm: Fixed bugs. Now passes the + testsuite. + + * sparc/machine.m4 (AES_ROUND, AES_FINAL_ROUND): Bugfixes. Put + NOPs in the load dely slots. + + * sparc/aes-encrypt-internal.asm: Implemented. Not yet working, + and not optimized. + + * sparc/machine.m4: Use TMP1 and TMP2, so we don't need to pass + them as arguments. + (AES_FINAL_ROUND): New macro. + +2005-10-15 Niels Möller + + * configure.ac (OBJDUMP): Substitute the program false if objdump + is not found. + + * asm.m4 (PROLOGUE): Use TYPE_FUNCTION. + + * config.m4.in: Substitute ASM_TYPE_FUNCTION as TYPE_FUNCTION. + + * configure.ac (ASM_ELF_STYLE): Check for %function and #function, + but not for @function. + (ASM_TYPE_FUNCTION): New substituted variable. + + * configure.ac (ASM_ELF_STYLE): Fixed .type foo,@function statement + used when checking for pseudo operations. + + * sparc/machine.m4 (AES_LOAD, AES_ROUND): Started writing new AES + macros. + + * sparc/aes-encrypt-internal.asm: New file. + +2005-10-14 Niels Möller + + * x86/aes-decrypt.asm, x86/aes-encrypt.asm: Deleted files. + + * x86/aes-decrypt-internal.asm: New file. + + * x86/machine.m4: Changed AES macros, to handle a table register. + Also take more of the used registers as argument. + + * x86/aes-encrypt-internal.asm: Rewritten to match new interface, + with the table pointer as an argument. Unlike the old code, this + should really be position independent. + + * configure.ac: When looking for assembler files, link in + aes-encrypt-internal.asm and aes-decrypt-internal.asm. Don't look + for aes.asm, aes-encrypt.asm and aes-decrypt.asm. + + * configure.ac (OBJDUMP): Use AC_CHECK_TOOL to check for objdump. + (ASM_MARK_NOEXEC_STACK): Use $OBJDUMP when examining the object file. + + * Makefile.in (nettle_SOURCES): Removed aes.c, + aes-decrypt-table.c. Added aes-decrypt-internal.c and aes-encrypt-internal.c. + + * aes.c, aes-decrypt-table.c: Deleted files. + + * aes-decrypt.c (_aes_decrypt_table): Moved table here, and made + static. + + * aes-internal.h (_aes_decrypt_table): Don't declare, it's no + longer globally visible. + + * aes-decrypt-internal.c (_nettle_aes_decrypt): New AES decryption + function, analogous to _nettle_aes_encrypt. + +2005-10-14 Niels Möller + + * aes-internal.h (AES_ROUND, AES_FINAL_ROUND): New macros. + + * aes-encrypt-internal.c (_nettle_aes_encrypt): New AES encryption + function, avoiding the table-based indexing. + + * sha1-compress.c: Added debugging code. + * md5-compress.c: Likewise. + +2005-10-13 Niels Möller + + * config.m4.in (ASM_MARK_NOEXEC_STACK): Use a diversion, to + substitute the value of ASM_MARK_NOEXEC_STACK at the end of each + assembler file. + + * configure.ac (ASM_MARK_NOEXEC_STACK): Check if the C compiler + generates a .note.GNU-stack section. If so, we should do the same + in our assembler files. + + * sparc64/aes.asm: New file. Copy of sparc/aes.asm, with minor + changes to the stack frame layout. Patch contributed by Henrik + Grubbström. Not yet tested. + + * x86/md5-compress.asm: Skip copying of input to the stack, and + don't allocate space for it. + (F1): Fixed bug. + + * testsuite/md5-test.c: Document intermediate values for first + test case. + + * configure.ac (asm_path): Check for sparc64, and use sparc64 + subdirectory. Link in md5-compress.asm, if it exists. + +2005-10-13 Niels Möller + + * x86/md5-compress.asm (REF): Fixed calculation of offset. + +2005-10-12 Niels Möller + + * x86/machine.m4 (OFFSET): Moved macro, used to be in... + * x86/sha1-compress.asm (OFFSET): ... removed macro. + + * x86/md5-compress.asm: New file, with first attempt at md5 + assembler. Not yet working. + +2005-10-11 Niels Möller + + * Makefile.in (nettle_SOURCES): Added md5-compress.c. + + * md5.c: Reorganized to use _nettle_md5_compress, in analogy with + sha1.c. + + * md5-compress.c (_nettle_md5_compress): New file and new function. + +2005-10-10 Niels Möller + + * testsuite/Makefile.in (EXTRA_SOURCES, EXTRA_TARGETS): New + variables, for test cases that are not run by default. + + * testsuite/sha1-huge-test.c (test_main): New test case, with a + very large sha1 input. + + * testsuite/testutils.c (test_hash_large): New function. + + * sha1.c (sha1_block): Deleted function; inlined where used. + (SHA1_INCR): New macro for incrementing the block count. + +2005-10-06 Niels Möller + + * configure.ac: Bumped version to 1.14. + + * Released nettle-1.13. + + * configure.ac: Check for openssl/aes.h. + + * Makefile.in (distdir): Use a loop to pick up the contents of + $(DISTFILES) from source and build directories. For some reason, + $? failed to find stamp-h.in in the source directory. + +2005-10-05 Niels Möller + + * x86/aes-decrypt.asm: Use C_NAME(_nettle_aes_decrypt_table) when + using the AES_SUBST_BYTE macro. Use PROLOGUE and EPILOGUE. + * x86/sha1-compress.asm: Use PROLOGUE and EPILOGUE. + * x86/arcfour-crypt.asm: Likewise. + * x86/aes-encrypt.asm: Likewise. + + * config.m4.in (ELF_STYLE): Substitute configure's ASM_ELF_STYLE. + + * asm.m4 (PROLOGUE, EPILOGUE): New macros, checking the value of + ELF_STYLE. So far, used and tested only for the x86 assembler + files, and needed to make the assembler happy both with ELF + (linux, solaris) and COFF (windows). + + * configure.ac (NM): Use AC_CHECK_TOOL to check for nm. + (ASM_SYMBOL_PREFIX): Use $NM when examining the object file. + (ASM_ELF_STYLE): New variable. Set to 'yes' if assembling a file + with ELF-style .type and .size pseudo ops works. + + * Makefile.in (TARGETS, DISTFILES): Added nettle.pdf. + (.texinfo.dvi, .dvi.ps, .ps.pdf): New targets, to build nettle.pdf. + (DOCTARGETS): New variable with targets that shouldn't be deleted + by make clean. + (maintainer-clean-here): New target. Deletes generated + documentation files. + + * nettle.texinfo: Define AUTHOR with accents, when running in TeX + mode, which doesn't handle latin-1 properly. Set UPDATED-FOR to + 1.13. Updated copyright years, and introduced a COPYRIGHT-YEARS + symbol. Updated copyright section, to mention assembler + implementations. + (Cipher modes): Transformed the Cipher Block Chaining to a section + Cipher modes, describing both CBC and the new CTR mode. + + * src/nettle/x86/aes_tables.asm: Deleted unused file. + + * x86/aes.asm: Deleted contents. This file is needed just to + override aes.c, which isn't needed for the x86 implementation. + + * configure.ac (SHLIBMINOR): Increased minor number. Library + version is now libnettle.so.2.4, soname still libnettle.so.2. + + * examples/nettle-benchmark.c (main): Reordered hash benchmarks. + + * x86/sha1-compress.asm (EXPAND): Use % 16 instead of & 15 to + compute offsets mod 16, since m4 on FreeBSD 49.RELEASE and NetBSD + doesn't implement & correctly in eval. + +2005-10-03 Niels Möller + + * x86/sha1-compress.asm (OFFSET): New macro. + (F3): Eliminated a movl. + (ROUND): New argument, for k. When using F3, it's TMP3, on the + stack, otherwise, it is kept in TMP2, a register. + +2005-10-03 Niels Möller + + * examples/nettle-openssl.c: Use correct block sizes for openssl + ciphers. + + * examples/nettle-benchmark.c: Also display cycles per block. + +2005-10-02 Niels Möller + + * sha1-compress.c (_nettle_sha1_compress): Updated to new + interface. Now responsible for byte conversion. + + * x86/sha1-compress.asm (_nettle_sha1_compress): Do byte order + conversion, and store the input data on the stack. This leaves one + more register free for other uses. + + * examples/nettle-benchmark.c: Now display cycles/byte, if the -f + option is used to say what the clock frequency is. + + * sha1.c (sha1_block): Don't convert data from uint8_t to + uint32_t, that's now the responsibility of _nettle_sha1_compress. + + * sha.h (_nettle_sha1_compress): Changed interface. Second + argument is now a pointer to the input data in unaligned, + big-endian form. + +2005-09-28 Niels Möller + + * sha1.c (sha1_final): Call sha1_block, don't call the compression + function _nettle_sha1_compress directly. + + * nettle-internal.h (nettle_openssl_md5) + (nettle_openssl_sha1): Declare. + + * examples/nettle-benchmark.c (main): Benchmark openssl md5 and + sha1. + + * examples/nettle-openssl.c (nettle_openssl_md5) + (nettle_openssl_sha1): Added glue for openssl hash functions. + + * nettle-internal.h (nettle_openssl_aes128, nettle_openssl_aes192) + (nettle_openssl_aes256, nettle_openssl_arcfour128): Declare. + + * examples/nettle-benchmark.c: Check WITH_OPENSSL, not + HAVE_LIBCRYPTO. Benchmark openssl's aes and arcfour code. + + * examples/nettle-openssl.c: Updated openssl des glue to use the + new openssl des interface. Added glue for arcfour and aes. + +2005-09-27 Niels Möller + + * nettle.texinfo (RSA): Improved text about the RSA patent. + Use @documentencoding ISO-8859-1. + +2005-09-07 Niels Möller + + * tools/sexp-conv.c (parse_options): New option --raw-hash, for + compatibility with lsh-1.x. Equivalent to --hash. + +2005-09-06 Niels Möller + + * tools/sexp-conv.c (main): With --hash, output a newline after + each hash. + +2005-07-02 Niels Möller + + * testsuite/Makefile.in (TS_SOURCES): Added ctr-test.c. + + * testsuite/testutils.c (test_cipher_ctr): New function. + + * testsuite/ctr-test.c: New file. + + * testsuite/cbc-test.c (test_main): Use static const for msg. + + * Makefile.in (nettle_SOURCES): Added ctr.c. + (HEADERS): Added ctr.h. + (HEADERS): Added nettle-types.h. + (INSTALL_HEADERS): Install nettle-stdint.h. + (distclean-here): Delete nettle-stdint.h, not nettle-types.h. + + * ctr.c (ctr_crypt): New file, new function. + + * memxor.c (memxor3): New function, suggested by Adam Langley. + + * nettle-internal.h (NETTLE_MAX_CIPHER_BLOCK_SIZE): New constant. + + * nettle.texinfo (Cipher functions): Fixed typo in prototype for + arctwo_encrypt (noticed by Adam Langley). + + * nettle-meta.h: No longer needs to include cbc.h. + + * cbc.h (nettle_crypt_func): Moved typedef to nettle-types.h. + (CBC_ENCRYPT, CBC_DECRYPT): Deleted older #if:ed out versions. + + * configure.ac (AX_CREATE_STDINT_H): Use the file name + nettle-stdint.h, not nettle-types.h. + + * nettle-types.h: New file. Automatically generated declarations + are now in nettle-stdint.h. + +2005-03-17 Niels Möller + + * config.guess: Support Solaris on x86_64. Fix by Henrik + Grubbström. + +2005-01-03 Niels Möller + + * examples/io.h: Include RSA declarations only when public key + algorithms are enabled. Problem reported by Meilof Veeningen + . + +2004-12-07 Niels Möller + + * Makefile.in: Install directories, using $(INSTALL) -d, only if + they don't exist already. + +2004-12-05 Niels Möller + + * config.make.in (.PRECIOUS): Reverted earlier change. We need + .PRECIOUS to stop GNU make from deleting object files for the test + programs. + +2004-12-02 Niels Möller + + * Makefile.in (.SUFFIXES): Moved from Makefile.in to... + * config.make.in (.SUFFIXES): ... here. This helps compilation + with BSD make. + * testsuite/Makefile.in (.SUFFIXES): Deleted target. + + * config.make.in (.c): Disable default rule for BSD-make. + + * Makefile.in (all check install uninstall) + (clean distclean mostlyclean maintainer-clean): Don't use the -C + flag when invoking make, for compatibility with Solaris make. + +2004-12-02 Niels Möller + + * Makefile.in (aesdata, desdata): Commented out the explicit + targets. + (shadata): Avoid using $< in non-pattern rule. + +2004-12-01 Niels Möller + + * config.make.in: Added a default target. + +2004-11-29 Niels Möller + + * testsuite/Makefile.in: Use .$(OBJEXT). Explicitly set .SUFFIXES. + + * Makefile.in: Use .$(OBJEXT). + +2004-11-28 Niels Möller + + * tools/Makefile.in (nettle-lfib-stream): Avoid using $< in + non-suffix rule. + + * Makefile.in (distdir): Handle absolute $distdir. + Avoid using the GNU extension $^. + + * examples/Makefile.in: Avoid using the GNU extension $^. + * tools/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2004-11-24 Niels Möller + + * configure.ac: Fixed typo, preventing the creation of dependency + files. + +2004-11-23 Niels Möller + + * Makefile.in: Use DEP_INCLUDE. + * tools/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * examples/Makefile.in: Likewise. + + * configure.ac (dummy-dep-files): Generate only of dependency + tracking is enabled. + +2004-11-18 Niels Möller + + * Makefile.in (clean-here): The clean target should not delete the + dependency files. Moved to the distclean target. + * examples/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * tools/Makefile.in: Likewise. + + * configure.ac (ASM_SYMBOL_PREFIX): Fixed test. + (dummy-dep-files): Added quotes to sed command. + +2004-11-17 Niels Möller + + * testsuite/symbols-test: Try plain nm if nm -g doesn't work. + + * x86/sha1-compress.asm: Use C_NAME for global symbols. + * x86/aes-encrypt.asm: Likewise. + * x86/aes-decrypt.asm: Likewise. + * x86/arcfour-crypt.asm: Likewise. + + * Makefile.in (config.m4): New rule. + + * config.m4.in (C_NAME): New macro. + + * configure.ac (ASM_SYMBOL_PREFIX): Check if global symbols have a + leading underscore. + +2004-11-16 Niels Möller + + * Deleted getopt.c, getopt.h and getopt1.c from the CVS tree. Link + them from shared copies in lsh/misc instead. + +2004-11-14 Niels Möller + + * Makefile.in (DEP_FILES): Try include with only one macro + argument to be expanted. + + * configure.ac (dummy-dep-files): Create dummy dependency files, + so that they can be included by the makefiles. + +2004-11-13 Niels Möller + + * Makefile.in: Don't use -include, as it's GNU make specific. + * examples/Makefile.in, tools/Makefile.in, testsuite/Makefile.in: + Likewise. + + * examples/nettle-openssl.c: Check WITH_OPENSSL, not HAVE_LIBCRYPTO. + + * configure.ac: Check for individual openssl headers blowfish.h, + cast.h, des.h. Renamed symbol HAVE_LIBCRYPTO to WITH_OPENSSL. New + configure option --disable-openssl. + +2004-11-04 Niels Möller + + * configure.ac: Bumped version to 1.13. + + * Released nettle-1.12. + +2004-11-04 Niels Möller + + * nettle.texinfo (UPDATED-FOR): Bumped to 1.12. + +2004-11-02 Niels Möller + + * nettle.texinfo (Cipher functions): Updated AES documentation, + for aes_set_encrypt_key and aes_set_decrypt_key. + (UPDATED-FOR): Set to 1.11. I think the manual should be updated + with all user-visible changes. + + * aclocal.m4 (LSH_DEPENDENCY_TRACKING): Need extra quoting in case + pattern. (This file really lives in the lsh tree, as + lsh/acinclude.m4. For a complete ChangeLog, see lsh/Changelog). + +2004-10-26 Niels Möller + + * configure.ac: Bumped version to 1.12. + + * Released nettle-1.11. + + * Makefile.in (clean-here): Delete *.s files. + (PRE_CPPFLAGS): Use this variable, not INCLUDES. Removed + -I$(srcdir). + + * x86/arcfour-crypt.asm: Use movzbl when extending %cl to 32 bits. + +2004-10-24 Niels Möller + + * x86/arcfour-crypt.asm: Reverted the latest two changes; update + bost src and dst pointers in the loop, and use plain addb when + updating j. These two previous changes slowed the code down on AMD + Duron. + +2004-10-21 Niels Möller + + * Makefile.in (install-shared): Use $(INSTALL_PROGRAM). + + * configure.ac (SHLIBMINOR): Updated, shared library version is + now libnettle.so.2.3, soname still libnettle.so.2. + + * Makefile.in (DISTFILES): Added asm.m4. + +2004-10-21 Niels Möller + + * examples/Makefile.in: Deleted all configure-related rules, + except the one rebuilding this Makefile. One should run make at + top level if other configure related files change. + * tools/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + + * configure.ac: Replaced AC_OUTPUT(list...) with an AC_OUTPUT + without arguments, and AC_CONFIG_FILES listing the files. + + * Makefile.in: Changed the assembler rules as suffix rules. + Rewrote the configure-related rules, mostly based on the example + in the autoconf manual. + +2004-10-20 Niels Möller + + * examples/nettle-openssl.c (NCOMPAT): Disable openssl backwards + compatibility. + + * config.make.in: Insert $(PRE_CPPFLAGS) and $(PRE_LDFLAGS) before + $(CPPFLAGS) and $(LDFLAGS). This mechanism replaces $(INCLUDES). + + * examples/Makefile.in (PRE_CPPFLAGS, PRE_LDFLAGS): Use these + flags to get -I.. and -L.. early on the command line. + * testsuite/Makefile.in: Likewise + * tools/Makefile.in: Likewise. + +2004-10-20 Niels Möller + + * Makefile.in: In the assembler rules, there's no need to look in + $(srcdir) for the input file. + + * x86/arcfour-crypt.asm: Reduced inner loop by one instruction, by + precomputing the offset between src and dst. + + * tools/Makefile.in (.c.$(OBJEXT)): Removed redundant -I.. flag. + + * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Replaced addb -> + addl + andl $0xff, improving speed on PPro by another 15%. + +2004-10-20 Niels Möller + + * tools/Makefile.in (install): Support DESTDIR. + (uninstall): New target. + + * testsuite/Makefile.in (uninstall): New dummy target. + + * config.sub: Copied from automake-1.8.5. + + * examples/Makefile.in (SOURCES): Added rsa-sign.c and rsa-verify.c. + (DISTFILES): Added getopt.h. + (install uninstall): New dummy targets. + + * config.make.in (.PHONY): Added more targets. + + * Makefile.in (.texinfo.info, .texinfo.html): New targets. Added + support for uninstall and DESTDIR. Various fixes to install and + distcheck. + + * examples/Makefile.in (INCLUDES): Added -I flags. + (distdir): Use $^ to refer to the files. + (distclean): New target. + * testsuite/Makefile.in: Likewise. + * tools/Makefile.in: Likewise. + + * Makefile.in (INCLUDES): Need -I flags for VPATH build. + (clean distclean mostlyclean maintainer-clean): Clean + subdirectories first. + (DISTFILES): Added a bunch of files. + (des_headers): Added desCore rules. + (install-here): Split off target install-headers, which uses $^ to + refer to the files. + (distdir): Use $^ to refer to the files. + distcheck): Fixes. + + * config.make.in (COMPILE): Add $(INCLUDE) to the line. + +2004-10-19 Niels Möller + + Stop using automake. Replaced each Makefile.am with a hand-written + Makefile.in. + * configure.ac: New output variable CCPIC_MAYBE. New output file + config.make. Replaced automake constructions. + * .bootstrap: Don't run aclocal and automake. + * config.make.in: New file, with shared Makefile variables and rules. + +2004-10-18 Niels Möller + + * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Replace incb -> + incl + andl, to improve speed on PPro and PII. Suggested by + Fredrik Olsson. + +2004-10-08 Niels Möller + + * examples/rsa-encrypt-test: Avoid reading and executing a file at + the same time. + * examples/setup-env: Likewise. + +2004-10-06 Niels Möller + + * testsuite/symbols-test: Ignore __i686.get_pc_thunk.bx and + similar symbols. + +2004-10-05 Niels Möller + + * twofish.c (q_table): Use a const pointer array. + + * sexp2dsa.c (dsa_keypair_from_sexp_alist): Use a const pointer + array for the keywords. + (dsa_signature_from_sexp): Likewise. + * sexp2rsa.c (rsa_keypair_from_sexp_alist): Likewise. + (rsa_keypair_from_sexp): Likewise. + + * sexp.c (sexp_iterator_check_types): Use an argument of type + "const uint8_t * const *" for the types list. + (sexp_iterator_assoc): Likewise, for the keys list. + + * list-obj-sizes.awk: Fixes to handle multiple .data and .rodata + sections. Also fixed to handle the last file correctly. + +2004-09-23 Niels Möller + + * configure.ac (SHLIBLINK, SHLIBLIBS): On cygwin, linking needs + -Wl,--whole-archive $(OBJECTS) -Wl,--no-whole-archive $(LIBS). + +2004-09-22 Niels Möller + + * configure.ac: Setup SHLIBFORLINK and friends for cygwin. + + * list-obj-sizes.awk: Strip *_a-prefix from all file names. + + * Makefile.am (libnettle_a_SOURCES): List only .c files. Headers + moved to noinst_HEADERS. + (SHLIBOBJECTS): Substitute from libnettle_a_SOURCES, not + am_libnettle_a_OBJECTS, since the latter includes + libnettle_a-prefixes with some automake versions. + (SHLIBSONAME): Check if this name is empty, which is the case on + cygwin, before using it. + +2004-08-31 Niels Möller + + * configure.ac: New command line option --disable-pic. Use + LSH_CCPIC. + + * Makefile.am (libnettle_a_CFLAGS): Added $(CCPIC), to attempt to + build also the static library as position independent code. + +2004-08-24 Niels Möller + + * des-compat.c (des_cbc_cksum): Pad input with NUL's, if it's not + an integral number of blocks. + +2004-08-24 Niels Möller + + * testsuite/arctwo-test.c, arctwo.h, arctwo.c + (arctwo_set_key_ekb): Fixed typo; it should be "ekb", not "ebk". + + Integrated arctwo patch from Simon Josefsson. + * testsuite/Makefile.am (noinst_PROGRAMS): Added arctwo-test. + + * Makefile.am (libnettleinclude_HEADERS): Added arctwo.h. + (libnettle_a_SOURCES): Added arctwo.c, arctwo.h and arctwo-meta.c. + + * nettle-meta.h (nettle_arctwo40, nettle_arctwo64) + (nettle_arctwo64, nettle_arctwo_gutmann128): Declare ciphers. + + * arctwo-meta.c, arctwo.c, arctwo.h, testsuite/arctwo-test.c: New + files. + + * macros.h (LE_READ_UINT16, LE_WRITE_UINT16): New macros. + +2004-08-23 Niels Möller + + * testsuite/md5-test.c (test_main): Added collision, found in 2004. + (test_main): Added second collision. + +2004-08-23 Niels Möller + + * testsuite/md5-test.c (test_main): Added first half of a + collision test case. + + * des-compat.c (des_cbc_cksum): Changed input argument to be of + type const uint8_t * (was const des_cblock *). + + * des-compat.h (const_des_cblock): New bogus type. Disabled use of + const, for compatibility with openssl. + +2004-06-08 Niels Möller + + * aesdata.c: Renamed log and ilog to gf2_log and gf2_exp. + +2004-04-07 Niels Möller + + * aes-set-encrypt-key.c (log, ilog): Deleted unused tables. + + * aes-set-decrypt-key.c (gf2_log, gf2_exp, mult): Renamed tables, + were log and ilog. + +2004-03-20 Niels Möller + + * configure.ac: Use AC_CONFIG_AUX_DIR([.]). + +2004-03-18 Niels Möller + + * examples/io.c (read_file): Display a message if fopen fails. + +2004-03-05 Niels Möller + + * Released nettle-1.10. + + * configure.ac (SHLIBMINOR): Shared library version is now 2.2. + +2004-03-04 Niels Möller + + * testsuite/symbols-test: Pass -g flag to nm. + +2004-03-02 Niels Möller + + * configure.ac: Fixed EXEEXT workaround. + +2004-03-02 Niels Möller + + * configure.ac: Added workaround to get the correct $(EXEEXT)='' + when compiling with rntcl. + +2004-03-02 Niels Möller + + * testsuite/Makefile.am (noinst_PROGRAMS): Put test program list + here, to let automake add $(EXEEXT). + + * configure.ac (RSA_EXAMPLES): Append $(EXEEXT) to the filenames. + +2004-03-01 Niels Möller + + * examples/rsa-keygen.c, examples/rsa-encrypt.c, + examples/rsa-decrypt.c: Include "getopt.h" instead of . + + * examples/Makefile.am (rsa_encrypt_SOURCES, rsa_decrypt_SOURCES) + (rsa_keygen_SOURCES): Added getopt.h, getopt.c and getopt1.c. + + * examples/getopt.h, examples/getopt.c, examples/getopt1.c: New + files. + + * testsuite/des-compat-test.c: Don't include . + + * testsuite/testutils.c (main): Don't use getopt. Then we don't + need to include . + +2004-03-01 Niels Möller + + * config.guess: Copied from automake-1.8.2. Hacked to recognize + Windows_NT (and Windows_95 and Windows_98) running on "x86" and + "686". + + * install-sh: Removed from CVS repository. Let automake supply it. + +2004-02-26 Niels Möller + + * nettle-meta.h (nettle_crypt_func): Typedef moved to cbc.h. + Include cbc.h instead. + + * des-compat.c: Reverted const change, now all the des_key_sched + arguments are not const. This is also what openssl's interface + looks like. + (cbc_crypt_func): Deleted typedef, use nettle_crypt_func instead. + + * cbc.h (nettle_crypt_func): Moved typedef here. + * cbc.c (cbc_encrypt, cbc_decrypt_internal, cbc_decrypt): Use it + for typing the f argument. Reverted the const change, for + compatibility with nettle_crypt_func. + +2004-02-25 Niels Möller + + * testsuite/des-compat-test.c: Use des_cblock for typing more of + the variables. Use const. Got rid of most of the explicit casts. + Disabled the input/output alignment tests. + + * des.c (des_encrypt, des_decrypt): Use a const context pointer. + * des3.c (des3_encrypt, des3_decrypt): Likewise. + + * cbc.c (cbc_encrypt, cbc_decrypt): Use a _const_ void *ctx argument. + + * des-compat.c: Use const for all unchanged arguments. + (des_key_sched): Use a copy of the key if we need to fix the + parity. + + * testsuite/des-compat-test.c (C_Block, Key_schedule): Deleted + defines. Deleted some of the explicit casts. + + * des-compat.c (des_cbc_cksum): Dereference DST pointer. + +2004-02-25 Niels Möller + + * pgp.h: Include nettle-types.h. + +2004-02-24 Niels Möller + + * testsuite/symbols-test: Allow symbols starting with double + underscores, like on darwin. + +2004-02-17 Niels Möller + + * Makefile.am: Protected %-rules used for building pure objects, + and for assembler files, by automake conditionals. Needed for + makes such as tru64's, which tries to understand %-patterns, but + doesn't get it right. + (SUFFIXES): Added .html. + (.texinfo.html): Rewrote rule to use a traditional suffix target. + + * configure.ac (enable_assembler): Explicitly set + enable_assembler=no, on architectures where we have no assembler + files. + (ENABLE_ASSEMBLER, ENABLE_SHARED): New automake conditionals. + + * testsuite/testutils.c (xalloc): xalloc(0) should work also on + systems where malloc(0) returns NULL. + +2004-02-16 Niels Möller + + * Makefile.am (%.o: %.asm): Added comment about OSF1 make problem. + +2004-02-15 Niels Möller + + * testsuite/testutils.h: #include nettle-types.h instead of + inttypes.h. + +2004-02-12 Niels Möller + + * examples/rsa-encrypt-test: Use -r option when invoking + rsa-encrypt. Needed for the test to work on systems with no + /dev/urandom. + +2004-02-12 Niels Möller + + * configure.ac (CPPFLAGS, LDFLAGS): No spaces after -I and -L, as + some C compilers, in particular True64 cc, don't like that. + +2004-02-08 Niels Möller + + * configure.ac: Bumped version number to 1.10. + +2004-02-07 Niels Möller + + * Released nettle-1.9. + + * configure.ac (SHLIBMINOR): Bumped, library version is now 2.1. + + * testsuite/sexp-format-test.c: Include bignum.h only if HAVE_LIBGMP. + * testsuite/rsa-encrypt-test.c: Include rsa.h only if WITH_PUBLIC_KEY. + * testsuite/pkcs1-test.c: Include pkcs1.h only if WITH_PUBLIC_KEY. + + * pgp-encode.c [!HAVE_LIBGMP]: Kludge around the pgp.h's + dependency on gmp.h. + (pgp_put_mpi): Condition on HAVE_LIBGMP. + + * pgp.h: Don't include bignum.h, to make it possible to compile + the non-bignum parts of pgp-encode.c without bignum support. Needs + to be fixed properly before the pgp interface is advertised. + + * tools/sexp-conv.c (xalloc): New function. + (main): Use xalloc. + + * tools/output.c (sexp_put_digest): Use TMP_DECL instead of alloca. + + * testsuite/testutils.c (xalloc): New function. Made all other + functions use xalloc instead of alloca. + + * examples/rsa-keygen.c (main): Use xalloc for allocation. + * examples/rsa-encrypt.c (write_bignum): Likewise. + * examples/rsa-decrypt.c (read_bignum): Likewise. + * testsuite/yarrow-test.c (open_file): Likewise. + * testsuite/rsa-encrypt-test.c (test_main): Likewise. + * testsuite/bignum-test.c (test_bignum): Likewise. + + * examples/nettle-openssl.c: When calling des_key_sched and + des_ecb_encrypt, cst arguments to (void *). Openssl's typedefs + des_cblock and const_des_cblock are too broken. + + * examples/nettle-benchmark.c (xalloc): New function. Use instead + of alloca, for better portability. + + * examples/io.c (xalloc): New function. + + * Makefile.am (nodist_libnettleinclude_HEADERS): nettle-types.h + should not be distributed. + +2004-02-06 Niels Möller + + * x86/sha1-compress.asm: Rename round -> ROUND. + + * x86/sha1-compress.asm: Store the magic constants on stack. + Accessing them via %esp should be a little faster than using large + immediate operands. + + * Makefile.am (EXTRA_DIST, DISTCLEANFILES): Handle + sha1-compress.asm. + + * configure.ac: Use assembler file sha1-compress.asm if available. + + * x86/sha1-compress.asm (EXPAND): Fixed the rotation part of the + data expansion. + +2004-02-06 Niels Möller + + * x86/sha1-compress.asm: Assembler implementation of + sha1_compress. (Not yet working). + + * Makefile.am (libnettle_a_SOURCES): Added sha1-compress.c. + + * sha1.c (sha1_transform): Function renamed to sha1_compress, and + moved to... + * sha1-compress.c: ... New file. + +2004-02-05 Niels Möller + + * examples/rsa-encrypt.c (process_file): Copy the leftover to the + start of the buffer, when preparing for the final processing. + + * examples/nettle-benchmark.c (bench_hash, time_hash): New functions. + (main): Benchmark hash functions too. + (BENCH_BLOCK): Increased 10K. + (BENCH_INTERVAL): Decreased to 0.25s. + + * examples/nettle-benchmark.c (time_function): Loop around calling + f, until 1s has elapsed. Returns seconds per call. Updated bench + functions to not loop themselves. + (display): Updated MB/s calculation. + + * testsuite/arcfour-test.c (test_main): Use test_cipher_stream. + + * testsuite/testutils.c (test_cipher_stream): New function, that + tries dividing the input into varying size blocks before + processing. + + * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Bug fix, half of + the S array swap was forgotten. + * arcfour.c (arcfour_stream): Likewise. + * arcfour-crypt.c (arcfour_crypt): Likewise. + +2004-02-05 Niels Möller + + * x86/arcfour-crypt.asm (nettle_arcfour_crypt): Must store the new + i, j at the end of the loop. + + * Makefile.am (EXTRA_DIST): Make sure x86 assembler files are + distributed. + (DISTCLEANFILES): And that the symlinks and .s files are deleted. + + * x86/aes-encrypt.asm, x86/aes-decrypt.asm, x86/arcfour-crypt.asm: + Fixed debug information. + + * x86/arcfour-crypt.asm: New file. About three times faster than + the optimized C code. + + * configure.ac: Use assembler file arcfour-crypt.asm if available. + + * arcfour.c (arcfour_crypt): Moved function too... + * arcfour-crypt.c (arcfour_crypt): New file. + + * arcfour.c (arcfour_crypt): Optimization suggested by Jonas + Walldén. Makes arcfour up to 50% faster on x86 and ppc, and + probably on other architectures as well. + +2004-01-31 Niels Möller + + * configure.ac (AX_CREATE_STDINT_H): Also look for uint32_t and + friends in sys/types.h. + +2004-01-11 Niels Möller + + * Makefile.am (libnettleinclude_HEADERS): Added bignum.h, + memxor.h, pkcs1.h and rsa-compat.h. + + * configure.ac: Bumped version to 1.9. + +2004-01-10 Niels Möller + + * Released nettle-1.8. + + * examples/teardown-env: Delete more test files. + + * nettle.texinfo (Hash functions): Documented md2 and md4. + + * configure.ac (SHLIBMAJOR): Bumped to 2. + +2004-01-09 Niels Möller + + * examples/rsa-encrypt-test: New testcase. + + * examples/rsa-encrypt.c, examples/rsa-session.h: Expanded the + comment describing the file format, and moved to rsa-session.h. + + * examples/rsa-decrypt.c (process_file): Finished this function. + (main): Initialize x. Check the size of the session key after rsa + decryption. + + * examples/io.c (write_string): Treat short item count as an error. + +2004-01-08 Niels Möller + + * index.html: Added instructions for CVS access. + + * dsa-keygen.c (dsa_nist_gen): Fixed declaration/statement order. + + * rsa-keygen.c (bignum_next_prime): Fixed off-by-one error when + comparing input to the largest listed prime. General cleanup, as + prime_limit > 0 always. Use TMP_DECL and TMP_ALLOC. + + * nettle-internal.h (TMP_DECL, TMP_ALLOC): New macros. When alloca + is unavailable, they work by allocating a fix amount of stack and + imposing a hard limit on what can be allocated. Updated all users + of alloca. + +2004-01-07 Niels Möller + + * nettle-types.h: New (generated) file, to be used instead of + including directly. Updated all users of inttypes.h. + + * Makefile.am (DISTCLEANFILES, libnettleinclude_HEADERS): Added + nettle-types.h. + + * configure.ac (AX_CREATE_STDINT_H): Create nettle-types.h. + +2003-11-16 Niels Möller + + * yarrow256.c (yarrow256_seed): Use const for the seed_file input. + +2003-11-12 Niels Möller + + * list-obj-sizes.awk: New function for decoding hex values, with a + new function hex2int. Also implemented calculation of total + storage, removed the dependence on the .comment section, and use + the $FILTER environment variable as a regexp for restricting the + object files that are considered. + +2003-09-21 Niels Möller + + * testsuite/rsa-encrypt-test.c (test_main): Don't use gmp_printf, + as it seems it's only available with the newer gmp. Use + mpz_out_str instead. + +2003-09-19 Niels Möller + + * examples/Makefile.am (EXTRA_DIST): Added rsa-session.h. + + * tools/nettle-lfib-stream.c: New tool, which outputs a sequence + of pseudorandom (non-cryptographic) bytes, using Knuth's lagged + fibonacci generator. + + * examples/rsa-decrypt.c: Fixes to get the file to compile. It + won't work yet. + + * examples/Makefile.am (EXTRA_PROGRAMS): Added rsa-encrypt and + rsa-decrypt. + + * examples/io.c (write_file): New function. + (write_string): Simplified error check, it's no real point in + calling ferror unless we also call fflush. + + * examples/rsa-keygen.c (main): Check return value from + simple_random. + + * examples/rsa-decrypt.c, examples/rsa-encrypt.c, + examples/rsa-session.h: New files, demonstrating rsa encryption + and decryption. + + * configure.ac (RSA_EXAMPLES): Added rsa-encrypt and rsa-decrypt. + +2003-09-01 Niels Möller + + * testsuite/testutils.c (print_hex): Use const. + +2003-08-30 Niels Möller + + * md2.c, md2.h: Added reference to RFC 1319. + * md4.c, md4.h: Added reference to RFC 1320 + +2003-08-26 Niels Möller + + * Makefile.am: Added md2 and md5 files. Deleted the print-path + hack. + + * configure.ac: Bumped version to 1.8. + + * testsuite/testutils.c (test_rsa_set_key_1): New function. + * testsuite/rsa-test.c (test_main): Use it. + + * testsuite/dsa-keygen-test.c: Deleted definition of UNUSED, it's + now in config.h. + * testsuite/rsa-keygen-test.c: Likewise. + + * testsuite/Makefile.am (TS_PROGS): Added rsa-encrypt-test, + md4-test, and md2-test. + + * testsuite/rsa-encrypt-test.c, testsuite/md4-test.c, + testsuite/md2-test.c: New test cases. + + * nettle-meta.h: Declare nettle_md2 and nettle_md4. + + * md5.c: Reorderd functions, putting md5_final at the end. + + * md2.c, md2.h, md2-meta.c: New files, implemented md2. + * md4.c, md4.h, md4-meta.c: New files, implemented md4. + +2003-08-17 Niels Möller + + * desCode.h (des_keymap, des_bigmap): Deleted extern declarations, + they conficted with the static definition in des.c. Reported by + Simon Josefsson. + + * des.c (DesSmallFipsEncrypt, DesSmallFipsDecrypt): Moved + definitions after the definition of the des_kemap array. + +2003-08-11 Niels Möller + + * rsa-encrypt.c (rsa_encrypt): Bugfix contributed by + leg@terra.com.br. + +2003-06-10 Niels Möller + + * Makefile.am (EXTRA_DIST): Distribute sha-example.c. + +2003-06-05 Niels Möller + + * Makefile.am (DISTCLEANFILES): Delete .s files. + +2003-05-27 Niels Möller + + * testsuite/symbols-test: And allow symbols that start at the + beginning of the line, as output by AIX nm. + +2003-05-26 Niels Möller + + * testsuite/symbols-test: Allow symbols to start with a dot. + +2003-05-14 Niels Möller + + * pgp.h (enum pgp_subpacket_tag): Copied values from RFC 2440. + Renamed PGP_SUBPACKET_ISSUER to PGP_SUBPACKET_ISSUER_KEY_ID. + +2003-05-13 Niels Möller + + * pgp.h: Do proper namemangling for pgp_put_public_rsa_key and + pgp_put_rsa_sha1_signature. + + * pgp-encode.c (pgp_put_mpi): Fixed nettle_mpz_get_str_256 call. + +2003-05-12 Niels Möller + + * rsa2openpgp.c (rsa_keypair_to_openpgp): Some bugfixes. + + * pgp.h (enum pgp_subpacket_tag): New enum. Definition is bogus + and needs to be fixed. + Added forward declarations of structs, and prototypes for + pgp_put_public_rsa_key and pgp_put_rsa_sha1_signature. + + * pgp-encode.c (pgp_put_mpi): Take a const mpz_t argument. Gugfix, + use nettle_mpz_get_str_256. + (pgp_put_public_rsa_key, pgp_put_rsa_sha1_signature): + Constification. Some bugfixes. + + * Use "config.h", not . + + * Reordered includes in most or all .c-files. All should now + include config.h. + +2003-05-12 Niels Möller + + * configure.ac: Use LSH_FUNC_ALLOCA. + +2003-04-25 Niels Möller + + * Makefile.am (libnettle_a_SOURCES): Added hmac-sha256.c. + + * testsuite/hmac-test.c (test_main): Added tests for hmac-sha256, + from draft-ietf-ipsec-ciph-sha-256-01.txt. + + * hmac-sha256.c (hmac_sha256_digest): New file. + +2003-04-22 Niels Möller + + * sha-example.c (display_hex): Simplified by using printf better. + + * nettle.texinfo (Example): Use @verbatiminclude to include the + example program. + + * sha-example.c: Example program, for inclusion in the manual. + Fixed bugs reported by Mark Arking. + +2003-04-14 Niels Möller + + * x86/aes-encrypt.asm (nettle_aes_encrypt): Fixed references to + _nettle_aes_encrypt_table. + * x86/aes-decrypt.asm (nettle_aes_decrypt): Fixed references to + _nettle_aes_decrypt_table. + +2003-04-12 Niels Möller + + * testsuite/Makefile.am (TS_SH): New test case symbols-test. + (EXTRA_PROGRAMS): Added testutils, as a kludge to + get automake to track dependencies for testutils.o. + + * x86/aes-encrypt.asm (nettle_aes_encrypt): Renamed function to + use the nettle_ prefix. + * x86/aes-decrypt.asm (nettle_aes_decrypt): Likewise. + * sparc/aes.asm (_nettle_aes_crypt): Likewise. + + * examples/Makefile.am (EXTRA_PROGRAMS): Add "io", as a kludge to + get automake to track dependencies for io.o. + (LDADD): Added ../libnettle.a, for the dependency. + + * des-compat.c: Use names with the nettle_ prefix when using + Nettle's des functions. + + * base16-meta.c (base16_encode_update): Need to undef before + redefining. + + * New name mangling, to reduce the risk of link collisions. All + functions (except memxor) now use a nettle_ or _nettle prefix when + seen by the linker. For most functions, the header file that + declares a function also use #define to provide a shorter more + readable name without the prefix. + +2003-03-11 Niels Möller + + * Released nettle-1.7. + + * configure.ac: Bumped version to 1.7. + + * nettle.texinfo (DSA): New section. + (RSA): Updated documentation. + +2003-03-02 Niels Möller + + * examples/nettle-benchmark.c (time_cipher): Don't use GNU C + non-constant initializers. + +2003-02-23 Niels Moller + + * configure.ac: Use LSH_GCC_ATTRIBUTES. + +2003-02-19 Niels Möller + + * acinclude.m4: Deleted file from cvs, use a link to lsh's + acinclude.m4 instead. + +2003-02-16 Niels Möller + + * Makefile.am (libnettleinclude_HEADERS): Added macros.h. + + * tools/Makefile.am (EXTRA_DIST): Added getopt.h. + +2003-02-14 Niels Möller + + * Makefile.am (print_path): Added target to print the used PATH, + for debugging. + (print-path): Moved dependency to all-local. + +2003-02-11 Niels Möller + + * buffer.c (nettle_buffer_copy): Bug fix, it didn't return any + value. + +2003-02-11 Niels Möller + + * testsuite/sexp-format-test.c (test_main): Added test for %( and + %). + + * sexp-format.c (sexp_vformat): Handle %( and %). + + * realloc.c (nettle_xrealloc): Fixed out-of-memory check. + + * configure.ac (SHLIBMAJOR): Bumped version number to 1. + + * buffer.c (nettle_buffer_init_realloc): New function. + * buffer-init.c (nettle_buffer_init): Use nettle_buffer_init_realloc. + +2003-02-10 Niels Möller + + * testsuite/sexp-format-test.c (test_main): New test with tokens + in the format string. + (test_main): Test space-searated literals too. + + * rsa2sexp.c (rsa_keypair_to_sexp): New argument ALGORITHM_NAME. + * examples/rsa-keygen.c (main): Updated call to rsa_keypair_to_sexp. + * testsuite/rsa2sexp-test.c (test_main): Likewise. + + * sexp-format.c (sexp_vformat): Allow whitespace in format string. + + * rsa2sexp.c (rsa_keypair_to_sexp): Use literals with sexp_format. + + * sexp-format.c (format_string): New function. + (sexp_vformat): Implemented support for literals in the format + string. + +2003-02-06 Niels Möller + + * testsuite/sexp-conv-test (print_raw, print_nl): New functions. + The testfunctions use these instead of using echo directly. + Use the test input '3:"\x' instead of '2:"\', to be friendlier to + sysv echo. + +2003-02-05 Niels Möller + + * des-compat.h (des_set_key): Different name mangling, if this + file is included, des_set_key should refer to a function that + behaves like openssl's. + + * des-compat.c (des_key_sched, des_is_weak_key): Use the name + nettle_des_set_key for referring to Nettle's function. + + * des.h (des_set_key): Name mangling, linker symbols should use a + "nettle_" prefix, and this one collided with openssl. Perhaps all + symbols should be mangled in a similar way, but that's for later. + + * configure.ac (LDFLAGS): --with-lib-path should add to LDFLAGS, + not replace it. + +2003-01-30 Niels Möller + + * tools/output.c (sexp_put_string): Fixed handling of escapable + characters. The code generated random escape sequences for + characters in the 0x10-0x1f range. + + * testsuite/sexp-conv-test: More tests for hex and base64 input + and output. + +2003-01-30 Niels Möller + + * sexp2bignum.c (nettle_mpz_set_sexp): Call sexp_iterator_next on + success. That means the iterator argument can't be const. + +2003-01-29 Niels Möller + + * tools/Makefile.am (LDADD): Add libnettle.a, for the dependency. + +2003-01-27 Niels Möller + + * sexp2dsa.c (dsa_signature_from_sexp): New function. + + RSA renaming. Updated all callers. + * rsa-sign.c (rsa_private_key_init, rsa_private_key_clear) + (rsa_private_key_prepare): Renamed functions. + * rsa.c (rsa_public_key_init, rsa_public_key_clear) + (rsa_public_key_prepare): Renamed functions. + +2003-01-23 Niels Möller + + * Makefile.am (libnettle_a_SOURCES): Added new rsa and pkcs1 + files. Removed old rsa_md5.c and rsa_sha1.c. + + * testsuite/Makefile.am (TS_PROGS): Added pkcs1-test. + + * dsa-verify.c (dsa_verify_digest): New function. + (dsa_verify): Most of the code moved to dsa_verify_digest, which + is used here. + * dsa-sign.c (dsa_sign_digest): New function. + (dsa_sign): Most of the code moved to dsa_sign_digest, which is + used here. + * dsa.c (_dsa_hash): Deleted function. + + * rsa_md5.c, rsa_sha1.c: Deleted files, contents spread over + several files for signing and verification. + * rsa-sign.c, rsa-sha1-verify.c, rsa-sha1-sign.c, + rsa-md5-verify.c, rsa-md5-sign.c: New files. + + * rsa-sha1-verify.c (rsa_sha1_verify_digest): New function. + * rsa-sha1-sign.c (rsa_sha1_sign_digest): New function. + * rsa-md5-verify.c (rsa_md5_verify_digest): New function. + * rsa-md5-sign.c (rsa_md5_sign_digest): New function. + * rsa-verify.c (_rsa_verify): New file, new function. + + * rsa.c (_rsa_check_size): Renamed from rsa_check_size, and made + non-static. Private key functions moved to rsa-sign.c. + + * pkcs1.c, pkcs1.h, pkcs1-rsa-md5.c, pkcs1-rsa-sha1.c: New files. + (pkcs1_signature_prefix): New function. + + * testsuite/pkcs1-test.c: New test. + +2003-01-22 Niels Möller + + * examples/Makefile.am (nettle_benchmark_LDADD): Use + OPENSSL_LIBFLAGS. + + * configure.ac (OPENSSL_LIBFLAGS): If libcrypto is found, add + -lcrypto to OPENSSL_LIBFLAGS, not the plain LDFLAGS. + +2003-01-20 Niels Möller + + * testsuite/Makefile.am (CLEANFILES): Delete test.in, test1.out + and test2.out. + +2003-01-17 Niels Möller + + * examples/Makefile.am (AM_CPPFLAGS): Use AM_CPPFLAGS instead of + AM_CFLAGS. + * testsuite/Makefile.am (AM_CPPFLAGS): Likewise. + +2003-01-16 Niels Möller + + * testsuite/Makefile.am (check): Can't use quotes around + $(srcdir). + +2003-01-14 Niels Möller + + * testsuite/Makefile.am (check): Don't use "run-tests" as a + target, as it's confused with the file with the same name. + + * .bootstrap: Added missing #! /bin/sh. + +2003-01-12 Niels Möller + + * buffer.c (nettle_buffer_reset): New function. + (nettle_buffer_copy): New function. + + * tools/input.c, tools/input.h, tools/output.c, tools/output.h, + tools/parse.c, tools/parse.h, tools/misc.c, tools/misc.h: Moved + parts ov sexp-conv.c to separate files + + * tools/sexp-conv.c (sexp_convert_list): Inlined into + sexp_convert_item. + + * tools/sexp-conv.c (struct sexp_input): Deleted string attribute. + Changed all related functions to take a struct nettle_buffer * + argument instead. + (struct sexp_compound_token): New struct. + (sexp_compound_token_init, sexp_compound_token_clear): New + functions. + (struct sexp_parser): Added a struct sexp_compound_token + attribute, as a temporary measure. + (sexp_parse): Take a struct sexp_compound_token * as argument. + Updated all callers. Simplified handling of display types and + transport encoding. + + * tools/sexp-conv.c (struct sexp_parser): Renamed struct (was + struct sexp_parse_state). Added input pointer. Updated users to + not pass around both parser and input. + (sexp_check_token): handle token == 0. + (sexp_parse): Simplified a little by calling sexp_check_token + unconditionally. + + * tools/sexp-conv.c (sexp_convert_string): Deleted function. + (sexp_skip_token): Likewise. + + * tools/sexp-conv.c (enum sexp_token): New constant SEXP_DISPLAY. + Start constants from 1, to keep 0 free for special uses. + (struct sexp_parse_state): New struct for keeping track of parser + state. + (sexp_parse_init): New function. + (sexp_check_token): New function, replacing sexp_skip_token. + (sexp_parse): New function. + (sexp_convert_item): Simplified by using sexp_parse. + (sexp_convert_list): Use sexp_parse. + (main): Likewise. + +2003-01-08 Niels Möller + + * tools/sexp-conv.c (parse_options): Initialize prefer_hex. + +2003-01-07 Niels Möller + + * Makefile.am (des_headers): Refer to the desdata binary using + $(EXEEXT). + +2003-01-01 Niels Möller + + * testsuite/sexp-conv-test: New tests for hex and base64 literal + output. + + * tools/sexp-conv.c (sexp_put_string): Print binary strings using + either hex or base 64 (in advanced mode). + (parse_options): Implemented -s hex, for output using hex rather + than base64. + +2002-12-30 Niels Möller + + * testsuite/rsa2sexp-test.c: Don't include rsa.h (done by + testutils.h, if enabled). + * testsuite/sexp2rsa-test.c: Likewise. + + * rsa-decrypt.c: Make compilation conditional on WITH_PUBLIC_KEY. + * rsa-encrypt.c: Likewise. + * rsa-compat.c: Likewise. + +2002-12-04 Niels Möller + + * testsuite/Makefile.am (LDADD): Added path to ../libnettle.a, + which is redundant except for the dependency. + +2002-12-04 Niels Möller + + * testsuite/sexp-format-test.c (test_main): Use %0s instead of %z. + New test for %t. + + * sexp-format.c (format_length_string): Deleted function. + (format_string): Deleted function. + (sexp_vformat): New %t specifier, formatting an optional display + type. Deleted %z specifier. Instead, introduced a new modifier "0" + that can be used with %s, %l and %t, which says that the data is + NUL-terminated. + + * rsa2sexp.c (rsa_keypair_to_sexp): Use %0s rather than %z, when + formatting s-expressions. + + * buffer.c (nettle_buffer_grow): Fixed assertion. + +2002-11-22 Niels Möller + + * buffer.c: Include assert.h. + +2002-11-21 Niels Möller + + * testsuite/testutils.c (print_hex): Add line breaks. + + * Makefile.am (libnettleinclude_HEADERS): Added realloc.h. + (libnettle_a_SOURCES): Added buffer-init.c and realloc.c. + + * sexp.c (sexp_iterator_exit_lists): New function, #if:ed out for + now. + + * desdata.c: Include config.h, to get definition of UNUSED. + * shadata.c: Likewise. + + * buffer.c (nettle_buffer_grow): New function, replacing + grow_realloc. + (nettle_buffer_clear): Rewritten to use buffer->realloc. + + * buffer.h (struct nettle_buffer): Replaced the GROW function + pointer with a nettle_realloc_func pointer and a + void *realloc_ctx. + (NETTLE_BUFFER_GROW): Deleted macro, use function instead. + + * buffer-init.c (nettle_buffer_init): Moved to a separate file. + + * realloc.c (nettle_realloc): New function. + (nettle_xrealloc): New function. + + * realloc.h (nettle_realloc_func): New typedef. + + * configure.ac: Check for gcc:s __attribute__. + +2002-11-16 Niels Möller + + * sexp2dsa.c, sexp2rsa.c: (macro GET): Check sign of parsed + numbers. + + * sexp2bignum.c (nettle_mpz_set_sexp): In the first check against + limit, added some margin to allow for sign octets. + +2002-11-15 Niels Möller + + * testsuite/testutils.h (LDATA): Use sizeof instead of strlen. Now + handles strings including NUL-characters. But works only with + literals and character arrays, no char pointers. + (LLENGTH): New macro, computing length the same way as LDATA. + + * testsuite/sexp-test.c (test_main): Test sexp_iterator_get_uint32. + + * testsuite/sexp-format-test.c (test_main): Check that %i and %b + generate leading zeroes when needed. Check that %b handles + negative numbers. + + * testsuite/rsa2sexp-test.c (test_main): Updated test, one leading + zero is needed in the private key expression. In verbose mode, + print the generated keys. + + * testsuite/sexp2rsa-test.c (test_main): Added a leading zero in + the private key expression. + + * testsuite/bignum-test.c (test_bignum): Use + nettle_mpz_init_set_str_256_s. + (test_size): New function. + (test_main): Test size computation and formatting of negative + numbers. + + * sexp2bignum.c (nettle_mpz_set_sexp): Use + nettle_mpz_set_str_256_s, to handle negative numbers correctly. + + * sexp-format.c (sexp_vformat): For %i, output a leading zero when + needed to get a correct, positive, sign. For %b, use + nettle_mpz_sizeinbase_256_s, to handle negative numbers properly. + + * bignum.c (nettle_mpz_sizeinbase_256_s): New function. + (nettle_mpz_sizeinbase_256_u): New name, was + nettle_mpz_sizeinbase_256. Updated all callers. + (nettle_mpz_to_octets): New function. + (nettle_mpz_get_str_256): Handle negative numbers. + (nettle_mpz_from_octets): New function. + (nettle_mpz_set_str_256_u): New name, was nettle_mpz_set_str_256. + (nettle_mpz_init_set_str_256_u): New name, was + nettle_mpz_init_set_str_256. + (nettle_mpz_set_str_256_s): New function, handling negative two's + complement numbers. + (nettle_mpz_init_set_str_256_s): And an init variant. + + * sexp.c (sexp_iterator_get_uint32): New function. + +2002-11-10 Niels Möller + + * testsuite/sexp-conv-test: Use input files without any trailing + newline character, in order to stress the end of file handling. + + * tools/sexp-conv.c (sexp_get_token_string): Fixed end of file + handling. + (sexp_get_string): Fixed end of encoding/end of file handling. + (parse_options): Check for negative width and complain. + + * tools/sexp-conv.c: Use supplied getopt. + (werror): New function. + (sexp_output_hash_init): New function. + (sexp_put_char): Made base64 linebreaking configurable. + Implemented hashing. + (sexp_put_code_start, sexp_put_code_end): Don't output any + delimiters here. + (sexp_put_string): Output base64 delimiters. + (sexp_put_digest): New function. + (sexp_convert_item): Output transport delimiters. + (sexp_convert_file): Deleted function, folded with main. + (parse_options): New function. + (main): Implemented --hash and --once, needed by lsh-authorize. + + * sexp.h (struct sexp_iterator): New field start. + + * sexp.c (sexp_iterator_subexpr): New function. + (sexp_iterator_parse): Initialize ITERATOR->start. + + * sexp-format.c (sexp_vformat): Abort if format string contains + unhandled characters. + +2002-11-08 Niels Möller + + * des-compat.c (des_ecb3_encrypt): Don't use struct initialization + (c89 doesn't allow non-constant initializers). Reported by James + Ralston. + (des_ede3_cbc_encrypt): Likewise. + + * examples/nettle-openssl.c: Moved from the top-level directory. + Should *not* be included in the nettle library. + +2002-11-08 Niels Möller + + * testsuite/testutils.c (test_dsa_key): Bugfix for renamed DSA + constant (noted by James Ralston). + +2002-11-07 Niels Möller + + * testsuite/run-tests: Copied new version rom lsh/src/testsuite. + This version handles test scripts located in $srcdir. + + * examples/Makefile.am (AM_CFLAGS): We need -I$(top_srcdir). + * tools/Makefile.am (AM_CFLAGS): Likewise. + * testsuite/Makefile.am (AM_CFLAGS): Likewise. + +2002-11-07 Niels Möller + + * Makefile.am (SUBDIRS): Added tools. + (libnettle_a_SOURCES): Added sexp-transport-format.c, + sexp2bignum.c, sexp2dsa.c. + + * sexp2dsa.c (dsa_keypair_from_sexp_alist, dsa_keypair_from_sexp): + New file, new functions. + + * rsa2sexp.c (rsa_keypair_to_sexp): %s -> %z renaming. + + * sexp-transport.c (sexp_transport_iterator_first): Fixed bug, + length was mishandled. + + * sexp-transport-format.c (sexp_transport_format, + sexp_transport_vformat): New file, new functions. + + * sexp-format.c (sexp_format): Return length of output. Allow + buffer == NULL, and only compute the needed length in this case. + Renamed %s to %z. New format specifiers %s, %i, and %l. + (sexp_vformat): New function. + (format_prefix): Rewrote to not use snprintf. + + * sexp2rsa.c (rsa_keypair_from_sexp): New limit argument. Use + nettle_mpz_set_sexp. + + * dsa-keygen.c (dsa_generate_keypair): Added some newlines to + progress display. Use DSA_P_MIN_BITS. + + * dsa.h (DSA_MIN_P_BITS): New constant (was DSA_MINIMUM_BITS). + (DSA_Q_OCTETS, DSA_Q_BITS): New constants. + (dsa_keypair_from_sexp_alist, dsa_keypair_from_sexp): New + prototypes. + + * configure.ac: Output tools/Makefile. + + * sexp2bignum.c (nettle_mpz_set_sexp): New file, and new function. + Moved from sexp2rsa.c:get_value. + + * examples/io.c (read_rsa_key): New limit argument in + call of rsa_keypair_from_sexp_alist. + + * examples/Makefile.am (noinst_PROGRAMS): Removed sexp-conv. + + * tools/sexp-conv.c: Moved file from examples directory. + + * testsuite/Makefile.am (TS_SH): New variable. Added + sexp-conv-test. + + * testsuite/testutils.h (LDUP): New macro. + + * testsuite/sexp2rsa-test.c (test_main): New limit argument in + call of rsa_keypair_from_sexp_alist. + + * testsuite/sexp-test.c (test_main): Added test for lengths with + more than one digit. Added tests for transport mode decoding. + + * testsuite/sexp-format-test.c (test_main): Added tests for %i and + %l. + + * testsuite/sexp-conv-test: Moved test from examples directory. + Updated path to sexp-conv, now in ../tools/sexp-conv. + +2002-11-03 Niels Möller + + * sexp-format.c, sexp_format.c: Renamed sexp_format.c to + sexp-format.c. + * Makefile.am (libnettle_a_SOURCES): Renamed sexp_format.c to + sexp-format.c. + + * examples/Makefile.am: Don't set CFLAGS or CPPFLAGS explicitly, + let automake handle that. + * testsuite/Makefile.am: Likewise. + + * sexp2rsa.c (rsa_keypair_from_sexp_alist): New function. + (rsa_keypair_from_sexp): Use it. + +2002-11-01 Niels Möller + + * examples/Makefile.am (LDADD): Use -lnettle, instead of an + explicit filename libnettle.a, so that we will use the shared + library, if it exists. + (AM_LDFLAGS): Added -L.., so we can find -lnettle. + (run-tests): Set LD_LIBRARY_PATH to ../.lib, when running the + testsuite. + * testsuite/Makefile.am: Similar changes. + + * Makefile.am (LIBOBJS): Put @LIBOBJS@ into the make variable + LIBOBJS. + (CLEANFILES): Delete libnettle.so. + (clean-local): Delete the .lib linkfarm. + ($(SHLIBFORLINK)): When building libnettle.so, create a link from + .lib/$SHLIBSONAME. Needed at runtime, for the testsuite. + +2002-11-01 Niels Möller + + * configure.ac: Fixed definitions using SHLIBMAJOR and SHLIBMINOR. + Also AC_SUBST SHLIBMAJOR and SHLIBMINOR. Reported by James + Ralston. + +2002-10-31 Niels Möller + + * examples/sexp-conv.c(sexp_put_list_start): Deleted function. + (sexp_put_list_end): Likewise. + (sexp_put_display_start): Likewise. + (sexp_put_display_end): Likewise. + (sexp_puts): Likewise. + + * examples/sexp-conv.c (sexp_get_quoted_string): Deleted function. + Merged with sexp_get_String. + (sexp_get_hex_string): Likewise. + (sexp_get_base64_string): Likewise. + (sexp_get_string): Do hex and base64 decoding. + + * examples/sexp-conv.c (enum sexp_char_type): New enum, for end + markers in the input strem. + (struct sexp_input): Deleted LEVEL attribute. Deleted all usage of + it. + (sexp_get_raw_char): Use INPUT->c and INPUT->ctype to store + results. Deleted OUT argument. + (sexp_get_char): Likewise. Also removed the + INPUT->coding->decode_final call, for symmetry. + (sexp_input_end_coding): Call INPUT->coding->decode_final. + (sexp_next_char): New function. + (sexp_push_char): New function. + (sexp_get_token_char): Deleted function. + (sexp_get_quoted_char): Simplified. Deleted output argument. + (sexp_get_quoted_string): Simplified. + (sexp_get_base64_string): Likewise. + (sexp_get_token_string): Likewise. + (sexp_get_string_length): Skip the character that terminates the + string. + (sexp_get_token): Cleared upp calling conventions. Always consume + the final character of the token. + (sexp_convert_list): Take responsibility for converting the start + and end of the list. + (sexp_convert_file): Call sexp_get_char first, to get the token + reading started. + (sexp_convert_item): Cleared up calling conventions. Should be + called with INPUT->token being the first token of the expression, + and returns with INPUT->token being the final token of the + expression. Return value changed to void.. + + * examples/sexp-conv-test: Added test for transport mode input. + + * examples/sexp-conv.c (sexp_get_char): Use the nettle_armor + interface for decoding. + (sexp_input_start_coding): New function. + (sexp_input_end_coding): New function. + (sexp_get_base64_string): Rewrote to use sexp_input_start_coding + and sexp_input_end_coding. + (sexp_get_token): Generate SEXP_TRANSPORT_START tokens. + (sexp_convert_list): Lists are ended only by SEXP_LIST_END. + (sexp_convert_item): Implemented transport mode, using + sexp_input_start_coding and sexp_input_end_coding. + +2002-10-30 Niels Möller + + * Makefile.am: Added base16 files. + + * examples/sexp-conv-test: New tests for transport output. + + * examples/sexp-conv.c: Deleted hex functions, moved to Nettle's + base16 files. + (struct sexp_output): Represent the current encoding as a + nettle_armor pointer and a state struct. + (sexp_output_init): Deleted MODE argument. Now passed to functions + that need it. + (sexp_get_char): Updated to new base64 conventions. + (sexp_get_base64_string): Likewise. + (sexp_put_raw_char): New function. + (sexp_put_newline): Use sexp_put_raw_char. + (sexp_put_char): Use nettle_armor interface for encoding data. + Use OUTPUT->coding_indent for line breaking, so the INDENT + argument was deleted. + (sexp_put_code_start): New function, replacing sexp_put_base64_start. + (sexp_put_code_end): New function, replacing sexp_put_base64_end. + (sexp_put_data): Deleted argument INDENT. + (sexp_puts): Likewise. + (sexp_put_length): Likewise. + (sexp_put_list_start): Likewise. + (sexp_put_list_end): Likewise. + (sexp_put_display_start): Likewise. + (sexp_put_display_end): Likewise. + (sexp_put_string): Likewise. Also changed base64 handling. + (sexp_convert_string): Deleted argument INDENT. New argument + MODE_OUT. + (sexp_convert_list): New argument MODE_OUT. + (sexp_convert_file): Likewise. + (sexp_convert_item): Likewise. Also handle output in transport + mode. + (match_argument): Simple string comparison. + (main): Adapted to above changes. + + * testsuite/testutils.c (test_armor): Allocate a larger buffer + CHECK, to make decode_update happy. Updated to new base64 + conventions. + + * testsuite/base64-test.c (test_main): Fixed overlap test to not + change the base64 before decoding. Updated to new base64 + conventions. + + * testsuite/Makefile.am (TS_PROGS): Added base16-test. + + * testsuite/base16-test.c: New test. + + * sexp-transport.c (sexp_transport_iterator_first): Updated to new + conventions for base64_decode_update and base64_decode_final. + + * nettle-meta.h: Updated ascii armor declarations. New declaration + for nettle_base16. + + * base64-decode.c (base64_decode_single): Return -1 on error. + Also keep track of the number of padding characters ('=') seen. + (base64_decode_update): New argument dst_length. Return -1 on error. + (base64_decode_status): Renamed function... + (base64_decode_final): ... to this. + + * base64.h (struct base64_decode_ctx): Deleted STATUS attribute. + Added PADDING attribute. + + * base16.h, base16-encode.c, base16-decode.c, base16-meta.c: New + files. + +2002-10-28 Niels Möller + + * examples/sexp-conv.c (struct hex_decode_ctx): New hex decoding + functions. + (sexp_get_raw_char): New function. + (sexp_get_char): Use sexp_get_raw_char. + +2002-10-26 Niels Möller + + * examples/sexp-conv.c (sexp_put_length): Bugfix, don't output any + leading zero. + (main): Implemented -s option. + + * examples/sexp-conv-test: Test for echo -n vs echo '\c'. Added a + few tests for canonical output. + +2002-10-25 Niels Möller + + * examples/sexp-conv.c (struct sexp_input): Deleted the mode from + the state, that should be passed as argument to relevant + functions. Instead, introduces enum sexp_coding, to say if base64 + coding is in effect. + (struct sexp_output): Added coding attribute. + (sexp_put_char): Use output->coding. + (sexp_put_base64_start): Likewise. + (sexp_put_base64_end): Likewise. + + * base64-decode.c (base64_decode_single): Simplified, got rid of + the done variable. + +2002-10-25 Niels Möller + + * examples/sexp-conv.c (sexp_put_newline): Return void, die on + error. + (sexp_put_char, sexp_put_data, sexp_puts, sexp_put_length, + sexp_put_base64_start, sexp_put_base64_end, sexp_put_string, + sexp_put_list_start, sexp_put_list_end, sexp_put_display_start, + sexp_put_display_end, sexp_convert_string, sexp_convert_list, + sexp_skip_token): Likewise. + (sexp_convert_item): Die on error. + +2002-10-24 Niels Möller + + * examples/sexp-conv-test: Doesn't need echo -n anymore. + + * examples/sexp-conv.c (die): New function. + (struct sexp_input): Deleted field ITEM. + (sexp_get_char): Die on failure, never return -1. + (sexp_get_quoted_char): Likewise. + (sexp_get_quoted_string): Die on failure, no returned value. + (sexp_get_base64_string): Likewise. + (sexp_get_token_string): Likewise. + (sexp_get_string): Likewise. + (sexp_get_string_length): Likewise. + (sexp_get_token): Likewise. + (sexp_convert_string): Adapted to sexp_get_token. + (sexp_convert_list): Likewise. + (sexp_convert_file): New function. + (main): Use sexp_convert_file. + +2002-10-23 Niels Möller + + * examples/Makefile.am (TS_PROGS): Added sexp-conv-test. + + * examples/sexp-conv.c (sexp_input_init): Initialize input->string + properly. + (sexp_get_char): Fixed non-transport case. + (sexp_get_quoted_char): Fixed default case. + (sexp_get_token): Loop over sexp_get_char (needed for handling of + white space). Don't modify input->level. Fixed the code that skips + comments. + (sexp_put_char): Fixed off-by-one bug in assertion. + (sexp_put_string): Fixed escape handling for output of quoted + strings. + (sexp_convert_list): Prettier output, hanging indent after the + first list element. + (sexp_skip_token): New function. + (sexp_convert_item): Use sexp_skip_token to skip the end of a + "[display-type]". + +2002-10-22 Niels Möller + + * examples/sexp-conv-test: New test program. + + * examples/Makefile.am (noinst_PROGRAMS): Added sexp-conv. + + * examples/sexp-conv.c (sexp_convert_list): New function. + (sexp_convert_item): New function. + (main): New function. Compiles and runs now, but doesn't work. + + * base64-decode.c (base64_decode_single): New function. + (base64_decode_update): Use base64_decode_single. + + * examples/sexp-conv.c: Added output functions. + +2002-10-21 Pontus Sköld + + * base64-encode.c (base64_encode_raw): Fixed null statement + amongst variable declarations, broke compilation for non C99 + compilers. + +2002-10-21 Niels Möller + + * examples/sexp-conv.c: New sexp conversion program. + +2002-10-21 Niels Möller + + * Makefile.am (libnettle_a_SOURCES): Added + sexp-format-transport.c. + + * sexp-transport.c (sexp_transport_iterator_first): New file and + function. + * sexp.h (sexp_transport_iterator_first): Added protoype. + + * sexp.c (sexp_iterator_next): Abort if iterator type is boogus. + +2002-10-19 Niels Möller + + * testsuite/testutils.c (test_armor): Updated to new armor + conventions. + + * testsuite/base64-test.c (test_main): Test BASE64_ENCODE_LENGTH + and BASE64_DECODE_LENGTH. Updated test of base64_encode_raw (used + to be base64_encode). + + * base64.h (BASE64_ENCODE_LENGTH, BASE64_DECODE_LENGTH): Fixed and + documented macros. + + * base64-meta.c (base64_encode_length, base64_decode_length): New + functions, corresponding to the macros with the same name. + + * Makefile.am (libnettle_a_SOURCES): base64.c replaced by + base64-encode.c and base64-decode.c. + + * pgp-encode.c (pgp_armor): Use new base64 conventions. + + * nettle-meta.h: Updated nettle_armor definitions. + + * base64.h: Major reorganization. + + * base64.c: Deleted file, contents moved to base64-encode.c or + base64-decode.c. + + * base64-encode.c: New file. New supporting both encode-at-once + and streamed operation. + + * base64-decode.c: New file. + +2002-10-09 Niels Möller + + * testsuite/Makefile.am (TS_PROGS): Added dsa-keygen-test. + + * dsa-keygen.c: Call the progress callback only if it's non-NULL. + + * Makefile.am (libnettle_a_SOURCES): Added bignum-random.c and + dsa-keygen.c. + + * testsuite/testutils.c (test_dsa_key): New function to sanity + check a dsa keypair. + + * testsuite/dsa-test.c (test_main): Call dsa_test_key. + + * testsuite/dsa-keygen-test.c: New test case. + + * dsa.h (DSA_MINIMUM_BITS): New constant. + + * bignum.h (nettle_mpz_random, nettle_mpz_random_size): Added + prototypes. + + * dsa-keygen.c: New file. + + * bignum-random.c: New file. + (nettle_mpz_random): New function, moved from... + * dsa-sign.c (nettle_mpz_random): ... here. Also changed argument + ordering and updated callers. + + * bignum-random.c: (nettle_mpz_random_size): New function, renamed + and moved here from... + * rsa-keygen.c (bignum_random_size): ... here. Updated all + callers. + + * testsuite/testutils.c (test_dsa): Needs both public and private + key as arguments. + + * testsuite/dsa-test.c (test_main): Updated to changes of the + private key struct. + + * testsuite/Makefile.am (TS_PROGS): Added dsa-test. + + * rsa-decrypt.c (rsa_decrypt): Constification. + * rsa-encrypt.c (rsa_encrypt): Likewise. + * rsa.c (rsa_compute_root): Likewise. + * rsa_md5.c (rsa_md5_sign): Likewise. + (rsa_md5_verify): Likewise. + * rsa_sha1.c (rsa_sha1_sign): Likewise. + (rsa_sha1_verify): Likewise. + + * dsa-verify.c (dsa_verify): Use const for the public key + argument. + + * dsa-sign.c (dsa_sign): Needs the public key as argument, in + addition to the private key. Use const. + + * dsa.h (struct dsa_private_key): Don't include the public + information here. + * dsa.c (dsa_private_key_init, dsa_private_key_clear): Updated to + new struct dsa_private_key. + + * dsa-sign.c (dsa_sign): Bugfix, added missing mpz_init call. + + * Makefile.am (libnettle_a_SOURCES): Added dsa files. + (libnettleinclude_HEADERS): Added dsa.h. + + * testsuite/testutils.c (test_dsa): New function. + + * testsuite/dsa-test.c: New test. + + * dsa.h, dsa.c, dsa-sign.c, dsa-verify.c: New files. + + * nettle-meta.h: Moved the nettle_random_func and + nettle_progress_func typedefs here... + * rsa.h: ... from here. + +2002-10-07 Niels Möller + + * sexp.h (enum sexp_type): Deleted SEXP_START. + + * sexp.c (sexp_iterator_parse): New function, similar to the old + sexp_iterator_next, but independent of the previous value of the + iterator->type. + (sexp_iterator_first): Use sexp_iterator_parse. + (sexp_iterator_next): Likewise. + (sexp_iterator_enter_list): Use sexp_iterator_parse. SEXP_START + not needed anymore. + (sexp_iterator_exit_list): Likewise. + +2002-10-06 Niels Möller + + * sexp2rsa.c (get_value): No need to call sexp_iterator_next + anymore. + + * sexp.c (sexp_iterator_assoc): Advance the iterator to the + element after a matching tag, before recording it. + * testsuite/sexp-test.c (test_main): Updated test. + + * testsuite/sexp-test.c (test_main): No need to call + sexp_iterator_next after sexp_iterator_exit_list. + + * sexp2rsa.c (rsa_keypair_from_sexp): No need to call + sexp_iterator_next anymore. + + * sexp.c (sexp_iterator_next): Updated to new sexp_iterator_exit_list. + (sexp_iterator_exit_list): Return with iterator pointing to the + element after the list. + (sexp_iterator_check_type): Call sexp_iterator_next before + returning. + (sexp_iterator_check_types): Likewise. + (sexp_iterator_assoc): Rearranged calls of sexp_iterator_next. + + * sexp.c (sexp_iterator_enter_list): Call sexp_iterator_next to + get to the first element of the list. Updated callers. + + * base64.c (base64_encode_group): New function, used by openpgp + armoring code. + + * Makefile.am: Added openpgp files. + + * sexp2rsa.c (rsa_keypair_from_sexp): Use sexp_iterator_first. + * testsuite/sexp-test.c (test_main): Likewise. + + * sexp.c (sexp_iterator_init): Made this function static. + (sexp_iterator_first): New, friendlier, initialization function. + + * pgp-encode.c: New file. Functions for writing openpgp data + packets. + + * pgp.h: New file, with pgp related declarations. + + * rsa2openpgp.c (rsa_keypair_to_openpgp): New file, new function. + +2002-10-04 Niels Möller + + * examples/rsa-keygen.c: Use malloc, instead of asprintf. + +2002-10-03 Niels Möller + + * Released nettle-1.6. + + * NEWS: Note the aes api change. + + * examples/Makefile.am (EXTRA_DIST): Distribute setup-env and + teardown-env. + +2002-10-02 Niels Möller + + * examples/rsa-keygen.c (main): Comment on the lax security of the + private key file. + + * index.html: Added link to mailing list. + +2002-10-02 Niels Möller + + * Makefile.am: Fixed assembler rules, and shared libraries. + + * configure.ac: Fixed the enable-shared option. + +2002-10-01 Niels Möller + + * configure.ac: New option --enable-shared, and a first attempt at + building a shared library (*without* using libtool). + + * Makefile.am: A first attempt at rules for building a shared + libnettle.so. + +2002-10-01 Niels Möller + + * examples/run-tests (test_program): Use basename. + + * examples/teardown-env: Delete some more files. + + * examples/run-tests (test_program): Strip directory part of + displayed name. + + * examples/Makefile.am (TS_PROGS): New variable. Run tests. + + * examples/io.c (read_file): Bug fix, used to overwrite pointer. + + * examples/rsa-keygen.c (main): Bug fix, private key wasn't + written properly. + + * testsuite/Makefile.am: Some cleanup of make check. + + * examples/setup-env, examples/teardown-env: Test environment scripts. + * examples/rsa-verify-test, examples/rsa-sign-test: New test cases. + + * examples/run-tests: New file (copied from lsh testsuite). + + * examples/Makefile.am: Use EXTRA_PROGRAMS and @RSA_EXAMPLES@. + + * examples/rsa-sign.c: No need to include config.h. Use werror + instead of fprintf. + * examples/rsa-verify.c: Likewise. + * examples/rsa-keygen.c: Likewise. + + * examples/io.h: Forward declare struct rsa_public_key and struct + rsa_private_key, to avoid dependences on config.h. + + * configure.ac (RSA_EXAMPLES): New substituted variable, + controlling which example programs to build. + + * examples/rsa-verify.c: New example program. + + * examples/rsa-keygen.c: Use functions from io.c. + * examples/rsa-sign.c: Likewise. + + * examples/Makefile.am (noinst_PROGRAMS): Added rsa-verify. + (LDADD): Added io.o. + + * configure.ac: New define WITH_PUBLIC_KEY, and new configure flag + --disable-public-key. Updated rsa-files to check for that, rather + than for HAVE_LIBGMP. + + * examples/io.c, examples/io.c: New files. Miscellaneous functions + used by the example programs. + + * base64.h (BASE64_DECODE_LENGTH): Comment fix. + +2002-09-30 Niels Möller + + * sexp2rsa.c (rsa_keypair_from_sexp): Bugfix: Call + rsa_prepare_public_key and rsa_prepare_private_key. + + * examples/Makefile.am (noinst_PROGRAMS): Added rsa-sign. + + * examples/rsa-sign.c: New example program. + + * testsuite/base64-test.c (test_main): Test encoding and decoding + in place. + + * base64.c (base64_encode): Encode from the end of the data + towards the start, in order to support overlapping areas. + (base64_encode): Broke out some common code from the switch.. + +2002-09-30 Niels Möller + + * sexp_format.c (sexp_format): Don't mix code and declarations. + +2002-09-29 Niels Möller + + * testsuite/Makefile.am (TS_PROGS): Added buffer-test + sexp-format-test rsa2sexp-test sexp2rsa-test. + + + * testsuite/sexp-test.c (test_main): Updated calls to + sexp_iterator_assoc. + + * testsuite/testutils.h (MEMEQH): New macro. + + * testsuite/sexp2rsa-test.c: New test. + * testsuite/sexp-format-test.c: New test. + * testsuite/rsa2sexp-test.c: New test. + * testsuite/buffer-test.c: New test. + + * testsuite/testutils.c (test_rsa_key): Copied this function + from... + testsuite/rsa-keygen-test.c: ... here. + + * examples/rsa-keygen.c: New file. + + * Makefile.am: Added new source files and headers buffer.h, + buffer.c, sexp_format.c, sexp2rsa.c, rsa2sexp.c. + + * rsa.h (rsa_keypair_to_sexp, rsa_keypair_from_sexp): New + prototypes. + + * rsa2sexp.c, sexp2rsa.c: New files. + + * sexp.c (sexp_iterator_assoc): Don't enter the list, associate + keys within the current list. Still exit the list when done. + (sexp_iterator_assoc): Represent keys as plain NUL-terminated + strings. + (sexp_iterator_check_type, sexp_iterator_check_types): New + functions. + + * sexp_format.c: New file, implementing an sexp canonical syntax + formatter. + + * buffer.c, buffer.h: New files, implementing a bare-bones string + stream. + + * bignum.c (nettle_mpz_sizeinbase_256): New function. + +2002-09-28 Niels Möller + + * sexp.c (sexp_iterator_assoc): Return 0 for missing or duplicate + keys. Now passes all the tests. + + * sexp.c (sexp_iterator_simple): Bugfixes. Check earlier that + length doesn't grow too large. + (sexp_iterator_next): Skip the current list only if type is + SEXP_LIST. Handle ')'. + (sexp_iterator_enter_list): Set type to SEXP_START. + (sexp_iterator_exit_list): Likewise. Don't skip the ')' here. + (sexp_iterator_assoc): Bug fix. + + * testsuite/sexp-test.c (test_main): Reordered sexp_iterator_assoc + tests. + + * nettle.texinfo (Randomness): Documented that yarrow256_init can + be called with a zero number of sources. + + * testsuite/testutils.h (ASSERT): New macro. + + * testsuite/sexp-test.c: Test sexp parser. + + * Makefile.am (SUBDIRS): Added sexp files. + + * sexp.c, sexp.h: New files, implementing an sexp-parser. + +2002-08-27 Niels Möller + + * Makefile.am (DISTCLEANFILES): make distclean should delete the + assembler-related symlinks. + +2002-08-26 Niels Möller + + * Makefile.am (%.o: %.asm): Create an empty (and unused) + dependency file, to make the make/automake dependency tracking + happier. + +2002-07-18 Niels Möller + + * examples/nettle-benchmark.c (main): Try openssl's ciphers as + well, if available. + + * Makefile.am (libnettle_a_SOURCES): Added nettle-openssl.c. + + * nettle-openssl.c: New file. + + * nettle-internal.h: Declare openssl glue ciphers. + + * des-compat.h: Extra name-mangling, to avoid collisions in case a + program links with both nettle and libcrypto (the nettle-benchmark + program does). + + * configure.ac: Don't use -ggdb3 with gcc-2.96. + Check for openssl's libcrypto (for benchmarking). + +2002-05-16 Niels Möller + + * sparc/aes.asm: Deleted registers i and t3. + (_aes_crypt): Moved some registers around. We now use input + registers only for arguments, local registers for loop invariants, + output registers for temporaries and loop variables, and no global + registers at all. + + * sparc/aes.asm (AES_FINAL_ROUND): New macro. + (_aes_crypt): Use AES_FINAL_ROUND for the first word of the final + round. + (_aes_crypt): And for the rest of the final round. + (AES_FINAL_ROUND): Don't update dst, just access it offseted by i. + (_aes_crypt): Add 16 to dst at the end of the final round. + (AES_ROUND): Use ldub, not ld + and, to get the third byte + of wtxt. + (AES_ROUND): Use ldub, not lduh + and, to get the second + byte of a word. + (AES_ROUND): Reordered instructions, so that we can save one + register. + (AES_ROUND): Eliminated use of t3. + (AES_FINAL_ROUND): Eliminated ands. + (AES_FINAL_ROUND): Reordered, so that we can save one register. + (AES_FINAL_ROUND): Eliminated t3. + (AES_LOAD): New macro. + (_aes_crypt): Unrolled source loop. + (_aes_crypt): Use AES_LOAD macro. + (_aes_crypt): Deleted cruft from the old source loop. + (AES_LOAD): Eliminated t3. + +2002-05-15 Niels Möller + + * sparc/aes.asm (AES_ROUND): New macro. + (_aes_crypt): Use AES_ROUND for first word of the + round function. + (_aes_crypt): And for the rest of the round function. + + * sparc/aes.asm (_aes_crypt): Deleted a bunch of additions, + after accessing IDX1. + + * aes-internal.h (struct aes_table): sparc_idx[0] should now + contain index values shifted by the size of a word, and with 2 + added. This saves some additions in the sparc assembler code. + Updates aes-encrypt-table.c and aes-decrypt-table.c. + + * sparc/aes.asm (_aes_crypt): Unrolled final loop, preparing for + optimizations. + (_aes_crypt): Eliminated i from forst copy of the loop. Some + cleanup. + (_aes_crypt): And from second copy. + (_aes_crypt): And from third. + (_aes_crypt): And fourth. + (_aes_crypt): Eliminated updates of i from the loop. + (_aes_crypt): Access IDX1 and IDX3 through the T pointer, saving + two registers. + + * aes-internal.h (struct aes_table): Renamed the shift_idx field + to sparc_idx, as it will be tweaked to improve the sparc code. + Also reduced its size to [2][4]. + (IDX_FACTOR): Deleted constant. + * aes-encrypt-table.c (_aes_encrypt_table): Adapted initializer of + sparc_idx. + * aes-decrypt-table.c (_aes_decrypt_table): Likewise. + * asm.m4: Deleted AES_SIDX2, to match struct aes_table. + + * sparc/aes.asm (_aes_crypt): Unrolled the inner loop, preparing + for optimizations suggested by Marcus Comstedt. + (_aes_crypt): Eliminated i from the first copy of the inner loop. + (_aes_crypt): And from the second copy. + (_aes_crypt): And from the third copy. + (_aes_crypt): And from the fourth copy. + (_aes_crypt): Renamed .Linner_loop to .Lround_loop. + (_aes_crypt): Eliminated the loop variable i from the unrolled + loop. + (_aes_crypt): Deleted moves of constants into t2. + +2002-05-15 Niels Möller + + * x86/aes-encrypt.asm (aes_encrypt): Use AES_SUBST_BYTE. + * x86/aes-decrypt.asm (aes_decrypt): Likewise. + (aes_decrypt): Use AES_STORE. + (aes_decrypt): Deleted first xchgl instruction into, permuting the + AES_ROUND calls instead. + (aes_decrypt): Likewise for the final round. + (aes_decrypt): Got rid if the xchgl instruction after the final + round, folding it into the final round. + + * x86/machine.m4: Renamed AES_LAST_ROUND to AES_FINAL_ROUND. + Updated users. + + * x86/aes-decrypt.asm (aes_decrypt): Use the AES_LOAD macro. + (aes_decrypt): Start using AES_ROUND. + (aes_decrypt): Use AES_LAST_ROUND. + + * x86/aes-decrypt.asm (aes_decrypt): Moved function to a separate + file... + * x86/aes.asm: ... from here. + + * x86/aes.asm (aes_decrypt): Use _aes_decrypt_table instead of + itbl1-4. Commented out the inclusion of aes_tables.asm. + (aes_decrypt): Use _aes_decrypt_table instead of isbox. + + + * x86/aes-decrypt.asm: New file, empty at the start. + + * Makefile.am (libnettle_a_SOURCES): Added aes-decrypt-table.c. + + * aes-decrypt.c (_aes_decrypt_table): Moved from this file... + * aes-decrypt-table.c (_aes_decrypt_table): ... to a new file. + + * testsuite/aes-test.out: New file, with the output of + testsuite/aes-test, when aes.c has been compiled with debugging + printouts of intermediate state. + +2002-05-15 Niels Möller + + * sparc/aes.asm: (_aes_crypt): Restore %fp at end of function, to + make %fp available for other uses. + + * sparc/aes.asm: The frame setup was broken. Tried to fix it. + Reverted to revision 1.70 + minor changes from the head revision. + + * x86/aes-encrypt.asm (aes_encrypt): Use test instead of cmpl $0,. + + * x86/machine.m4 (AES_SUBST_BYTE): New macro. + + * sparc/aes.asm: wtxt needs no register of it's own, as its + pointed to by %sp. %g5 moved to %l0, the register previously + allocated for wtxt, so that we stay clean of the reserved %g + registers. + +2002-05-14 Niels Möller + + * sparc/aes.asm: Avoid using %g6 and %g7, as they are reserved for + operating sytem use. Use %i5 and %o7 instead. Also moved %g4 to %g1. + (_aes_crypt): Allocate only 32 bytes local storage on the stack. + Calculate wtxt and tmp using offsets from %sp, not %fp. + +2002-05-14 Niels Möller + + * x86/aes-encrypt.asm (aes_encrypt): Replaced first quarter of the + round function with an invocation of AES_ROUND. + (aes_encrypt): Similarly for the second column. + (aes_encrypt): Similarly for the rest of the round function. + + * x86/machine.m4 (AES_ROUND): New macro. + + * x86/aes-encrypt.asm (aes_encrypt): Use AES_LOAD macro. + + * x86/machine.m4 (AES_LOAD): New macro. + + * x86/aes-encrypt.asm (aes_encrypt): Use AES_STORE. + + * x86/machine.m4 (AES_STORE): New macro. + + * x86/aes-encrypt.asm (aes_encrypt): Use the AES_LAST_ROUND macro + for the first column of the final round. + (aes_encrypt): Similarly for the second column. + (aes_encrypt): Similarly for the third and fourth column. + + (aes_encrypt): Deleted xchgl instruction in final round, by + reordering the second and fourth round. + + * x86/machine.m4 (AES_LAST_ROUND): New macro. + + * x86/aes-encrypt.asm (aes_encrypt): Move code here... + * x86/aes.asm: ...from here. + + * x86/aes.asm: Use addl and subl, not add and sub. Replaced + references to dtbl1-4 with references to _aes_encrypt_table. + + * configure.ac (asm_path): Enable x86 assembler. + + * x86/aes.asm (aes_decrypt): Adapted to the current interface. + Notably, the order of the subkeys was reversed. Single block + encrypt/decrypt works now. + (aes_encrypt, aes_decrypt): Added an outer loop, so that we can + encrypt more than one block at a time. + +2002-05-07 Niels Möller + + * configure.ac: Generate config.m4. + + * x86/aes.asm: Use C for comments, include the tables using + include_src, and commented out the key setup functions. + Fixed the processing of the first handling of the round function. + Now, encryption of a single block works! Multiple blocks, and + decryption, is still broken. + + * x86/machine.m4: New file (empty). + + * x86/aes-encrypt.asm: New file, empty for now. + + * Makefile.am (%.asm): Added asm.m4, machine.m4 and config.m4 to + the m4 command line. + (libnettle_a_SOURCES): Added aes-encrypt-table.c. + + * sparc/aes.asm: No need to include asm.m4, that is taken care of + by the Makefile. + + * config.m4.in: New file, configuration for asm.m4. + + * asm.m4 (C, include_src): New macros. + + * aes-encrypt-table.c: New file, table moved out from + aes-encrypt.c. + +2002-05-06 Niels Möller + + * configure.ac (CFLAGS): Don't enable -Waggregate-return. + +2002-05-05 Niels Möller + + * configure.ac: Pass no arguments to AM_INIT_AUTOMAKE. + +2002-05-05 Niels Möller + + * configure.ac: Update for automake-1.6. + + * configure.ac: Renamed file, used to be configure.in. + +2002-03-20 Niels Möller + + * testsuite/run-tests (test_program): Added missing single quote. + +2002-03-20 Niels Möller + + * testsuite/run-tests (test_program): Test the exit status of the + right process. + +2002-03-19 Pontus Sköld + + * testsuite/run-tests: Removed /bin/bashisms to use with /bin/sh. + +2002-03-18 Niels Möller + + * rsa-keygen.c (rsa_generate_keypair): Output a newline after a + non-empty line of 'e':s (bad e was chosen, try again). + +2002-03-16 Niels Möller + + * configure.in (asm_path): AC_CONFIG_LINKS adds $srcdir + automatically. + +2002-03-14 Niels Möller + + * sparc/aes.asm, x86/aes.asm: Added copyright notice. + + * Makefile.am (libnettle_a_SOURCES): Added aes-internal.h. + (EXTRA_DIST): Added assembler files. + + * configure.in (asm_path): Use $srcdir when looking for the files. + * configure.in (asm_path): For now, disable x86 assembler code. + Bumped version to 1.6. + +2002-02-25 Niels Möller + + * sparc/aes.asm (_aes_crypt): Moved increment of src into the + source_loop. Also fixed stop condition, the loop was run 5 times, + not 4, as it should. + (_aes_crypt): Use src directly when accessing the source data, + don't use %o5. + (_aes_crypt): Renamed variables in source_loop. + (_aes_crypt): Changed stop condition in source_loop to not depend + on i. Finally reduced the source_loop to 16 instructions. Also + increased the alignment of the code to 16. + (_aes_crypt): In final_loop, use preshifted indices. + (_aes_crypt): In final_loop, construct the result in t0. Use t0-t3 + for intermediate values. + (_aes_crypt): In final_loop, use the register idx. + (_aes_crypt): In final_loop, keep i multiplied by 4. Use key to + get to the current roundkey. + (_aes_crypt): In final_loop, use i for indexing. + (_aes_crypt): Update dst in the output loop. This yields a delay + slot that isn't filled yet. + (_aes_crypt): Decrement round when looping, saving yet some + instructions. + (_aes_crypt): Reformatted code as blocks of four instructions + each. + (_aes_crypt): Copy the addresses of the indexing tables into + registers at the start. No more need for the idx register. + (_aes_crypt): Deleted idx register. + (_aes_crypt): Some peep hole optimizations, duplicating some + instructions to fill nop:s, and put branch instructions on even + word addresses. + +2002-02-22 Niels Möller + + * sparc/aes.asm (_aes_crypt): Moved some more additions out of the + inner loop, using additional registers. + (_aes_crypt): Deleted one more addition from the inner loop, by + using the subkey pointer. + +2002-02-19 Niels Möller + + * configure.in (asm_path): Renamed "path" to "asm_path". Also look + for a machine.m4. + +2002-02-16 Niels Möller + + * sparc/aes.asm: Use that IDX2(j) == j ^ 2 + + * Makefile.am (libnettle_a_SOURCES): Reordered aes-decrypt.c and + aes-encrypt.c. For some strange reason it makes the benchmark go + faster... + + * sparc/aes.asm (_aes_crypt): Use double-buffering, and no + separate loop for adding the round key. + (round): Keep round index muliplied by 16, so it can be used + directly for indexing the subkeys. + (_aes_crypt): In the final loop, use ctx+round to access the + subkeys, no need for an extra register. + +2002-02-15 Niels Möller + + * sparc/aes.asm (_aes_crypt): Renaming variables, allocating + locals starting from %l0. + (_aes_crypt): Consistently use %l4, aka i, as the variable for the + innermost loops. + (_aes_crypt): Moved reading of ctx->nrounds out of the loop. + (_aes_crypt): In final_loop, deleted a redundant mov, and use i as + loop variable. + (_aes_crypt): Started renumbering registers in the inner loop. The + computation for the table[j] sub-expression should be kept in + register %o[j]. + (_aes_crypt): Renamed more variables in the inner loop. Now the + primary variables are t0, t1, t2, t3. + + * sparc/aes.asm (_aes_crypt): Swapped register %i0 and %o5, %i1 + and %o0, %i2 and %o4, %i3 and %o3, %i4 and %o2. + (_aes_crypt): wtxt was stored in both %l1 and %l2 for the entire + function. Freed %l2 for other uses. + (_aes_crypt): Likewise for tmp, freeing register %o1. + + * sparc/machine.m4: New file, for sparc-specific macros. + + * sparc/aes.asm (_aes_crypt): Hacked the source_loop, to get rid + of yet another redundant loop variable, and one instruction. + (_aes_crypt): Strength reduce loop variable in the + inner loop, getting rid of one register. + (_aes_crypt): Use pre-shifted indices (aes_table.idx_shift), to + avoid some shifts in the inner loop. + (_aes_crypt): Don't check for nrounds==0 at the start of the loop. + + * asm.m4: Define and use structure-defining macros. + + * Makefile.am (%.asm): Use a GNU pattern rule, to make %.o depend + on both %.asm and asm.m4. + + * aes-internal.h (struct aes_table): New subtable idx_shift. + Updated tables in aes_encrypt.c and aes_decrypt.c. + + * asm.m4: Use eval to compute values. + + * sparc/aes.asm (_aes_crypt): Deleted commented out old version of + the code. + + * asm.m4: Added constants for individual rows of the aes table. + + * aes.c (IDX0, IDX1, IDX2, IDX3): New macros, encapsualting the + structure of the idx table. + + * asm.m4: Define various aes struct offsets. + + * testsuite/cbc-test.c (test_cbc_bulk): Use aes_set_encrypt_key + and aes_set_decrypt_key. + + * sparc/aes.asm (_aes_crypt): Use symbolic names for the fucntion + arguments. + +2002-02-14 Niels Möller + + * sparc/aes.asm: Copied gcc assembler code for _aes_crypt. + + * aesdata.c: New program for generating AES-related tables. + + * testsuite/testutils.c (print_hex): New function (moved from + yarrow-test.c). + + * testsuite/rsa-keygen-test.c (progress): Declare the ctx argument + as UNUSED. + + * testsuite/cbc-test.c (test_cbc_bulk): New function, testing CBC + with larger blocks. + + * yarrow256.c: Replaced uses of aes_set_key with + aes_set_encrypt_key. + + * nettle-meta.h (_NETTLE_CIPHER_SEP): New macro, useful for + algorithms with separate encyption and decryption key setup. + + * aes-internal.h (struct aes_table): New structure, including all + constant tables needed by the unified encryption or decryption + function _aes_crypt. + + * aes.c (_aes_crypt): New function, which unifies encryption and + decryption. + + AES key setup now uses two separate functions for setting + encryption and decryption keys. Applications that don't do + decryption need no inverted subkeys and no code to generate them. + Similarly, the tables (about 4K each for encryption and + decryption), are put into separate files. + + * aes.h (struct aes_ctx): Deleted space for inverse subkeys. For + decryption, the inverse subkeys replace the normal subkeys, and + they are stored _in the order they are used_. + + * aes-set-key.c (aes_set_key): Deleted file, code moved... + * aes-set-decrypt-key.c, aes-set-encrypt-key.c: New files, + separated normal and inverse key setup. + + * aes-tables.c: Deleted, tables moved elsewhere... + * aes-encrypt.c, aes-decrypt.c: New files; moved encryption and + decryption funktions, and needed tables, into separate files. + +2002-02-13 Niels Möller + + * aes.c (aes_encrypt): Don't unroll the innerloop. + (aes_encrypt): Don't unroll the loop for the final round. + (aes_decrypt): Likewise, no loop unrolling. + + * aes-set-key.c (aes_set_key): Reversed the order of the inverted + subkeys. They are now stored in the same order as they are used. + + * aes-tables.c (itable): New bigger table, generated by aesdata.c. + + * aes.c (aes_decrypt): Rewrote to use the bigger tables. + +2002-02-12 Niels Möller + + * aes.c (aes_encrypt): Interleave computation and output in the + final round. + + * aes-internal.h (AES_SMALL): New macro. + + * aes.c (aes_encrypt): Optionally use smaller rotating inner loop. + + * aes-tables.c (dtbl): Replaced with table generated by aesdata. + + * aes.c (aes_encrypt): Rewrite, now uses larger tables in order to + avoid rotates. + + * sparc/aes.asm (aes_encrypt): Strength reduced on j, getting rid + of one register and one instruction in the inner loop. + + * sparc/aes.asm (idx, aes_encrypt): Multiplied tabled values by 4, + making it possible to get rid of some shifts in the inner loop. + + * configure.in: Fixed spelling of --enable-assembler. Commented + out debug echo:s. + + * asm.m4: New file. For now, only doing changequote and changecom. + + * sparc/aes.asm (aes_encrypt): Added comments. + (aes_encrypt): Cut off redundant instruction per block, also + saving one redundant register pointing to idx. + (idx_row): New macro. Include asm.m4. + +2002-02-11 Niels Möller + + * sparc/aes.asm (key_addition_8to32): Cleaned up. + Deleted gcc-generated debugging information. + + * sparc/aes.asm (key_addition32): First attempt at optimization. + Made it slower ;-) + + * sparc/aes.asm (key_addition32): Unrolled loop, gained 4% + speed, payed four instructions compared to gcc + generated code. + + * Makefile.am (.asm.o): New rule for assembling via m4. + (libnettle_a_SOURCES): Added new rsa and aes files. + + * configure.in: New command line option --enable-assembler. + Selects assembler code depending on the host system. + + * rsa-decrypt.c, rsa-encrypt.c: New files for rsa pkcs#1 + encryption. + + * aes-set-key.c, aes-tables.c: New files, split off from aes.c. + Tables are now not static, but use a _aes_ prefix on their names. + + * aes-internal.h: New file. + + * cast128-meta.c (_NETTLE_CIPHER_FIX): Use _NETTLE_CIPHER_FIX. + + * cbc.c (cbc_decrypt_internal): New function, doing the real CBC + procesing and requiring that src != dst. + (cbc_decrypt): Use cbc_decrypt_internal. If src == dst, use a + buffer of limited size to copy the ciphertext. + + * nettle-internal.c (nettle_blowfish128): Fixed definition, with + key size in bits. + + * nettle-meta.h (_NETTLE_CIPHER_FIX): New macro, suitable for + ciphers with a fixed key size. + + * examples/nettle-benchmark.c (display): New function for + displaying the results, including MB/s figures. + + * sparc/aes.asm: New file. Not yet tuned in any way (it's just the + code generated by gcc). + +2002-02-11 Niels Möller + + * x86/aes.asm, x86/aes_tables.asm: New assembler implementation by + Rafael Sevilla. + +2002-02-06 Niels Möller + + Applied patch from Dan Egnor improving the base64 code. + * base64.h (BASE64_ENCODE_LENGTH): New macro. + (struct base64_ctx): New context struct, for decoding. + (BASE64_DECODE_LENGTH): New macro. + * base64.c (base64_decode_init): New function. + (base64_decode_update): New function, replacing base64_decode. + Takes a struct base64_ctx argument. + * nettle-meta.h: Updated nettle_armor, and related typedefs and + macros. + * testsuite/testutils.c (test_armor): Updated. + * configure.in: Use AC_PREREQ(2.50). + +2002-02-01 Niels Möller + + * Released nettle-1.5. + +2002-01-31 Niels Möller + + * acinclude.m4: Commented out gmp-related macros, they're probably + not needed anymore. + +2002-01-31 Niels Möller + + * configure.in: Added command line options --with-lib-path and + --with-include-path. Use the RPATH-macros to get correct flags for + linking the test programs with gmp. + + * acinclude.m4: New file. + +2002-01-31 Niels Möller + + * nettle.texinfo (Randomness): New subsection on Yarrow. + +2002-01-30 Niels Möller + + * nettle.texinfo (Randomness): New chapter. + Spell checking and ispell configuration. + + * md5.c: Added reference to RFC 1321. + +2002-01-24 Niels Möller + + * nettle.texinfo (Public-key algorithms): Minor fixes. + +2002-01-22 Niels Möller + + * nettle.texinfo (Nettle soup): New chapter. + (Hash functions): New subsection on struct nettle_hash. + (Hash functions): New subsection on struct nettle_cipher. + (Keyed hash functions): New section, describing MAC:s and HMAC. + (Public-key algorithms): New chapter. + + * testsuite/testutils.c (test_armor): New function. + + * testsuite/base64-test.c: New testcase. + + * testsuite/Makefile.am (TS_PROGS): Added base64-test. + + * nettle-meta.h (struct nettle_armor): New struct. + + * configure.in: Bumped version to 1.5. + + * Makefile.am (libnettle_a_SOURCES): Added base64 files, and some + missing header files. + + * base64.c, base64.h, base64-meta.c: New files, hacked by Dan + Egnor. + +2002-01-16 Niels Möller + + * testsuite/yarrow-test.c: Deleted ran_array code, use + knuth-lfib.h instead. + + * testsuite/testutils.c (test_rsa_md5, test_rsa_sha1): Moved + functions here... + * testsuite/rsa-test.c: ...from here. + + * testsuite/rsa-keygen-test.c: New file. + + * testsuite/knuth-lfib-test.c: New file. + + * Makefile.am (libnettle_a_SOURCES): Added knuth-lfib.c and + rsa-keygen.c. + + * rsa-keygen.c: New file. + + * rsa.h (RSA_MINIMUM_N_OCTETS): New constant. + (RSA_MINIMUM_N_BITS): New constant. + (nettle_random_func, nettle_progress_func): New typedefs. Perhaps + they don't really belong in this file. + (rsa_generate_keypair): Added progress-callback argument. + + * macros.h (READ_UINT24, WRITE_UINT24, READ_UINT16, WRITE_UINT16): + New macros. + + * knuth-lfib.c, knuth-lfib.h: New files, implementing a + non-cryptographic prng. + +2002-01-15 Niels Möller + + * hmac-sha1.c: New file. + +2002-01-14 Niels Möller + + * configure.in: Bumped version to 1.1. + + * testsuite/hmac-test.c (test_main): Added hmac-sha1 test cases. + + * rsa.c (rsa_init_private_key, rsa_clear_private_key): Handle d. + + * rsa.h (struct rsa_private_key): Reintroduced d attribute, to be + used only for key generation output. + (rsa_generate_keypair): Wrote a prototype. + + * Makefile.am (libnettle_a_SOURCES): Added hmac-sha1.c and + nettle-internal.h. + + * des.c: Use static const for all tables. + (des_set_key): Use a new const * variable for the parity + procesing, for constness reasons. + + * list-obj-sizes.awk: New file. + + * nettle-internal.c, nettle-internal.h: New files. + + * testsuite/Makefile.am (TS_PROGS): Added hmac-test. Deleted old + m4-stuff. + + * testsuite/testutils.h (LDATA): Moved this macro here,... + * testsuite/rsa-test.c: ... from here. + + * testsuite/hmac-test.c: New file. + + * hmac.h: General cleanup. Added declarations of hmac-md5, + hmac-sha1 and hmac-sha256. + + * hmac.c: Bug fixes. + + * hmac-md5.c: First working version. + + * Makefile.am (libnettle_a_SOURCES): Added hmac.c and hmac-md5.c. + (libnettleinclude_HEADERS): Added hmac.h. + + * testsuite/rsa-test.c: Also test a 777-bit key. + + * rsa.c (rsa_check_size): Changed argument to an mpz_t. Updated + callers. + (rsa_prepare_private_key): Compute the size of the key by + computing n = p * q. + + * rsa-compat.c: Adapted to new private key struct. + * rsa_md5.c: Likesize. + * rsa_sha1.c: Likesize. + + * rsa.c (rsa_check_size): New function, for computing and checking + the size of the modulo in octets. + (rsa_prepare_public_key): Usa rsa_check_size. + (rsa_init_private_key): Removed code handling n, e and d. + (rsa_clear_private_key): Likewise. + (rsa_compute_root): Always use CRT. + + * rsa.h (struct rsa_private_key): Deleted public key and d from + the struct, as they are not needed. Added size attribute. + +2002-01-12 Niels Möller + + * Makefile.am: Added *-meta files. + + * rsa.c (rsa_init_public_key): New function. + (rsa_clear_public_key): Likewise. + (rsa_init_private_key): Likewise. + (rsa_clear_private_key): Likewise. + + * aes-meta.c: New file. + * arcfour-meta.c: New file. + * cast128-meta.c: New file. + * serpent-meta.c: New file. + * twofish-meta.c: New file. + + * examples/nettle-benchmark.c: Use the interface in nettle-meta.h. + +2002-01-11 Niels Möller + + Don't use m4 for generating test programs, it's way overkill. Use + the C preprocessor instead. + * testsuite/*-test.c: New file. + + * hmac.c, hmac.h, hmac-md5.c: New files. + + Defined structures describing the algoriths. Useful for code that + wants to treat an algorithm as a black box. + * nettle-meta.h, md5-meta.c, sha1-meta.c, sha256-meta.c: New + files. + +2002-01-09 Niels Möller + + * rsa-compat.c: Updated for new md5 and rsa conventions. + + * rsa_md5.c: Represent a signature as an mpz_t, not a string. + Updated calls of md5 functions. + * rsa_sha1.c: Likewise. + + * rsa.c (rsa_prepare_public_key): Renamed function, was + rsa_init_public_key. + (rsa_prepare_private_key): Renamed function, was + rsa_init_private_key. + + * nettle.texinfo (Hash functions): Update for the changed + interface without *_final. Document sha256. + + * testsuite/md5-test.m4, testsuite/sha1-test.m4, + testsuite/sha256-test.m4, testsuite/yarrow-test.c: Updated for new + hash function interface. + + * yarrow256.c: Removed calls of sha256_final and and some calls of + sha256_init. + + * md5-compat.c (MD5Final): Call only md5_digest. + + * md5.c (md5_digest): Call md5_final and md5_init. + (md5_final): Declared static. + sha1.c, sha256.c: Analogous changes. + + * bignum.c (nettle_mpz_get_str_256): Declare the input argument + const. + +2001-12-14 Niels Möller + + * Makefile.am (EXTRA_DIST): Added $(des_headers). Changed + dependencies for $(des_headers) to depend only on the source file + desdata.c, not on the executable. + +2001-12-12 Niels Möller + + * testsuite/yarrow-test.c (main): Updated testcase to match fixed + generator. Send verbose output to stdout, not stderr. + + * yarrow256.c (yarrow_slow_reseed): Bug fix, update the fast pool + with the digest of the slow pool. + (yarrow256_init): Initialize seed_file and counter to zero, to + ease debugging. + +2001-12-07 Niels Möller + + * bignum.c (nettle_mpz_get_str_256): Fixed handling of leading + zeroes. + +2001-12-05 Niels Möller + + * testsuite/yarrow-test.c (main): Updated test to match the fixed + key event estimator. + + * yarrow_key_event.c (yarrow_key_event_estimate): Fixed handling + of timing info. + + * nettle.texinfo (Copyright): Say that under certain + circumstances, Nettle can be used as if under the LGPL. + + * README: Added a paragraph on copyright. + +2001-11-15 Niels Möller + + * yarrow256.c (yarrow256_force_reseed): New function. + +2001-11-14 Niels Möller + + * testsuite/yarrow-test.c (main): Use yarrow256_is_seeded. + + * yarrow256.c (yarrow256_needed_sources): New function. + (yarrow256_is_seeded): New function. + (yarrow256_update): Use yarrow256_needed_sources. + +2001-11-14 Niels Möller + + * testsuite/yarrow-test.out: Updated, to match the seed-file aware + generator. + + * testsuite/yarrow-test.c: Updated expected_output. Check the seed + file contents at the end. + + * yarrow256.c (yarrow256_seed): New function. + (yarrow_fast_reseed): Create new seed file contents. + +2001-11-13 Niels Möller + + * yarrow.h: Deleted yarrow160 declarations. + +2001-11-02 Niels Möller + + * yarrow256.c (yarrow256_init): Fixed order of code and + declarations. + +2001-10-30 Niels Möller + + * rsa-compat.h: Added real prototypes and declarations. + + * Makefile.am (libnettle_a_SOURCES): Added rsa-compat.h and + rsa-compat.c. + + * rsa-compat.c: New file, implementing RSA ref signature and + verification functions. + + * configure.in: Check for libgmp. Deleted tests for SIZEOF_INT and + friends. + + * rsa_sha1.c: New file, PKCS#1 rsa-sha1 signatures. + * rsa_md5.c: New file, PKCS#1 rsa-md5 signatures. + + * rsa.c: New file with general rsa functions. + + * Makefile.am (libnettle_a_SOURCES): Added rsa and bignum files. + + * bignum.c, bignum.h: New file, with base256 functions missing in + gmp. + + * testsuite/Makefile.am: Added bignum-test. + + * testsuite/run-tests (test_program): Check the xit code more + carefully, and treat 77 as skip. This convention was borrowed from + autotest. + + * testsuite/macros.m4: New macro SKIP which exits with code 77. + + * testsuite/bignum-test.m4: New file. + +2001-10-15 Niels Möller + + * testsuite/Makefile.am (EXTRA_DIST): Include rfc1750.txt in the + distribution. + +2001-10-14 Niels Möller + + * testsuite/des-test.m4: Added testcase taken from applied + cryptography. + + * testsuite/yarrow-test.c: Use sha256 instead of sha1 for checking + input and output. Updated the expected values. + + * yarrow256.c (YARROW_RESEED_ITERATIONS): New constant. + (yarrow_iterate): New function. + (yarrow_fast_reseed): Call yarrow_iterate. + + * testsuite/yarrow-test.c: Added verbose flag, disabled by + default. + +2001-10-12 Niels Möller + + * examples/nettle-benchmark.c: Added more ciphers. + + * Makefile.am (SUBDIRS): Added the examples subdir. + + * configure.in: Output examples/Makefile. + +2001-10-12 Niels Möller + + * examples/nettle-benchmark.c: New benchmarking program. + +2001-10-10 Niels Möller + + * testsuite/yarrow-test.c: Open rfc1750.txt. Hash input and + output, and compare to expected values. + + * testsuite/Makefile.am (CFLAGS): Don't disable optimization. + (run-tests): Set srcdir in the environment when running run-tests. + + * testsuite/rfc1750.txt: Added this rfc as test input for yarrow. + + * yarrow_key_event.c (yarrow_key_event_estimate): Check if + previous is zero. + (yarrow_key_event_init): Initialize previous to zero. + + * yarrow256.c: Added debug some output. + + * testsuite/yarrow-test.c (main): Better output of entropy + estimates at the end. + +2001-10-09 Niels Möller + + * testsuite/Makefile.am (TS_PROGS): Added yarrow-test. + + * testsuite/yarrow-test.c: New file. + + * yarrow256.c (yarrow256_init): Initialize the sources. + (yarrow256_random): Fixed loop condition. + + * yarrow.h (YARROW_KEY_EVENT_BUFFER): New constant. + + * yarrow_key_event.c: New file. + + * Makefile.am (libnettle_a_SOURCES): Added yarrow_key_event.c. + +2001-10-08 Niels Möller + + * yarrow.h (struct yarrow_key_event_ctx): New struct. + + * yarrow256.c (yarrow_fast_reseed): Generate two block of output + using the old key and feed into the pool. + + * yarrow.h (struct yarrow256_ctx): Deleted buffer, index and + block_count. + + * yarrow256.c (yarrow_fast_reseed): New function. + (yarrow_slow_reseed): New function. + (yarrow256_update): Check seed/reseed thresholds. + (yarrow_gate): New function, extracted from + yarrow_generate_block_with_gate which was deleted. + (yarrow_generate_block_with_gate): Deleted function. + (yarrow256_random): Don't buffer any output, instead gate after + each request. + (YARROW_GATE_THRESHOLD): Deleted constant. + +2001-10-07 Niels Möller + + * Makefile.am: Added yarrow files. + + * yarrow256.c: New file, implementing Yarrow. Work in progress. + + * sha256.c: New file, implementing sha256. + + * testsuite/Makefile.am (CFLAGS): Added sha256-test. + + * testsuite/sha256-test.m4: New testcases for sha256. + + * shadata.c: New file, for generating sha256 constants. + + * sha.h: Renamed sha1.h to sha.h, and added declarations for + sha256. + +2001-10-05 Niels Möller + + * testsuite/aes-test.m4: Added a comment with NIST test vectors. + +2001-10-04 Niels Möller + + * rsa.h, rsa-compat.h, yarrow.h: New files. + +2001-09-25 Niels Möller + + * Released version 1.0. + +2001-09-25 Niels Möller + + * sha1.c: Include stdlib.h, for abort. + + * md5.c: Include string.h, for memcpy. + + * testsuite/Makefile.am (M4_FILES): New variable. Explicitly list + those C source files that should be generated by m4. + + * configure.in: Changed package name from "libnettle" to "nettle". + + * Makefile.am (EXTRA_DIST): Added .bootstrap. + + * AUTHORS: Added a reference to the manual. + +2001-09-25 Niels Möller + + * des-compat.c (des_cbc_cksum): Bug fix, local variable was + declared in the middle of a block. + +2001-09-19 Niels Möller + + * nettle.texinfo (Compatibility functions): New section, + mentioning md5-compat.h and des-compat.h. + +2001-09-18 Niels Möller + + * index.html: New file. + +2001-09-16 Niels Möller + + * nettle.texinfo: Added description of des3. Minor fixes. + + * testsuite/des-compat-test.c (cbc_data): Shorten to 32 bytes (4 + blocks), the last block of zeroes wasn't used anyway. + + * des-compat.c (des_compat_des3_decrypt): Decrypt in the right + order. + (des_ncbc_encrypt): Bug fixed. + (des_cbc_encrypt): Rewritten as a wrapper around des_ncbc_encrypt. + +2001-09-14 Niels Möller + + * testsuite/des-compat-test.c: New file, copied from libdes + (freeswan). All implemented functions but des_cbc_cksum seems to + work now. + + * testsuite/Makefile.am (TS_PROGS): Added des-compat-test. + + * des-compat.c: Added libdes typedef:s. Had to remove all use of + const in the process. + (des_check_key): New global variable, checked by des_set_key. + + * des.c (des_set_key): Go on and expand the key even if it is + weak. + + * des-compat.c (des_cbc_cksum): Implemented. + (des_key_sched): Fixed return values. + +2001-09-11 Niels Möller + + * Makefile.am: Added des-compat.c and des-compat.h + + * des-compat.c: Bugfixes, more functions implemented. + + * des-compat.h: Define DES_ENCRYPT and DES_DECRYPT. Bugfixes. + +2001-09-10 Niels Möller + + * nettle.texinfo (Copyright): Added copyright information for + serpent. + (Miscellaneous functions): Started writing documentation on the CBC + functions. + (Cipher Block Chaining): This section more or less complete now. + +2001-09-09 Niels Möller + + * testsuite/cbc-test.m4: Record intermediate values in a comment. + * testsuite/des3-test.m4: Likewise. + + * testsuite/aes-test.m4: Added test case that appeared broken in + the cbc test. + + * cbc.c (cbc_encrypt): Bug fix, encrypt block *after* XOR:ing the + iv. + + * Makefile.am (libnettleinclude_HEADERS): Added cbc.h. Deleted + des3.h. + (libnettle_a_SOURCES): Added des3.c. + + * testsuite/Makefile.am (TS_PROGS): Added des3-test and cbc-test. + + * testsuite/cbc-test.m4: New testcase. + + * testsuite/des3-test.m4: New testcase. + + * cbc.h (CBC_CTX): New macro. + (CBC_ENCRYPT): New macro. + (CBC_DECRYPT): New macro. + + * des.c (des_fix_parity): New function. + + * des3.c: New file, implementing triple des. + +2001-09-06 Niels Möller + + * cbc.c, cbc.h: New files, for general CBC encryption. + + * des-compat.h: Added some prototypes. + +2001-09-05 Niels Möller + + * testsuite/Makefile.am (TS_PROGS): Added md5-compat-test. + + * README: Copied introduction from the manual. + + * configure.in: Bumped version to 1.0. + + * Makefile.am (libnettleinclude_HEADERS): Added missing includes. + (libnettle_a_SOURCES): Added md5-compat.c and md5-compat.h. + + * md5-compat.c, md5-compat.h: New files, implementing an RFC + 1321-style interface. + +2001-09-02 Niels Möller + + * twofish.c (twofish_decrypt): Fixed for();-bug in the block-loop. + Spotted by Jean-Pierre. + (twofish_encrypt): Likewise. + +2001-07-03 Niels Möller + + * testsuite/testutils.c: Include string.h. + + * twofish.c: Include string.h. + +2001-06-17 Niels Möller + + * Makefile.am (des_headers): Dont use $(srcdir)/-prefixes as that + seems to break with GNU make 3.79.1. + + * testsuite/testutils.c, testsuite/testutils.h: Use , + not . + Include . + +2001-06-17 Niels Möller + + * Use , not . + + * blowfish.h (BLOWFISH_MAX_KEY_SIZE): Fixed, should be 56. + + * Fixed copyright notices. + + * Makefile.am (libnettle_a_SOURCES): Added desinfo.h and + desCode.h. + (info_TEXINFOS): Added manual. + (EXTRA_DIST): Added nettle.html. + (%.html): Added rule for building nettle.html. + + * nettle.texinfo: New manual. + + * configure.in: Bumped version to 0.2. + + * testsuite/Makefile.am (TS_PROGS): Added cast128 test. + + * Added CAST128. + + * testsuite/serpent-test.m4: Added a few rudimentary tests + extracted from the serpent package. + + * twofish.c: Adapted to nettle. Made constant tables const. + Deleted bytes_to_word and word_to_bytes; use LE_READ_UINT32 and + LE_WRITE_UINT32 instead. + (twofish_selftest): Deleted. Moved the tests to the external + testsuite. + (twofish_set_key): Don't silently truncate too large keys. + + * sha1.c (sha1_update): Use unsigned for length. + + * serpent.c (serpent_set_key): Read the key backwards. Fixed + padding (but there are no test vectors for key_size not a multiple + of 4). + (serpent_encrypt): Read and write data in the strange order used + by the reference implementation. + (serpent_decrypt): Likewise. + + * macros.h (FOR_BLOCKS): New macro, taken from lsh. + + * blowfish.h (struct blowfish_ctx): Use a two-dimensional array + for s. + + * blowfish.c (initial_ctx): Arrange constants into a struct, to + simplify key setup. + (F): Deleted all but one definitions of the F function/macro. + Added a context argument, and use that to find the subkeys. + (R): Added context argument, and use that to find the subkeys. + (blowfish_set_key): Some simplification. + + (encrypt): Deleted code for non-standard number of rounds. Deleted + a bunch of local variables. Using the context pointer for + everything should consume less registers. + (decrypt): Likewise. + + * Makefile.am (libnettle_a_SOURCES): Added twofish. + +2001-06-16 Niels Möller + + * testsuite/blowfish-test.m4: Fixed test. + + * Added twofish implementation. + + * blowfish.h (struct blowfish_ctx): Use the correct size for the p + array. + +2001-06-15 Niels Möller + + * testsuite/blowfish-test.m4: Fixed testcase, use correct key + length. + + * Makefile.am (libnettle_a_SOURCES): Added blowfish files. + ($(des_headers)): Strip directory part when passing file name to + desdata. + + * testsuite/blowfish-test.m4: Added one test, from GNUPG. + + * Created blowfish.c and blowfish.h (from GNUPG via LSH). Needs + more work. + + * aes.h: Fixed copyright notice to not mention GNU MP. XXX: Review + all nettle copyrights. + + * testsuite/Makefile.am (TS_PROGS): Added tests for twofish and + blowfish. + +2001-06-13 Niels Möller + + * Makefile.am (libnettle_a_SOURCES): Added serpent files. + +2001-06-12 Niels Möller + + * des.c (des_encrypt, des_decrypt): Assert that the key setup was + successful. + + * testsuite/Makefile.am (TS_PROGS): Added tests for des and sha1. + + * testsuite/sha1-test.m4: New file. + + * testsuite/des-test.m4: New file. + + * Added sha1 files. + + * Added desCore files. + + * Makefile.am: Added desCore and sha1. + +2001-04-17 Niels Möller + + * install-sh: Copied the standard install script. + + * testsuite/Makefile.am (CFLAGS): Disable optimization. Add + $(top_srcdir) to the include path. + (EXTRA_DIST): Added testutils.h, testutils.c and run-tests. + (run-tests): Fixed path to run-tests. + + * Makefile.am (EXTRA_DIST): Added memxor.h. + (libnettleinclude_HEADERS): Install headers in + $(libnettleincludedir). + +2001-04-13 Niels Möller + + * Initial checkin. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..5458714 --- /dev/null +++ b/INSTALL @@ -0,0 +1,234 @@ +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. + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..ff15d74 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,431 @@ +# Nettle Makefile + +@SET_MAKE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +LIBOBJS = @LIBOBJS@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = $(INSTALL_PROGRAM) -s +MKDIR_P = @MKDIR_P@ + +SUBDIRS = tools testsuite examples + +include config.make + +PRE_CPPFLAGS = -I. +# FIXME: Add configuration of LIBEXT? +LIBTARGETS = libnettle.a @IF_HOGWEED@ libhogweed.a +SHLIBTARGETS = $(LIBNETTLE_FORLINK) @IF_HOGWEED@ $(LIBHOGWEED_FORLINK) + +TARGETS = aesdata$(EXEEXT) desdata$(EXEEXT) shadata$(EXEEXT) \ + $(LIBTARGETS) @IF_SHARED@ $(SHLIBTARGETS) + +DOCTARGETS = nettle.info nettle.html nettle.pdf + +all check install uninstall: + $(MAKE) $@-here + set -e; for d in $(SUBDIRS); do \ + echo "Making $@ in $$d" ; (cd $$d && $(MAKE) $@); done + +clean distclean mostlyclean maintainer-clean tags: + set -e; for d in $(SUBDIRS); do \ + echo "Making $@ in $$d" ; (cd $$d && $(MAKE) $@); done + $(MAKE) $@-here + +check-here: + true + +# FIXME: Remove. These targets aren't supported, but they are expected by the +# automake generated Makefiles in the lsh build. +dvi installcheck uninstallcheck: + true + +all-here: $(TARGETS) $(DOCTARGETS) + +nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \ + aes-encrypt-internal.c aes-encrypt.c aes-encrypt-table.c \ + aes-set-encrypt-key.c aes-set-decrypt-key.c aes-meta.c \ + arcfour.c arcfour-crypt.c arcfour-meta.c \ + arctwo.c arctwo-meta.c \ + base16-encode.c base16-decode.c base16-meta.c \ + base64-encode.c base64-decode.c base64-meta.c \ + camellia-crypt.c camellia-crypt-internal.c \ + camellia-set-encrypt-key.c camellia-set-decrypt-key.c \ + camellia-table.c camellia-meta.c \ + cast128.c cast128-meta.c \ + blowfish.c \ + cbc.c ctr.c \ + des.c \ + des3.c des-compat.c \ + hmac.c hmac-md5.c hmac-sha1.c \ + hmac-sha224.c hmac-sha256.c hmac-sha384.c hmac-sha512.c \ + knuth-lfib.c \ + md2.c md2-meta.c md4.c md4-meta.c \ + md5.c md5-compress.c md5-compat.c md5-meta.c \ + sha1.c sha1-compress.c sha1-meta.c \ + sha256.c sha256-compress.c sha224-meta.c sha256-meta.c \ + sha512.c sha512-compress.c sha384-meta.c sha512-meta.c \ + serpent.c serpent-meta.c \ + twofish.c twofish-meta.c \ + yarrow256.c yarrow_key_event.c \ + buffer.c buffer-init.c realloc.c \ + nettle-internal.c write-be32.c + +hogweed_SOURCES = sexp.c sexp-format.c \ + sexp-transport.c sexp-transport-format.c \ + bignum.c bignum-next-prime.c \ + bignum-random.c bignum-random-prime.c \ + sexp2bignum.c \ + pkcs1.c pkcs1-rsa-md5.c pkcs1-rsa-sha1.c \ + pkcs1-rsa-sha256.c pkcs1-rsa-sha512.c \ + rsa.c rsa-sign.c rsa-verify.c \ + rsa-md5-sign.c rsa-md5-verify.c \ + rsa-sha1-sign.c rsa-sha1-verify.c \ + rsa-sha256-sign.c rsa-sha256-verify.c \ + rsa-sha512-sign.c rsa-sha512-verify.c \ + rsa-encrypt.c rsa-decrypt.c \ + rsa-keygen.c rsa-compat.c \ + rsa2sexp.c sexp2rsa.c \ + dsa.c dsa-sign.c dsa-verify.c dsa-keygen.c \ + dsa-sha1-sign.c dsa-sha1-verify.c \ + dsa-sha256-sign.c dsa-sha256-verify.c \ + dsa2sexp.c sexp2dsa.c \ + pgp-encode.c rsa2openpgp.c \ + der-iterator.c der2rsa.c der2dsa.c + +HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \ + base16.h base64.h buffer.h camellia.h cast128.h \ + cbc.h ctr.h \ + des.h des-compat.h dsa.h \ + hmac.h \ + knuth-lfib.h \ + macros.h \ + md2.h md4.h \ + md5.h md5-compat.h \ + memxor.h \ + nettle-meta.h nettle-types.h \ + pgp.h pkcs1.h realloc.h rsa.h rsa-compat.h \ + sexp.h \ + serpent.h sha.h twofish.h \ + yarrow.h + +INSTALL_HEADERS = $(HEADERS) nettle-stdint.h + +SOURCES = $(nettle_SOURCES) $(hogweed_SOURCES) aesdata.c desdata.c shadata.c + +DISTFILES = $(SOURCES) $(HEADERS) .bootstrap aclocal.m4 configure.ac \ + configure stamp-h.in \ + config.guess config.sub install-sh texinfo.tex \ + config.h.in config.m4.in config.make.in Makefile.in \ + README AUTHORS COPYING COPYING.LIB INSTALL NEWS TODO ChangeLog \ + memxor.c $(des_headers) descore.README \ + aes-internal.h camellia-internal.h cast128_sboxes.h desinfo.h desCode.h \ + serpent_sboxes.h nettle-internal.h nettle-write.h prime-list.h \ + asm.m4 \ + nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c + +# Rules building static libraries +nettle_OBJS = $(nettle_SOURCES:.c=.$(OBJEXT)) $(LIBOBJS) +nettle_PURE_OBJS = $(nettle_OBJS:.$(OBJEXT)=.p$(OBJEXT)) + +hogweed_OBJS = $(hogweed_SOURCES:.c=.$(OBJEXT)) +hogweed_PURE_OBJS = $(hogweed_OBJS:.$(OBJEXT)=.p$(OBJEXT)) + +# FIXME: Do we really need to delete the archive first? +libnettle.a: $(nettle_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(nettle_OBJS) + $(RANLIB) $@ + +# FIXME: Do we really need to delete the archive first? +libhogweed.a: $(hogweed_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(hogweed_OBJS) + $(RANLIB) $@ + +.c.$(OBJEXT): + $(COMPILE) $(CCPIC_MAYBE) -c $< \ + && $(DEP_PROCESS) + +# Rules building shared libraries +$(LIBNETTLE_FORLINK): $(nettle_PURE_OBJS) + $(LIBNETTLE_LINK) $(nettle_PURE_OBJS) -o $@ $(LIBNETTLE_LIBS) + -mkdir .lib 2>/dev/null + [ -z "$(LIBNETTLE_SONAME)" ] || (cd .lib \ + && ln -sf ../$(LIBNETTLE_FORLINK) $(LIBNETTLE_SONAME)) + +$(LIBHOGWEED_FORLINK): $(hogweed_PURE_OBJS) $(LIBNETTLE_FORLINK) + $(LIBHOGWEED_LINK) $(hogweed_PURE_OBJS) -o $@ $(LIBHOGWEED_LIBS) + -mkdir .lib 2>/dev/null + [ -z "$(LIBHOGWEED_SONAME)" ] || (cd .lib \ + && ln -sf ../$(LIBHOGWEED_FORLINK) $(LIBHOGWEED_SONAME)) + +.c.p$(OBJEXT): + $(COMPILE) $(SHLIBCFLAGS) -c $< -o $@ \ + && $(DEP_PROCESS) + +# For Solaris and BSD make, we have to use an explicit rule for each executable +aesdata$(EXEEXT): aesdata.$(OBJEXT) + $(LINK) aesdata.$(OBJEXT) $(LIBS) -o aesdata$(EXEEXT) + +desdata$(EXEEXT): desdata.$(OBJEXT) + $(LINK) desdata.$(OBJEXT) $(LIBS) -o desdata$(EXEEXT) + +shadata$(EXEEXT): shadata.$(OBJEXT) + $(LINK) shadata.$(OBJEXT) $(LIBS) -lm -o shadata$(EXEEXT) + +# .$(OBJEXT)$(EXEEXT): +# $(LINK) $< $(LIBS) -o $@ + +# desCore rules +# It seems using $(srcdir)/ doesn't work with GNU make 3.79.1 +# des_headers = $(srcdir)/rotors.h $(srcdir)/keymap.h +des_headers = rotors.h keymap.h + +# Generate DES headers. +$(des_headers): desdata.c + $(MAKE) desdata$(EXEEXT) + f="$(srcdir)/`basename $@`"; \ + ./desdata$(EXEEXT) $(@F) > $${f}T; \ + test -s $${f}T && mv -f $${f}T $$f + +des.$(OBJEXT): des.c des.h $(des_headers) + +.asm.$(OBJEXT): + $(M4) $(srcdir)/asm.m4 machine.m4 config.m4 \ + $< >$*.s + $(COMPILE) $(CCPIC_MAYBE) -c $*.s + echo "$@ : $< $(srcdir)/asm.m4 machine.m4 config.m4" >$@.d + +.asm.p$(OBJEXT): + $(M4) $(srcdir)/asm.m4 machine.m4 config.m4 \ + $< >$*.s + $(COMPILE) $(SHLIBCFLAGS) -c $*.s -o $@ + echo "$@ : $< $(srcdir)/asm.m4 machine.m4 config.m4" >$@.d + +# Texinfo rules +.texinfo.info: + cd $(srcdir) && $(MAKEINFO) --output $@ `basename "$<"` + +.texinfo.html: + cd $(srcdir) && $(MAKEINFO) --html --no-split \ + --output $@T `basename "$<"` \ + && test -s $@T && mv -f $@T $@ + +.texinfo.dvi: + cd $(srcdir) && texi2dvi `basename "$<"` + +.dvi.ps: + cd $(srcdir) && dvips -Ppdf -G0 -o `basename "$<" .dvi`.ps `basename "$<"` + +# Avoid rebuilding .dvi and .ps files when the .texinfo source is unchanged. +PS2PDFFLAGS=-dCompatibilityLevel=1.3 -dMAxSubsetPct=100 -dSubsetFonts=true -dEmbedAllFonts=true +.texinfo.pdf: + $(MAKE) `basename "$<" .texinfo`.ps + cd $(srcdir) && ps2pdf $(PS2PDFFLAGS) `basename "$<" .texinfo`.ps + +# Configure-related rules, mostly copied from the autoconf manual. No +# $(srcdir) prefixes on the targets, though. + +configure: configure.ac aclocal.m4 + cd $(srcdir) && $(AUTOCONF) + +# autoheader might not change config.h.in, so touch a stamp file. +config.h.in: stamp-h.in +stamp-h.in: configure.ac aclocal.m4 + cd $(srcdir) && $(AUTOHEADER) + echo timestamp > $(srcdir)/stamp-h.in + +config.status: configure + ./config.status --recheck + +config.h: stamp-h +stamp-h: config.h.in config.status + ./config.status config.h + echo timestamp > stamp-h + +Makefile: Makefile.in config.status + ./config.status $@ + +config.make: config.make.in config.status + ./config.status $@ + +config.m4: config.m4.in config.status + ./config.status $@ + +# Installation +install-here: install-info install-headers install-static \ + @IF_SHARED@ install-shared-nettle @IF_HOGWEED@ install-shared-hogweed + +install-static: $(LIBTARGETS) + $(MKDIR_P) $(DESTDIR)$(libdir) + for f in $(LIBTARGETS); do \ + $(INSTALL_DATA) $$f $(DESTDIR)$(libdir) ; \ + done + +install-shared-nettle: $(LIBNETTLE_FORLINK) + $(MKDIR_P) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) $(LIBNETTLE_FORLINK) $(DESTDIR)$(libdir)/$(LIBNETTLE_FILE) + [ -z "$(LIBNETTLE_SONAME)" ] \ + || (cd $(DESTDIR)$(libdir) \ + && ln -sf $(LIBNETTLE_FILE) $(LIBNETTLE_SONAME) \ + && ln -sf $(LIBNETTLE_FILE) $(LIBNETTLE_FORLINK)) + +install-shared-hogweed: $(LIBHOGWEED_FORLINK) + $(MKDIR_P) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) $(LIBHOGWEED_FORLINK) $(DESTDIR)$(libdir)/$(LIBHOGWEED_FILE) + [ -z "$(LIBHOGWEED_SONAME)" ] \ + || (cd $(DESTDIR)$(libdir) \ + && ln -sf $(LIBHOGWEED_FILE) $(LIBHOGWEED_SONAME) \ + && ln -sf $(LIBHOGWEED_FILE) $(LIBHOGWEED_FORLINK)) + +# I'd like to use makes VPATH search to locate the files to be +# installed. But it seems most make programs don't set $<, $^, $? and +# friends for ordinary explicit rules. + +install-info: nettle.info + $(MKDIR_P) $(DESTDIR)$(infodir) + f=nettle.info ; \ + [ -f $$f ] || f="$(srcdir)/$$f" ; \ + $(INSTALL_DATA) "$$f" $(DESTDIR)$(infodir) ; \ + if (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + install-info --info-dir="$(DESTDIR)$(infodir)" "$$f" ; \ + else : ; fi + +# NOTE: I'd like to use $^, but that's a GNU extension. $? should be +# more portable, and equivalent for phony targets. +install-headers: $(INSTALL_HEADERS) + $(MKDIR_P) $(DESTDIR)$(includedir)/nettle + for f in $(INSTALL_HEADERS) ; do \ + if [ -f "$$f" ] ; then \ + $(INSTALL_DATA) "$$f" $(DESTDIR)$(includedir)/nettle ; \ + else \ + $(INSTALL_DATA) "$(srcdir)/$$f" $(DESTDIR)$(includedir)/nettle ; \ + fi ; done + +# Uninstall +uninstall-here: uninstall-info uninstall-headers uninstall-static \ + @IF_SHARED@ uninstall-shared + +uninstall-static: + for f in $(LIBTARGETS) ; do \ + rm -f $(DESTDIR)$(libdir)/$$f ; \ + done + +uninstall-headers: + for f in $(INSTALL_HEADERS) ; do \ + rm -f $(DESTDIR)$(includedir)/nettle/$$f ; \ + done + +uninstall-info: + if (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)"/nettle.info ; \ + else : ; fi + -rm -f $(DESTDIR)$(infodir)/nettle.info + +# FIXME: Leaves the links around +uninstall-shared: uninstall-shared-nettle @IF_HOGWEED@ uninstall-shared-hogweed + +uninstall-shared-nettle: + rm -f $(DESTDIR)$(libdir)/$(LIBNETTLE_FILE) + [ -z "$(LIBNETTLE_SONAME)" ] \ + || rm -f $(LIBNETTLE_SONAME) $(LIBNETTLE_FORLINK) + +uninstall-shared-hogweed: + rm -f $(DESTDIR)$(libdir)/$(LIBHOGWEED_FILE) + [ -z "$(LIBHOGWEED_SONAME)" ] \ + || rm -f $(LIBHOGWEED_SONAME) $(LIBHOGWEED_FORLINK) + +# Distribution +distdir = $(PACKAGE_NAME)-$(PACKAGE_VERSION) +top_distdir = $(distdir) + +# NOTE: We should handle both absolute and relative $destdir. + +distdir: $(DISTFILES) + rm -rf "$(distdir)" + mkdir "$(distdir)" + set -e; for f in $(DISTFILES) ; do \ + if [ -f "$$f" ] ; then cp "$$f" "$(distdir)" ; \ + else cp "$(srcdir)/$$f" "$(distdir)" ; \ + fi ; \ + done + set -e; for d in sparc32 sparc64 x86 x86_64; do \ + mkdir "$(distdir)/$$d" ; \ + cp $(srcdir)/$$d/*.asm $(srcdir)/$$d/*.m4 "$(distdir)/$$d" ; \ + done + set -e; for d in $(SUBDIRS); do \ + sd="$(distdir)/$$d" ; \ + mkdir "$$sd" && $(MAKE) -C $$d distdir="`cd $$sd && pwd`" $@ ; \ + done + +dist: distdir + tar cf - $(distdir) | gzip -c >$(distdir).tar.gz + rm -rf $(distdir) + +rm_distcheck = test ! -d distcheck-tmp \ + || { find distcheck-tmp -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr distcheck-tmp; }; + +distcheck: dist + $(rm_distcheck) + mkdir distcheck-tmp + gzip -d < $(distdir).tar.gz \ + | { cd distcheck-tmp && tar xf - && chmod -R a-w $(distdir) ; } + mkdir distcheck-tmp/build + mkdir distcheck-tmp/install + cd distcheck-tmp/build && ../$(distdir)/configure --prefix="`cd ../install && pwd`" + cd distcheck-tmp/build && $(MAKE) + cd distcheck-tmp/build && $(MAKE) check + cd distcheck-tmp/build && $(MAKE) install + cd distcheck-tmp/build && $(MAKE) uninstall + cd distcheck-tmp && find install -type f -print > leftover-install-files + @test `cat distcheck-tmp/leftover-install-files | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + cat distcheck-tmp/leftover-install-files ; \ + exit 1; } + chmod -R a-w distcheck-tmp/install + mkdir distcheck-tmp/destdir + destdir="`cd distcheck-tmp/destdir && pwd`" \ + && cd distcheck-tmp/build \ + && $(MAKE) install DESTDIR="$$destdir" \ + && $(MAKE) uninstall DESTDIR="$$destdir" + cd distcheck-tmp && find destdir -type f -print > leftover-destdir-files + @test `cat distcheck-tmp/leftover-destdir-files | wc -l` -le 1 \ + || { echo "ERROR: destdir files left after uninstall:" ; \ + cat distcheck-tmp/leftover-destdir-files ; \ + exit 1; } + cd distcheck-tmp/build && $(MAKE) dist + cd distcheck-tmp/build && rm *.gz + cd distcheck-tmp/build && $(MAKE) distclean + cd distcheck-tmp && find build -type f -print > leftover-build-files + @test `cat distcheck-tmp/leftover-build-files | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + cat distcheck-tmp/leftover-build-files ; \ + exit 1; } + $(rm_distcheck) + +clean-here: + -rm -f $(TARGETS) *.$(OBJEXT) *.p$(OBJEXT) *.s + -rm -rf .lib + +distclean-here: clean-here + -rm -f config.h stamp-h config.log config.status machine.m4 \ + config.make config.m4 Makefile nettle-stdint.h *.asm *.d + +maintainer-clean-here: + -rm -f $(DOCTARGETS) *.dvi *.ps + +tags-here: + etags -o $(srcdir)/TAGS $(srcdir)/*.c $(srcdir)/*.h + +DEP_FILES = $(SOURCES:.c=.$(OBJEXT).d) $(SOURCES:.c=.p$(OBJEXT).d) +@DEP_INCLUDE@ $(DEP_FILES) diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e219630 --- /dev/null +++ b/NEWS @@ -0,0 +1,410 @@ +NEWS for the 2.1 release + + *Important*: this release breaks source and binary + compatibility for the digital signature functions, and for the + DES and BLOWFISH ciphers which have weak keys. + + Incompatible changes: + + * The functions rsa_md5_sign, rsa_sha1_sign and + rsa_sha256_sign, and the corresponding _digest variants, now + have a return value which callers should check. The functions + return failure if the key is too small for the type of + signature. + + * The functions dsa_sign and dsa_verify are renamed to + dsa_sha1_sign and dsa_sha1_verify. The _-digest variants are + renamed similarly. These functions now have a return value + which callers should check, and they return failure if the + number q is not of the appropriate size. + + * The return value from des_set_key, des3_set_key and + blowfish_set_key now indicates whether or not the given key + is weak. But in either case, the key setup is done, and + applications that don't care about weak keys can ignore the + return value. + + The incompatible part of this change is that enum des_error + and enum blowfish_error has been deleted, and so has the + status attribute in struct des_ctx, struct des3_ctx, and + struct blowfish_ctx. + + The shared library names are libnettle.so.4.0 and + libhogweed.so.2.0, with sonames libnettle.so.4 and + libhogweed.so.2. + + Other changes: + + * Support for the Camellia block cipher, including an + assembler implementation for x86_32. + + * New function aes_invert_key, useful for applications that + need both encryption and decryption using the same AES key. + + * des_set_key and des3_set_key no longer check the key parity + bits. Parity bits are silently ignored. A new function + des_check_parity is provided, for applications that care + about the DES parity bits. + + * Support for sha224, sha384 and sha512. + + * Support for digital signatures using rsa-sha512 and + dsa-sha256. Due to lack of official test vectors and interop + testing, this support should be considered somewhat + experimental. + + * Key generation for RSA and DSA changed to use Maurer's + algorithm to generate provably prime numbers (as usual, the + mathematical proof does not guaranteee that the + implementation is bug free). + + * x86_64 assembler implementation actually included in the + distribution (was accidentally left out in nettle-2.0). + + * Configure script now detects if the compiler uses a 32-bit + or 64-bit ABI on x86_64 (prevously did this for sparc only). + Also sets the default location for installing libraries + (libdir) depending on system type and the ABI used. + + * Added the nettle and gmp libraries as dependencies when + linking shared library libhogweed.so. On systems using + shared libraries where such dependencies work (in + particular, ELF systems), it is sufficient to link + applications with -lhogweed. For static linking -lhogweed + -lnettle -lgmp is still required. + + * The program pkcs1-conv is extended to also handle dsa keys. + Contributed by Magnus Holmgren. + + * Slightly improved sha1 performance on x86. + +NEWS for the 2.0 release + + This release breaks binary compatibility by splitting the + library into two. Some other smaller changes that are not + backwards compatible are also done at the same time. + + * The nettle library is split into two libraries, libnettle + and libhogweed. libnettle contains the symmetric crypto + algorithms that don't depend on GMP, while libhogweed + contains the public key algorithms that depend on GMP. + Using a single library worked fine with static linking, but + not with dynamic linking. Consider an application that uses + nettle and which doesn't use any public key cryptography. If + this application is linked dynamically to nettle, it would + have to be linked also with GMP if and only if public key + support was enabled when the nettle library was installed. + + The library names are libnettle.so.3.0 and + libhogweed.so.1.0, with sonames libnettle.so.3 and + libhogweed.so.1. + + * Function typedefs have been changed to non-pointer types. + E.g, the + + typedef void (nettle_hash_init_func *)(void *ctx); + + of previous versions is replaced by + + typedef void (nettle_hash_init_func)(void *ctx); + + This makes it possible to use the type when declaring + functions, like + + nettle_hash_init_func foo_hash_init; + + void foo_hash_init(void *ctx) { ... } + + * Changes to the yarrow256 interface. The automatic seed file + generation, and the seed_file member in struct + yarrow256_ctx, has been removed. To generate a new seed + file, use yarrow256_random. The function + yarrow256_force_reseed has been replaced by the two + functions yarrow256_fast_reseed and yarrow256_slow_reseed, + which were previously static. This interface change makes it + easier to mix in the current content of the seed file before + overwriting it with newly generated data. + + Other changes: + + * Nettle manual now contributed to the public domain, to + enable remixing into documentation of programs that use + Nettle. + + * The sexp-conv program preserves comments when using the + advanced syntax for output. Optionally locks the output + file. + + * The base64 decoder recognizes ASCII FF (form feed) and VT + (vertical tab) as white space. + + * New x86_64 implementations of AES and SHA1. On a 2.2 GHz + opteron, SHA1 was benchmarked at 250 MByte/s, and AES-128 at + 110 MByte/s. + + * Performance of AES increased by 20-30% on x86. + + * New programs in the examples directory: erathostenes and + next-prime. + +NEWS for the 1.15 release + + Added support for PKCS#1 style RSA signatures using SHA256, + according to RFC 3447. Currently lacks interoperability + testing. + + Header files are now C++ aware, so C++ programs using Nettle + should now use plain + + #include + + rather than + + #extern "C" { + #include + } + + as was the recommendation for the previous version. This + breaks source-level compatibility with C++, even though + there's full binary compatibility. + + The file rfc1750.txt (which is considered non-free by debian) + has been removed from the distribution. The file was used as input + for the Yarrow testcase, and has been replaced by the short + story "The Gold-bug" by Edgar Allan Poe. Anyway, RFC 1750 is + obsoleted by RFC 4086. + + Fixes for Darwin shared library support, contributed by Grant + Robinsson. + + Example programs now use a supplied getopt.c. + + Configure tests for assemblers with a logarithmic .align + directive. + + The library is intended to be upwards binary compatible with + earlier versions. The library name is libnettle.so.2.6, soname + is still libnettle.so.2. + +NEWS for the 1.14 release + + Experimental support for reading keys in PKCS#1 ASN1/DER + format, and a new command line tool pkcs1-conv. + + Improved MD5 performance on x86. + + Fixed support for sparc64. + + Reorganized AES code. Better performance for all three + implementations (C, x86 assembler, sparc assembler). + + New sparc assembler for arcfour. Compared to the code + generated by gcc, the new code is about 25% faster on old + sparcs, and 6 times faster on ultrasparc. + + Replaced the internal function nettle_mpz_from_octets with a + call to mpz_import, if available in the installed GMP library. + + More Makefile fixes; it now seems to work to build with + the the make programs on Solaris and FreeBSD (although + --disable-dependency-tracking is required for the latter). + + The library is intended to be binary compatible with earlier + versions. The library name is libnettle.so.2.5, soname is + still libnettle.so.2. + +NEWS for the 1.13 release + + Fixed problem with broken m4 on bsd, which resulted in + corrupted x86 assembler for sha1. + + Nettle probably works on windows: I've been able to cross + compile it with ./configure --host=i586-mingw32msvc (without + public-key support), and the testsuite binaries seem to run + fine in Wine. + + Implemented CTR mode. + + Improved sha1 performance on x86. + + Configure check to figure out if symbols in assembler files + need a leading underscore. + + Improved benchmark program. Displays cycles per byte and block, + and compares with openssl (if openssl is installed). + + Terminating newline in output from sexp-conv --hash. + + The library is intended to be binary compatible with earlier + versions. The library name is libnettle.so.2.4. However, the + interface for the internal function _nettle_sha1_compress has + changed; any program that calls this function directly will + break. + +NEWS for the 1.12 release + + Fixed a bug in the configure script. + + Updated the description of aes_set_encrypt_key and + aes_set_decrypt_key in the manual. + +NEWS for the 1.11 release + + Nettle no longer uses automake. Side effects: + + * Dependency tracking is enabled only for gcc-3 (help with + supporting dependency tracking with other compilers is + appreciated). + + * Makefile compatibility with make programs other than GNU + make is mostly unknown, please report any problems. + + Support for arctwo. + + Fixes to the libdes compatibility code. Declarations should + now match openssl/libdes better. des_cbc_cksum pads + input with NUL's, if it's not an integral number of blocks (in + general, such unreversible padding is a bad idea). + + By default, also the static library is compiled as position + independent code. This is needed on some systems to make it + possible to link nettle into a dynamically loaded module. Use + the configure flag --disable-pic if this is not desired. + + Stricter constness typing for the sexp_iterator_assoc and + sexp_iterator_check_types arguments. + + Minor tweaks of arcfour on x86 cpu:s, to speed it up on older + x86 variants such as PII and PPro. + + The shared library is intended to be binary compatible with + nettle-1.8 - nettle-1.10. Only the minor version number of the + shared library is increased. The soname is still + libnettle.so.2. + +NEWS for the 1.10 release + + Nettle should now compile also on Tru64, Darwin, FreeBSD and + Windows. (The only tested windows build uses the rntcl rsh + wrapper to run the command line M$ C compiler "cl". See + http://pike.ida.liu.se for those tools, I don't know all + details about the Pike team's windows setup). + + There are some known testsuite failures, on Windows and on one + of the xenofarm HPUX machines, see + http://www.lysator.liu.se/~nisse/xeno-lsh/latest.html. Help + tracking these down is appreciated. + + There are no new features. + + This release is intended to be binary compatible with + nettle-1.8 and nettle-1.9. + +NEWS for the 1.9 release + + Optimized C implementation of arcfour. Optimized x86 + implementations of arcfour and sha1. + + Improved benchmark program. + + Fixed bug in the rsa-encrypt example program. + + Fixed bug in make install, some of the header files were + forgotten. + + Portability fixes. Fixes to make Nettle compile on systems + without gmp. This version has been tested on GNU/Linux, + Solaris, HPUX and AIX. + + The shared library is intended to be binary compatible with + nettle-1.8. Only the minor version number of the shared + library is increased. + +NEWS for the 1.8 release + + New example programs, demonstrating encrypting and decrypting + files using RSA, and random sessions keys for bulk encryption + and message authentication. + + Support for systems that don't have alloca. On such systems, + some of Nettle's functions have arbitrary limits applied to + their input. + + Uses AX_CREATE_STDINT_H, to support systems without + inttypes.h. + + Support for the md2 and md4 hash functions. + + New name mangling, to reduce the risk of link collisions. All + functions (except memxor) now use a nettle_ or _nettle_ prefix + when seen by the linker. For most functions, the header file + that declares a function also uses #define to provide a + shorter more readable name without the prefix. + + The shared library soname for this version is libnettle.so.2. + +NEWS for the 1.7 release + + Implemented DSA. + + Renamed RSA functions for consistency. Now it's + rsa_public_key_init, not rsa_init_public_key, etc. + + Both RSA and DSA now have sign/verify functions that take the + hash digest as argument. + + A rewritten and much more powerful sexp-conv program. + + Other changes to the sexp code, in particular updating it to + the latest SPKI draft. + + Building nettle as a shared library (ELF only) seems to work. + The version number is increased, so the library "soname" for + this release is "libnettle.so.1". + + Bugfixes. Fixes for build and portability problems. + +NEWS for the 1.6 release + + Optimized assembler implementations of aes, for sparc and x86. + + The aes interface has changed slightly. The function + aes_set_key is no more. Instead one has to use + aes_set_encrypt_key or aes_set_decrypt_key. Sorry about that. + + New example programs, rsa-keygen, rsa-sign and rsa-verify, + located in the examples directory. + + New configure option --enable-shared, which builds a shared + library. Not tested. + + New experimental features, including sexp parsing and + formatting, and changes to base64 encoding and decoding. The + interfaces to these functions are subject to change, and are + documented only in the source code. + +NEWS for the 1.5 release + + RSA support. Key generation and signatures. + + Support for HMAC (RFC-2104). + + An implementation of the Yarrow-256 PRNG. + + New sections in the manual. + + Changed the interface for hash functions. The md5_digest + function is now equivalent to the old sequence of md5_final, + md5_digest, md5_init, and similarly for the other hashing + algorithms. This makes the interface simpler. + +NEWS for the 1.0 release + + Fixed twofish bug spotted by Jean-Pierre Stierlin. + + Added des3 and cbc. + + New RFC-1321-like interface in nettle/md5-compat.h, suggested + by Assar Westerlund. + + New libdes-style compatibility interface in nettle/des-compat.h. diff --git a/README b/README new file mode 100644 index 0000000..6e5efbb --- /dev/null +++ b/README @@ -0,0 +1,53 @@ +What is Nettle? A quote from the introduction in the Nettle Manual: + + Nettle is a cryptographic library that is designed to fit easily in more + or less any context: In crypto toolkits for object-oriented languages + (C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in + kernel space. In most contexts, you need more than the basic + cryptographic algorithms, you also need some way to keep track of available + algorithms, their properties and variants. You often have some algorithm + selection process, often dictated by a protocol you want to implement. + + And as the requirements of applications differ in subtle and not so + subtle ways, an API that fits one application well can be a pain to use + in a different context. And that is why there are so many different + cryptographic libraries around. + + Nettle tries to avoid this problem by doing one thing, the low-level + crypto stuff, and providing a simple but general interface to it. + In particular, Nettle doesn't do algorithm selection. It doesn't do + memory allocation. It doesn't do any I/O. + + The idea is that one can build several application and context specific + interfaces on top of Nettle, and share the code, test cases, benchmarks, + documentation, etc. Examples are the Nettle module for the Pike + language, and LSH, which both use an object-oriented abstraction on top + of the library. + +Nettle 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. See the file COPYING for details. Most, but not +all, of Nettle can also be used under the terms of the GNU Lesser +General Public License; please read the Copyright section of the +manual if you want to exercise this option. + +Build nettle with the usual ./configure && make && make check && make +install. Read the manual. Mail me if you have any questions or +suggestions. + +You can also build Nettle from cvs, using + + cvs -d :pserver:anonymous@cvs.lysator.liu.se:/cvsroot/lsh login + [ empty password ] + cvs -d :pserver:anonymous@cvs.lysator.liu.se:/cvsroot/lsh co nettle + +If you get it from cvs, you need to build it with + + ./.bootstrap && ./configure && make && make check + +You may want to subscribe to the nettle-bugs mailing list. See +. + + +Happy hacking, +/Niels Möller diff --git a/TODO b/TODO new file mode 100644 index 0000000..4d788b1 --- /dev/null +++ b/TODO @@ -0,0 +1,29 @@ +Public key support, analogous to that provided by RSAREF. Suggested by +Dan Egnor. Signatures are done now, but RSA encryption is still +missing. References: + + http://download.gale.org/rsaref20.tar.Z + http://www.openssl.org/docs/crypto/evp.html + http://www.openssl.org/docs/crypto/rsa.html + +More feedback modes, in order of decreasing priority: CBC-MAC, OFB, +and CFB. Suggested by Rafael 'Dido' Sevilla. References: + + http://csrc.nist.gov/encryption/modes/Recommendation/Modes01.pdf + +Valgrind reports errors on the des-compat test program. Investigate. + + +Change the convention for declaring function pointers. Instead of for +example + + typedef void * + nettle_realloc_func(void *ctx, void *p, unsigned length); + +use + + typedef void + nettle_realloc_func(void *ctx, void *p, unsigned length); + +The make rules for building position independent *_p.o files doesn't +get dependencies right. diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..7263307 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1062 @@ +dnl Try to detect the type of the third arg to getsockname() et al +AC_DEFUN([LSH_TYPE_SOCKLEN_T], +[AH_TEMPLATE([socklen_t], [Length type used by getsockopt]) +AC_CACHE_CHECK([for socklen_t in sys/socket.h], ac_cv_type_socklen_t, +[AC_EGREP_HEADER(socklen_t, sys/socket.h, + [ac_cv_type_socklen_t=yes], [ac_cv_type_socklen_t=no])]) +if test $ac_cv_type_socklen_t = no; then + AC_MSG_CHECKING(for AIX) + AC_EGREP_CPP(yes, [ +#ifdef _AIX + yes +#endif +],[ +AC_MSG_RESULT(yes) +AC_DEFINE(socklen_t, size_t) +],[ +AC_MSG_RESULT(no) +AC_DEFINE(socklen_t, int) +]) +fi +]) + +dnl Choose cc flags for compiling position independent code +dnl FIXME: Doesn't do the right thing when crosscompiling. +AC_DEFUN([LSH_CCPIC], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_MSG_CHECKING(CCPIC) +AC_CACHE_VAL(lsh_cv_sys_ccpic,[ + if test -z "$CCPIC" ; then + if test "$GCC" = yes ; then + case "$host_os" in + bsdi4.*) CCPIC="-fPIC" ;; + bsdi*) CCPIC="" ;; + darwin*) CCPIC="-fPIC" ;; + # Could also use -fpic, depending on the number of symbol references + solaris*) CCPIC="-fPIC" ;; + cygwin*) CCPIC="" ;; + mingw32*) CCPIC="" ;; + *) CCPIC="-fpic" ;; + esac + else + case "$host_os" in + darwin*) CCPIC="-fPIC" ;; + irix*) CCPIC="-share" ;; + hpux*) CCPIC="+z"; ;; + *freebsd*) CCPIC="-fpic" ;; + sco*|sysv4.*) CCPIC="-KPIC -dy -Bdynamic" ;; + solaris*) CCPIC="-KPIC -Bdynamic" ;; + winnt*) CCPIC="-shared" ;; + *) CCPIC="" ;; + esac + fi + fi + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $CCPIC" + AC_TRY_COMPILE([], [exit(0);], + lsh_cv_sys_ccpic="$CCPIC", lsh_cv_sys_ccpic='') + CFLAGS="$OLD_CFLAGS" +]) +CCPIC="$lsh_cv_sys_ccpic" +AC_MSG_RESULT($CCPIC) +AC_SUBST([CCPIC])]) + +dnl LSH_PATH_ADD(path-id, directory) +AC_DEFUN([LSH_PATH_ADD], +[AC_MSG_CHECKING($2) +ac_exists=no +if test -d "$2/." ; then + ac_real_dir=`cd $2 && pwd` + if test -n "$ac_real_dir" ; then + ac_exists=yes + for old in $1_REAL_DIRS ; do + ac_found=no + if test x$ac_real_dir = x$old ; then + ac_found=yes; + break; + fi + done + if test $ac_found = yes ; then + AC_MSG_RESULT(already added) + else + AC_MSG_RESULT(added) + # LDFLAGS="$LDFLAGS -L $2" + $1_REAL_DIRS="$ac_real_dir [$]$1_REAL_DIRS" + $1_DIRS="$2 [$]$1_DIRS" + fi + fi +fi +if test $ac_exists = no ; then + AC_MSG_RESULT(not found) +fi +]) + +dnl LSH_RPATH_ADD(dir) +AC_DEFUN([LSH_RPATH_ADD], [LSH_PATH_ADD(RPATH_CANDIDATE, $1)]) + +dnl LSH_RPATH_INIT(candidates) +AC_DEFUN([LSH_RPATH_INIT], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_MSG_CHECKING([for -R flag]) +RPATHFLAG='' +case "$host_os" in + osf1*) RPATHFLAG="-rpath " ;; + irix6.*|irix5.*) RPATHFLAG="-rpath " ;; + solaris*) + if test "$TCC" = "yes"; then + # tcc doesn't know about -R + RPATHFLAG="-Wl,-R," + else + RPATHFLAG=-R + fi + ;; + linux*) RPATHFLAG="-Wl,-rpath," ;; + *) RPATHFLAG="" ;; +esac + +if test x$RPATHFLAG = x ; then + AC_MSG_RESULT(none) +else + AC_MSG_RESULT([using $RPATHFLAG]) +fi + +RPATH_CANDIDATE_REAL_DIRS='' +RPATH_CANDIDATE_DIRS='' + +AC_MSG_RESULT([Searching for libraries]) + +for d in $1 ; do + LSH_RPATH_ADD($d) +done +]) + +dnl Try to execute a main program, and if it fails, try adding some +dnl -R flag. +dnl LSH_RPATH_FIX +AC_DEFUN([LSH_RPATH_FIX], +[if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then + ac_success=no + AC_TRY_RUN([int main(int argc, char **argv) { return 0; }], + ac_success=yes, ac_success=no, :) + + if test $ac_success = no ; then + AC_MSG_CHECKING([Running simple test program failed. Trying -R flags]) +dnl echo RPATH_CANDIDATE_DIRS = $RPATH_CANDIDATE_DIRS + ac_remaining_dirs='' + ac_rpath_save_LDFLAGS="$LDFLAGS" + for d in $RPATH_CANDIDATE_DIRS ; do + if test $ac_success = yes ; then + ac_remaining_dirs="$ac_remaining_dirs $d" + else + LDFLAGS="$RPATHFLAG$d $LDFLAGS" +dnl echo LDFLAGS = $LDFLAGS + AC_TRY_RUN([int main(int argc, char **argv) { return 0; }], + [ac_success=yes + ac_rpath_save_LDFLAGS="$LDFLAGS" + AC_MSG_RESULT([adding $RPATHFLAG$d]) + ], + [ac_remaining_dirs="$ac_remaining_dirs $d"], :) + LDFLAGS="$ac_rpath_save_LDFLAGS" + fi + done + RPATH_CANDIDATE_DIRS=$ac_remaining_dirs + fi + if test $ac_success = no ; then + AC_MSG_RESULT(failed) + fi +fi +]) + +dnl Like AC_CHECK_LIB, but uses $KRB_LIBS rather than $LIBS. +dnl LSH_CHECK_KRB_LIB(LIBRARY, FUNCTION, [, ACTION-IF-FOUND [, +dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) + +AC_DEFUN([LSH_CHECK_KRB_LIB], +[AC_CHECK_LIB([$1], [$2], + ifelse([$3], , + [[ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + AC_DEFINE_UNQUOTED($ac_tr_lib) + KRB_LIBS="-l$1 $KRB_LIBS" + ]], [$3]), + ifelse([$4], , , [$4 +])dnl +, [$5 $KRB_LIBS]) +]) + +dnl LSH_LIB_ARGP(ACTION-IF-OK, ACTION-IF-BAD) +AC_DEFUN([LSH_LIB_ARGP], +[ ac_argp_save_LIBS="$LIBS" + ac_argp_save_LDFLAGS="$LDFLAGS" + ac_argp_ok=no + # First check if we can link with argp. + AC_SEARCH_LIBS(argp_parse, argp, + [ LSH_RPATH_FIX + AC_CACHE_CHECK([for working argp], + lsh_cv_lib_argp_works, + [ AC_TRY_RUN( +[#include +#include + +static const struct argp_option +options[] = +{ + { NULL, 0, NULL, 0, NULL, 0 } +}; + +struct child_state +{ + int n; +}; + +static error_t +child_parser(int key, char *arg, struct argp_state *state) +{ + struct child_state *input = (struct child_state *) state->input; + + switch(key) + { + default: + return ARGP_ERR_UNKNOWN; + case ARGP_KEY_END: + if (!input->n) + input->n = 1; + break; + } + return 0; +} + +const struct argp child_argp = +{ + options, + child_parser, + NULL, NULL, NULL, NULL, NULL +}; + +struct main_state +{ + struct child_state child; + int m; +}; + +static error_t +main_parser(int key, char *arg, struct argp_state *state) +{ + struct main_state *input = (struct main_state *) state->input; + + switch(key) + { + default: + return ARGP_ERR_UNKNOWN; + case ARGP_KEY_INIT: + state->child_inputs[0] = &input->child; + break; + case ARGP_KEY_END: + if (!input->m) + input->m = input->child.n; + + break; + } + return 0; +} + +static const struct argp_child +main_children[] = +{ + { &child_argp, 0, "", 0 }, + { NULL, 0, NULL, 0} +}; + +static const struct argp +main_argp = +{ options, main_parser, + NULL, + NULL, + main_children, + NULL, NULL +}; + +int main(int argc, char **argv) +{ + struct main_state input = { { 0 }, 0 }; + char *v[2] = { "foo", NULL }; + + argp_parse(&main_argp, 1, v, 0, NULL, &input); + + if ( (input.m == 1) && (input.child.n == 1) ) + return 0; + else + return 1; +} +], lsh_cv_lib_argp_works=yes, + lsh_cv_lib_argp_works=no, + lsh_cv_lib_argp_works=no)]) + + if test x$lsh_cv_lib_argp_works = xyes ; then + ac_argp_ok=yes + else + # Reset link flags + LIBS="$ac_argp_save_LIBS" + LDFLAGS="$ac_argp_save_LDFLAGS" + fi]) + + if test x$ac_argp_ok = xyes ; then + ifelse([$1],, true, [$1]) + else + ifelse([$2],, true, [$2]) + fi +]) + +dnl LSH_GCC_ATTRIBUTES +dnl Check for gcc's __attribute__ construction + +AC_DEFUN([LSH_GCC_ATTRIBUTES], +[AC_CACHE_CHECK(for __attribute__, + lsh_cv_c_attribute, +[ AC_TRY_COMPILE([ +#include + +static void foo(void) __attribute__ ((noreturn)); + +static void __attribute__ ((noreturn)) +foo(void) +{ + exit(1); +} +],[], +lsh_cv_c_attribute=yes, +lsh_cv_c_attribute=no)]) + +AH_TEMPLATE([HAVE_GCC_ATTRIBUTE], [Define if the compiler understands __attribute__]) +if test "x$lsh_cv_c_attribute" = "xyes"; then + AC_DEFINE(HAVE_GCC_ATTRIBUTE) +fi + +AH_BOTTOM( +[#if __GNUC__ && HAVE_GCC_ATTRIBUTE +# define NORETURN __attribute__ ((__noreturn__)) +# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) +# define UNUSED __attribute__ ((__unused__)) +#else +# define NORETURN +# define PRINTF_STYLE(f, a) +# define UNUSED +#endif +])]) + +# Check for alloca, and include the standard blurb in config.h +AC_DEFUN([LSH_FUNC_ALLOCA], +[AC_FUNC_ALLOCA +AC_CHECK_HEADERS([malloc.h]) +AH_BOTTOM( +[/* AIX requires this to be the first thing in the file. */ +#ifndef __GNUC__ +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +/* Needed for alloca on windows */ +# if HAVE_MALLOC_H +# include +# endif +# endif +#else /* defined __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# endif +#endif +])]) + +AC_DEFUN([LSH_FUNC_STRERROR], +[AC_CHECK_FUNCS(strerror) +AH_BOTTOM( +[#if HAVE_STRERROR +#define STRERROR strerror +#else +#define STRERROR(x) (sys_errlist[x]) +#endif +])]) + +AC_DEFUN([LSH_FUNC_STRSIGNAL], +[AC_CHECK_FUNCS(strsignal) +AC_CHECK_DECLS([sys_siglist, _sys_siglist]) +AH_BOTTOM( +[#if HAVE_STRSIGNAL +# define STRSIGNAL strsignal +#else /* !HAVE_STRSIGNAL */ +# if HAVE_DECL_SYS_SIGLIST +# define STRSIGNAL(x) (sys_siglist[x]) +# else +# if HAVE_DECL__SYS_SIGLIST +# define STRSIGNAL(x) (_sys_siglist[x]) +# else +# define STRSIGNAL(x) "Unknown signal" +# if __GNUC__ +# warning Using dummy STRSIGNAL +# endif +# endif +# endif +#endif /* !HAVE_STRSIGNAL */ +])]) + +dnl LSH_MAKE_CONDITIONAL(symbol, test) +AC_DEFUN([LSH_MAKE_CONDITIONAL], +[if $2 ; then + IF_$1='' + UNLESS_$1='# ' +else + IF_$1='# ' + UNLESS_$1='' +fi +AC_SUBST(IF_$1) +AC_SUBST(UNLESS_$1)]) + +dnl LSH_DEPENDENCY_TRACKING + +dnl Defines compiler flags DEP_FLAGS to generate dependency +dnl information, and DEP_PROCESS that is any shell commands needed for +dnl massaging the dependency information further. Dependencies are +dnl generated as a side effect of compilation. Dependency files +dnl themselves are not treated as targets. + +AC_DEFUN([LSH_DEPENDENCY_TRACKING], +[AC_ARG_ENABLE(dependency_tracking, + AC_HELP_STRING([--disable-dependency-tracking], + [Disable dependency tracking. Dependency tracking doesn't work with BSD make]),, + [enable_dependency_tracking=yes]) + +DEP_FLAGS='' +DEP_PROCESS='true' +if test x$enable_dependency_tracking = xyes ; then + if test x$GCC = xyes ; then + gcc_version=`gcc --version | head -1` + case "$gcc_version" in + 2.*|*[[!0-9.]]2.*) + enable_dependency_tracking=no + AC_MSG_WARN([Dependency tracking disabled, gcc-3.x is needed]) + ;; + *) + DEP_FLAGS='-MT $[]@ -MD -MP -MF $[]@.d' + DEP_PROCESS='true' + ;; + esac + else + enable_dependency_tracking=no + AC_MSG_WARN([Dependency tracking disabled]) + fi +fi + +if test x$enable_dependency_tracking = xyes ; then + DEP_INCLUDE='include ' +else + DEP_INCLUDE='# ' +fi + +AC_SUBST([DEP_INCLUDE]) +AC_SUBST([DEP_FLAGS]) +AC_SUBST([DEP_PROCESS])]) + +dnl GMP_TRY_ASSEMBLE(asm-code,[action-success][,action-fail]) +dnl ---------------------------------------------------------- +dnl Attempt to assemble the given code. +dnl Do "action-success" if this succeeds, "action-fail" if not. +dnl +dnl conftest.o and conftest.out are available for inspection in +dnl "action-success". If either action does a "break" out of a loop then +dnl an explicit "rm -f conftest*" will be necessary. +dnl +dnl This is not unlike AC_TRY_COMPILE, but there's no default includes or +dnl anything in "asm-code", everything wanted must be given explicitly. + +AC_DEFUN([GMP_TRY_ASSEMBLE], +[cat >conftest.s <&AC_FD_CC + ifelse([$2],,:,[$2]) +else + cat conftest.out >&AC_FD_CC + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.s >&AC_FD_CC + ifelse([$3],,:,[$3]) +fi +rm -f conftest* +]) + +dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEADERS-TO-CHECK])] +dnl +dnl the "ISO C9X: 7.18 Integer types " section requires the +dnl existence of an include file that defines a set of +dnl typedefs, especially uint8_t,int32_t,uintptr_t. +dnl Many older installations will not provide this file, but some will +dnl have the very same definitions in . In other enviroments +dnl we can use the inet-types in which would define the +dnl typedefs int8_t and u_int8_t respectivly. +dnl +dnl This macros will create a local "_stdint.h" or the headerfile given as +dnl an argument. In many cases that file will just "#include " +dnl or "#include ", while in other environments it will provide +dnl the set of basic 'stdint's definitions/typedefs: +dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t +dnl int_least32_t.. int_fast32_t.. intmax_t +dnl which may or may not rely on the definitions of other files, +dnl or using the AC_CHECK_SIZEOF macro to determine the actual +dnl sizeof each type. +dnl +dnl if your header files require the stdint-types you will want to create an +dnl installable file mylib-int.h that all your other installable header +dnl may include. So if you have a library package named "mylib", just use +dnl AX_CREATE_STDINT_H(mylib-int.h) +dnl in configure.ac and go to install that very header file in Makefile.am +dnl along with the other headers (mylib.h) - and the mylib-specific headers +dnl can simply use "#include " to obtain the stdint-types. +dnl +dnl Remember, if the system already had a valid , the generated +dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things... +dnl +dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/) +dnl @version $Id: aclocal.m4,v 1.1 2007/05/03 20:49:15 nisse Exp $ +dnl @author Guido Draheim + +AC_DEFUN([AX_CREATE_STDINT_H], +[# ------ AX CREATE STDINT H ------------------------------------- +AC_MSG_CHECKING([for stdint types]) +ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` +# try to shortcircuit - if the default include path of the compiler +# can find a "stdint.h" header then we assume that all compilers can. +AC_CACHE_VAL([ac_cv_header_stdint_t],[ +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +AC_TRY_COMPILE([#include ],[int_least32_t v = 0;], +[ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h"; ], +[ac_cv_header_stdint_t=""]) +CXXFLAGS="$old_CXXFLAGS" +CPPFLAGS="$old_CPPFLAGS" +CFLAGS="$old_CFLAGS" ]) + +v="... $ac_cv_header_stdint_h" +if test "$ac_stdint_h" = "stdint.h" ; then + AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)]) +elif test "$ac_stdint_h" = "inttypes.h" ; then + AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)]) +elif test "_$ac_cv_header_stdint_t" = "_" ; then + AC_MSG_RESULT([(putting them into $ac_stdint_h)$v]) +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)]) +fi + +if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit.. + +dnl .....intro message done, now do a few system checks..... +dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore +dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead + +inttype_headers=`echo $2 | sed -e 's/,/ /g'` + +ac_cv_stdint_result="(no helpful system typedefs seen)" +AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[ + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + AC_MSG_RESULT([(..)]) + for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do + unset ac_cv_type_uintptr_t + unset ac_cv_type_uint64_t + _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl + continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" + break; + done + AC_MSG_CHECKING([for stdint uintptr_t]) + ]) + +if test "_$ac_cv_header_stdint_x" = "_" ; then +AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[ + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + AC_MSG_RESULT([(..)]) + for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do + unset ac_cv_type_uint32_t + unset ac_cv_type_uint64_t + AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl + continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + ac_cv_stdint_result="(seen uint32_t$and64 in $i)" + break; + done + AC_MSG_CHECKING([for stdint uint32_t]) + ]) +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[ + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + AC_MSG_RESULT([(..)]) + for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do + unset ac_cv_type_u_int32_t + unset ac_cv_type_u_int64_t + AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl + continue,[#include <$i>]) + AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" + break; + done + AC_MSG_CHECKING([for stdint u_int32_t]) + ]) +fi fi + +dnl if there was no good C99 header file, do some typedef checks... +if test "_$ac_cv_header_stdint_x" = "_" ; then + AC_MSG_CHECKING([for stdint datatype model]) + AC_MSG_RESULT([(..)]) + AC_CHECK_SIZEOF(char) + AC_CHECK_SIZEOF(short) + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(void*) + ac_cv_stdint_char_model="" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int" + ac_cv_stdint_long_model="" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp" + name="$ac_cv_stdint_long_model" + case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in + 122/242) name="$name, IP16 (standard 16bit machine)" ;; + 122/244) name="$name, LP32 (standard 32bit mac/win)" ;; + 122/*) name="$name (unusual int16 model)" ;; + 124/444) name="$name, ILP32 (standard 32bit unixish)" ;; + 124/488) name="$name, LP64 (standard 64bit unixish)" ;; + 124/448) name="$name, LLP64 (unusual 64bit unixish)" ;; + 124/*) name="$name (unusual int32 model)" ;; + 128/888) name="$name, ILP64 (unusual 64bit numeric)" ;; + 128/*) name="$name (unusual int64 model)" ;; + 222/*|444/*) name="$name (unusual dsptype)" ;; + *) name="$name (very unusal model)" ;; + esac + AC_MSG_RESULT([combined for stdint datatype model... $name]) +fi + +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_x" +elif test "_$ac_cv_header_stdint_o" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_o" +elif test "_$ac_cv_header_stdint_u" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_u" +else + ac_cv_header_stdint="stddef.h" +fi + +AC_MSG_CHECKING([for extra inttypes in chosen header]) +AC_MSG_RESULT([($ac_cv_header_stdint)]) +dnl see if int_least and int_fast types are present in _this_ header. +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) +AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) +AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>]) + +fi # shortcircut to system "stdint.h" +# ------------------ PREPARE VARIABLES ------------------------------ +if test "$GCC" = "yes" ; then +ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` +else +ac_cv_stdint_message="using $CC" +fi + +AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl +$ac_cv_stdint_result]) + +# ----------------- DONE inttypes.h checks START header ------------- +AC_CONFIG_COMMANDS([$ac_stdint_h],[ +AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h) +ac_stdint=$tmp/_stdint.h + +echo "#ifndef" $_ac_stdint_h >$ac_stdint +echo "#define" $_ac_stdint_h "1" >>$ac_stdint +echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint +echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint +echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint +if test "_$ac_cv_header_stdint_t" != "_" ; then +echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint +fi + +cat >>$ac_stdint < +#else +#include + +/* .................... configured part ............................ */ + +STDINT_EOF + +echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_header="$ac_cv_header_stdint_x" + echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint +fi + +echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_o" != "_" ; then + ac_header="$ac_cv_header_stdint_o" + echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint +fi + +echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint +if test "_$ac_cv_header_stdint_u" != "_" ; then + ac_header="$ac_cv_header_stdint_u" + echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint +fi + +echo "" >>$ac_stdint + +if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then + echo "#include <$ac_header>" >>$ac_stdint + echo "" >>$ac_stdint +fi fi + +echo "/* which 64bit typedef has been found */" >>$ac_stdint +if test "$ac_cv_type_uint64_t" = "yes" ; then +echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint +fi +if test "$ac_cv_type_u_int64_t" = "yes" ; then +echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* which type model has been detected */" >>$ac_stdint +if test "_$ac_cv_stdint_char_model" != "_" ; then +echo "#define _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint +echo "#define _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint +else +echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint +echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* whether int_least types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_least32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint +fi +echo "/* whether int_fast types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_fast32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint +fi +echo "/* whether intmax_t type was detected */" >>$ac_stdint +if test "$ac_cv_type_intmax_t" = "yes"; then +echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + + cat >>$ac_stdint <= 199901L +#define _HAVE_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif !defined __STRICT_ANSI__ +#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ +#define _HAVE_UINT64_T +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ +/* note: all ELF-systems seem to have loff-support which needs 64-bit */ +#if !defined _NO_LONGLONG +#define _HAVE_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif + +#elif defined __alpha || (defined __mips && defined _ABIN32) +#if !defined _NO_LONGLONG +typedef long int64_t; +typedef unsigned long uint64_t; +#endif + /* compiler/cpu type to define int64_t */ +#endif +#endif +#endif + +#if defined _STDINT_HAVE_U_INT_TYPES +/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; + +/* glibc compatibility */ +#ifndef __int8_t_defined +#define __int8_t_defined +#endif +#endif + +#ifdef _STDINT_NEED_INT_MODEL_T +/* we must guess all the basic types. Apart from byte-adressable system, */ +/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ +/* (btw, those nibble-addressable systems are way off, or so we assume) */ + +dnl /* have a look at "64bit and data size neutrality" at */ +dnl /* http://unix.org/version2/whatsnew/login_64bit.html */ +dnl /* (the shorthand "ILP" types always have a "P" part) */ + +#if defined _STDINT_BYTE_MODEL +#if _STDINT_LONG_MODEL+0 == 242 +/* 2:4:2 = IP16 = a normal 16-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 +/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ +/* 4:4:4 = ILP32 = a normal 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 +/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ +/* 4:8:8 = LP64 = a normal 64-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* this system has a "long" of 64bit */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long uint64_t; +typedef long int64_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 448 +/* LLP64 a 64-bit system derived from a 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* assuming the system has a "long long" */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#else +#define _STDINT_NO_INT32_T +#endif +#else +#define _STDINT_NO_INT8_T +#define _STDINT_NO_INT32_T +#endif +#endif + +/* + * quote from SunOS-5.8 sys/inttypes.h: + * Use at your own risk. As of February 1996, the committee is squarely + * behind the fixed sized types; the "least" and "fast" types are still being + * discussed. The probability that the "fast" types may be removed before + * the standard is finalized is high enough that they are not currently + * implemented. + */ + +#if defined _STDINT_NEED_INT_LEAST_T +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_least64_t; +#endif + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_least64_t; +#endif + /* least types */ +#endif + +#if defined _STDINT_NEED_INT_FAST_T +typedef int8_t int_fast8_t; +typedef int int_fast16_t; +typedef int32_t int_fast32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_fast64_t; +#endif + +typedef uint8_t uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef uint32_t uint_fast32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_fast64_t; +#endif + /* fast types */ +#endif + +#ifdef _STDINT_NEED_INTMAX_T +#ifdef _HAVE_UINT64_T +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#else +typedef long intmax_t; +typedef unsigned long uintmax_t; +#endif +#endif + +#ifdef _STDINT_NEED_INTPTR_T +#ifndef __intptr_t_defined +#define __intptr_t_defined +/* we encourage using "long" to store pointer values, never use "int" ! */ +#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 +typedef unsinged int uintptr_t; +typedef int intptr_t; +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 +typedef unsigned long uintptr_t; +typedef long intptr_t; +#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; +#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ +typedef unsigned long uintptr_t; +typedef long intptr_t; +#endif +#endif +#endif + + /* shortcircuit*/ +#endif + /* once */ +#endif +#endif +STDINT_EOF + if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then + AC_MSG_NOTICE([$ac_stdint_h is unchanged]) + else + ac_dir=`AS_DIRNAME(["$ac_stdint_h"])` + AS_MKDIR_P(["$ac_dir"]) + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi +],[# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h) +ac_cv_stdint_message="$ac_cv_stdint_message" +ac_cv_header_stdint_t="$ac_cv_header_stdint_t" +ac_cv_header_stdint_x="$ac_cv_header_stdint_x" +ac_cv_header_stdint_o="$ac_cv_header_stdint_o" +ac_cv_header_stdint_u="$ac_cv_header_stdint_u" +ac_cv_type_uint64_t="$ac_cv_type_uint64_t" +ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" +ac_cv_stdint_char_model="$ac_cv_stdint_char_model" +ac_cv_stdint_long_model="$ac_cv_stdint_long_model" +ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" +ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" +ac_cv_type_intmax_t="$ac_cv_type_intmax_t" +]) +]) diff --git a/aes-decrypt-internal.c b/aes-decrypt-internal.c new file mode 100644 index 0000000..9dff166 --- /dev/null +++ b/aes-decrypt-internal.c @@ -0,0 +1,83 @@ +/* aes-decrypt-internal.c + * + * Decryption function for the aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" +#include "macros.h" + +void +_nettle_aes_decrypt(const struct aes_ctx *ctx, + const struct aes_table *T, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + FOR_BLOCKS(length, dst, src, AES_BLOCK_SIZE) + { + uint32_t w0, w1, w2, w3; /* working ciphertext */ + uint32_t t0, t1, t2, t3; + unsigned round; + + /* Get clear text, using little-endian byte order. + * Also XOR with the first subkey. */ + + w0 = LE_READ_UINT32(src) ^ ctx->keys[0]; + w1 = LE_READ_UINT32(src + 4) ^ ctx->keys[1]; + w2 = LE_READ_UINT32(src + 8) ^ ctx->keys[2]; + w3 = LE_READ_UINT32(src + 12) ^ ctx->keys[3]; + + for (round = 1; round < ctx->nrounds; round++) + { + t0 = AES_ROUND(T, w0, w3, w2, w1, ctx->keys[4*round]); + t1 = AES_ROUND(T, w1, w0, w3, w2, ctx->keys[4*round + 1]); + t2 = AES_ROUND(T, w2, w1, w0, w3, ctx->keys[4*round + 2]); + t3 = AES_ROUND(T, w3, w2, w1, w0, ctx->keys[4*round + 3]); + + /* We could unroll the loop twice, to avoid these + assignments. If all eight variables fit in registers, + that should give a slight speedup. */ + w0 = t0; + w1 = t1; + w2 = t2; + w3 = t3; + } + + /* Final round */ + + t0 = AES_FINAL_ROUND(T, w0, w3, w2, w1, ctx->keys[4*round]); + t1 = AES_FINAL_ROUND(T, w1, w0, w3, w2, ctx->keys[4*round + 1]); + t2 = AES_FINAL_ROUND(T, w2, w1, w0, w3, ctx->keys[4*round + 2]); + t3 = AES_FINAL_ROUND(T, w3, w2, w1, w0, ctx->keys[4*round + 3]); + + LE_WRITE_UINT32(dst, t0); + LE_WRITE_UINT32(dst + 8, t2); + LE_WRITE_UINT32(dst + 4, t1); + LE_WRITE_UINT32(dst + 12, t3); + } +} diff --git a/aes-decrypt.c b/aes-decrypt.c new file mode 100644 index 0000000..39b79c6 --- /dev/null +++ b/aes-decrypt.c @@ -0,0 +1,347 @@ +/* aes-decrypt.c + * + * Decryption function for aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" + +static const struct aes_table +_aes_decrypt_table = + { /* isbox */ + { + 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, + }, + { /* itable */ + { + 0x50a7f451,0x5365417e,0xc3a4171a,0x965e273a, + 0xcb6bab3b,0xf1459d1f,0xab58faac,0x9303e34b, + 0x55fa3020,0xf66d76ad,0x9176cc88,0x254c02f5, + 0xfcd7e54f,0xd7cb2ac5,0x80443526,0x8fa362b5, + 0x495ab1de,0x671bba25,0x980eea45,0xe1c0fe5d, + 0x02752fc3,0x12f04c81,0xa397468d,0xc6f9d36b, + 0xe75f8f03,0x959c9215,0xeb7a6dbf,0xda595295, + 0x2d83bed4,0xd3217458,0x2969e049,0x44c8c98e, + 0x6a89c275,0x78798ef4,0x6b3e5899,0xdd71b927, + 0xb64fe1be,0x17ad88f0,0x66ac20c9,0xb43ace7d, + 0x184adf63,0x82311ae5,0x60335197,0x457f5362, + 0xe07764b1,0x84ae6bbb,0x1ca081fe,0x942b08f9, + 0x58684870,0x19fd458f,0x876cde94,0xb7f87b52, + 0x23d373ab,0xe2024b72,0x578f1fe3,0x2aab5566, + 0x0728ebb2,0x03c2b52f,0x9a7bc586,0xa50837d3, + 0xf2872830,0xb2a5bf23,0xba6a0302,0x5c8216ed, + 0x2b1ccf8a,0x92b479a7,0xf0f207f3,0xa1e2694e, + 0xcdf4da65,0xd5be0506,0x1f6234d1,0x8afea6c4, + 0x9d532e34,0xa055f3a2,0x32e18a05,0x75ebf6a4, + 0x39ec830b,0xaaef6040,0x069f715e,0x51106ebd, + 0xf98a213e,0x3d06dd96,0xae053edd,0x46bde64d, + 0xb58d5491,0x055dc471,0x6fd40604,0xff155060, + 0x24fb9819,0x97e9bdd6,0xcc434089,0x779ed967, + 0xbd42e8b0,0x888b8907,0x385b19e7,0xdbeec879, + 0x470a7ca1,0xe90f427c,0xc91e84f8,0x00000000, + 0x83868009,0x48ed2b32,0xac70111e,0x4e725a6c, + 0xfbff0efd,0x5638850f,0x1ed5ae3d,0x27392d36, + 0x64d90f0a,0x21a65c68,0xd1545b9b,0x3a2e3624, + 0xb1670a0c,0x0fe75793,0xd296eeb4,0x9e919b1b, + 0x4fc5c080,0xa220dc61,0x694b775a,0x161a121c, + 0x0aba93e2,0xe52aa0c0,0x43e0223c,0x1d171b12, + 0x0b0d090e,0xadc78bf2,0xb9a8b62d,0xc8a91e14, + 0x8519f157,0x4c0775af,0xbbdd99ee,0xfd607fa3, + 0x9f2601f7,0xbcf5725c,0xc53b6644,0x347efb5b, + 0x7629438b,0xdcc623cb,0x68fcedb6,0x63f1e4b8, + 0xcadc31d7,0x10856342,0x40229713,0x2011c684, + 0x7d244a85,0xf83dbbd2,0x1132f9ae,0x6da129c7, + 0x4b2f9e1d,0xf330b2dc,0xec52860d,0xd0e3c177, + 0x6c16b32b,0x99b970a9,0xfa489411,0x2264e947, + 0xc48cfca8,0x1a3ff0a0,0xd82c7d56,0xef903322, + 0xc74e4987,0xc1d138d9,0xfea2ca8c,0x360bd498, + 0xcf81f5a6,0x28de7aa5,0x268eb7da,0xa4bfad3f, + 0xe49d3a2c,0x0d927850,0x9bcc5f6a,0x62467e54, + 0xc2138df6,0xe8b8d890,0x5ef7392e,0xf5afc382, + 0xbe805d9f,0x7c93d069,0xa92dd56f,0xb31225cf, + 0x3b99acc8,0xa77d1810,0x6e639ce8,0x7bbb3bdb, + 0x097826cd,0xf418596e,0x01b79aec,0xa89a4f83, + 0x656e95e6,0x7ee6ffaa,0x08cfbc21,0xe6e815ef, + 0xd99be7ba,0xce366f4a,0xd4099fea,0xd67cb029, + 0xafb2a431,0x31233f2a,0x3094a5c6,0xc066a235, + 0x37bc4e74,0xa6ca82fc,0xb0d090e0,0x15d8a733, + 0x4a9804f1,0xf7daec41,0x0e50cd7f,0x2ff69117, + 0x8dd64d76,0x4db0ef43,0x544daacc,0xdf0496e4, + 0xe3b5d19e,0x1b886a4c,0xb81f2cc1,0x7f516546, + 0x04ea5e9d,0x5d358c01,0x737487fa,0x2e410bfb, + 0x5a1d67b3,0x52d2db92,0x335610e9,0x1347d66d, + 0x8c61d79a,0x7a0ca137,0x8e14f859,0x893c13eb, + 0xee27a9ce,0x35c961b7,0xede51ce1,0x3cb1477a, + 0x59dfd29c,0x3f73f255,0x79ce1418,0xbf37c773, + 0xeacdf753,0x5baafd5f,0x146f3ddf,0x86db4478, + 0x81f3afca,0x3ec468b9,0x2c342438,0x5f40a3c2, + 0x72c31d16,0x0c25e2bc,0x8b493c28,0x41950dff, + 0x7101a839,0xdeb30c08,0x9ce4b4d8,0x90c15664, + 0x6184cb7b,0x70b632d5,0x745c6c48,0x4257b8d0, + }, +#if !AES_SMALL + { /* Before: itable[1] */ + 0xa7f45150,0x65417e53,0xa4171ac3,0x5e273a96, + 0x6bab3bcb,0x459d1ff1,0x58faacab,0x03e34b93, + 0xfa302055,0x6d76adf6,0x76cc8891,0x4c02f525, + 0xd7e54ffc,0xcb2ac5d7,0x44352680,0xa362b58f, + 0x5ab1de49,0x1bba2567,0x0eea4598,0xc0fe5de1, + 0x752fc302,0xf04c8112,0x97468da3,0xf9d36bc6, + 0x5f8f03e7,0x9c921595,0x7a6dbfeb,0x595295da, + 0x83bed42d,0x217458d3,0x69e04929,0xc8c98e44, + 0x89c2756a,0x798ef478,0x3e58996b,0x71b927dd, + 0x4fe1beb6,0xad88f017,0xac20c966,0x3ace7db4, + 0x4adf6318,0x311ae582,0x33519760,0x7f536245, + 0x7764b1e0,0xae6bbb84,0xa081fe1c,0x2b08f994, + 0x68487058,0xfd458f19,0x6cde9487,0xf87b52b7, + 0xd373ab23,0x024b72e2,0x8f1fe357,0xab55662a, + 0x28ebb207,0xc2b52f03,0x7bc5869a,0x0837d3a5, + 0x872830f2,0xa5bf23b2,0x6a0302ba,0x8216ed5c, + 0x1ccf8a2b,0xb479a792,0xf207f3f0,0xe2694ea1, + 0xf4da65cd,0xbe0506d5,0x6234d11f,0xfea6c48a, + 0x532e349d,0x55f3a2a0,0xe18a0532,0xebf6a475, + 0xec830b39,0xef6040aa,0x9f715e06,0x106ebd51, + 0x8a213ef9,0x06dd963d,0x053eddae,0xbde64d46, + 0x8d5491b5,0x5dc47105,0xd406046f,0x155060ff, + 0xfb981924,0xe9bdd697,0x434089cc,0x9ed96777, + 0x42e8b0bd,0x8b890788,0x5b19e738,0xeec879db, + 0x0a7ca147,0x0f427ce9,0x1e84f8c9,0x00000000, + 0x86800983,0xed2b3248,0x70111eac,0x725a6c4e, + 0xff0efdfb,0x38850f56,0xd5ae3d1e,0x392d3627, + 0xd90f0a64,0xa65c6821,0x545b9bd1,0x2e36243a, + 0x670a0cb1,0xe757930f,0x96eeb4d2,0x919b1b9e, + 0xc5c0804f,0x20dc61a2,0x4b775a69,0x1a121c16, + 0xba93e20a,0x2aa0c0e5,0xe0223c43,0x171b121d, + 0x0d090e0b,0xc78bf2ad,0xa8b62db9,0xa91e14c8, + 0x19f15785,0x0775af4c,0xdd99eebb,0x607fa3fd, + 0x2601f79f,0xf5725cbc,0x3b6644c5,0x7efb5b34, + 0x29438b76,0xc623cbdc,0xfcedb668,0xf1e4b863, + 0xdc31d7ca,0x85634210,0x22971340,0x11c68420, + 0x244a857d,0x3dbbd2f8,0x32f9ae11,0xa129c76d, + 0x2f9e1d4b,0x30b2dcf3,0x52860dec,0xe3c177d0, + 0x16b32b6c,0xb970a999,0x489411fa,0x64e94722, + 0x8cfca8c4,0x3ff0a01a,0x2c7d56d8,0x903322ef, + 0x4e4987c7,0xd138d9c1,0xa2ca8cfe,0x0bd49836, + 0x81f5a6cf,0xde7aa528,0x8eb7da26,0xbfad3fa4, + 0x9d3a2ce4,0x9278500d,0xcc5f6a9b,0x467e5462, + 0x138df6c2,0xb8d890e8,0xf7392e5e,0xafc382f5, + 0x805d9fbe,0x93d0697c,0x2dd56fa9,0x1225cfb3, + 0x99acc83b,0x7d1810a7,0x639ce86e,0xbb3bdb7b, + 0x7826cd09,0x18596ef4,0xb79aec01,0x9a4f83a8, + 0x6e95e665,0xe6ffaa7e,0xcfbc2108,0xe815efe6, + 0x9be7bad9,0x366f4ace,0x099fead4,0x7cb029d6, + 0xb2a431af,0x233f2a31,0x94a5c630,0x66a235c0, + 0xbc4e7437,0xca82fca6,0xd090e0b0,0xd8a73315, + 0x9804f14a,0xdaec41f7,0x50cd7f0e,0xf691172f, + 0xd64d768d,0xb0ef434d,0x4daacc54,0x0496e4df, + 0xb5d19ee3,0x886a4c1b,0x1f2cc1b8,0x5165467f, + 0xea5e9d04,0x358c015d,0x7487fa73,0x410bfb2e, + 0x1d67b35a,0xd2db9252,0x5610e933,0x47d66d13, + 0x61d79a8c,0x0ca1377a,0x14f8598e,0x3c13eb89, + 0x27a9ceee,0xc961b735,0xe51ce1ed,0xb1477a3c, + 0xdfd29c59,0x73f2553f,0xce141879,0x37c773bf, + 0xcdf753ea,0xaafd5f5b,0x6f3ddf14,0xdb447886, + 0xf3afca81,0xc468b93e,0x3424382c,0x40a3c25f, + 0xc31d1672,0x25e2bc0c,0x493c288b,0x950dff41, + 0x01a83971,0xb30c08de,0xe4b4d89c,0xc1566490, + 0x84cb7b61,0xb632d570,0x5c6c4874,0x57b8d042, + },{ /* Before: itable[2] */ + 0xf45150a7,0x417e5365,0x171ac3a4,0x273a965e, + 0xab3bcb6b,0x9d1ff145,0xfaacab58,0xe34b9303, + 0x302055fa,0x76adf66d,0xcc889176,0x02f5254c, + 0xe54ffcd7,0x2ac5d7cb,0x35268044,0x62b58fa3, + 0xb1de495a,0xba25671b,0xea45980e,0xfe5de1c0, + 0x2fc30275,0x4c8112f0,0x468da397,0xd36bc6f9, + 0x8f03e75f,0x9215959c,0x6dbfeb7a,0x5295da59, + 0xbed42d83,0x7458d321,0xe0492969,0xc98e44c8, + 0xc2756a89,0x8ef47879,0x58996b3e,0xb927dd71, + 0xe1beb64f,0x88f017ad,0x20c966ac,0xce7db43a, + 0xdf63184a,0x1ae58231,0x51976033,0x5362457f, + 0x64b1e077,0x6bbb84ae,0x81fe1ca0,0x08f9942b, + 0x48705868,0x458f19fd,0xde94876c,0x7b52b7f8, + 0x73ab23d3,0x4b72e202,0x1fe3578f,0x55662aab, + 0xebb20728,0xb52f03c2,0xc5869a7b,0x37d3a508, + 0x2830f287,0xbf23b2a5,0x0302ba6a,0x16ed5c82, + 0xcf8a2b1c,0x79a792b4,0x07f3f0f2,0x694ea1e2, + 0xda65cdf4,0x0506d5be,0x34d11f62,0xa6c48afe, + 0x2e349d53,0xf3a2a055,0x8a0532e1,0xf6a475eb, + 0x830b39ec,0x6040aaef,0x715e069f,0x6ebd5110, + 0x213ef98a,0xdd963d06,0x3eddae05,0xe64d46bd, + 0x5491b58d,0xc471055d,0x06046fd4,0x5060ff15, + 0x981924fb,0xbdd697e9,0x4089cc43,0xd967779e, + 0xe8b0bd42,0x8907888b,0x19e7385b,0xc879dbee, + 0x7ca1470a,0x427ce90f,0x84f8c91e,0x00000000, + 0x80098386,0x2b3248ed,0x111eac70,0x5a6c4e72, + 0x0efdfbff,0x850f5638,0xae3d1ed5,0x2d362739, + 0x0f0a64d9,0x5c6821a6,0x5b9bd154,0x36243a2e, + 0x0a0cb167,0x57930fe7,0xeeb4d296,0x9b1b9e91, + 0xc0804fc5,0xdc61a220,0x775a694b,0x121c161a, + 0x93e20aba,0xa0c0e52a,0x223c43e0,0x1b121d17, + 0x090e0b0d,0x8bf2adc7,0xb62db9a8,0x1e14c8a9, + 0xf1578519,0x75af4c07,0x99eebbdd,0x7fa3fd60, + 0x01f79f26,0x725cbcf5,0x6644c53b,0xfb5b347e, + 0x438b7629,0x23cbdcc6,0xedb668fc,0xe4b863f1, + 0x31d7cadc,0x63421085,0x97134022,0xc6842011, + 0x4a857d24,0xbbd2f83d,0xf9ae1132,0x29c76da1, + 0x9e1d4b2f,0xb2dcf330,0x860dec52,0xc177d0e3, + 0xb32b6c16,0x70a999b9,0x9411fa48,0xe9472264, + 0xfca8c48c,0xf0a01a3f,0x7d56d82c,0x3322ef90, + 0x4987c74e,0x38d9c1d1,0xca8cfea2,0xd498360b, + 0xf5a6cf81,0x7aa528de,0xb7da268e,0xad3fa4bf, + 0x3a2ce49d,0x78500d92,0x5f6a9bcc,0x7e546246, + 0x8df6c213,0xd890e8b8,0x392e5ef7,0xc382f5af, + 0x5d9fbe80,0xd0697c93,0xd56fa92d,0x25cfb312, + 0xacc83b99,0x1810a77d,0x9ce86e63,0x3bdb7bbb, + 0x26cd0978,0x596ef418,0x9aec01b7,0x4f83a89a, + 0x95e6656e,0xffaa7ee6,0xbc2108cf,0x15efe6e8, + 0xe7bad99b,0x6f4ace36,0x9fead409,0xb029d67c, + 0xa431afb2,0x3f2a3123,0xa5c63094,0xa235c066, + 0x4e7437bc,0x82fca6ca,0x90e0b0d0,0xa73315d8, + 0x04f14a98,0xec41f7da,0xcd7f0e50,0x91172ff6, + 0x4d768dd6,0xef434db0,0xaacc544d,0x96e4df04, + 0xd19ee3b5,0x6a4c1b88,0x2cc1b81f,0x65467f51, + 0x5e9d04ea,0x8c015d35,0x87fa7374,0x0bfb2e41, + 0x67b35a1d,0xdb9252d2,0x10e93356,0xd66d1347, + 0xd79a8c61,0xa1377a0c,0xf8598e14,0x13eb893c, + 0xa9ceee27,0x61b735c9,0x1ce1ede5,0x477a3cb1, + 0xd29c59df,0xf2553f73,0x141879ce,0xc773bf37, + 0xf753eacd,0xfd5f5baa,0x3ddf146f,0x447886db, + 0xafca81f3,0x68b93ec4,0x24382c34,0xa3c25f40, + 0x1d1672c3,0xe2bc0c25,0x3c288b49,0x0dff4195, + 0xa8397101,0x0c08deb3,0xb4d89ce4,0x566490c1, + 0xcb7b6184,0x32d570b6,0x6c48745c,0xb8d04257, + },{ /* Before: itable[3] */ + 0x5150a7f4,0x7e536541,0x1ac3a417,0x3a965e27, + 0x3bcb6bab,0x1ff1459d,0xacab58fa,0x4b9303e3, + 0x2055fa30,0xadf66d76,0x889176cc,0xf5254c02, + 0x4ffcd7e5,0xc5d7cb2a,0x26804435,0xb58fa362, + 0xde495ab1,0x25671bba,0x45980eea,0x5de1c0fe, + 0xc302752f,0x8112f04c,0x8da39746,0x6bc6f9d3, + 0x03e75f8f,0x15959c92,0xbfeb7a6d,0x95da5952, + 0xd42d83be,0x58d32174,0x492969e0,0x8e44c8c9, + 0x756a89c2,0xf478798e,0x996b3e58,0x27dd71b9, + 0xbeb64fe1,0xf017ad88,0xc966ac20,0x7db43ace, + 0x63184adf,0xe582311a,0x97603351,0x62457f53, + 0xb1e07764,0xbb84ae6b,0xfe1ca081,0xf9942b08, + 0x70586848,0x8f19fd45,0x94876cde,0x52b7f87b, + 0xab23d373,0x72e2024b,0xe3578f1f,0x662aab55, + 0xb20728eb,0x2f03c2b5,0x869a7bc5,0xd3a50837, + 0x30f28728,0x23b2a5bf,0x02ba6a03,0xed5c8216, + 0x8a2b1ccf,0xa792b479,0xf3f0f207,0x4ea1e269, + 0x65cdf4da,0x06d5be05,0xd11f6234,0xc48afea6, + 0x349d532e,0xa2a055f3,0x0532e18a,0xa475ebf6, + 0x0b39ec83,0x40aaef60,0x5e069f71,0xbd51106e, + 0x3ef98a21,0x963d06dd,0xddae053e,0x4d46bde6, + 0x91b58d54,0x71055dc4,0x046fd406,0x60ff1550, + 0x1924fb98,0xd697e9bd,0x89cc4340,0x67779ed9, + 0xb0bd42e8,0x07888b89,0xe7385b19,0x79dbeec8, + 0xa1470a7c,0x7ce90f42,0xf8c91e84,0x00000000, + 0x09838680,0x3248ed2b,0x1eac7011,0x6c4e725a, + 0xfdfbff0e,0x0f563885,0x3d1ed5ae,0x3627392d, + 0x0a64d90f,0x6821a65c,0x9bd1545b,0x243a2e36, + 0x0cb1670a,0x930fe757,0xb4d296ee,0x1b9e919b, + 0x804fc5c0,0x61a220dc,0x5a694b77,0x1c161a12, + 0xe20aba93,0xc0e52aa0,0x3c43e022,0x121d171b, + 0x0e0b0d09,0xf2adc78b,0x2db9a8b6,0x14c8a91e, + 0x578519f1,0xaf4c0775,0xeebbdd99,0xa3fd607f, + 0xf79f2601,0x5cbcf572,0x44c53b66,0x5b347efb, + 0x8b762943,0xcbdcc623,0xb668fced,0xb863f1e4, + 0xd7cadc31,0x42108563,0x13402297,0x842011c6, + 0x857d244a,0xd2f83dbb,0xae1132f9,0xc76da129, + 0x1d4b2f9e,0xdcf330b2,0x0dec5286,0x77d0e3c1, + 0x2b6c16b3,0xa999b970,0x11fa4894,0x472264e9, + 0xa8c48cfc,0xa01a3ff0,0x56d82c7d,0x22ef9033, + 0x87c74e49,0xd9c1d138,0x8cfea2ca,0x98360bd4, + 0xa6cf81f5,0xa528de7a,0xda268eb7,0x3fa4bfad, + 0x2ce49d3a,0x500d9278,0x6a9bcc5f,0x5462467e, + 0xf6c2138d,0x90e8b8d8,0x2e5ef739,0x82f5afc3, + 0x9fbe805d,0x697c93d0,0x6fa92dd5,0xcfb31225, + 0xc83b99ac,0x10a77d18,0xe86e639c,0xdb7bbb3b, + 0xcd097826,0x6ef41859,0xec01b79a,0x83a89a4f, + 0xe6656e95,0xaa7ee6ff,0x2108cfbc,0xefe6e815, + 0xbad99be7,0x4ace366f,0xead4099f,0x29d67cb0, + 0x31afb2a4,0x2a31233f,0xc63094a5,0x35c066a2, + 0x7437bc4e,0xfca6ca82,0xe0b0d090,0x3315d8a7, + 0xf14a9804,0x41f7daec,0x7f0e50cd,0x172ff691, + 0x768dd64d,0x434db0ef,0xcc544daa,0xe4df0496, + 0x9ee3b5d1,0x4c1b886a,0xc1b81f2c,0x467f5165, + 0x9d04ea5e,0x015d358c,0xfa737487,0xfb2e410b, + 0xb35a1d67,0x9252d2db,0xe9335610,0x6d1347d6, + 0x9a8c61d7,0x377a0ca1,0x598e14f8,0xeb893c13, + 0xceee27a9,0xb735c961,0xe1ede51c,0x7a3cb147, + 0x9c59dfd2,0x553f73f2,0x1879ce14,0x73bf37c7, + 0x53eacdf7,0x5f5baafd,0xdf146f3d,0x7886db44, + 0xca81f3af,0xb93ec468,0x382c3424,0xc25f40a3, + 0x1672c31d,0xbc0c25e2,0x288b493c,0xff41950d, + 0x397101a8,0x08deb30c,0xd89ce4b4,0x6490c156, + 0x7b6184cb,0xd570b632,0x48745c6c,0xd04257b8, + }, +#endif /* !AES_SMALL */ + } + }; + +void +aes_decrypt(const struct aes_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_decrypt(ctx, &_aes_decrypt_table, + length, dst, src); +} diff --git a/aes-encrypt-internal.c b/aes-encrypt-internal.c new file mode 100644 index 0000000..84ed6cf --- /dev/null +++ b/aes-encrypt-internal.c @@ -0,0 +1,105 @@ +/* aes-encrypt-internal.c + * + * Encryption function for the aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" +#include "macros.h" + +void +_nettle_aes_encrypt(const struct aes_ctx *ctx, + const struct aes_table *T, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + FOR_BLOCKS(length, dst, src, AES_BLOCK_SIZE) + { + uint32_t w0, w1, w2, w3; /* working ciphertext */ + uint32_t t0, t1, t2, t3; + unsigned round; + + /* Get clear text, using little-endian byte order. + * Also XOR with the first subkey. */ + + w0 = LE_READ_UINT32(src) ^ ctx->keys[0]; + w1 = LE_READ_UINT32(src + 4) ^ ctx->keys[1]; + w2 = LE_READ_UINT32(src + 8) ^ ctx->keys[2]; + w3 = LE_READ_UINT32(src + 12) ^ ctx->keys[3]; + + for (round = 1; round < ctx->nrounds; round++) + { + t0 = AES_ROUND(T, w0, w1, w2, w3, ctx->keys[4*round]); + t1 = AES_ROUND(T, w1, w2, w3, w0, ctx->keys[4*round + 1]); + t2 = AES_ROUND(T, w2, w3, w0, w1, ctx->keys[4*round + 2]); + t3 = AES_ROUND(T, w3, w0, w1, w2, ctx->keys[4*round + 3]); + + /* We could unroll the loop twice, to avoid these + assignments. If all eight variables fit in registers, + that should give a slight speedup. */ + w0 = t0; + w1 = t1; + w2 = t2; + w3 = t3; + } + + /* Final round */ + + t0 = AES_FINAL_ROUND(T, w0, w1, w2, w3, ctx->keys[4*round]); + t1 = AES_FINAL_ROUND(T, w1, w2, w3, w0, ctx->keys[4*round + 1]); + t2 = AES_FINAL_ROUND(T, w2, w3, w0, w1, ctx->keys[4*round + 2]); + t3 = AES_FINAL_ROUND(T, w3, w0, w1, w2, ctx->keys[4*round + 3]); + + LE_WRITE_UINT32(dst, t0); + LE_WRITE_UINT32(dst + 8, t2); + LE_WRITE_UINT32(dst + 4, t1); + LE_WRITE_UINT32(dst + 12, t3); + } +} + +/* Some stats, all for AES 128: + + A. Table-driven indexing (the approach of the old unified + _aes_crypt function). + B. Unrolling the j-loop. + + C. Eliminated the use of IDXk(j) in the main loop. + + D. Put wtxt in four scalar variables. + + E. Also put t in four scalar variables. + + P4 2.2 GHz AMD Duron 1.4GHz + + MB/s code size + A 35.9 0x202 17 MB/s + B 37.3 0x334 + C 33.0 0x2a7 + D 40.7 0x3f9 + E 42.9 0x44a 26 MB/s + */ diff --git a/aes-encrypt-table.c b/aes-encrypt-table.c new file mode 100644 index 0000000..000498d --- /dev/null +++ b/aes-encrypt-table.c @@ -0,0 +1,346 @@ +/* aes-encrypt-table.c + * + * Encryption table for the aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aes-internal.h" + +/* Tables are assembled using little-endian byte order, including the + * pre-rotated variants. Generated by aesdata.c. + * + * Note that AES is byte order agnostic, we only need to be consistent + * and use the same byteorder when processing key, cleartext and + * ciphertext bytes. + * + * Little-endian means that the first row of the AES state arrays + * occupy the least significant byte of the words, which is also + * consistent with the row numbering. */ + +const struct aes_table +_aes_encrypt_table = + { /* sbox */ + { + 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5, + 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, + 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0, + 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, + 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc, + 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, + 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a, + 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, + 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0, + 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, + 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b, + 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, + 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85, + 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, + 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5, + 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, + 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17, + 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, + 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88, + 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, + 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c, + 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, + 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9, + 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, + 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6, + 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, + 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e, + 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, + 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94, + 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, + 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68, + 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16, + }, + { /* dtable */ + { + 0xa56363c6,0x847c7cf8,0x997777ee,0x8d7b7bf6, + 0x0df2f2ff,0xbd6b6bd6,0xb16f6fde,0x54c5c591, + 0x50303060,0x03010102,0xa96767ce,0x7d2b2b56, + 0x19fefee7,0x62d7d7b5,0xe6abab4d,0x9a7676ec, + 0x45caca8f,0x9d82821f,0x40c9c989,0x877d7dfa, + 0x15fafaef,0xeb5959b2,0xc947478e,0x0bf0f0fb, + 0xecadad41,0x67d4d4b3,0xfda2a25f,0xeaafaf45, + 0xbf9c9c23,0xf7a4a453,0x967272e4,0x5bc0c09b, + 0xc2b7b775,0x1cfdfde1,0xae93933d,0x6a26264c, + 0x5a36366c,0x413f3f7e,0x02f7f7f5,0x4fcccc83, + 0x5c343468,0xf4a5a551,0x34e5e5d1,0x08f1f1f9, + 0x937171e2,0x73d8d8ab,0x53313162,0x3f15152a, + 0x0c040408,0x52c7c795,0x65232346,0x5ec3c39d, + 0x28181830,0xa1969637,0x0f05050a,0xb59a9a2f, + 0x0907070e,0x36121224,0x9b80801b,0x3de2e2df, + 0x26ebebcd,0x6927274e,0xcdb2b27f,0x9f7575ea, + 0x1b090912,0x9e83831d,0x742c2c58,0x2e1a1a34, + 0x2d1b1b36,0xb26e6edc,0xee5a5ab4,0xfba0a05b, + 0xf65252a4,0x4d3b3b76,0x61d6d6b7,0xceb3b37d, + 0x7b292952,0x3ee3e3dd,0x712f2f5e,0x97848413, + 0xf55353a6,0x68d1d1b9,0x00000000,0x2cededc1, + 0x60202040,0x1ffcfce3,0xc8b1b179,0xed5b5bb6, + 0xbe6a6ad4,0x46cbcb8d,0xd9bebe67,0x4b393972, + 0xde4a4a94,0xd44c4c98,0xe85858b0,0x4acfcf85, + 0x6bd0d0bb,0x2aefefc5,0xe5aaaa4f,0x16fbfbed, + 0xc5434386,0xd74d4d9a,0x55333366,0x94858511, + 0xcf45458a,0x10f9f9e9,0x06020204,0x817f7ffe, + 0xf05050a0,0x443c3c78,0xba9f9f25,0xe3a8a84b, + 0xf35151a2,0xfea3a35d,0xc0404080,0x8a8f8f05, + 0xad92923f,0xbc9d9d21,0x48383870,0x04f5f5f1, + 0xdfbcbc63,0xc1b6b677,0x75dadaaf,0x63212142, + 0x30101020,0x1affffe5,0x0ef3f3fd,0x6dd2d2bf, + 0x4ccdcd81,0x140c0c18,0x35131326,0x2fececc3, + 0xe15f5fbe,0xa2979735,0xcc444488,0x3917172e, + 0x57c4c493,0xf2a7a755,0x827e7efc,0x473d3d7a, + 0xac6464c8,0xe75d5dba,0x2b191932,0x957373e6, + 0xa06060c0,0x98818119,0xd14f4f9e,0x7fdcdca3, + 0x66222244,0x7e2a2a54,0xab90903b,0x8388880b, + 0xca46468c,0x29eeeec7,0xd3b8b86b,0x3c141428, + 0x79dedea7,0xe25e5ebc,0x1d0b0b16,0x76dbdbad, + 0x3be0e0db,0x56323264,0x4e3a3a74,0x1e0a0a14, + 0xdb494992,0x0a06060c,0x6c242448,0xe45c5cb8, + 0x5dc2c29f,0x6ed3d3bd,0xefacac43,0xa66262c4, + 0xa8919139,0xa4959531,0x37e4e4d3,0x8b7979f2, + 0x32e7e7d5,0x43c8c88b,0x5937376e,0xb76d6dda, + 0x8c8d8d01,0x64d5d5b1,0xd24e4e9c,0xe0a9a949, + 0xb46c6cd8,0xfa5656ac,0x07f4f4f3,0x25eaeacf, + 0xaf6565ca,0x8e7a7af4,0xe9aeae47,0x18080810, + 0xd5baba6f,0x887878f0,0x6f25254a,0x722e2e5c, + 0x241c1c38,0xf1a6a657,0xc7b4b473,0x51c6c697, + 0x23e8e8cb,0x7cdddda1,0x9c7474e8,0x211f1f3e, + 0xdd4b4b96,0xdcbdbd61,0x868b8b0d,0x858a8a0f, + 0x907070e0,0x423e3e7c,0xc4b5b571,0xaa6666cc, + 0xd8484890,0x05030306,0x01f6f6f7,0x120e0e1c, + 0xa36161c2,0x5f35356a,0xf95757ae,0xd0b9b969, + 0x91868617,0x58c1c199,0x271d1d3a,0xb99e9e27, + 0x38e1e1d9,0x13f8f8eb,0xb398982b,0x33111122, + 0xbb6969d2,0x70d9d9a9,0x898e8e07,0xa7949433, + 0xb69b9b2d,0x221e1e3c,0x92878715,0x20e9e9c9, + 0x49cece87,0xff5555aa,0x78282850,0x7adfdfa5, + 0x8f8c8c03,0xf8a1a159,0x80898909,0x170d0d1a, + 0xdabfbf65,0x31e6e6d7,0xc6424284,0xb86868d0, + 0xc3414182,0xb0999929,0x772d2d5a,0x110f0f1e, + 0xcbb0b07b,0xfc5454a8,0xd6bbbb6d,0x3a16162c, + }, +#if !AES_SMALL + { + 0x6363c6a5,0x7c7cf884,0x7777ee99,0x7b7bf68d, + 0xf2f2ff0d,0x6b6bd6bd,0x6f6fdeb1,0xc5c59154, + 0x30306050,0x01010203,0x6767cea9,0x2b2b567d, + 0xfefee719,0xd7d7b562,0xabab4de6,0x7676ec9a, + 0xcaca8f45,0x82821f9d,0xc9c98940,0x7d7dfa87, + 0xfafaef15,0x5959b2eb,0x47478ec9,0xf0f0fb0b, + 0xadad41ec,0xd4d4b367,0xa2a25ffd,0xafaf45ea, + 0x9c9c23bf,0xa4a453f7,0x7272e496,0xc0c09b5b, + 0xb7b775c2,0xfdfde11c,0x93933dae,0x26264c6a, + 0x36366c5a,0x3f3f7e41,0xf7f7f502,0xcccc834f, + 0x3434685c,0xa5a551f4,0xe5e5d134,0xf1f1f908, + 0x7171e293,0xd8d8ab73,0x31316253,0x15152a3f, + 0x0404080c,0xc7c79552,0x23234665,0xc3c39d5e, + 0x18183028,0x969637a1,0x05050a0f,0x9a9a2fb5, + 0x07070e09,0x12122436,0x80801b9b,0xe2e2df3d, + 0xebebcd26,0x27274e69,0xb2b27fcd,0x7575ea9f, + 0x0909121b,0x83831d9e,0x2c2c5874,0x1a1a342e, + 0x1b1b362d,0x6e6edcb2,0x5a5ab4ee,0xa0a05bfb, + 0x5252a4f6,0x3b3b764d,0xd6d6b761,0xb3b37dce, + 0x2929527b,0xe3e3dd3e,0x2f2f5e71,0x84841397, + 0x5353a6f5,0xd1d1b968,0x00000000,0xededc12c, + 0x20204060,0xfcfce31f,0xb1b179c8,0x5b5bb6ed, + 0x6a6ad4be,0xcbcb8d46,0xbebe67d9,0x3939724b, + 0x4a4a94de,0x4c4c98d4,0x5858b0e8,0xcfcf854a, + 0xd0d0bb6b,0xefefc52a,0xaaaa4fe5,0xfbfbed16, + 0x434386c5,0x4d4d9ad7,0x33336655,0x85851194, + 0x45458acf,0xf9f9e910,0x02020406,0x7f7ffe81, + 0x5050a0f0,0x3c3c7844,0x9f9f25ba,0xa8a84be3, + 0x5151a2f3,0xa3a35dfe,0x404080c0,0x8f8f058a, + 0x92923fad,0x9d9d21bc,0x38387048,0xf5f5f104, + 0xbcbc63df,0xb6b677c1,0xdadaaf75,0x21214263, + 0x10102030,0xffffe51a,0xf3f3fd0e,0xd2d2bf6d, + 0xcdcd814c,0x0c0c1814,0x13132635,0xececc32f, + 0x5f5fbee1,0x979735a2,0x444488cc,0x17172e39, + 0xc4c49357,0xa7a755f2,0x7e7efc82,0x3d3d7a47, + 0x6464c8ac,0x5d5dbae7,0x1919322b,0x7373e695, + 0x6060c0a0,0x81811998,0x4f4f9ed1,0xdcdca37f, + 0x22224466,0x2a2a547e,0x90903bab,0x88880b83, + 0x46468cca,0xeeeec729,0xb8b86bd3,0x1414283c, + 0xdedea779,0x5e5ebce2,0x0b0b161d,0xdbdbad76, + 0xe0e0db3b,0x32326456,0x3a3a744e,0x0a0a141e, + 0x494992db,0x06060c0a,0x2424486c,0x5c5cb8e4, + 0xc2c29f5d,0xd3d3bd6e,0xacac43ef,0x6262c4a6, + 0x919139a8,0x959531a4,0xe4e4d337,0x7979f28b, + 0xe7e7d532,0xc8c88b43,0x37376e59,0x6d6ddab7, + 0x8d8d018c,0xd5d5b164,0x4e4e9cd2,0xa9a949e0, + 0x6c6cd8b4,0x5656acfa,0xf4f4f307,0xeaeacf25, + 0x6565caaf,0x7a7af48e,0xaeae47e9,0x08081018, + 0xbaba6fd5,0x7878f088,0x25254a6f,0x2e2e5c72, + 0x1c1c3824,0xa6a657f1,0xb4b473c7,0xc6c69751, + 0xe8e8cb23,0xdddda17c,0x7474e89c,0x1f1f3e21, + 0x4b4b96dd,0xbdbd61dc,0x8b8b0d86,0x8a8a0f85, + 0x7070e090,0x3e3e7c42,0xb5b571c4,0x6666ccaa, + 0x484890d8,0x03030605,0xf6f6f701,0x0e0e1c12, + 0x6161c2a3,0x35356a5f,0x5757aef9,0xb9b969d0, + 0x86861791,0xc1c19958,0x1d1d3a27,0x9e9e27b9, + 0xe1e1d938,0xf8f8eb13,0x98982bb3,0x11112233, + 0x6969d2bb,0xd9d9a970,0x8e8e0789,0x949433a7, + 0x9b9b2db6,0x1e1e3c22,0x87871592,0xe9e9c920, + 0xcece8749,0x5555aaff,0x28285078,0xdfdfa57a, + 0x8c8c038f,0xa1a159f8,0x89890980,0x0d0d1a17, + 0xbfbf65da,0xe6e6d731,0x424284c6,0x6868d0b8, + 0x414182c3,0x999929b0,0x2d2d5a77,0x0f0f1e11, + 0xb0b07bcb,0x5454a8fc,0xbbbb6dd6,0x16162c3a, + },{ + 0x63c6a563,0x7cf8847c,0x77ee9977,0x7bf68d7b, + 0xf2ff0df2,0x6bd6bd6b,0x6fdeb16f,0xc59154c5, + 0x30605030,0x01020301,0x67cea967,0x2b567d2b, + 0xfee719fe,0xd7b562d7,0xab4de6ab,0x76ec9a76, + 0xca8f45ca,0x821f9d82,0xc98940c9,0x7dfa877d, + 0xfaef15fa,0x59b2eb59,0x478ec947,0xf0fb0bf0, + 0xad41ecad,0xd4b367d4,0xa25ffda2,0xaf45eaaf, + 0x9c23bf9c,0xa453f7a4,0x72e49672,0xc09b5bc0, + 0xb775c2b7,0xfde11cfd,0x933dae93,0x264c6a26, + 0x366c5a36,0x3f7e413f,0xf7f502f7,0xcc834fcc, + 0x34685c34,0xa551f4a5,0xe5d134e5,0xf1f908f1, + 0x71e29371,0xd8ab73d8,0x31625331,0x152a3f15, + 0x04080c04,0xc79552c7,0x23466523,0xc39d5ec3, + 0x18302818,0x9637a196,0x050a0f05,0x9a2fb59a, + 0x070e0907,0x12243612,0x801b9b80,0xe2df3de2, + 0xebcd26eb,0x274e6927,0xb27fcdb2,0x75ea9f75, + 0x09121b09,0x831d9e83,0x2c58742c,0x1a342e1a, + 0x1b362d1b,0x6edcb26e,0x5ab4ee5a,0xa05bfba0, + 0x52a4f652,0x3b764d3b,0xd6b761d6,0xb37dceb3, + 0x29527b29,0xe3dd3ee3,0x2f5e712f,0x84139784, + 0x53a6f553,0xd1b968d1,0x00000000,0xedc12ced, + 0x20406020,0xfce31ffc,0xb179c8b1,0x5bb6ed5b, + 0x6ad4be6a,0xcb8d46cb,0xbe67d9be,0x39724b39, + 0x4a94de4a,0x4c98d44c,0x58b0e858,0xcf854acf, + 0xd0bb6bd0,0xefc52aef,0xaa4fe5aa,0xfbed16fb, + 0x4386c543,0x4d9ad74d,0x33665533,0x85119485, + 0x458acf45,0xf9e910f9,0x02040602,0x7ffe817f, + 0x50a0f050,0x3c78443c,0x9f25ba9f,0xa84be3a8, + 0x51a2f351,0xa35dfea3,0x4080c040,0x8f058a8f, + 0x923fad92,0x9d21bc9d,0x38704838,0xf5f104f5, + 0xbc63dfbc,0xb677c1b6,0xdaaf75da,0x21426321, + 0x10203010,0xffe51aff,0xf3fd0ef3,0xd2bf6dd2, + 0xcd814ccd,0x0c18140c,0x13263513,0xecc32fec, + 0x5fbee15f,0x9735a297,0x4488cc44,0x172e3917, + 0xc49357c4,0xa755f2a7,0x7efc827e,0x3d7a473d, + 0x64c8ac64,0x5dbae75d,0x19322b19,0x73e69573, + 0x60c0a060,0x81199881,0x4f9ed14f,0xdca37fdc, + 0x22446622,0x2a547e2a,0x903bab90,0x880b8388, + 0x468cca46,0xeec729ee,0xb86bd3b8,0x14283c14, + 0xdea779de,0x5ebce25e,0x0b161d0b,0xdbad76db, + 0xe0db3be0,0x32645632,0x3a744e3a,0x0a141e0a, + 0x4992db49,0x060c0a06,0x24486c24,0x5cb8e45c, + 0xc29f5dc2,0xd3bd6ed3,0xac43efac,0x62c4a662, + 0x9139a891,0x9531a495,0xe4d337e4,0x79f28b79, + 0xe7d532e7,0xc88b43c8,0x376e5937,0x6ddab76d, + 0x8d018c8d,0xd5b164d5,0x4e9cd24e,0xa949e0a9, + 0x6cd8b46c,0x56acfa56,0xf4f307f4,0xeacf25ea, + 0x65caaf65,0x7af48e7a,0xae47e9ae,0x08101808, + 0xba6fd5ba,0x78f08878,0x254a6f25,0x2e5c722e, + 0x1c38241c,0xa657f1a6,0xb473c7b4,0xc69751c6, + 0xe8cb23e8,0xdda17cdd,0x74e89c74,0x1f3e211f, + 0x4b96dd4b,0xbd61dcbd,0x8b0d868b,0x8a0f858a, + 0x70e09070,0x3e7c423e,0xb571c4b5,0x66ccaa66, + 0x4890d848,0x03060503,0xf6f701f6,0x0e1c120e, + 0x61c2a361,0x356a5f35,0x57aef957,0xb969d0b9, + 0x86179186,0xc19958c1,0x1d3a271d,0x9e27b99e, + 0xe1d938e1,0xf8eb13f8,0x982bb398,0x11223311, + 0x69d2bb69,0xd9a970d9,0x8e07898e,0x9433a794, + 0x9b2db69b,0x1e3c221e,0x87159287,0xe9c920e9, + 0xce8749ce,0x55aaff55,0x28507828,0xdfa57adf, + 0x8c038f8c,0xa159f8a1,0x89098089,0x0d1a170d, + 0xbf65dabf,0xe6d731e6,0x4284c642,0x68d0b868, + 0x4182c341,0x9929b099,0x2d5a772d,0x0f1e110f, + 0xb07bcbb0,0x54a8fc54,0xbb6dd6bb,0x162c3a16, + },{ + 0xc6a56363,0xf8847c7c,0xee997777,0xf68d7b7b, + 0xff0df2f2,0xd6bd6b6b,0xdeb16f6f,0x9154c5c5, + 0x60503030,0x02030101,0xcea96767,0x567d2b2b, + 0xe719fefe,0xb562d7d7,0x4de6abab,0xec9a7676, + 0x8f45caca,0x1f9d8282,0x8940c9c9,0xfa877d7d, + 0xef15fafa,0xb2eb5959,0x8ec94747,0xfb0bf0f0, + 0x41ecadad,0xb367d4d4,0x5ffda2a2,0x45eaafaf, + 0x23bf9c9c,0x53f7a4a4,0xe4967272,0x9b5bc0c0, + 0x75c2b7b7,0xe11cfdfd,0x3dae9393,0x4c6a2626, + 0x6c5a3636,0x7e413f3f,0xf502f7f7,0x834fcccc, + 0x685c3434,0x51f4a5a5,0xd134e5e5,0xf908f1f1, + 0xe2937171,0xab73d8d8,0x62533131,0x2a3f1515, + 0x080c0404,0x9552c7c7,0x46652323,0x9d5ec3c3, + 0x30281818,0x37a19696,0x0a0f0505,0x2fb59a9a, + 0x0e090707,0x24361212,0x1b9b8080,0xdf3de2e2, + 0xcd26ebeb,0x4e692727,0x7fcdb2b2,0xea9f7575, + 0x121b0909,0x1d9e8383,0x58742c2c,0x342e1a1a, + 0x362d1b1b,0xdcb26e6e,0xb4ee5a5a,0x5bfba0a0, + 0xa4f65252,0x764d3b3b,0xb761d6d6,0x7dceb3b3, + 0x527b2929,0xdd3ee3e3,0x5e712f2f,0x13978484, + 0xa6f55353,0xb968d1d1,0x00000000,0xc12ceded, + 0x40602020,0xe31ffcfc,0x79c8b1b1,0xb6ed5b5b, + 0xd4be6a6a,0x8d46cbcb,0x67d9bebe,0x724b3939, + 0x94de4a4a,0x98d44c4c,0xb0e85858,0x854acfcf, + 0xbb6bd0d0,0xc52aefef,0x4fe5aaaa,0xed16fbfb, + 0x86c54343,0x9ad74d4d,0x66553333,0x11948585, + 0x8acf4545,0xe910f9f9,0x04060202,0xfe817f7f, + 0xa0f05050,0x78443c3c,0x25ba9f9f,0x4be3a8a8, + 0xa2f35151,0x5dfea3a3,0x80c04040,0x058a8f8f, + 0x3fad9292,0x21bc9d9d,0x70483838,0xf104f5f5, + 0x63dfbcbc,0x77c1b6b6,0xaf75dada,0x42632121, + 0x20301010,0xe51affff,0xfd0ef3f3,0xbf6dd2d2, + 0x814ccdcd,0x18140c0c,0x26351313,0xc32fecec, + 0xbee15f5f,0x35a29797,0x88cc4444,0x2e391717, + 0x9357c4c4,0x55f2a7a7,0xfc827e7e,0x7a473d3d, + 0xc8ac6464,0xbae75d5d,0x322b1919,0xe6957373, + 0xc0a06060,0x19988181,0x9ed14f4f,0xa37fdcdc, + 0x44662222,0x547e2a2a,0x3bab9090,0x0b838888, + 0x8cca4646,0xc729eeee,0x6bd3b8b8,0x283c1414, + 0xa779dede,0xbce25e5e,0x161d0b0b,0xad76dbdb, + 0xdb3be0e0,0x64563232,0x744e3a3a,0x141e0a0a, + 0x92db4949,0x0c0a0606,0x486c2424,0xb8e45c5c, + 0x9f5dc2c2,0xbd6ed3d3,0x43efacac,0xc4a66262, + 0x39a89191,0x31a49595,0xd337e4e4,0xf28b7979, + 0xd532e7e7,0x8b43c8c8,0x6e593737,0xdab76d6d, + 0x018c8d8d,0xb164d5d5,0x9cd24e4e,0x49e0a9a9, + 0xd8b46c6c,0xacfa5656,0xf307f4f4,0xcf25eaea, + 0xcaaf6565,0xf48e7a7a,0x47e9aeae,0x10180808, + 0x6fd5baba,0xf0887878,0x4a6f2525,0x5c722e2e, + 0x38241c1c,0x57f1a6a6,0x73c7b4b4,0x9751c6c6, + 0xcb23e8e8,0xa17cdddd,0xe89c7474,0x3e211f1f, + 0x96dd4b4b,0x61dcbdbd,0x0d868b8b,0x0f858a8a, + 0xe0907070,0x7c423e3e,0x71c4b5b5,0xccaa6666, + 0x90d84848,0x06050303,0xf701f6f6,0x1c120e0e, + 0xc2a36161,0x6a5f3535,0xaef95757,0x69d0b9b9, + 0x17918686,0x9958c1c1,0x3a271d1d,0x27b99e9e, + 0xd938e1e1,0xeb13f8f8,0x2bb39898,0x22331111, + 0xd2bb6969,0xa970d9d9,0x07898e8e,0x33a79494, + 0x2db69b9b,0x3c221e1e,0x15928787,0xc920e9e9, + 0x8749cece,0xaaff5555,0x50782828,0xa57adfdf, + 0x038f8c8c,0x59f8a1a1,0x09808989,0x1a170d0d, + 0x65dabfbf,0xd731e6e6,0x84c64242,0xd0b86868, + 0x82c34141,0x29b09999,0x5a772d2d,0x1e110f0f, + 0x7bcbb0b0,0xa8fc5454,0x6dd6bbbb,0x2c3a1616, + }, +#endif /* !AES_SMALL */ + } + }; diff --git a/aes-encrypt.c b/aes-encrypt.c new file mode 100644 index 0000000..19fe071 --- /dev/null +++ b/aes-encrypt.c @@ -0,0 +1,45 @@ +/* aes-encrypt.c + * + * Encryption function for the aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" + +/* The main point on this function is to help the assembler + implementations of _nettle_aes_encrypt to get the table pointer. + For PIC code, the details can be complex and system dependent. */ +void +aes_encrypt(const struct aes_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_encrypt(ctx, &_aes_encrypt_table, + length, dst, src); +} diff --git a/aes-internal.h b/aes-internal.h new file mode 100644 index 0000000..a1e8d02 --- /dev/null +++ b/aes-internal.h @@ -0,0 +1,96 @@ +/* aes-internal.h + * + * The aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_AES_INTERNAL_H_INCLUDED +#define NETTLE_AES_INTERNAL_H_INCLUDED + +#include "aes.h" + +/* Name mangling */ +#define _aes_encrypt _nettle_aes_encrypt +#define _aes_decrypt _nettle_aes_decrypt +#define _aes_encrypt_table _nettle_aes_encrypt_table + +/* Define to use only small tables. */ +#ifndef AES_SMALL +# define AES_SMALL 0 +#endif + +#if AES_SMALL +# define AES_TABLE_SIZE 1 +#else +# define AES_TABLE_SIZE 4 +#endif + +struct aes_table +{ + uint8_t sbox[0x100]; + uint32_t table[AES_TABLE_SIZE][0x100]; +}; + +void +_aes_encrypt(const struct aes_ctx *ctx, + const struct aes_table *T, + unsigned length, uint8_t *dst, + const uint8_t *src); + +void +_aes_decrypt(const struct aes_ctx *ctx, + const struct aes_table *T, + unsigned length, uint8_t *dst, + const uint8_t *src); + +/* Macros */ +#define ROTBYTE(x) (((x) >> 8) | (((x) & 0xff) << 24)) +#define ROTRBYTE(x) (((x) << 8) | (((x) >> 24) & 0xff)) +#define SUBBYTE(x, box) (((box)[((x) & 0xff)]) | \ + ((box)[(((x) >> 8) & 0xff)] << 8) | \ + ((box)[(((x) >> 16) & 0xff)] << 16) | \ + ((box)[(((x) >> 24) & 0xff)] << 24)) + +/* Get the byte with index 0, 1, 2 and 3 */ +#define B0(x) ((x) & 0xff) +#define B1(x) (((x) >> 8) & 0xff) +#define B2(x) (((x) >> 16) & 0xff) +#define B3(x) (((x) >> 24) & 0xff) + +#define AES_ROUND(T, w0, w1, w2, w3, k) \ +(( T->table[0][ B0(w0) ] \ + ^ T->table[1][ B1(w1) ] \ + ^ T->table[2][ B2(w2) ] \ + ^ T->table[3][ B3(w3) ]) ^ (k)) + +#define AES_FINAL_ROUND(T, w0, w1, w2, w3, k) \ +(( (uint32_t) T->sbox[ B0(w0) ] \ + | ((uint32_t) T->sbox[ B1(w1) ] << 8) \ + | ((uint32_t) T->sbox[ B2(w2) ] << 16) \ + | ((uint32_t) T->sbox[ B3(w3) ] << 24)) ^ (k)) + +/* Globally visible so that the same sbox table can be used by aes_set_encrypt_key */ + +extern const struct aes_table _aes_encrypt_table; +#define aes_sbox (_aes_encrypt_table.sbox) + +#endif /* NETTLE_AES_INTERNAL_H_INCLUDED */ diff --git a/aes-meta.c b/aes-meta.c new file mode 100644 index 0000000..7b6fc5a --- /dev/null +++ b/aes-meta.c @@ -0,0 +1,38 @@ +/* aes-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "aes.h" + +const struct nettle_cipher nettle_aes128 += _NETTLE_CIPHER_SEP(aes, AES, 128); + +const struct nettle_cipher nettle_aes192 += _NETTLE_CIPHER_SEP(aes, AES, 192); + +const struct nettle_cipher nettle_aes256 += _NETTLE_CIPHER_SEP(aes, AES, 256); diff --git a/aes-set-decrypt-key.c b/aes-set-decrypt-key.c new file mode 100644 index 0000000..ec44118 --- /dev/null +++ b/aes-set-decrypt-key.c @@ -0,0 +1,186 @@ +/* aes-set-decrypt-key.c + * + * Inverse key setup for the aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Originally written by Rafael R. Sevilla */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aes-internal.h" + +/* Tables for computations in the AES GF2 field. */ +static const uint8_t gf2_log[0x100] = +{ + 0x00,0x00,0x19,0x01,0x32,0x02,0x1a,0xc6, + 0x4b,0xc7,0x1b,0x68,0x33,0xee,0xdf,0x03, + 0x64,0x04,0xe0,0x0e,0x34,0x8d,0x81,0xef, + 0x4c,0x71,0x08,0xc8,0xf8,0x69,0x1c,0xc1, + 0x7d,0xc2,0x1d,0xb5,0xf9,0xb9,0x27,0x6a, + 0x4d,0xe4,0xa6,0x72,0x9a,0xc9,0x09,0x78, + 0x65,0x2f,0x8a,0x05,0x21,0x0f,0xe1,0x24, + 0x12,0xf0,0x82,0x45,0x35,0x93,0xda,0x8e, + 0x96,0x8f,0xdb,0xbd,0x36,0xd0,0xce,0x94, + 0x13,0x5c,0xd2,0xf1,0x40,0x46,0x83,0x38, + 0x66,0xdd,0xfd,0x30,0xbf,0x06,0x8b,0x62, + 0xb3,0x25,0xe2,0x98,0x22,0x88,0x91,0x10, + 0x7e,0x6e,0x48,0xc3,0xa3,0xb6,0x1e,0x42, + 0x3a,0x6b,0x28,0x54,0xfa,0x85,0x3d,0xba, + 0x2b,0x79,0x0a,0x15,0x9b,0x9f,0x5e,0xca, + 0x4e,0xd4,0xac,0xe5,0xf3,0x73,0xa7,0x57, + 0xaf,0x58,0xa8,0x50,0xf4,0xea,0xd6,0x74, + 0x4f,0xae,0xe9,0xd5,0xe7,0xe6,0xad,0xe8, + 0x2c,0xd7,0x75,0x7a,0xeb,0x16,0x0b,0xf5, + 0x59,0xcb,0x5f,0xb0,0x9c,0xa9,0x51,0xa0, + 0x7f,0x0c,0xf6,0x6f,0x17,0xc4,0x49,0xec, + 0xd8,0x43,0x1f,0x2d,0xa4,0x76,0x7b,0xb7, + 0xcc,0xbb,0x3e,0x5a,0xfb,0x60,0xb1,0x86, + 0x3b,0x52,0xa1,0x6c,0xaa,0x55,0x29,0x9d, + 0x97,0xb2,0x87,0x90,0x61,0xbe,0xdc,0xfc, + 0xbc,0x95,0xcf,0xcd,0x37,0x3f,0x5b,0xd1, + 0x53,0x39,0x84,0x3c,0x41,0xa2,0x6d,0x47, + 0x14,0x2a,0x9e,0x5d,0x56,0xf2,0xd3,0xab, + 0x44,0x11,0x92,0xd9,0x23,0x20,0x2e,0x89, + 0xb4,0x7c,0xb8,0x26,0x77,0x99,0xe3,0xa5, + 0x67,0x4a,0xed,0xde,0xc5,0x31,0xfe,0x18, + 0x0d,0x63,0x8c,0x80,0xc0,0xf7,0x70,0x07, +}; + +static const uint8_t gf2_exp[0x100] = +{ + 0x01,0x03,0x05,0x0f,0x11,0x33,0x55,0xff, + 0x1a,0x2e,0x72,0x96,0xa1,0xf8,0x13,0x35, + 0x5f,0xe1,0x38,0x48,0xd8,0x73,0x95,0xa4, + 0xf7,0x02,0x06,0x0a,0x1e,0x22,0x66,0xaa, + 0xe5,0x34,0x5c,0xe4,0x37,0x59,0xeb,0x26, + 0x6a,0xbe,0xd9,0x70,0x90,0xab,0xe6,0x31, + 0x53,0xf5,0x04,0x0c,0x14,0x3c,0x44,0xcc, + 0x4f,0xd1,0x68,0xb8,0xd3,0x6e,0xb2,0xcd, + 0x4c,0xd4,0x67,0xa9,0xe0,0x3b,0x4d,0xd7, + 0x62,0xa6,0xf1,0x08,0x18,0x28,0x78,0x88, + 0x83,0x9e,0xb9,0xd0,0x6b,0xbd,0xdc,0x7f, + 0x81,0x98,0xb3,0xce,0x49,0xdb,0x76,0x9a, + 0xb5,0xc4,0x57,0xf9,0x10,0x30,0x50,0xf0, + 0x0b,0x1d,0x27,0x69,0xbb,0xd6,0x61,0xa3, + 0xfe,0x19,0x2b,0x7d,0x87,0x92,0xad,0xec, + 0x2f,0x71,0x93,0xae,0xe9,0x20,0x60,0xa0, + 0xfb,0x16,0x3a,0x4e,0xd2,0x6d,0xb7,0xc2, + 0x5d,0xe7,0x32,0x56,0xfa,0x15,0x3f,0x41, + 0xc3,0x5e,0xe2,0x3d,0x47,0xc9,0x40,0xc0, + 0x5b,0xed,0x2c,0x74,0x9c,0xbf,0xda,0x75, + 0x9f,0xba,0xd5,0x64,0xac,0xef,0x2a,0x7e, + 0x82,0x9d,0xbc,0xdf,0x7a,0x8e,0x89,0x80, + 0x9b,0xb6,0xc1,0x58,0xe8,0x23,0x65,0xaf, + 0xea,0x25,0x6f,0xb1,0xc8,0x43,0xc5,0x54, + 0xfc,0x1f,0x21,0x63,0xa5,0xf4,0x07,0x09, + 0x1b,0x2d,0x77,0x99,0xb0,0xcb,0x46,0xca, + 0x45,0xcf,0x4a,0xde,0x79,0x8b,0x86,0x91, + 0xa8,0xe3,0x3e,0x42,0xc6,0x51,0xf3,0x0e, + 0x12,0x36,0x5a,0xee,0x29,0x7b,0x8d,0x8c, + 0x8f,0x8a,0x85,0x94,0xa7,0xf2,0x0d,0x17, + 0x39,0x4b,0xdd,0x7c,0x84,0x97,0xa2,0xfd, + 0x1c,0x24,0x6c,0xb4,0xc7,0x52,0xf6,0x01, +}; + +static unsigned +mult(unsigned a, unsigned b) +{ + return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0; +} + +static void +inv_mix_column(uint32_t *a) +{ + uint8_t c[4][4]; + unsigned i, j; + + for (j = 0; j < 4; j++) + { + for(i = 0; i < 4; i++) + { + c[j][i] = mult(0xe, (a[j] >> i*8) & 0xff) + ^ mult(0xb, (a[j] >> ((i+1)%4)*8) & 0xff) + ^ mult(0xd, (a[j] >> ((i+2)%4)*8) & 0xff) + ^ mult(0x9, (a[j] >> ((i+3)%4)*8) & 0xff); + } + } + for (i = 0; i < 4; i++) + { + a[i] = 0; + for(j = 0; j < 4; j++) + a[i] |= c[i][j] << (j*8); + } +} + +#define SWAP(a, b) \ +do { uint32_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0) + +void +aes_invert_key(struct aes_ctx *dst, + const struct aes_ctx *src) +{ + unsigned nrounds; + unsigned i; + + nrounds = src->nrounds; + + /* Reverse the order of subkeys, in groups of 4. */ + /* FIXME: Instead of reordering the subkeys, change the access order + of aes_decrypt, since it's a separate function anyway? */ + if (src == dst) + { + unsigned j, k; + + for (i = 0, j = nrounds * 4; + i < j; + i += 4, j -= 4) + for (k = 0; k<4; k++) + SWAP(dst->keys[i+k], dst->keys[j+k]); + } + else + { + unsigned k; + + dst->nrounds = nrounds; + for (i = 0; i <= nrounds * 4; i += 4) + for (k = 0; k < 4; k++) + dst->keys[i+k] = src->keys[nrounds * 4 - i + k]; + } + + /* Transform all subkeys but the first and last. */ + for (i = 4; i < 4 * nrounds; i += 4) + inv_mix_column(dst->keys + i); +} + +void +aes_set_decrypt_key(struct aes_ctx *ctx, + unsigned keysize, const uint8_t *key) +{ + /* We first create subkeys for encryption, + * then modify the subkeys for decryption. */ + aes_set_encrypt_key(ctx, keysize, key); + aes_invert_key(ctx, ctx); +} + diff --git a/aes-set-encrypt-key.c b/aes-set-encrypt-key.c new file mode 100644 index 0000000..9c60c03 --- /dev/null +++ b/aes-set-encrypt-key.c @@ -0,0 +1,96 @@ +/* aes-set-encrypt-key.c + * + * Key setup for the aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Originally written by Rafael R. Sevilla */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" + +static unsigned +xtime(unsigned x) +{ + assert (x < 0x100); + + x <<= 1; + if (x & 0x100) + x ^= 0x11b; + + assert (x < 0x100); + + return x; +} + +void +aes_set_encrypt_key(struct aes_ctx *ctx, + unsigned keysize, const uint8_t *key) +{ + unsigned nk, nr, i, lastkey; + uint32_t temp, rcon; + + assert(keysize >= AES_MIN_KEY_SIZE); + assert(keysize <= AES_MAX_KEY_SIZE); + + /* Truncate keysizes to the valid key sizes provided by Rijndael */ + if (keysize == 32) { + nk = 8; + nr = 14; + } else if (keysize >= 24) { + nk = 6; + nr = 12; + } else { /* must be 16 or more */ + nk = 4; + nr = 10; + } + + lastkey = (AES_BLOCK_SIZE/4) * (nr + 1); + ctx->nrounds = nr; + rcon = 1; + for (i=0; ikeys[i] = key[i*4] + (key[i*4+1]<<8) + (key[i*4+2]<<16) + + (key[i*4+3]<<24); + } + + for (i=nk; ikeys[i-1]; + if (i % nk == 0) + { + temp = SUBBYTE(ROTBYTE(temp), aes_sbox) ^ rcon; + rcon = (uint32_t)xtime((uint8_t)rcon&0xff); + } + else if (nk > 6 && (i%nk) == 4) + { + temp = SUBBYTE(temp, aes_sbox); + } + ctx->keys[i] = ctx->keys[i-nk] ^ temp; + } +} + diff --git a/aes.h b/aes.h new file mode 100644 index 0000000..23cc0cf --- /dev/null +++ b/aes.h @@ -0,0 +1,85 @@ +/* aes.h + * + * The aes/rijndael block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_AES_H_INCLUDED +#define NETTLE_AES_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define aes_set_encrypt_key nettle_aes_set_encrypt_key +#define aes_set_decrypt_key nettle_aes_set_decrypt_key +#define aes_invert_key nettle_aes_invert_key +#define aes_encrypt nettle_aes_encrypt +#define aes_decrypt nettle_aes_decrypt + +#define AES_BLOCK_SIZE 16 + +/* Variable key size between 128 and 256 bits. But the only valid + * values are 16 (128 bits), 24 (192 bits) and 32 (256 bits). */ +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 + +#define AES_KEY_SIZE 32 + +/* FIXME: Change to put nrounds first, to make it possible to use a + truncated ctx struct, with less subkeys, for the shorter key + sizes? */ +struct aes_ctx +{ + uint32_t keys[60]; /* maximum size of key schedule */ + unsigned nrounds; /* number of rounds to use for our key size */ +}; + +void +aes_set_encrypt_key(struct aes_ctx *ctx, + unsigned length, const uint8_t *key); + +void +aes_set_decrypt_key(struct aes_ctx *ctx, + unsigned length, const uint8_t *key); + +void +aes_invert_key(struct aes_ctx *dst, + const struct aes_ctx *src); + +void +aes_encrypt(const struct aes_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +aes_decrypt(const struct aes_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_AES_H_INCLUDED */ diff --git a/aesdata.c b/aesdata.c new file mode 100644 index 0000000..9077c54 --- /dev/null +++ b/aesdata.c @@ -0,0 +1,299 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "nettle-types.h" + +#if 1 +# define BYTE_FORMAT "0x%02x" +# define BYTE_COLUMNS 8 +#else +# define BYTE_FORMAT "%3d" +# define BYTE_COLUMNS 0x10 +#endif + +#define WORD_FORMAT "0x%08x" +#define WORD_COLUMNS 4 + +uint8_t sbox[0x100]; +uint8_t isbox[0x100]; + +uint8_t gf2_log[0x100]; +uint8_t gf2_exp[0x100]; + +uint32_t dtable[4][0x100]; +uint32_t itable[4][0x100]; + +static unsigned +xtime(unsigned x) +{ + assert (x < 0x100); + + x <<= 1; + if (x & 0x100) + x ^= 0x11b; + + assert (x < 0x100); + + return x; +} + +/* Computes the exponentiatiom and logarithm tables for GF_2, to the + * base x+1 (0x03). The unit element is 1 (0x01).*/ +static void +compute_log(void) +{ + unsigned i = 0; + unsigned x = 1; + + memset(gf2_log, 0, 0x100); + + for (i = 0; i < 0x100; i++, x = x ^ xtime(x)) + { + gf2_exp[i] = x; + gf2_log[x] = i; + } + /* Invalid. */ + gf2_log[0] = 0; + /* The loop above sets gf2_log[1] = 0xff, which is correct, + * but gf2_log[1] = 0 is nicer. */ + gf2_log[1] = 0; +} + +static unsigned +mult(unsigned a, unsigned b) +{ + return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0; +} + +static unsigned +invert(unsigned x) +{ + return x ? gf2_exp[0xff - gf2_log[x]] : 0; +} + +static unsigned +affine(unsigned x) +{ + return 0xff & + (0x63^x^(x>>4)^(x<<4)^(x>>5)^(x<<3)^(x>>6)^(x<<2)^(x>>7)^(x<<1)); +} + +static void +compute_sbox(void) +{ + unsigned i; + for (i = 0; i<0x100; i++) + { + sbox[i] = affine(invert(i)); + isbox[sbox[i]] = i; + } +} + +/* Generate little endian tables, i.e. the first row of the AES state + * arrays occupies the least significant byte of the words. + * + * The sbox values are multiplied with the column of GF2 coefficients + * of the polynomial 03 x^3 + x^2 + x + 02. */ +static void +compute_dtable(void) +{ + unsigned i; + for (i = 0; i<0x100; i++) + { + unsigned s = sbox[i]; + unsigned j; + uint32_t t =( ( (s ^ xtime(s)) << 24) + | (s << 16) | (s << 8) + | xtime(s) ); + + for (j = 0; j<4; j++, t = (t << 8) | (t >> 24)) + dtable[j][i] = t; + } +} + +/* The inverse sbox values are multiplied with the column of GF2 coefficients + * of the polynomial inverse 0b x^3 + 0d x^2 + 09 x + 0e. */ +static void +compute_itable(void) +{ + unsigned i; + for (i = 0; i<0x100; i++) + { + unsigned s = isbox[i]; + unsigned j; + uint32_t t = ( (mult(s, 0xb) << 24) + | (mult(s, 0xd) << 16) + | (mult(s, 0x9) << 8) + | (mult(s, 0xe) )); + + for (j = 0; j<4; j++, t = (t << 8) | (t >> 24)) + itable[j][i] = t; + } +} + +static void +display_byte_table(const char *name, uint8_t *table) +{ + unsigned i, j; + + printf("uint8_t %s[0x100] =\n{", name); + + for (i = 0; i<0x100; i+= BYTE_COLUMNS) + { + printf("\n "); + for (j = 0; j + +#include "arcfour.h" + +void +arcfour_crypt(struct arcfour_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + register uint8_t i, j; + register int si, sj; + + i = ctx->i; j = ctx->j; + while(length--) + { + i++; i &= 0xff; + si = ctx->S[i]; + j += si; j &= 0xff; + sj = ctx->S[i] = ctx->S[j]; + ctx->S[j] = si; + *dst++ = *src++ ^ ctx->S[ (si + sj) & 0xff ]; + } + ctx->i = i; ctx->j = j; +} diff --git a/arcfour-meta.c b/arcfour-meta.c new file mode 100644 index 0000000..d5f1467 --- /dev/null +++ b/arcfour-meta.c @@ -0,0 +1,38 @@ +/* arcfour-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "arcfour.h" + +const struct nettle_cipher nettle_arcfour128 = + { "arcfour128", sizeof(struct arcfour_ctx), + 0, 16, + (nettle_set_key_func *) arcfour_set_key, + (nettle_set_key_func *) arcfour_set_key, + (nettle_crypt_func *) arcfour_crypt, + (nettle_crypt_func *) arcfour_crypt + }; diff --git a/arcfour.c b/arcfour.c new file mode 100644 index 0000000..d833422 --- /dev/null +++ b/arcfour.c @@ -0,0 +1,78 @@ +/* arcfour.c + * + * The arcfour/rc4 stream cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "arcfour.h" + +#define SWAP(a,b) do { int _t = a; a = b; b = _t; } while(0) + +void +arcfour_set_key(struct arcfour_ctx *ctx, + unsigned length, const uint8_t *key) +{ + unsigned i, j, k; + + assert(length >= ARCFOUR_MIN_KEY_SIZE); + assert(length <= ARCFOUR_MAX_KEY_SIZE); + + /* Initialize context */ + for (i = 0; i<256; i++) + ctx->S[i] = i; + + for (i = j = k = 0; i<256; i++) + { + j += ctx->S[i] + key[k]; j &= 0xff; + SWAP(ctx->S[i], ctx->S[j]); + /* Repeat key as needed */ + k = (k + 1) % length; + } + ctx->i = ctx->j = 0; +} + +void +arcfour_stream(struct arcfour_ctx *ctx, + unsigned length, uint8_t *dst) +{ + register uint8_t i, j; + register int si, sj; + + i = ctx->i; j = ctx->j; + while(length--) + { + i++; i &= 0xff; + si = ctx->S[i]; + j += si; j &= 0xff; + sj = ctx->S[i] = ctx->S[j]; + ctx->S[j] = si; + *dst++ = ctx->S[ (si + sj) & 0xff ]; + } + ctx->i = i; ctx->j = j; +} + diff --git a/arcfour.h b/arcfour.h new file mode 100644 index 0000000..f8e6689 --- /dev/null +++ b/arcfour.h @@ -0,0 +1,71 @@ +/* arcfour.h + * + * The arcfour/rc4 stream cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_ARCFOUR_H_INCLUDED +#define NETTLE_ARCFOUR_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define arcfour_set_key nettle_arcfour_set_key +#define arcfour_crypt nettle_arcfour_crypt +#define arcfour_stream nettle_arcfour_stream + +/* Minimum and maximum keysizes, and a reasonable default. In + * octets.*/ +#define ARCFOUR_MIN_KEY_SIZE 1 +#define ARCFOUR_MAX_KEY_SIZE 256 +#define ARCFOUR_KEY_SIZE 16 + +struct arcfour_ctx +{ + uint8_t S[256]; + uint8_t i; + uint8_t j; +}; + +void +arcfour_set_key(struct arcfour_ctx *ctx, + unsigned length, const uint8_t *key); + +void +arcfour_crypt(struct arcfour_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +void +arcfour_stream(struct arcfour_ctx *ctx, + unsigned length, uint8_t *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ARCFOUR_H_INCLUDED */ + diff --git a/arctwo-meta.c b/arctwo-meta.c new file mode 100644 index 0000000..3401b9d --- /dev/null +++ b/arctwo-meta.c @@ -0,0 +1,48 @@ +/* arctwo-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2004 Simon Josefsson + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "arctwo.h" + +const struct nettle_cipher nettle_arctwo40 += _NETTLE_CIPHER (arctwo, ARCTWO, 40); + +const struct nettle_cipher nettle_arctwo64 += _NETTLE_CIPHER (arctwo, ARCTWO, 64); + +const struct nettle_cipher nettle_arctwo128 += _NETTLE_CIPHER (arctwo, ARCTWO, 128); + +/* Map Gutmann variant. */ +#define arctwo_gutmann_ctx arctwo_ctx +#define arctwo_gutmann_encrypt arctwo_encrypt +#define arctwo_gutmann_decrypt arctwo_decrypt +#define arctwo_gutmann_ctx arctwo_ctx +#define arctwo_gutmann_set_key arctwo_set_key_gutmann + +const struct nettle_cipher nettle_arctwo_gutmann128 += _NETTLE_CIPHER (arctwo_gutmann, ARCTWO, 128); diff --git a/arctwo.c b/arctwo.c new file mode 100644 index 0000000..9793467 --- /dev/null +++ b/arctwo.c @@ -0,0 +1,230 @@ +/* arctwo.c + * + * The cipher described in rfc2268; aka Ron's Cipher 2. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2004 Simon Josefsson + * Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation, Inc. + * Copyright (C) 2004 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* 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 and later adapted for direct + * use by Nettle by Simon Josefsson and Niels Möller. + * + * The implementation here is based on Peter Gutmann's RRC.2 paper and + * RFC 2268. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "arctwo.h" + +#include "macros.h" + +static const uint8_t arctwo_sbox[] = { + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, + 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, + 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, + 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, + 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, + 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, + 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82, + 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, + 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, + 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, + 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, + 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03, + 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, + 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, + 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, + 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, + 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec, + 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, + 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, + 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, + 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, + 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9, + 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, + 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, + 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, + 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, + 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad +}; + +#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n)))) +#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n)))) + +void +arctwo_encrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t *dst, const uint8_t *src) +{ + FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE) + { + register unsigned i; + uint16_t w0, w1, w2, w3; + + w0 = LE_READ_UINT16 (&src[0]); + w1 = LE_READ_UINT16 (&src[2]); + w2 = LE_READ_UINT16 (&src[4]); + w3 = LE_READ_UINT16 (&src[6]); + + for (i = 0; i < 16; i++) + { + register unsigned j = i * 4; + /* For some reason I cannot combine those steps. */ + w0 += (w1 & ~w3) + (w2 & w3) + ctx->S[j]; + w0 = rotl16 (w0, 1); + + w1 += (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1]; + w1 = rotl16 (w1, 2); + + w2 += (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2]; + w2 = rotl16 (w2, 3); + + w3 += (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3]; + w3 = rotl16 (w3, 5); + + if (i == 4 || i == 10) + { + w0 += ctx->S[w3 & 63]; + w1 += ctx->S[w0 & 63]; + w2 += ctx->S[w1 & 63]; + w3 += ctx->S[w2 & 63]; + } + } + LE_WRITE_UINT16 (&dst[0], w0); + LE_WRITE_UINT16 (&dst[2], w1); + LE_WRITE_UINT16 (&dst[4], w2); + LE_WRITE_UINT16 (&dst[6], w3); + } +} + +void +arctwo_decrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t *dst, const uint8_t *src) +{ + FOR_BLOCKS (length, dst, src, ARCTWO_BLOCK_SIZE) + { + register unsigned i; + uint16_t w0, w1, w2, w3; + + w0 = LE_READ_UINT16 (&src[0]); + w1 = LE_READ_UINT16 (&src[2]); + w2 = LE_READ_UINT16 (&src[4]); + w3 = LE_READ_UINT16 (&src[6]); + + for (i = 16; i-- > 0; ) + { + register unsigned j = i * 4; + + w3 = rotr16 (w3, 5); + w3 -= (w0 & ~w2) + (w1 & w2) + ctx->S[j + 3]; + + w2 = rotr16 (w2, 3); + w2 -= (w3 & ~w1) + (w0 & w1) + ctx->S[j + 2]; + + w1 = rotr16 (w1, 2); + w1 -= (w2 & ~w0) + (w3 & w0) + ctx->S[j + 1]; + + w0 = rotr16 (w0, 1); + w0 -= (w1 & ~w3) + (w2 & w3) + ctx->S[j]; + + if (i == 5 || i == 11) + { + w3 = w3 - ctx->S[w2 & 63]; + w2 = w2 - ctx->S[w1 & 63]; + w1 = w1 - ctx->S[w0 & 63]; + w0 = w0 - ctx->S[w3 & 63]; + } + + } + LE_WRITE_UINT16 (&dst[0], w0); + LE_WRITE_UINT16 (&dst[2], w1); + LE_WRITE_UINT16 (&dst[4], w2); + LE_WRITE_UINT16 (&dst[6], w3); + } +} + +void +arctwo_set_key_ekb (struct arctwo_ctx *ctx, + unsigned length, const uint8_t *key, unsigned ekb) +{ + unsigned i; + /* Expanded key, treated as octets */ + uint8_t S[128]; + uint8_t x; + + assert (length >= ARCTWO_MIN_KEY_SIZE); + assert (length <= ARCTWO_MAX_KEY_SIZE); + assert (ekb <= 1024); + + for (i = 0; i < length; i++) + S[i] = key[i]; + + /* Phase 1: Expand input key to 128 bytes */ + for (i = length; i < ARCTWO_MAX_KEY_SIZE; i++) + S[i] = arctwo_sbox[(S[i - length] + S[i - 1]) & 255]; + + S[0] = arctwo_sbox[S[0]]; + + /* Reduce effective key size to ekb bits, if requested by caller. */ + if (ekb > 0 && ekb < 1024) + { + int len = (ekb + 7) >> 3; + i = 128 - len; + x = arctwo_sbox[S[i] & (255 >> (7 & -ekb))]; + S[i] = x; + + while (i--) + { + x = arctwo_sbox[x ^ S[i + len]]; + S[i] = x; + } + } + + /* Make the expanded key endian independent. */ + for (i = 0; i < 64; i++) + ctx->S[i] = LE_READ_UINT16(S + i * 2); +} + +void +arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, length, key, 8 * length); +} + +void +arctwo_set_key_gutmann (struct arctwo_ctx *ctx, + unsigned length, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, length, key, 0); +} diff --git a/arctwo.h b/arctwo.h new file mode 100644 index 0000000..cf3c96d --- /dev/null +++ b/arctwo.h @@ -0,0 +1,82 @@ +/* arctwo.h + * + * The arctwo/rfc2268 block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2004 Simon Josefsson + * Copyright (C) 2002, 2004 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_ARCTWO_H_INCLUDED +#define NETTLE_ARCTWO_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define arctwo_set_key nettle_arctwo_set_key +#define arctwo_set_key_ekb nettle_arctwo_set_key_ekb +#define arctwo_encrypt nettle_arctwo_encrypt +#define arctwo_decrypt nettle_arctwo_decrypt +#define arctwo_set_key_gutmann nettle_arctwo_set_key_gutmann + +#define ARCTWO_BLOCK_SIZE 8 + +/* Variable key size from 1 byte to 128 bytes. */ +#define ARCTWO_MIN_KEY_SIZE 1 +#define ARCTWO_MAX_KEY_SIZE 128 + +#define ARCTWO_KEY_SIZE 8 + +struct arctwo_ctx +{ + uint16_t S[64]; +}; + +/* Key expansion function that takes the "effective key bits", 1-1024, + as an explicit argument. 0 means maximum key bits. */ +void +arctwo_set_key_ekb (struct arctwo_ctx *ctx, + unsigned length, const uint8_t * key, unsigned ekb); + +/* Equvivalent to arctwo_set_key_ekb, with ekb = 8 * length */ +void +arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key); + +/* Equvivalent to arctwo_set_key_ekb, with ekb = 1024 */ +void +arctwo_set_key_gutmann (struct arctwo_ctx *ctx, + unsigned length, const uint8_t *key); + +void +arctwo_encrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t *dst, const uint8_t *src); +void +arctwo_decrypt (struct arctwo_ctx *ctx, + unsigned length, uint8_t *dst, const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ARCTWO_H_INCLUDED */ diff --git a/asm.m4 b/asm.m4 new file mode 100644 index 0000000..e2721d4 --- /dev/null +++ b/asm.m4 @@ -0,0 +1,65 @@ +changequote(<,>)dnl +dnl (progn (modify-syntax-entry ?< "(>") (modify-syntax-entry ?> ")<") ) + +dnl FORTRAN style comment character +define(, < +dnl>)dnl + +dnl Including files from the srcdir +define(, )dnl + +dnl Pseudo ops + +define(, +, +<.globl C_NAME($1) +C_NAME($1):>)>) + +define(, +,<>)>) + +dnl Argument to ALIGN is always logarithmic +dnl Can't use << operator with our choice of quote characters... +define(, +<.align ifelse(ALIGN_LOG,yes,$1,eval(2 ** $1))>) + +dnl Struct defining macros + +dnl STRUCTURE(prefix) +define(, , 0)define(, <$1>)>)dnl + +dnl STRUCT(name, size) +define(, +$1, SOFFSET)dnl + define(, eval(SOFFSET + ($2)))>)dnl + +dnl UCHAR(name) +define(, , 1)>)dnl + +dnl UNSIGNED(name) +define(, , 4)>)dnl + +dnl Offsets in arcfour_ctx +STRUCTURE(ARCFOUR) + STRUCT(S, 256) + UCHAR(I) + UCHAR(J) + +dnl Offsets in aes_ctx and aes_table +STRUCTURE(AES) + STRUCT(KEYS, 4*60) + UNSIGNED(NROUNDS) + +define(AES_SBOX_SIZE, 256)dnl +define(AES_TABLE_SIZE, 1024)dnl + +STRUCTURE(AES) + STRUCT(SBOX, AES_SBOX_SIZE) + STRUCT(TABLE0, AES_TABLE_SIZE) + STRUCT(TABLE1, AES_TABLE_SIZE) + STRUCT(TABLE2, AES_TABLE_SIZE) + STRUCT(TABLE3, AES_TABLE_SIZE) diff --git a/asn1.h b/asn1.h new file mode 100644 index 0000000..7933ce2 --- /dev/null +++ b/asn1.h @@ -0,0 +1,144 @@ +/* asn1.h + * + * Some very limited asn.1 support. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_ASN1_H_INCLUDED +#define NETTLE_ASN1_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define asn1_der_iterator_first nettle_asn1_der_iterator_first +#define asn1_der_iterator_next nettle_asn1_der_iterator_next +#define asn1_der_decode_constructed nettle_asn1_der_decode_constructed +#define asn1_der_decode_constructed_last nettle_asn1_der_decode_constructed_last +#define asn1_der_decode_bitstring nettle_asn1_der_decode_bitstring +#define asn1_der_decode_bitstring_last nettle_asn1_der_decode_bitstring_last +#define asn1_der_get_uint32 nettle_asn1_der_get_uint32 +#define asn1_der_get_bignum nettle_asn1_der_get_bignum + + +/* enum asn1_type keeps the class number and the constructive in bits + 13-14, and the constructive flag in bit 12. The remaining 14 bits + are the tag (although currently, only tags in the range 0-30 are + supported). */ + +enum + { + ASN1_TYPE_CONSTRUCTED = 1 << 12, + + ASN1_CLASS_UNIVERSAL = 0, + ASN1_CLASS_APPLICATION = 1 << 13, + ASN1_CLASS_CONTEXT_SPECIFIC = 2 << 13, + ASN1_CLASS_PRIVATE = 3 << 13, + + ASN1_CLASS_MASK = 3 << 13, + ASN1_CLASS_SHIFT = 13, + }; + +enum asn1_type + { + ASN1_BOOLEAN = 1, + ASN1_INTEGER = 2, + ASN1_BITSTRING = 3, + ASN1_OCTETSTRING = 4, + ASN1_NULL = 5, + ASN1_IDENTIFIER = 6, + ASN1_REAL = 9, + ASN1_ENUMERATED = 10, + ASN1_UTF8STRING = 12, + ASN1_SEQUENCE = 16 | ASN1_TYPE_CONSTRUCTED, + ASN1_SET = 17 | ASN1_TYPE_CONSTRUCTED, + ASN1_PRINTABLESTRING = 19, + ASN1_TELETEXSTRING = 20, + ASN1_IA5STRING = 22, + ASN1_UTC = 23, + ASN1_UNIVERSALSTRING = 28, + ASN1_BMPSTRING = 30, + }; + +enum asn1_iterator_result + { + ASN1_ITERATOR_ERROR, + ASN1_ITERATOR_PRIMITIVE, + ASN1_ITERATOR_CONSTRUCTED, + ASN1_ITERATOR_END, + }; + +/* Parsing DER objects. */ +struct asn1_der_iterator +{ + unsigned buffer_length; + const uint8_t *buffer; + + /* Next object to parse. */ + unsigned pos; + + enum asn1_type type; + + /* Pointer to the current object */ + unsigned length; + const uint8_t *data; +}; + +/* Initializes the iterator. */ +enum asn1_iterator_result +asn1_der_iterator_first(struct asn1_der_iterator *iterator, + unsigned length, const uint8_t *input); + +enum asn1_iterator_result +asn1_der_iterator_next(struct asn1_der_iterator *iterator); + +/* Starts parsing of a constructed object. */ +enum asn1_iterator_result +asn1_der_decode_constructed(struct asn1_der_iterator *i, + struct asn1_der_iterator *contents); + +/* For the common case that we have a sequence at the end of the + object. Checks that the current object is the final one, and then + reinitializes the iterator to parse its ontents. */ +enum asn1_iterator_result +asn1_der_decode_constructed_last(struct asn1_der_iterator *i); + +enum asn1_iterator_result +asn1_der_decode_bitstring(struct asn1_der_iterator *i, + struct asn1_der_iterator *contents); + +enum asn1_iterator_result +asn1_der_decode_bitstring_last(struct asn1_der_iterator *i); + +/* All these functions return 1 on success, 0 on failure */ +int +asn1_der_get_uint32(struct asn1_der_iterator *i, + uint32_t *x); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ASN1_H_INCLUDED */ diff --git a/base16-decode.c b/base16-decode.c new file mode 100644 index 0000000..2689411 --- /dev/null +++ b/base16-decode.c @@ -0,0 +1,130 @@ +/* base16-encode.c + * + * Hex decoding. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "base16.h" + +void +base16_decode_init(struct base16_decode_ctx *ctx) +{ + ctx->word = ctx->bits = 0; +} + +enum { HEX_INVALID = -1, HEX_SPACE=-2 }; + +static const signed char +hex_decode_table[0x80] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + +/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on + * errors. */ +int +base16_decode_single(struct base16_decode_ctx *ctx, + uint8_t *dst, + uint8_t src) +{ + int digit; + + if (src >= 0x80) + return -1; + + digit = hex_decode_table[src]; + switch (digit) + { + case -1: + return -1; + case -2: + return 0; + default: + assert(digit >= 0); + assert(digit < 0x10); + + if (ctx->bits) + { + *dst = (ctx->word << 4) | digit; + ctx->bits = 0; + return 1; + } + else + { + ctx->word = digit; + ctx->bits = 4; + return 0; + } + } +} + +int +base16_decode_update(struct base16_decode_ctx *ctx, + unsigned *dst_length, + uint8_t *dst, + unsigned src_length, + const uint8_t *src) +{ + unsigned done; + unsigned i; + + assert(*dst_length >= BASE16_DECODE_LENGTH(src_length)); + + for (i = 0, done = 0; ibits == 0; +} diff --git a/base16-encode.c b/base16-encode.c new file mode 100644 index 0000000..b2267ab --- /dev/null +++ b/base16-encode.c @@ -0,0 +1,57 @@ +/* base16-encode.c + * + * Hex encoding. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "base16.h" + + +static const uint8_t +hex_digits[16] = "0123456789abcdef"; + +#define DIGIT(x) (hex_digits[(x) & 0xf]) + +/* Encodes a single byte. Always stores two digits in dst[0] and dst[1]. */ +void +base16_encode_single(uint8_t *dst, + uint8_t src) +{ + dst[0] = DIGIT(src/0x10); + dst[1] = DIGIT(src); +} + +/* Always stores BASE16_ENCODE_LENGTH(length) digits in dst. */ +void +base16_encode_update(uint8_t *dst, + unsigned length, + const uint8_t *src) +{ + unsigned i; + + for (i = 0, dst; i +#include + +#include "base64.h" + +#define TABLE_INVALID -1 +#define TABLE_SPACE -2 +#define TABLE_END -3 + +static const signed char +decode_table[0x100] = +{ + /* White space is HT, VT, FF, CR, LF and SPC */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + +void +base64_decode_init(struct base64_decode_ctx *ctx) +{ + ctx->word = ctx->bits = ctx->padding = 0; +} + +int +base64_decode_single(struct base64_decode_ctx *ctx, + uint8_t *dst, + uint8_t src) +{ + int data; + + data = decode_table[src]; + + switch(data) + { + default: + assert(data >= 0 && data < 0x40); + + if (ctx->padding) + return -1; + + ctx->word = ctx->word << 6 | data; + ctx->bits += 6; + + if (ctx->bits >= 8) + { + ctx->bits -= 8; + dst[0] = ctx->word >> ctx->bits; + return 1; + } + else return 0; + + case TABLE_INVALID: + return -1; + + case TABLE_SPACE: + return 0; + + case TABLE_END: + /* There can be at most two padding characters. */ + if (!ctx->bits || ctx->padding > 2) + return -1; + + if (ctx->word & ( (1<bits) - 1)) + /* We shouldn't have any leftover bits */ + return -1; + + ctx->padding++; + ctx->bits -= 2; + return 0; + } +} + +int +base64_decode_update(struct base64_decode_ctx *ctx, + unsigned *dst_length, + uint8_t *dst, + unsigned src_length, + const uint8_t *src) +{ + unsigned done; + unsigned i; + + assert(*dst_length >= BASE64_DECODE_LENGTH(src_length)); + + for (i = 0, done = 0; ibits == 0; +} diff --git a/base64-encode.c b/base64-encode.c new file mode 100644 index 0000000..6fc5e6b --- /dev/null +++ b/base64-encode.c @@ -0,0 +1,229 @@ +/* base64-encode.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "base64.h" + +static const uint8_t encode_table[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +#define ENCODE(x) (encode_table[0x3F & (x)]) + +void +base64_encode_raw(uint8_t *dst, unsigned length, const uint8_t *src) +{ + const uint8_t *in = src + length; + uint8_t *out = dst + BASE64_ENCODE_RAW_LENGTH(length); + + unsigned left_over = length % 3; + + if (left_over) + { + in -= left_over; + *--out = '='; + switch(left_over) + { + case 1: + *--out = '='; + *--out = ENCODE(in[0] << 4); + break; + + case 2: + *--out = ENCODE( in[1] << 2); + *--out = ENCODE((in[0] << 4) | (in[1] >> 4)); + break; + + default: + abort(); + } + *--out = ENCODE(in[0] >> 2); + } + + while (in > src) + { + in -= 3; + *--out = ENCODE( in[2]); + *--out = ENCODE((in[1] << 2) | (in[2] >> 6)); + *--out = ENCODE((in[0] << 4) | (in[1] >> 4)); + *--out = ENCODE( in[0] >> 2); + } + assert(in == src); + assert(out == dst); +} + +#if 0 +unsigned +base64_encode(uint8_t *dst, + unsigned src_length, + const uint8_t *src) +{ + unsigned dst_length = BASE64_ENCODE_RAW_LENGTH(src_length); + unsigned n = src_length / 3; + unsigned left_over = src_length % 3; + unsigned done = 0; + + if (left_over) + { + const uint8_t *in = src + n * 3; + uint8_t *out = dst + dst_length; + + switch(left_over) + { + case 1: + *--out = '='; + *--out = ENCODE(in[0] << 4); + break; + + case 2: + *--out = ENCODE( in[1] << 2); + *--out = ENCODE((in[0] << 4) | (in[1] >> 4)); + break; + + default: + abort(); + } + *--out = ENCODE(in[0] >> 2); + + done = 4; + } + base64_encode_raw(n, dst, src); + done += n * 4; + + assert(done == dst_length); + + return done; +} +#endif + +void +base64_encode_group(uint8_t *dst, uint32_t group) +{ + *dst++ = ENCODE(group >> 18); + *dst++ = ENCODE(group >> 12); + *dst++ = ENCODE(group >> 6); + *dst++ = ENCODE(group); +} + +void +base64_encode_init(struct base64_encode_ctx *ctx) +{ + ctx->word = ctx->bits = 0; +} + +/* Encodes a single byte. */ +unsigned +base64_encode_single(struct base64_encode_ctx *ctx, + uint8_t *dst, + uint8_t src) +{ + unsigned done = 0; + unsigned word = ctx->word << 8 | src; + unsigned bits = ctx->bits + 8; + + while (bits >= 6) + { + bits -= 6; + dst[done++] = ENCODE(word >> bits); + } + + ctx->bits = bits; + ctx->word = word; + + assert(done <= 2); + + return done; +} + +/* Returns the number of output characters. DST should point to an + * area of size at least BASE64_ENCODE_LENGTH(length). */ +unsigned +base64_encode_update(struct base64_encode_ctx *ctx, + uint8_t *dst, + unsigned length, + const uint8_t *src) +{ + unsigned done = 0; + unsigned left = length; + unsigned left_over; + unsigned bulk; + + while (ctx->bits && left) + { + left--; + done += base64_encode_single(ctx, dst + done, *src++); + } + + left_over = left % 3; + bulk = left - left_over; + + if (bulk) + { + assert(!(bulk % 3)); + + base64_encode_raw(dst + done, bulk, src); + done += BASE64_ENCODE_RAW_LENGTH(bulk); + src += bulk; + left = left_over; + } + + while (left) + { + left--; + done += base64_encode_single(ctx, dst + done, *src++); + } + + assert(done <= BASE64_ENCODE_LENGTH(length)); + + return done; +} + +/* DST should point to an area of size at least + * BASE64_ENCODE_FINAL_SIZE */ +unsigned +base64_encode_final(struct base64_encode_ctx *ctx, + uint8_t *dst) +{ + unsigned done = 0; + unsigned bits = ctx->bits; + + if (bits) + { + dst[done++] = ENCODE(ctx->word << (6 - ctx->bits)); + for (; bits < 6; bits += 2) + dst[done++] = '='; + + ctx->bits = 0; + } + + assert(done <= BASE64_ENCODE_FINAL_LENGTH); + return done; +} diff --git a/base64-meta.c b/base64-meta.c new file mode 100644 index 0000000..608e7b6 --- /dev/null +++ b/base64-meta.c @@ -0,0 +1,45 @@ +/* base64-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Dan Egnor, Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "base64.h" + +/* Same as the macros with the same name */ +static unsigned +base64_encode_length(unsigned length) +{ + return BASE64_ENCODE_LENGTH(length); +} + +static unsigned +base64_decode_length(unsigned length) +{ + return BASE64_DECODE_LENGTH(length); +} + +const struct nettle_armor nettle_base64 += _NETTLE_ARMOR(base64, BASE64); diff --git a/base64.h b/base64.h new file mode 100644 index 0000000..2be1865 --- /dev/null +++ b/base64.h @@ -0,0 +1,153 @@ +/* base64.h + * + * "ASCII armor" codecs. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller, Dan Egnor + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_BASE64_H_INCLUDED +#define NETTLE_BASE64_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define base64_encode_init nettle_base64_encode_init +#define base64_encode_single nettle_base64_encode_single +#define base64_encode_update nettle_base64_encode_update +#define base64_encode_final nettle_base64_encode_final +#define base64_encode_raw nettle_base64_encode_raw +#define base64_encode_group nettle_base64_encode_group +#define base64_decode_init nettle_base64_decode_init +#define base64_decode_single nettle_base64_decode_single +#define base64_decode_update nettle_base64_decode_update +#define base64_decode_final nettle_base64_decode_final + +#define BASE64_BINARY_BLOCK_SIZE 3 +#define BASE64_TEXT_BLOCK_SIZE 4 + +/* Base64 encoding */ + +/* Maximum length of output for base64_encode_update. NOTE: Doesn't + * include any padding that base64_encode_final may add. */ +/* We have at most 4 buffered bits, and a total of (4 + length * 8) bits. */ +#define BASE64_ENCODE_LENGTH(length) (((length) * 8 + 4)/6) + +/* Maximum lengbth of output generated by base64_encode_final. */ +#define BASE64_ENCODE_FINAL_LENGTH 3 + +/* Exact length of output generated by base64_encode_raw, including + * padding. */ +#define BASE64_ENCODE_RAW_LENGTH(length) ((((length) + 2)/3)*4) + +struct base64_encode_ctx +{ + unsigned word; /* Leftover bits */ + unsigned bits; /* Number of bits, always 0, 2, or 4. */ +}; + +void +base64_encode_init(struct base64_encode_ctx *ctx); + +/* Encodes a single byte. Returns amount of output (always 1 or 2). */ +unsigned +base64_encode_single(struct base64_encode_ctx *ctx, + uint8_t *dst, + uint8_t src); + +/* Returns the number of output characters. DST should point to an + * area of size at least BASE64_ENCODE_LENGTH(length). */ +unsigned +base64_encode_update(struct base64_encode_ctx *ctx, + uint8_t *dst, + unsigned length, + const uint8_t *src); + +/* DST should point to an area of size at least + * BASE64_ENCODE_FINAL_LENGTH */ +unsigned +base64_encode_final(struct base64_encode_ctx *ctx, + uint8_t *dst); + +/* Lower level functions */ + +/* Encodes a string in one go, including any padding at the end. + * Generates exactly BASE64_ENCODE_RAW_LENGTH(length) bytes of output. + * Supports overlapped operation, if src <= dst. */ +void +base64_encode_raw(uint8_t *dst, unsigned length, const uint8_t *src); + +void +base64_encode_group(uint8_t *dst, uint32_t group); + + +/* Base64 decoding */ + +/* Maximum length of output for base64_decode_update. */ +/* We have at most 6 buffered bits, and a total of (length + 1) * 6 bits. */ +#define BASE64_DECODE_LENGTH(length) ((((length) + 1) * 6) / 8) + +struct base64_decode_ctx +{ + unsigned word; /* Leftover bits */ + unsigned bits; /* Number buffered bits */ + + /* Number of padding characters encountered */ + unsigned padding; +}; + +void +base64_decode_init(struct base64_decode_ctx *ctx); + +/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on + * errors. */ +int +base64_decode_single(struct base64_decode_ctx *ctx, + uint8_t *dst, + uint8_t src); + +/* Returns 1 on success, 0 on error. DST should point to an area of + * size at least BASE64_DECODE_LENGTH(length), and for sanity + * checking, *DST_LENGTH should be initialized to the size of that + * area before the call. *DST_LENGTH is updated to the amount of + * decoded output. */ + +/* Currently results in an assertion failure if *DST_LENGTH is + * too small. FIXME: Return some error instead? */ +int +base64_decode_update(struct base64_decode_ctx *ctx, + unsigned *dst_length, + uint8_t *dst, + unsigned src_length, + const uint8_t *src); + +/* Returns 1 on success. */ +int +base64_decode_final(struct base64_decode_ctx *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_BASE64_H_INCLUDED */ diff --git a/bignum-next-prime.c b/bignum-next-prime.c new file mode 100644 index 0000000..91ba8fd --- /dev/null +++ b/bignum-next-prime.c @@ -0,0 +1,162 @@ +/* bignum-next-prime.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +/* Needed for alloca on freebsd */ +#include + +#include "bignum.h" + +#include "nettle-internal.h" + +/* From gmp.h */ +/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */ +#if defined (__GNUC__) && defined (__GNUC_MINOR__) +#define GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +#define GNUC_PREREQ(maj, min) 0 +#endif + +#if GNUC_PREREQ (3,0) +# define UNLIKELY(cond) __builtin_expect ((cond) != 0, 0) +#else +# define UNLIKELY(cond) cond +#endif + +/* From some benchmarking using the examples nextprime(200!) and + nextprime(240!), it seems that it pays off to use a prime list up + to around 5000--10000 primes. There are 6541 odd primes less than + 2^16. */ +static const uint16_t primes[] = { + /* Generated by + + ./examples/eratosthenes 65535 \ + | awk '{ if (NR % 10 == 2) printf ("\n"); if (NR > 1) printf("%d, ", $1); } + END { printf("\n"); }' > prime-list.h + */ + #include "prime-list.h" +}; + +#define NUMBER_OF_PRIMES (sizeof(primes) / sizeof(primes[0])) + +#ifdef mpz_millerrabin +# define PRIME_P mpz_millerrabin +#else +# define PRIME_P mpz_probab_prime_p +#endif + +/* NOTE: The mpz_nextprime in current GMP is unoptimized. */ +void +nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit, + void *progress_ctx, nettle_progress_func progress) +{ + mpz_t tmp; + TMP_DECL(moduli, unsigned, NUMBER_OF_PRIMES); + + unsigned difference; + + if (prime_limit > NUMBER_OF_PRIMES) + prime_limit = NUMBER_OF_PRIMES; + + /* First handle tiny numbers */ + if (mpz_cmp_ui(n, 2) <= 0) + { + mpz_set_ui(p, 2); + return; + } + mpz_set(p, n); + mpz_setbit(p, 0); + + if (mpz_cmp_ui(p, 8) < 0) + return; + + mpz_init(tmp); + + if (mpz_cmp_ui(p, primes[prime_limit-1]) <= 0) + /* Use only 3, 5 and 7 */ + /* FIXME: Could do binary search in the table. */ + prime_limit = 3; + + /* Compute residues modulo small odd primes */ + /* FIXME: Could be sped up by collecting limb-sized products of the + primes, to reduce the calls to mpz_fdiv_ui */ + + /* FIXME: Could also handle the first few primes separately; compute + the residue mod 15015 = 3 * 7 * 11 * 13, and tabulate the steps + between the 5760 odd numbers in this interval that have no factor + in common with 15015. + */ + TMP_ALLOC(moduli, prime_limit); + { + unsigned i; + for (i = 0; i < prime_limit; i++) + moduli[i] = mpz_fdiv_ui(p, primes[i]); + } + + for (difference = 0; ; difference += 2) + { + int composite = 0; + unsigned i; + + if (difference >= UINT_MAX - 10) + { /* Should not happen, at least not very often... */ + mpz_add_ui(p, p, difference); + difference = 0; + } + + /* First check residues */ + for (i = 0; i < prime_limit; i++) + { + if (moduli[i] == 0) + composite = 1; + + moduli[i] += 2; + if (UNLIKELY(moduli[i] >= primes[i])) + moduli[i] -= primes[i]; + } + if (composite) + continue; + + mpz_add_ui(p, p, difference); + difference = 0; + + if (progress) + progress(progress_ctx, '.'); + + /* Miller-Rabin test */ + if (PRIME_P(p, count)) + break; + +#if 0 + if (progress) + progress(progress_ctx, '*'); +#endif + } + mpz_clear(tmp); +} diff --git a/bignum-random-prime.c b/bignum-random-prime.c new file mode 100644 index 0000000..bc2938f --- /dev/null +++ b/bignum-random-prime.c @@ -0,0 +1,415 @@ +/* bignum-random-prime.c + * + * Generation of random provable primes. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef RANDOM_PRIME_VERBOSE +#define RANDOM_PRIME_VERBOSE 0 +#endif + +#include +#include + +#if RANDOM_PRIME_VERBOSE +#include +#define VERBOSE(x) (fputs((x), stderr)) +#else +#define VERBOSE(x) +#endif + +#include "bignum.h" + +#include "macros.h" + +/* Use a table of p_2 = 3 to p_{172} = 1021, used for sieving numbers + of up to 20 bits. */ + +#define NPRIMES 171 +#define TRIAL_DIV_BITS 20 +#define TRIAL_DIV_MASK ((1 << TRIAL_DIV_BITS) - 1) + +/* A 20-bit number x is divisible by p iff + + ((x * inverse) & TRIAL_DIV_MASK) <= limit +*/ +struct trial_div_info { + uint32_t inverse; /* p^{-1} (mod 2^20) */ + uint32_t limit; /* floor( (2^20 - 1) / p) */ +}; + +static const uint16_t +primes[NPRIMES] = { + 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, +}; + +static const uint32_t +prime_square[NPRIMES+1] = { + 9,25,49,121,169,289,361,529, + 841,961,1369,1681,1849,2209,2809,3481, + 3721,4489,5041,5329,6241,6889,7921,9409, + 10201,10609,11449,11881,12769,16129,17161,18769, + 19321,22201,22801,24649,26569,27889,29929,32041, + 32761,36481,37249,38809,39601,44521,49729,51529, + 52441,54289,57121,58081,63001,66049,69169,72361, + 73441,76729,78961,80089,85849,94249,96721,97969, + 100489,109561,113569,120409,121801,124609,128881,134689, + 139129,143641,146689,151321,157609,160801,167281,175561, + 177241,185761,187489,192721,196249,201601,208849,212521, + 214369,218089,229441,237169,241081,249001,253009,259081, + 271441,273529,292681,299209,310249,316969,323761,326041, + 332929,344569,351649,358801,361201,368449,375769,380689, + 383161,398161,410881,413449,418609,426409,434281,436921, + 452929,458329,466489,477481,491401,502681,516961,528529, + 537289,546121,552049,564001,573049,579121,591361,597529, + 619369,635209,654481,657721,674041,677329,683929,687241, + 703921,727609,734449,737881,744769,769129,776161,779689, + 786769,822649,829921,844561,863041,877969,885481,896809, + 908209,935089,942841,954529,966289,982081,994009,1018081, + 1026169,1038361,1042441,1L<<20 +}; + +static const struct trial_div_info +trial_div_table[NPRIMES] = { + {699051,349525},{838861,209715},{748983,149796},{953251,95325}, + {806597,80659},{61681,61680},{772635,55188},{866215,45590}, + {180789,36157},{1014751,33825},{793517,28339},{1023001,25575}, + {48771,24385},{870095,22310},{217629,19784},{710899,17772}, + {825109,17189},{281707,15650},{502135,14768},{258553,14364}, + {464559,13273},{934875,12633},{1001449,11781},{172961,10810}, + {176493,10381},{203607,10180},{568387,9799},{788837,9619}, + {770193,9279},{1032063,8256},{544299,8004},{619961,7653}, + {550691,7543},{182973,7037},{229159,6944},{427445,6678}, + {701195,6432},{370455,6278},{90917,6061},{175739,5857}, + {585117,5793},{225087,5489},{298817,5433},{228877,5322}, + {442615,5269},{546651,4969},{244511,4702},{83147,4619}, + {769261,4578},{841561,4500},{732687,4387},{978961,4350}, + {133683,4177},{65281,4080},{629943,3986},{374213,3898}, + {708079,3869},{280125,3785},{641833,3731},{618771,3705}, + {930477,3578},{778747,3415},{623751,3371},{40201,3350}, + {122389,3307},{950371,3167},{1042353,3111},{18131,3021}, + {285429,3004},{549537,2970},{166487,2920},{294287,2857}, + {919261,2811},{636339,2766},{900735,2737},{118605,2695}, + {10565,2641},{188273,2614},{115369,2563},{735755,2502}, + {458285,2490},{914767,2432},{370513,2421},{1027079,2388}, + {629619,2366},{462401,2335},{649337,2294},{316165,2274}, + {484655,2264},{65115,2245},{326175,2189},{1016279,2153}, + {990915,2135},{556859,2101},{462791,2084},{844629,2060}, + {404537,2012},{457123,2004},{577589,1938},{638347,1916}, + {892325,1882},{182523,1862},{1002505,1842},{624371,1836}, + {69057,1817},{210787,1786},{558769,1768},{395623,1750}, + {992745,1744},{317855,1727},{384877,1710},{372185,1699}, + {105027,1693},{423751,1661},{408961,1635},{908331,1630}, + {74551,1620},{36933,1605},{617371,1591},{506045,1586}, + {24929,1558},{529709,1548},{1042435,1535},{31867,1517}, + {166037,1495},{928781,1478},{508975,1458},{4327,1442}, + {779637,1430},{742091,1418},{258263,1411},{879631,1396}, + {72029,1385},{728905,1377},{589057,1363},{348621,1356}, + {671515,1332},{710453,1315},{84249,1296},{959363,1292}, + {685853,1277},{467591,1274},{646643,1267},{683029,1264}, + {439927,1249},{254461,1229},{660713,1223},{554195,1220}, + {202911,1215},{753253,1195},{941457,1190},{776635,1187}, + {509511,1182},{986147,1156},{768879,1151},{699431,1140}, + {696417,1128},{86169,1119},{808997,1114},{25467,1107}, + {201353,1100},{708087,1084},{1018339,1079},{341297,1073}, + {434151,1066},{96287,1058},{950765,1051},{298257,1039}, + {675933,1035},{167731,1029},{815445,1027}, +}; + +/* Element j gives the index of the first prime of size 3+j bits */ +static uint8_t +prime_by_size[9] = { + 1,3,5,10,17,30,53,96,171 +}; + +/* Combined Miller-Rabin test to the base a, and checking the + conditions from Pocklington's theorem. */ +static int +miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a) +{ + mpz_t r; + mpz_t y; + int is_prime = 0; + + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned k; + unsigned j; + + VERBOSE("."); + + if (mpz_even_p(n) || mpz_cmp_ui(n, 3) < 0) + return 0; + + mpz_init(r); + mpz_init(y); + + k = mpz_scan1(nm1, 0); + assert(k > 0); + + mpz_fdiv_q_2exp (r, nm1, k); + + mpz_powm(y, a, r, n); + + if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, nm1) == 0) + goto passed_miller_rabin; + + for (j = 1; j < k; j++) + { + mpz_powm_ui (y, y, 2, n); + + if (mpz_cmp_ui (y, 1) == 0) + break; + + if (mpz_cmp (y, nm1) == 0) + { + passed_miller_rabin: + /* We know that a^{n-1} = 1 (mod n) + + Remains to check that gcd(a^{(n-1)/q} - 1, n) == 1 */ + VERBOSE("x"); + + mpz_powm(y, a, nm1dq, n); + mpz_sub_ui(y, y, 1); + mpz_gcd(y, y, n); + is_prime = mpz_cmp_ui (y, 1) == 0; + VERBOSE(is_prime ? "\n" : ""); + break; + } + + } + + mpz_clear(r); + mpz_clear(y); + + return is_prime; +} + +/* The algorithm is based on the following special case of + Pocklington's theorem: + + Assume that n = 1 + f q, where q is a prime, q > sqrt(n) - 1. If we + can find an a such that + + a^{n-1} = 1 (mod n) + gcd(a^f - 1, n) = 1 + + then n is prime. + + Proof: Assume that n is composite, with smallest prime factor p <= + sqrt(n). Since q is prime, and q > sqrt(n) - 1 >= p - 1, q and p-1 + are coprime, so that we can define u = q^{-1} (mod (p-1)). The + assumption a^{n-1} = 1 (mod n) implies that also a^{n-1} = 1 (mod + p). Since p is prime, we have a^{(p-1)} = 1 (mod p). Now, r = + (n-1)/q = (n-1) u (mod (p-1)), and it follows that a^r = a^{(n-1) + u} = 1 (mod p). Then p is a common factor of a^r - 1 and n. This + contradicts gcd(a^r - 1, n) = 1, and concludes the proof. + + If n is specified as k bits, we need q of size ceil(k/2) + 1 bits + (or more) to make the theorem apply. +*/ + +/* Generate a prime number p of size bits with 2 p0q dividing (p-1). + p0 must be of size >= ceil(bits/2) + 1. The extra factor q can be + omitted. If top_bits_set is one, the top most two bits are one, + suitable for RSA primes. */ +void +_nettle_generate_pocklington_prime (mpz_t p, mpz_t r, + unsigned bits, int top_bits_set, + void *ctx, nettle_random_func random, + const mpz_t p0, + const mpz_t q, + const mpz_t p0q) +{ + mpz_t r_min, r_range, pm1,a; + + assert (2*mpz_sizeinbase (p0, 2) > bits + 1); + + mpz_init (r_min); + mpz_init (r_range); + mpz_init (pm1); + mpz_init (a); + + if (top_bits_set) + { + /* i = floor (2^{bits-3} / p0q), then 3I + 3 <= r <= 4I, with I + - 2 possible values. */ + mpz_set_ui (r_min, 1); + mpz_mul_2exp (r_min, r_min, bits-3); + mpz_fdiv_q (r_min, r_min, p0q); + mpz_sub_ui (r_range, r_min, 2); + mpz_mul_ui (r_min, r_min, 3); + mpz_add_ui (r_min, r_min, 3); + } + else + { + /* i = floor (2^{bits-2} / p0q), I + 1 <= r <= 2I */ + mpz_set_ui (r_range, 1); + mpz_mul_2exp (r_range, r_range, bits-2); + mpz_fdiv_q (r_range, r_range, p0q); + mpz_add_ui (r_min, r_range, 1); + } + for (;;) + { + uint8_t buf[1]; + + nettle_mpz_random (r, ctx, random, r_range); + mpz_add (r, r, r_min); + + /* Set p = 2*r*p0q + 1 */ + mpz_mul_2exp(r, r, 1); + mpz_mul (pm1, r, p0q); + mpz_add_ui (p, pm1, 1); + + assert(mpz_sizeinbase(p, 2) == bits); + + /* Should use GMP trial division interface when that + materializes, we don't need any testing beyond trial + division. */ + if (!mpz_probab_prime_p (p, 1)) + continue; + + random(ctx, sizeof(buf), buf); + + mpz_set_ui (a, buf[0] + 2); + + if (q) + { + mpz_t e; + int is_prime; + + mpz_init (e); + + mpz_mul (e, r, q); + is_prime = miller_rabin_pocklington(p, pm1, e, a); + mpz_clear (e); + + if (is_prime) + break; + } + else if (miller_rabin_pocklington(p, pm1, r, a)) + break; + } + mpz_clear (r_min); + mpz_clear (r_range); + mpz_clear (pm1); + mpz_clear (a); +} + +/* Generate random prime of a given size. Maurer's algorithm (Alg. + 6.42 Handbook of applied cryptography), but with ratio = 1/2 (like + the variant in fips186-3). */ +void +nettle_random_prime(mpz_t p, unsigned bits, int top_bits_set, + void *random_ctx, nettle_random_func random, + void *progress_ctx, nettle_progress_func progress) +{ + assert (bits >= 3); + if (bits <= 10) + { + unsigned first; + unsigned choices; + uint8_t buf; + + assert (!top_bits_set); + + random (random_ctx, sizeof(buf), &buf); + + first = prime_by_size[bits-3]; + choices = prime_by_size[bits-2] - first; + + mpz_set_ui (p, primes[first + buf % choices]); + } + else if (bits <= 20) + { + unsigned long highbit; + uint8_t buf[3]; + unsigned long x; + unsigned j; + + assert (!top_bits_set); + + highbit = 1L << (bits - 1); + + again: + random (random_ctx, sizeof(buf), buf); + x = READ_UINT24(buf); + x &= (highbit - 1); + x |= highbit | 1; + + for (j = 0; prime_square[j] <= x; j++) + { + unsigned q = x * trial_div_table[j].inverse & TRIAL_DIV_MASK; + if (q <= trial_div_table[j].limit) + goto again; + } + mpz_set_ui (p, x); + } + else + { + mpz_t q, r; + + mpz_init (q); + mpz_init (r); + + /* Bit size ceil(k/2) + 1, slightly larger than used in Alg. 4.62 + in Handbook of Applied Cryptography (which seems to be + incorrect for odd k). */ + nettle_random_prime (q, (bits+3)/2, 0, random_ctx, random, + progress_ctx, progress); + + _nettle_generate_pocklington_prime (p, r, bits, top_bits_set, + random_ctx, random, + q, NULL, q); + + if (progress) + progress (progress_ctx, 'x'); + + mpz_clear (q); + mpz_clear (r); + } +} diff --git a/bignum-random.c b/bignum-random.c new file mode 100644 index 0000000..dc2fd1c --- /dev/null +++ b/bignum-random.c @@ -0,0 +1,85 @@ +/* bignum-random.c + * + * Generating big random numbers + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "bignum.h" +#include "nettle-internal.h" + +void +nettle_mpz_random_size(mpz_t x, + void *ctx, nettle_random_func random, + unsigned bits) +{ + unsigned length = (bits + 7) / 8; + TMP_DECL(data, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(data, length); + + random(ctx, length, data); + + nettle_mpz_set_str_256_u(x, length, data); + + if (bits % 8) + mpz_fdiv_r_2exp(x, x, bits); +} + +/* Returns a random number x, 0 <= x < n */ +void +nettle_mpz_random(mpz_t x, + void *ctx, nettle_random_func random, + const mpz_t n) +{ + /* NOTE: This leaves some bias, which may be bad for DSA. A better + * way might be to generate a random number of mpz_sizeinbase(n, 2) + * bits, and loop until one smaller than n is found. */ + + /* From Daniel Bleichenbacher (via coderpunks): + * + * There is still a theoretical attack possible with 8 extra bits. + * But, the attack would need about 2^66 signatures 2^66 memory and + * 2^66 time (if I remember that correctly). Compare that to DSA, + * where the attack requires 2^22 signatures 2^40 memory and 2^64 + * time. And of course, the numbers above are not a real threat for + * PGP. Using 16 extra bits (i.e. generating a 176 bit random number + * and reducing it modulo q) will defeat even this theoretical + * attack. + * + * More generally log_2(q)/8 extra bits are enough to defeat my + * attack. NIST also plans to update the standard. + */ + + /* Add a few bits extra, to decrease the bias from the final modulo + * operation. */ + + nettle_mpz_random_size(x, + ctx, random, + mpz_sizeinbase(n, 2) + 16); + + mpz_fdiv_r(x, x, n); +} diff --git a/bignum.c b/bignum.c new file mode 100644 index 0000000..bb18791 --- /dev/null +++ b/bignum.c @@ -0,0 +1,195 @@ +/* bignum.c + * + * bignum operations that are missing from gmp. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "bignum.h" + +/* Two's complement negation means that -x = ~x + 1, ~x = -(x+1), + * and we use that x = ~~x = ~(-x-1). + * + * Examples: + * + * x ~x = -x+1 ~~x = x + * -1 0 ff + * -2 1 fe + * -7f 7e 81 + * -80 7f 80 + * -81 80 ff7f + */ + +/* Including extra sign bit, if needed. Also one byte for zero. */ +unsigned +nettle_mpz_sizeinbase_256_s(const mpz_t x) +{ + if (mpz_sgn(x) >= 0) + return 1 + mpz_sizeinbase(x, 2) / 8; + else + { + /* We'll output ~~x, so we need as many bits as for ~x */ + unsigned size; + mpz_t c; + + mpz_init(c); + mpz_com(c, x); /* Same as c = - x - 1 = |x| + 1 */ + size = 1 + mpz_sizeinbase(c,2) / 8; + mpz_clear(c); + + return size; + } +} + +unsigned +nettle_mpz_sizeinbase_256_u(const mpz_t x) +{ + return (mpz_sizeinbase(x,2) + 7) / 8; +} + +static void +nettle_mpz_to_octets(unsigned length, uint8_t *s, + const mpz_t x, uint8_t sign) +{ + uint8_t *dst = s + length - 1; + unsigned size = mpz_size(x); + unsigned i; + + for (i = 0; i>= 8; + length--; + } + } + + if (length) + memset(s, sign, length); +} + +void +nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x) +{ + if (!length) + { + /* x must be zero */ + assert(!mpz_sgn(x)); + return; + } + + if (mpz_sgn(x) >= 0) + { + assert(nettle_mpz_sizeinbase_256_u(x) <= length); + nettle_mpz_to_octets(length, s, x, 0); + } + else + { + mpz_t c; + mpz_init(c); + mpz_com(c, x); + + assert(nettle_mpz_sizeinbase_256_u(c) <= length); + nettle_mpz_to_octets(length, s, c, 0xff); + + mpz_clear(c); + } +} + +/* Converting from strings */ + +#ifdef mpz_import +/* Was introduced in GMP-4.1 */ +# define nettle_mpz_from_octets(x, length, s) \ + mpz_import((x), (length), 1, 1, 0, 0, (s)) +#else +static void +nettle_mpz_from_octets(mpz_t x, + unsigned length, const uint8_t *s) +{ + unsigned i; + + mpz_set_ui(x, 0); + + for (i = 0; i < length; i++) + { + mpz_mul_2exp(x, x, 8); + mpz_add_ui(x, x, s[i]); + } +} +#endif + +void +nettle_mpz_set_str_256_u(mpz_t x, + unsigned length, const uint8_t *s) +{ + nettle_mpz_from_octets(x, length, s); +} + +void +nettle_mpz_init_set_str_256_u(mpz_t x, + unsigned length, const uint8_t *s) +{ + mpz_init(x); + nettle_mpz_from_octets(x, length, s); +} + +void +nettle_mpz_set_str_256_s(mpz_t x, + unsigned length, const uint8_t *s) +{ + if (!length) + { + mpz_set_ui(x, 0); + return; + } + + nettle_mpz_from_octets(x, length, s); + + if (s[0] & 0x80) + { + mpz_t t; + + mpz_init_set_ui(t, 1); + mpz_mul_2exp(t, t, length*8); + mpz_sub(x, x, t); + mpz_clear(t); + } +} + +void +nettle_mpz_init_set_str_256_s(mpz_t x, + unsigned length, const uint8_t *s) +{ + mpz_init(x); + nettle_mpz_set_str_256_s(x, length, s); +} diff --git a/bignum.h b/bignum.h new file mode 100644 index 0000000..06287d2 --- /dev/null +++ b/bignum.h @@ -0,0 +1,121 @@ +/* bignum.h + * + * bignum operations that are missing from gmp. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_BIGNUM_H_INCLUDED +#define NETTLE_BIGNUM_H_INCLUDED + +#include "nettle-meta.h" + +#include +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Size needed for signed encoding, including extra sign byte if + * necessary. */ +unsigned +nettle_mpz_sizeinbase_256_s(const mpz_t x); + +/* Size needed for unsigned encoding */ +unsigned +nettle_mpz_sizeinbase_256_u(const mpz_t x); + +/* Writes an integer as length octets, using big endian byte order, + * and two's complement for negative numbers. */ +void +nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x); + +/* Reads a big endian, two's complement, integer. */ +void +nettle_mpz_set_str_256_s(mpz_t x, + unsigned length, const uint8_t *s); + +void +nettle_mpz_init_set_str_256_s(mpz_t x, + unsigned length, const uint8_t *s); + +/* Similar, but for unsigned format. These function don't interpret + * the most significant bit as the sign. */ +void +nettle_mpz_set_str_256_u(mpz_t x, + unsigned length, const uint8_t *s); + +void +nettle_mpz_init_set_str_256_u(mpz_t x, + unsigned length, const uint8_t *s); + +/* Returns a uniformly distributed random number 0 <= x < 2^n */ +void +nettle_mpz_random_size(mpz_t x, + void *ctx, nettle_random_func random, + unsigned bits); + +/* Returns a number x, almost uniformly random in the range + * 0 <= x < n. */ +void +nettle_mpz_random(mpz_t x, + void *ctx, nettle_random_func random, + const mpz_t n); + +void +nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit, + void *progress_ctx, nettle_progress_func progress); + +void +nettle_random_prime(mpz_t p, unsigned bits, int top_bits_set, + void *ctx, nettle_random_func random, + void *progress_ctx, nettle_progress_func progress); + +void +_nettle_generate_pocklington_prime (mpz_t p, mpz_t r, + unsigned bits, int top_bits_set, + void *ctx, nettle_random_func random, + const mpz_t p0, + const mpz_t q, + const mpz_t p0q); + +/* sexp parsing */ +struct sexp_iterator; + +/* If LIMIT is non-zero, the number must be at most LIMIT bits. + * Implies sexp_iterator_next. */ +int +nettle_mpz_set_sexp(mpz_t x, unsigned limit, struct sexp_iterator *i); + + +/* der parsing */ +struct asn1_der_iterator; + +int +nettle_asn1_der_get_bignum(struct asn1_der_iterator *iterator, + mpz_t x, unsigned max_bits); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_BIGNUM_H_INCLUDED */ diff --git a/blowfish.c b/blowfish.c new file mode 100644 index 0000000..25c99c2 --- /dev/null +++ b/blowfish.c @@ -0,0 +1,409 @@ +/* blowfish.c + * + * The blowfish block cipher. + * + * For a description of the algorithm, see: + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. + * ISBN 0-471-11709-9. Pages 336 ff. + */ + +/* NOTE: This file is distributed under the GPL, not the LGPL. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 1998, 2001 + * Free Software Foundation, Inc, Ray Dassen, Niels Möller + * + * This file is part of GNUPG. + * + * GNUPG 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. + * + * GNUPG is distributed in the hope that 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 + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "blowfish.h" + +#include "macros.h" + +/* Initial keysetup state */ +static const struct blowfish_ctx +initial_ctx = +{ /* precomputed S boxes */ + { + { + 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 + }, { + 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 + }, { + 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 + }, { + 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 + } + }, + /* p constants */ + { + 0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0, + 0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C, + 0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B + }, +}; + +/* It's unfortunate to have to pick the bytes apart in the round + * function. Werner's GNUPG code stored took the address of x, and + * then read the individual bytes depending on the endianness. But xr + * and xl ought to live in registers, so I'm not sure that really is a + * good way to do it. */ + +#define F(c, x) \ + ((( (c->s[0][(x>>24) &0xff] + c->s[1][(x>>16) & 0xff]) \ + ^ c->s[2][(x>>8) & 0xff]) + c->s[3][x & 0xff]) & 0xffffffff) + +#define R(c, l, r, i) do { l ^= c->p[i]; r ^= F(c, l); } while(0) + +static void +encrypt(const struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr) +{ + uint32_t xl, xr; + + xl = *ret_xl; + xr = *ret_xr; + R(bc, xl, xr, 0); + R(bc, xr, xl, 1); + R(bc, xl, xr, 2); + R(bc, xr, xl, 3); + R(bc, xl, xr, 4); + R(bc, xr, xl, 5); + R(bc, xl, xr, 6); + R(bc, xr, xl, 7); + R(bc, xl, xr, 8); + R(bc, xr, xl, 9); + R(bc, xl, xr, 10); + R(bc, xr, xl, 11); + R(bc, xl, xr, 12); + R(bc, xr, xl, 13); + R(bc, xl, xr, 14); + R(bc, xr, xl, 15); + + xl ^= bc->p[_BLOWFISH_ROUNDS]; + xr ^= bc->p[_BLOWFISH_ROUNDS+1]; + + *ret_xl = xr; + *ret_xr = xl; +} + +static void +decrypt(const struct blowfish_ctx *bc, uint32_t *ret_xl, uint32_t *ret_xr ) +{ + uint32_t xl, xr; + + xl = *ret_xl; + xr = *ret_xr; + + R(bc, xl, xr, 17); + R(bc, xr, xl, 16); + R(bc, xl, xr, 15); + R(bc, xr, xl, 14); + R(bc, xl, xr, 13); + R(bc, xr, xl, 12); + R(bc, xl, xr, 11); + R(bc, xr, xl, 10); + R(bc, xl, xr, 9); + R(bc, xr, xl, 8); + R(bc, xl, xr, 7); + R(bc, xr, xl, 6); + R(bc, xl, xr, 5); + R(bc, xr, xl, 4); + R(bc, xl, xr, 3); + R(bc, xr, xl, 2); + + xl ^= bc->p[1]; + xr ^= bc->p[0]; + + *ret_xl = xr; + *ret_xr = xl; +} + +#undef F +#undef R + +void +blowfish_encrypt(const struct blowfish_ctx *bc, unsigned length, + uint8_t *outbuf, const uint8_t *inbuf) +{ + uint32_t d1, d2; + + FOR_BLOCKS(length, outbuf, inbuf, BLOWFISH_BLOCK_SIZE) + { + d1 = READ_UINT32(inbuf); + d2 = READ_UINT32(inbuf+ 4); + + encrypt( bc, &d1, &d2 ); + + WRITE_UINT32(outbuf, d1); + WRITE_UINT32(outbuf + 4, d2); + } +} + + +void +blowfish_decrypt(const struct blowfish_ctx *bc, unsigned length, + uint8_t *outbuf, const uint8_t *inbuf ) +{ + uint32_t d1, d2; + + FOR_BLOCKS(length, outbuf, inbuf, BLOWFISH_BLOCK_SIZE) + { + d1 = READ_UINT32(inbuf); + d2 = READ_UINT32(inbuf+ 4); + + decrypt( bc, &d1, &d2 ); + + WRITE_UINT32(outbuf, d1); + WRITE_UINT32(outbuf + 4, d2); + } +} + +int +blowfish_set_key(struct blowfish_ctx *ctx, + unsigned keylen, const uint8_t *key) +{ + int i, j; + uint32_t data, datal, datar; + + *ctx = initial_ctx; + + for(i=j=0; i < _BLOWFISH_ROUNDS+2; i++ ) + { + data = key[j] << 24 | key[(j+1) % keylen] <<16 + | key[(j+2)%keylen] << 8 | key[(j+3)%keylen]; + + ctx->p[i] ^= data; + j = (j+4) % keylen; + } + + datal = datar = 0; + for(i=0; i < _BLOWFISH_ROUNDS+2; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->p[i] = datal; + ctx->p[i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[0][i] = datal; + ctx->s[0][i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[1][i] = datal; + ctx->s[1][i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[2][i] = datal; + ctx->s[2][i+1] = datar; + } + for(i=0; i < 256; i += 2 ) + { + encrypt( ctx, &datal, &datar ); + ctx->s[3][i] = datal; + ctx->s[3][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( (ctx->s[0][i] == ctx->s[0][j]) || (ctx->s[1][i] == ctx->s[1][j]) || + (ctx->s[2][i] == ctx->s[2][j]) || (ctx->s[3][i] == ctx->s[3][j]) ) + return 0; + + return 1; +} diff --git a/blowfish.h b/blowfish.h new file mode 100644 index 0000000..3775b4b --- /dev/null +++ b/blowfish.h @@ -0,0 +1,76 @@ +/* blowfish.h + * + * Blowfish block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 1998, 2001 FSF, Ray Dassen, Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_BLOWFISH_H_INCLUDED +#define NETTLE_BLOWFISH_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define blowfish_set_key nettle_blowfish_set_key +#define blowfish_encrypt nettle_blowfish_encrypt +#define blowfish_decrypt nettle_blowfish_decrypt + +#define BLOWFISH_BLOCK_SIZE 8 + +/* Variable key size between 64 and 448 bits. */ +#define BLOWFISH_MIN_KEY_SIZE 8 +#define BLOWFISH_MAX_KEY_SIZE 56 + +/* Default to 128 bits */ +#define BLOWFISH_KEY_SIZE 16 + +#define _BLOWFISH_ROUNDS 16 + +struct blowfish_ctx +{ + uint32_t s[4][256]; + uint32_t p[_BLOWFISH_ROUNDS+2]; +}; + +/* On success, returns 1 and sets ctx->status to BLOWFISH_OK (zero). + * On error, returns 0 and sets ctx->status to BLOWFISH_WEAK_KEY. */ +int +blowfish_set_key(struct blowfish_ctx *ctx, + unsigned length, const uint8_t *key); + +void +blowfish_encrypt(const struct blowfish_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +blowfish_decrypt(const struct blowfish_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_BLOWFISH_H_INCLUDED */ diff --git a/buffer-init.c b/buffer-init.c new file mode 100644 index 0000000..1eccd7f --- /dev/null +++ b/buffer-init.c @@ -0,0 +1,41 @@ +/* buffer-init.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "buffer.h" +#include "realloc.h" + +/* This is in a separate file so that we don't link in realloc in + * programs that don't need it. */ + +void +nettle_buffer_init(struct nettle_buffer *buffer) +{ + nettle_buffer_init_realloc(buffer, NULL, nettle_realloc); +} diff --git a/buffer.c b/buffer.c new file mode 100644 index 0000000..4e96b55 --- /dev/null +++ b/buffer.c @@ -0,0 +1,134 @@ +/* buffer.c + * + * A bare-bones string stream. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "buffer.h" + +int +nettle_buffer_grow(struct nettle_buffer *buffer, + unsigned length) +{ + assert(buffer->size <= buffer->alloc); + + if (buffer->size + length > buffer->alloc) + { + unsigned alloc; + uint8_t *p; + + if (!buffer->realloc) + return 0; + + alloc = buffer->alloc * 2 + length + 100; + p = buffer->realloc(buffer->realloc_ctx, buffer->contents, alloc); + if (!p) + return 0; + + buffer->contents = p; + buffer->alloc = alloc; + } + return 1; +} + +void +nettle_buffer_init_realloc(struct nettle_buffer *buffer, + void *realloc_ctx, + nettle_realloc_func realloc) +{ + buffer->contents = NULL; + buffer->alloc = 0; + buffer->realloc = realloc; + buffer->realloc_ctx = realloc_ctx; + buffer->size = 0; +} + +void +nettle_buffer_init_size(struct nettle_buffer *buffer, + unsigned length, uint8_t *space) +{ + buffer->contents = space; + buffer->alloc = length; + buffer->realloc = NULL; + buffer->realloc_ctx = NULL; + buffer->size = 0; +} + +void +nettle_buffer_clear(struct nettle_buffer *buffer) +{ + if (buffer->realloc) + buffer->realloc(buffer->realloc_ctx, buffer->contents, 0); + + buffer->contents = NULL; + buffer->alloc = 0; + buffer->size = 0; +} + +void +nettle_buffer_reset(struct nettle_buffer *buffer) +{ + buffer->size = 0; +} + +uint8_t * +nettle_buffer_space(struct nettle_buffer *buffer, + unsigned length) +{ + uint8_t *p; + + if (!nettle_buffer_grow(buffer, length)) + return NULL; + + p = buffer->contents + buffer->size; + buffer->size += length; + return p; +} + +int +nettle_buffer_write(struct nettle_buffer *buffer, + unsigned length, const uint8_t *data) +{ + uint8_t *p = nettle_buffer_space(buffer, length); + if (p) + { + memcpy(p, data, length); + return 1; + } + else + return 0; +} + +int +nettle_buffer_copy(struct nettle_buffer *dst, + const struct nettle_buffer *src) +{ + return nettle_buffer_write(dst, src->size, src->contents); +} diff --git a/buffer.h b/buffer.h new file mode 100644 index 0000000..466ad92 --- /dev/null +++ b/buffer.h @@ -0,0 +1,98 @@ +/* buffer.h + * + * A bare-bones string stream. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_BUFFER_H_INCLUDED +#define NETTLE_BUFFER_H_INCLUDED + +#include "realloc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct nettle_buffer +{ + uint8_t *contents; + /* Allocated size */ + unsigned alloc; + + void *realloc_ctx; + nettle_realloc_func *realloc; + + /* Current size */ + unsigned size; +}; + +/* Initializes a buffer that uses plain realloc */ +void +nettle_buffer_init(struct nettle_buffer *buffer); + +void +nettle_buffer_init_realloc(struct nettle_buffer *buffer, + void *realloc_ctx, + nettle_realloc_func realloc); + +/* Initializes a buffer of fix size */ +void +nettle_buffer_init_size(struct nettle_buffer *buffer, + unsigned length, uint8_t *space); + +void +nettle_buffer_clear(struct nettle_buffer *buffer); + +/* Resets the buffer, without freeing the buffer space. */ +void +nettle_buffer_reset(struct nettle_buffer *buffer); + +int +nettle_buffer_grow(struct nettle_buffer *buffer, + unsigned length); + +#define NETTLE_BUFFER_PUTC(buffer, c) \ +( (((buffer)->size < (buffer)->alloc) || nettle_buffer_grow((buffer), 1)) \ + && ((buffer)->contents[(buffer)->size++] = (c), 1) ) + +int +nettle_buffer_write(struct nettle_buffer *buffer, + unsigned length, const uint8_t *data); + +/* Like nettle_buffer_write, but instead of copying data to the + * buffer, it returns a pointer to the area where the caller can copy + * the data. The pointer is valid only until the next call that can + * reallocate the buffer. */ +uint8_t * +nettle_buffer_space(struct nettle_buffer *buffer, + unsigned length); + +/* Copy the contents of SRC to the end of DST. */ +int +nettle_buffer_copy(struct nettle_buffer *dst, + const struct nettle_buffer *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_BUFFER_H_INCLUDED */ diff --git a/camellia-crypt-internal.c b/camellia-crypt-internal.c new file mode 100644 index 0000000..c38c225 --- /dev/null +++ b/camellia-crypt-internal.c @@ -0,0 +1,139 @@ +/* camellia-crypt-internal.c + * + * Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * Copyright (C) 2010 Niels Möller + * + * 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 + */ + +/* Based on camellia.c ver 1.2.0, see + http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz. + */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "camellia-internal.h" + +#include "macros.h" + +#define CAMELLIA_FL(x, k) do { \ + uint32_t __xl, __xr, __kl, __kr, __t; \ + __xl = (x) >> 32; \ + __xr = (x) & 0xffffffff; \ + __kl = (k) >> 32; \ + __kr = (k) & 0xffffffff; \ + __t = __xl & __kl; \ + __xr ^= ROL32(1, __t); \ + __xl ^= (__xr | __kr); \ + (x) = ((uint64_t) __xl << 32) | __xr; \ +} while (0) + +#define CAMELLIA_FLINV(x, k) do { \ + uint32_t __xl, __xr, __kl, __kr, __t; \ + __xl = (x) >> 32; \ + __xr = (x) & 0xffffffff; \ + __kl = (k) >> 32; \ + __kr = (k) & 0xffffffff; \ + __xl ^= (__xr | __kr); \ + __t = __xl & __kl; \ + __xr ^= ROL32(1, __t); \ + (x) = ((uint64_t) __xl << 32) | __xr; \ +} while (0) + +#define CAMELLIA_ROUNDSM(T, x, k, y) do { \ + uint32_t __il, __ir; \ + __ir \ + = T->sp1110[(x) & 0xff] \ + ^ T->sp0222[((x) >> 24) & 0xff] \ + ^ T->sp3033[((x) >> 16) & 0xff] \ + ^ T->sp4404[((x) >> 8) & 0xff]; \ + /* ir == (t6^t7^t8),(t5^t7^t8),(t5^t6^t8),(t5^t6^t7) */ \ + __il \ + = T->sp1110[ (x) >> 56] \ + ^ T->sp0222[((x) >> 48) & 0xff] \ + ^ T->sp3033[((x) >> 40) & 0xff] \ + ^ T->sp4404[((x) >> 32) & 0xff]; \ + /* il == (t1^t3^t4),(t1^t2^t4),(t1^t2^t3),(t2^t3^t4) */ \ + __il ^= (k) >> 32; \ + __ir ^= (k) & 0xffffffff; \ + __ir ^= __il; \ + /* ir == (t1^t3^t4^t6^t7^t8),(t1^t2^t4^t5^t7^t8), \ + (t1^t2^t3^t5^t6^t8),(t2^t3^t4^t5^t6^t7) \ + == y1,y2,y3,y4 */ \ + __il = ROL32(24, __il); \ + /* il == (t2^t3^t4),(t1^t3^t4),(t1^t2^t4),(t1^t2^t3) */ \ + __il ^= __ir; \ + /* il == (t1^t2^t6^t7^t8),(t2^t3^t5^t7^t8), \ + (t3^t4^t5^t6^t8),(t1^t4^t5^t6^t7) \ + == y5,y6,y7,y8 */ \ + y ^= ((uint64_t) __ir << 32) | __il; \ + } while (0) + +void +_camellia_crypt(const struct camellia_ctx *ctx, + const struct camellia_table *T, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + FOR_BLOCKS(length, dst, src, CAMELLIA_BLOCK_SIZE) + { + uint64_t i0,i1; + unsigned i; + + i0 = READ_UINT64(src); + i1 = READ_UINT64(src + 8); + + /* pre whitening but absorb kw2*/ + i0 ^= ctx->keys[0]; + + /* main iteration */ + + CAMELLIA_ROUNDSM(T, i0,ctx->keys[1], i1); + CAMELLIA_ROUNDSM(T, i1,ctx->keys[2], i0); + CAMELLIA_ROUNDSM(T, i0,ctx->keys[3], i1); + CAMELLIA_ROUNDSM(T, i1,ctx->keys[4], i0); + CAMELLIA_ROUNDSM(T, i0,ctx->keys[5], i1); + CAMELLIA_ROUNDSM(T, i1,ctx->keys[6], i0); + + for (i = 0; i < ctx->nkeys - 8; i+= 8) + { + CAMELLIA_FL(i0, ctx->keys[i+7]); + CAMELLIA_FLINV(i1, ctx->keys[i+8]); + + CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+9], i1); + CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+10], i0); + CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+11], i1); + CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+12], i0); + CAMELLIA_ROUNDSM(T, i0,ctx->keys[i+13], i1); + CAMELLIA_ROUNDSM(T, i1,ctx->keys[i+14], i0); + } + + /* post whitening but kw4 */ + i1 ^= ctx->keys[i+7]; + + WRITE_UINT64(dst , i1); + WRITE_UINT64(dst + 8, i0); + } +} diff --git a/camellia-crypt.c b/camellia-crypt.c new file mode 100644 index 0000000..62c3435 --- /dev/null +++ b/camellia-crypt.c @@ -0,0 +1,45 @@ +/* camellia-encrypt.c + * + * Crypt function for the camellia block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "camellia-internal.h" + +/* The main point on this function is to help the assembler + implementations of _nettle_camellia_crypt to get the table pointer. + For PIC code, the details can be complex and system dependent. */ +void +camellia_crypt(const struct camellia_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % CAMELLIA_BLOCK_SIZE) ); + _camellia_crypt(ctx, &_camellia_table, + length, dst, src); +} diff --git a/camellia-internal.h b/camellia-internal.h new file mode 100644 index 0000000..f9d40fc --- /dev/null +++ b/camellia-internal.h @@ -0,0 +1,74 @@ +/* camellia-internal.h + * + * The camellia block cipher. + */ + +/* Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * Copyright (C) 2010 Niels Möller + * + * 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 + */ + +/* Based on camellia.c ver 1.2.0, see + http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz. + */ + +#ifndef NETTLE_CAMELLIA_INTERNAL_H_INCLUDED +#define NETTLE_CAMELLIA_INTERNAL_H_INCLUDED + +#include "camellia.h" + +/* Name mangling */ +#define _camellia_crypt _nettle_camellia_crypt +#define _camellia_table _nettle_camellia_table + +/* + * macros + */ + +/* Rotation of 32-bit values. */ +#define ROL32(bits, x) (((x) << (bits)) | ((x) >> (32 - (bits)))) + +/* Destructive rotation of 128 bit values. */ +#define ROL128(bits, xl, xr) do { \ + uint64_t __rol128_t = (xl); \ + (xl) = ((xl) << (bits)) | ((xr) >> (64 - (bits))); \ + (xr) = ((xr) << (bits)) | (__rol128_t >> (64 - (bits))); \ + } while (0) + +struct camellia_table +{ + uint32_t sp1110[256]; + uint32_t sp0222[256]; + uint32_t sp3033[256]; + uint32_t sp4404[256]; +}; + +void +_camellia_crypt(const struct camellia_ctx *ctx, + const struct camellia_table *T, + unsigned length, uint8_t *dst, + const uint8_t *src); + +extern const struct camellia_table _camellia_table; + +#endif /* NETTLE_CAMELLIA_INTERNAL_H_INCLUDED */ diff --git a/camellia-meta.c b/camellia-meta.c new file mode 100644 index 0000000..68eef3d --- /dev/null +++ b/camellia-meta.c @@ -0,0 +1,38 @@ +/* camellia-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "camellia.h" + +const struct nettle_cipher nettle_camellia128 += _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 128); + +const struct nettle_cipher nettle_camellia192 += _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 192); + +const struct nettle_cipher nettle_camellia256 += _NETTLE_CIPHER_SEP_SET_KEY(camellia, CAMELLIA, 256); diff --git a/camellia-set-decrypt-key.c b/camellia-set-decrypt-key.c new file mode 100644 index 0000000..cd49c11 --- /dev/null +++ b/camellia-set-decrypt-key.c @@ -0,0 +1,61 @@ +/* camellia-set-decrypt-key.c + * + * Inverse key setup for the camellia block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "camellia.h" + +#define SWAP(a, b) \ +do { uint64_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0) + +void +camellia_invert_key(struct camellia_ctx *dst, + const struct camellia_ctx *src) +{ + unsigned nkeys = src->nkeys; + unsigned i; + if (dst == src) + { + for (i = 0; i < nkeys - 1 - i; i++) + SWAP(dst->keys[i], dst->keys[nkeys - 1 - i]); + } + else + { + dst->nkeys = nkeys; + + for (i = 0; i < nkeys; i++) + dst->keys[i] = src->keys[nkeys - 1 - i]; + } +} + +void +camellia_set_decrypt_key(struct camellia_ctx *ctx, + unsigned length, const uint8_t *key) +{ + camellia_set_encrypt_key(ctx, length, key); + camellia_invert_key(ctx, ctx); +} diff --git a/camellia-set-encrypt-key.c b/camellia-set-encrypt-key.c new file mode 100644 index 0000000..500128f --- /dev/null +++ b/camellia-set-encrypt-key.c @@ -0,0 +1,331 @@ +/* camellia-set-encrypt-key.c + * + * Key setup for the camellia block cipher. + */ +/* + * Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * Copyright (C) 2010 Niels Möller + * + * 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 + */ + +/* Based on camellia.c ver 1.2.0, see + http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz. + */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "camellia-internal.h" + +#include "macros.h" + +/* key constants */ + +#define SIGMA1 0xA09E667F3BCC908BULL +#define SIGMA2 0xB67AE8584CAA73B2ULL +#define SIGMA3 0xC6EF372FE94F82BEULL +#define SIGMA4 0x54FF53A5F1D36F1CULL +#define SIGMA5 0x10E527FADE682D1DULL +#define SIGMA6 0xB05688C2B3E6C1FDULL + +#define CAMELLIA_SP1110(INDEX) (_nettle_camellia_table.sp1110[(int)(INDEX)]) +#define CAMELLIA_SP0222(INDEX) (_nettle_camellia_table.sp0222[(int)(INDEX)]) +#define CAMELLIA_SP3033(INDEX) (_nettle_camellia_table.sp3033[(int)(INDEX)]) +#define CAMELLIA_SP4404(INDEX) (_nettle_camellia_table.sp4404[(int)(INDEX)]) + +#define CAMELLIA_F(x, k, y) do { \ + uint32_t __yl, __yr; \ + uint64_t __i = (x) ^ (k); \ + __yl \ + = CAMELLIA_SP1110( __i & 0xff) \ + ^ CAMELLIA_SP0222((__i >> 24) & 0xff) \ + ^ CAMELLIA_SP3033((__i >> 16) & 0xff) \ + ^ CAMELLIA_SP4404((__i >> 8) & 0xff); \ + __yr \ + = CAMELLIA_SP1110( __i >> 56) \ + ^ CAMELLIA_SP0222((__i >> 48) & 0xff) \ + ^ CAMELLIA_SP3033((__i >> 40) & 0xff) \ + ^ CAMELLIA_SP4404((__i >> 32) & 0xff); \ + __yl ^= __yr; \ + __yr = ROL32(24, __yr); \ + __yr ^= __yl; \ + (y) = ((uint64_t) __yl << 32) | __yr; \ + } while (0) + +#define CAMELLIA_F_HALF_INV(x) do { \ + uint32_t __t, __w; \ + __t = (x) >> 32; \ + __w = __t ^(x); \ + __w = ROL32(8, __w); \ + (x) = ((uint64_t) __w << 32) | (__t ^ __w); \ + } while (0) + +void +camellia_set_encrypt_key(struct camellia_ctx *ctx, + unsigned length, const uint8_t *key) +{ + uint64_t k0, k1; + + uint64_t subkey[34]; + uint64_t w, kw2, kw4; + + uint32_t dw, tl, tr; + unsigned i; + + k0 = READ_UINT64(key); + k1 = READ_UINT64(key + 8); + + if (length == 16) + { + ctx->nkeys = 24; + /** + * generate KL dependent subkeys + */ + subkey[0] = k0; subkey[1] = k1; + ROL128(15, k0, k1); + subkey[4] = k0; subkey[5] = k1; + ROL128(30, k0, k1); + subkey[10] = k0; subkey[11] = k1; + ROL128(15, k0, k1); + subkey[13] = k1; + ROL128(17, k0, k1); + subkey[16] = k0; subkey[17] = k1; + ROL128(17, k0, k1); + subkey[18] = k0; subkey[19] = k1; + ROL128(17, k0, k1); + subkey[22] = k0; subkey[23] = k1; + + /* generate KA. D1 is k0, d2 is k1. */ + /* FIXME: Make notation match the spec better. */ + /* For the 128-bit case, KR = 0, the construction of KA reduces to: + + D1 = KL >> 64; + W = KL & MASK64; + D2 = F(D1, Sigma1); + W = D2 ^ W + D1 = F(W, Sigma2) + D2 = D2 ^ F(D1, Sigma3); + D1 = D1 ^ F(D2, Sigma4); + KA = (D1 << 64) | D2; + */ + k0 = subkey[0]; w = subkey[1]; + CAMELLIA_F(k0, SIGMA1, k1); + w ^= k1; + CAMELLIA_F(w, SIGMA2, k0); + CAMELLIA_F(k0, SIGMA3, w); + k1 ^= w; + CAMELLIA_F(k1, SIGMA4, w); + k0 ^= w; + + /* generate KA dependent subkeys */ + subkey[2] = k0; subkey[3] = k1; + ROL128(15, k0, k1); + subkey[6] = k0; subkey[7] = k1; + ROL128(15, k0, k1); + subkey[8] = k0; subkey[9] = k1; + ROL128(15, k0, k1); + subkey[12] = k0; + ROL128(15, k0, k1); + subkey[14] = k0; subkey[15] = k1; + ROL128(34, k0, k1); + subkey[20] = k0; subkey[21] = k1; + ROL128(17, k0, k1); + subkey[24] = k0; subkey[25] = k1; + } + else + { + uint64_t k2, k3; + + ctx->nkeys = 32; + k2 = READ_UINT64(key + 16); + + if (length == 24) + k3 = ~k2; + else + { + assert (length == 32); + k3 = READ_UINT64(key + 24); + } + /* generate KL dependent subkeys */ + subkey[0] = k0; subkey[1] = k1; + ROL128(45, k0, k1); + subkey[12] = k0; subkey[13] = k1; + ROL128(15, k0, k1); + subkey[16] = k0; subkey[17] = k1; + ROL128(17, k0, k1); + subkey[22] = k0; subkey[23] = k1; + ROL128(34, k0, k1); + subkey[30] = k0; subkey[31] = k1; + + /* generate KR dependent subkeys */ + ROL128(15, k2, k3); + subkey[4] = k2; subkey[5] = k3; + ROL128(15, k2, k3); + subkey[8] = k2; subkey[9] = k3; + ROL128(30, k2, k3); + subkey[18] = k2; subkey[19] = k3; + ROL128(34, k2, k3); + subkey[26] = k2; subkey[27] = k3; + ROL128(34, k2, k3); + + /* generate KA */ + /* The construction of KA is done as + + D1 = (KL ^ KR) >> 64 + D2 = (KL ^ KR) & MASK64 + W = F(D1, SIGMA1) + D2 = D2 ^ W + D1 = F(D2, SIGMA2) ^ (KR >> 64) + D2 = F(D1, SIGMA3) ^ W ^ (KR & MASK64) + D1 = D1 ^ F(W, SIGMA2) + D2 = D2 ^ F(D1, SIGMA3) + D1 = D1 ^ F(D2, SIGMA4) + */ + + k0 = subkey[0] ^ k2; + k1 = subkey[1] ^ k3; + + CAMELLIA_F(k0, SIGMA1, w); + k1 ^= w; + + CAMELLIA_F(k1, SIGMA2, k0); + k0 ^= k2; + + CAMELLIA_F(k0, SIGMA3, k1); + k1 ^= w ^ k3; + + CAMELLIA_F(k1, SIGMA4, w); + k0 ^= w; + + /* generate KB */ + k2 ^= k0; k3 ^= k1; + CAMELLIA_F(k2, SIGMA5, w); + k3 ^= w; + CAMELLIA_F(k3, SIGMA6, w); + k2 ^= w; + + /* generate KA dependent subkeys */ + ROL128(15, k0, k1); + subkey[6] = k0; subkey[7] = k1; + ROL128(30, k0, k1); + subkey[14] = k0; subkey[15] = k1; + ROL128(32, k0, k1); + subkey[24] = k0; subkey[25] = k1; + ROL128(17, k0, k1); + subkey[28] = k0; subkey[29] = k1; + + /* generate KB dependent subkeys */ + subkey[2] = k2; subkey[3] = k3; + ROL128(30, k2, k3); + subkey[10] = k2; subkey[11] = k3; + ROL128(30, k2, k3); + subkey[20] = k2; subkey[21] = k3; + ROL128(51, k2, k3); + subkey[32] = k2; subkey[33] = k3; + } + + /* At this point, the subkey array contains the subkeys as described + in the spec, 26 for short keys and 34 for large keys. */ + + /* absorb kw2 to other subkeys */ + kw2 = subkey[1]; + + subkey[3] ^= kw2; + subkey[5] ^= kw2; + subkey[7] ^= kw2; + for (i = 8; i < ctx->nkeys; i += 8) + { + /* FIXME: gcc for x86_32 is smart enough to fetch the 32 low bits + and xor the result into the 32 high bits, but it still generates + worse code than for explicit 32-bit operations. */ + kw2 ^= (kw2 & ~subkey[i+1]) << 32; + dw = (kw2 & subkey[i+1]) >> 32; kw2 ^= ROL32(1, dw); + + subkey[i+3] ^= kw2; + subkey[i+5] ^= kw2; + subkey[i+7] ^= kw2; + } + subkey[i] ^= kw2; + + /* absorb kw4 to other subkeys */ + kw4 = subkey[ctx->nkeys + 1]; + + for (i = ctx->nkeys - 8; i > 0; i -= 8) + { + subkey[i+6] ^= kw4; + subkey[i+4] ^= kw4; + subkey[i+2] ^= kw4; + kw4 ^= (kw4 & ~subkey[i]) << 32; + dw = (kw4 & subkey[i]) >> 32; kw4 ^= ROL32(1, dw); + } + + subkey[6] ^= kw4; + subkey[4] ^= kw4; + subkey[2] ^= kw4; + subkey[0] ^= kw4; + + /* key XOR is end of F-function */ + ctx->keys[0] = subkey[0] ^ subkey[2]; + ctx->keys[1] = subkey[3]; + + ctx->keys[2] = subkey[2] ^ subkey[4]; + ctx->keys[3] = subkey[3] ^ subkey[5]; + ctx->keys[4] = subkey[4] ^ subkey[6]; + ctx->keys[5] = subkey[5] ^ subkey[7]; + + for (i = 8; i < ctx->nkeys; i += 8) + { + tl = (subkey[i+2] >> 32) ^ (subkey[i+2] & ~subkey[i]); + dw = tl & (subkey[i] >> 32); + tr = subkey[i+2] ^ ROL32(1, dw); + ctx->keys[i-2] = subkey[i-2] ^ ( ((uint64_t) tl << 32) | tr); + + ctx->keys[i-1] = subkey[i]; + ctx->keys[i] = subkey[i+1]; + + tl = (subkey[i-1] >> 32) ^ (subkey[i-1] & ~subkey[i+1]); + dw = tl & (subkey[i+1] >> 32); + tr = subkey[i-1] ^ ROL32(1, dw); + ctx->keys[i+1] = subkey[i+3] ^ ( ((uint64_t) tl << 32) | tr); + + ctx->keys[i+2] = subkey[i+2] ^ subkey[i+4]; + ctx->keys[i+3] = subkey[i+3] ^ subkey[i+5]; + ctx->keys[i+4] = subkey[i+4] ^ subkey[i+6]; + ctx->keys[i+5] = subkey[i+5] ^ subkey[i+7]; + } + ctx->keys[i-2] = subkey[i-2]; + ctx->keys[i-1] = subkey[i] ^ subkey[i-1]; + + for (i = 0; i < ctx->nkeys; i += 8) + { + /* apply the inverse of the last half of F-function */ + CAMELLIA_F_HALF_INV(ctx->keys[i+1]); + CAMELLIA_F_HALF_INV(ctx->keys[i+2]); + CAMELLIA_F_HALF_INV(ctx->keys[i+3]); + CAMELLIA_F_HALF_INV(ctx->keys[i+4]); + CAMELLIA_F_HALF_INV(ctx->keys[i+5]); + CAMELLIA_F_HALF_INV(ctx->keys[i+6]); + } +} diff --git a/camellia-table.c b/camellia-table.c new file mode 100644 index 0000000..9245bc9 --- /dev/null +++ b/camellia-table.c @@ -0,0 +1,310 @@ +/* camellia-table.c + * + * SBOX tables used by both encryption and key setup. + */ + +/* Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * Copyright (C) 2010 Niels Möller + * + * 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 + */ + +/* Based on camellia.c ver 1.2.0, see + http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/camellia-LGPL-1.2.0.tar.gz. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "camellia-internal.h" + +const struct camellia_table _camellia_table = { + /* sp1110 */ + { + 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, + }, + /* sp0222 */ + { + 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, + }, + /* sp3033 */ + { + 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, + }, + /* sp4404 */ + { + 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, + } +}; diff --git a/camellia.h b/camellia.h new file mode 100644 index 0000000..f4f3e1e --- /dev/null +++ b/camellia.h @@ -0,0 +1,82 @@ +/* camellia.h + * + * Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * Copyright (C) 2010 Niels Möller + * + * 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 NETTLE_CAMELLIA_H_INCLUDED +#define NETTLE_CAMELLIA_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define camellia_set_encrypt_key nettle_camellia_set_encrypt_key +#define camellia_set_decrypt_key nettle_camellia_set_decrypt_key +#define camellia_invert_key nettle_camellia_invert_key +#define camellia_crypt nettle_camellia_crypt +#define camellia_crypt nettle_camellia_crypt + +#define CAMELLIA_BLOCK_SIZE 16 +/* Valid key sizes are 128, 192 or 256 bits (16, 24 or 32 bytes) */ +#define CAMELLIA_MIN_KEY_SIZE 16 +#define CAMELLIA_MAX_KEY_SIZE 32 +#define CAMELLIA_KEY_SIZE 32 + +struct camellia_ctx +{ + /* Number of subkeys. */ + unsigned nkeys; + + /* For 128-bit keys, there are 18 regular rounds, pre- and + post-whitening, and two FL and FLINV rounds, using a total of 26 + subkeys, each of 64 bit. For 192- and 256-bit keys, there are 6 + additional regular rounds and one additional FL and FLINV, using + a total of 34 subkeys. */ + /* The clever combination of subkeys imply one of the pre- and + post-whitening keys is folded with the round keys, so that subkey + #1 and the last one (#25 or #33) is not used. The result is that + we have only 24 or 32 subkeys at the end of key setup. */ + uint64_t keys[32]; +}; + +void +camellia_set_encrypt_key(struct camellia_ctx *ctx, + unsigned length, const uint8_t *key); + +void +camellia_set_decrypt_key(struct camellia_ctx *ctx, + unsigned length, const uint8_t *key); + +void +camellia_invert_key(struct camellia_ctx *dst, + const struct camellia_ctx *src); + +void +camellia_crypt(const struct camellia_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CAMELLIA_H_INCLUDED */ diff --git a/cast128-meta.c b/cast128-meta.c new file mode 100644 index 0000000..5c15a08 --- /dev/null +++ b/cast128-meta.c @@ -0,0 +1,32 @@ +/* cast128-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "cast128.h" + +const struct nettle_cipher nettle_cast128 += _NETTLE_CIPHER_FIX(cast128, CAST128, 128); diff --git a/cast128.c b/cast128.c new file mode 100644 index 0000000..884cfa7 --- /dev/null +++ b/cast128.c @@ -0,0 +1,276 @@ +/* cast128.c + * + * The CAST-128 block cipher, described in RFC 2144. + */ + +/* CAST-128 in C + * Written by Steve Reid + * 100% Public Domain - no warranty + * Released 1997.10.11 + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "cast128.h" +#include "cast128_sboxes.h" + +#include "macros.h" + +#define CAST_SMALL_KEY 10 +#define CAST_SMALL_ROUNDS 12 +#define CAST_FULL_ROUNDS 16 + +/* Macros to access 8-bit bytes out of a 32-bit word */ +#define U8a(x) ( (uint8_t) (x>>24) ) +#define U8b(x) ( (uint8_t) ((x>>16)&0xff) ) +#define U8c(x) ( (uint8_t) ((x>>8)&0xff) ) +#define U8d(x) ( (uint8_t) ((x)&0xff) ) + +/* Circular left shift */ +#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) ) + +/* CAST-128 uses three different round functions */ +#define F1(l, r, i) \ + t = ROL(ctx->keys[i] + r, ctx->keys[i+16]); \ + l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \ + - cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)]; +#define F2(l, r, i) \ + t = ROL(ctx->keys[i] ^ r, ctx->keys[i+16]); \ + l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \ + + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)]; +#define F3(l, r, i) \ + t = ROL(ctx->keys[i] - r, ctx->keys[i+16]); \ + l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \ + ^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)]; + + +/***** Encryption Function *****/ + +void +cast128_encrypt(const struct cast128_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE) + { + uint32_t t, l, r; + + /* Get inblock into l,r */ + l = READ_UINT32(src); + r = READ_UINT32(src+4); + + /* Do the work */ + F1(l, r, 0); + F2(r, l, 1); + F3(l, r, 2); + F1(r, l, 3); + F2(l, r, 4); + F3(r, l, 5); + F1(l, r, 6); + F2(r, l, 7); + F3(l, r, 8); + F1(r, l, 9); + F2(l, r, 10); + F3(r, l, 11); + /* Only do full 16 rounds if key length > 80 bits */ + if (ctx->rounds > 12) { + F1(l, r, 12); + F2(r, l, 13); + F3(l, r, 14); + F1(r, l, 15); + } + /* Put l,r into outblock */ + WRITE_UINT32(dst, r); + WRITE_UINT32(dst + 4, l); + /* Wipe clean */ + t = l = r = 0; + } +} + + +/***** Decryption Function *****/ + +void +cast128_decrypt(const struct cast128_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + FOR_BLOCKS(length, dst, src, CAST128_BLOCK_SIZE) + { + uint32_t t, l, r; + + /* Get inblock into l,r */ + r = READ_UINT32(src); + l = READ_UINT32(src+4); + + /* Do the work */ + /* Only do full 16 rounds if key length > 80 bits */ + if (ctx->rounds > 12) { + F1(r, l, 15); + F3(l, r, 14); + F2(r, l, 13); + F1(l, r, 12); + } + F3(r, l, 11); + F2(l, r, 10); + F1(r, l, 9); + F3(l, r, 8); + F2(r, l, 7); + F1(l, r, 6); + F3(r, l, 5); + F2(l, r, 4); + F1(r, l, 3); + F3(l, r, 2); + F2(r, l, 1); + F1(l, r, 0); + + /* Put l,r into outblock */ + WRITE_UINT32(dst, l); + WRITE_UINT32(dst + 4, r); + + /* Wipe clean */ + t = l = r = 0; + } +} + +/***** Key Schedule *****/ + +void +cast128_set_key(struct cast128_ctx *ctx, + unsigned keybytes, const uint8_t *rawkey) +{ + uint32_t t[4], z[4], x[4]; + unsigned i; + + /* Set number of rounds to 12 or 16, depending on key length */ + ctx->rounds = (keybytes <= CAST_SMALL_KEY) + ? CAST_SMALL_ROUNDS : CAST_FULL_ROUNDS; + + /* Copy key to workspace x */ + for (i = 0; i < 4; i++) { + x[i] = 0; + if ((i*4+0) < keybytes) x[i] = (uint32_t)rawkey[i*4+0] << 24; + if ((i*4+1) < keybytes) x[i] |= (uint32_t)rawkey[i*4+1] << 16; + if ((i*4+2) < keybytes) x[i] |= (uint32_t)rawkey[i*4+2] << 8; + if ((i*4+3) < keybytes) x[i] |= (uint32_t)rawkey[i*4+3]; + } + /* FIXME: For the shorter key sizes, the last 4 subkeys are not + used, and need not be generatedd, nor stored. */ + /* Generate 32 subkeys, four at a time */ + for (i = 0; i < 32; i+=4) { + switch (i & 4) { + case 0: + t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])] + ^ cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])] + ^ cast_sbox8[U8c(x[3])] ^ cast_sbox7[U8a(x[2])]; + t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])] + ^ cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])] + ^ cast_sbox8[U8d(z[0])] ^ cast_sbox8[U8c(x[2])]; + t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])] + ^ cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])] + ^ cast_sbox8[U8a(z[1])] ^ cast_sbox5[U8b(x[2])]; + t[3] = z[3] = x[1] ^ cast_sbox5[U8c(z[2])] ^ + cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])] + ^ cast_sbox8[U8a(z[2])] ^ cast_sbox6[U8d(x[2])]; + break; + case 4: + t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])] + ^ cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])] + ^ cast_sbox8[U8c(z[1])] ^ cast_sbox7[U8a(z[0])]; + t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])] + ^ cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])] + ^ cast_sbox8[U8d(x[0])] ^ cast_sbox8[U8c(z[0])]; + t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])] + ^ cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])] + ^ cast_sbox8[U8a(x[1])] ^ cast_sbox5[U8b(z[0])]; + t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])] + ^ cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])] + ^ cast_sbox8[U8a(x[2])] ^ cast_sbox6[U8d(z[0])]; + break; + } + switch (i & 12) { + case 0: + case 12: + ctx->keys[i+0] = cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])] + ^ cast_sbox7[U8d(t[1])] ^ cast_sbox8[U8c(t[1])]; + ctx->keys[i+1] = cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])] + ^ cast_sbox7[U8b(t[1])] ^ cast_sbox8[U8a(t[1])]; + ctx->keys[i+2] = cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])] + ^ cast_sbox7[U8d(t[0])] ^ cast_sbox8[U8c(t[0])]; + ctx->keys[i+3] = cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])] + ^ cast_sbox7[U8b(t[0])] ^ cast_sbox8[U8a(t[0])]; + break; + case 4: + case 8: + ctx->keys[i+0] = cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])] + ^ cast_sbox7[U8a(t[3])] ^ cast_sbox8[U8b(t[3])]; + ctx->keys[i+1] = cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])] + ^ cast_sbox7[U8c(t[3])] ^ cast_sbox8[U8d(t[3])]; + ctx->keys[i+2] = cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])] + ^ cast_sbox7[U8a(t[2])] ^ cast_sbox8[U8b(t[2])]; + ctx->keys[i+3] = cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])] + ^ cast_sbox7[U8c(t[2])] ^ cast_sbox8[U8d(t[2])]; + break; + } + switch (i & 12) { + case 0: + ctx->keys[i+0] ^= cast_sbox5[U8c(z[0])]; + ctx->keys[i+1] ^= cast_sbox6[U8c(z[1])]; + ctx->keys[i+2] ^= cast_sbox7[U8b(z[2])]; + ctx->keys[i+3] ^= cast_sbox8[U8a(z[3])]; + break; + case 4: + ctx->keys[i+0] ^= cast_sbox5[U8a(x[2])]; + ctx->keys[i+1] ^= cast_sbox6[U8b(x[3])]; + ctx->keys[i+2] ^= cast_sbox7[U8d(x[0])]; + ctx->keys[i+3] ^= cast_sbox8[U8d(x[1])]; + break; + case 8: + ctx->keys[i+0] ^= cast_sbox5[U8b(z[2])]; + ctx->keys[i+1] ^= cast_sbox6[U8a(z[3])]; + ctx->keys[i+2] ^= cast_sbox7[U8c(z[0])]; + ctx->keys[i+3] ^= cast_sbox8[U8c(z[1])]; + break; + case 12: + ctx->keys[i+0] ^= cast_sbox5[U8d(x[0])]; + ctx->keys[i+1] ^= cast_sbox6[U8d(x[1])]; + ctx->keys[i+2] ^= cast_sbox7[U8a(x[2])]; + ctx->keys[i+3] ^= cast_sbox8[U8b(x[3])]; + break; + } + if (i >= 16) { + ctx->keys[i+0] &= 31; + ctx->keys[i+1] &= 31; + ctx->keys[i+2] &= 31; + ctx->keys[i+3] &= 31; + } + } + /* Wipe clean */ + for (i = 0; i < 4; i++) { + t[i] = x[i] = z[i] = 0; + } +} diff --git a/cast128.h b/cast128.h new file mode 100644 index 0000000..a1af0b0 --- /dev/null +++ b/cast128.h @@ -0,0 +1,77 @@ +/* cast128.h + * + * The CAST-128 block cipher. + */ + +/* CAST-128 in C + * Written by Steve Reid + * 100% Public Domain - no warranty + * Released 1997.10.11 + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_CAST128_H_INCLUDED +#define NETTLE_CAST128_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define cast128_set_key nettle_cast128_set_key +#define cast128_encrypt nettle_cast128_encrypt +#define cast128_decrypt nettle_cast128_decrypt + +#define CAST128_BLOCK_SIZE 8 + +/* Variable key size between 40 and 128. */ +#define CAST128_MIN_KEY_SIZE 5 +#define CAST128_MAX_KEY_SIZE 16 + +#define CAST128_KEY_SIZE 16 + +struct cast128_ctx +{ + uint32_t keys[32]; /* Key, after expansion */ + unsigned rounds; /* Number of rounds to use, 12 or 16 */ +}; + +void +cast128_set_key(struct cast128_ctx *ctx, + unsigned length, const uint8_t *key); + +void +cast128_encrypt(const struct cast128_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +cast128_decrypt(const struct cast128_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CAST128_H_INCLUDED */ diff --git a/cast128_sboxes.h b/cast128_sboxes.h new file mode 100644 index 0000000..4a1f10e --- /dev/null +++ b/cast128_sboxes.h @@ -0,0 +1,545 @@ +/* + * $Id: cast128_sboxes.h,v 1.1 2007/04/05 14:20:35 nisse Exp $ + * + * CAST-128 in C + * Written by Steve Reid + * 100% Public Domain - no warranty + * Released 1997.10.11 + */ + +static const uint32_t cast_sbox1[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 uint32_t cast_sbox2[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 uint32_t cast_sbox3[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 uint32_t cast_sbox4[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 uint32_t cast_sbox5[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 uint32_t cast_sbox6[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 uint32_t cast_sbox7[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 uint32_t cast_sbox8[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 +}; + diff --git a/cbc.c b/cbc.c new file mode 100644 index 0000000..6bd9f9a --- /dev/null +++ b/cbc.c @@ -0,0 +1,161 @@ +/* cbc.c + * + * Cipher block chaining mode. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "cbc.h" + +#include "memxor.h" +#include "nettle-internal.h" + +void +cbc_encrypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *iv, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % block_size)); + + for ( ; length; length -= block_size, src += block_size, dst += block_size) + { + memxor(iv, src, block_size); + f(ctx, block_size, dst, iv); + memcpy(iv, dst, block_size); + } +} + +/* Requires that dst != src */ +static void +cbc_decrypt_internal(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *iv, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(length); + assert( !(length % block_size) ); + assert(src != dst); + + /* Decrypt in ECB mode */ + f(ctx, length, dst, src); + + /* XOR the cryptotext, shifted one block */ + memxor(dst, iv, block_size); + memxor(dst + block_size, src, length - block_size); + memcpy(iv, src + length - block_size, block_size); +} + +/* Don't allocate any more space than this on the stack */ +#define CBC_BUFFER_LIMIT 4096 + +void +cbc_decrypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *iv, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % block_size)); + + if (!length) + return; + + if (src != dst) + cbc_decrypt_internal(ctx, f, block_size, iv, + length, dst, src); + else + { + /* We need a copy of the ciphertext, so we can't ECB decrypt in + * place. + * + * If length is small, we allocate a complete copy of src on the + * stack. Otherwise, we allocate a block of size at most + * CBC_BUFFER_LIMIT, and process that amount of data at a + * time. + * + * NOTE: We assume that block_size <= CBC_BUFFER_LIMIT. */ + + unsigned buffer_size; + + if (length <= CBC_BUFFER_LIMIT) + buffer_size = length; + else + buffer_size + = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size); + + { + TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT); + TMP_ALLOC(buffer, buffer_size); + + for ( ; length > buffer_size; + length -= buffer_size, dst += buffer_size, src += buffer_size) + { + memcpy(buffer, src, buffer_size); + cbc_decrypt_internal(ctx, f, block_size, iv, + buffer_size, dst, buffer); + } + /* Now, we have at most CBC_BUFFER_LIMIT octets left */ + memcpy(buffer, src, length); + + cbc_decrypt_internal(ctx, f, block_size, iv, + length, dst, buffer); + } + } +} + +#if 0 +#include "twofish.h" +#include "aes.h" + +static void foo(void) +{ + struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx; + uint8_t src[TWOFISH_BLOCK_SIZE]; + uint8_t dst[TWOFISH_BLOCK_SIZE]; + + CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, dst, src); + + /* Should result in a warning */ + CBC_ENCRYPT(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, dst, src); + +} + +static void foo2(void) +{ + struct twofish_ctx ctx; + uint8_t iv[TWOFISH_BLOCK_SIZE]; + uint8_t src[TWOFISH_BLOCK_SIZE]; + uint8_t dst[TWOFISH_BLOCK_SIZE]; + + CBC_ENCRYPT2(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src); + /* Should result in a warning */ + CBC_ENCRYPT2(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src); +} + +#endif diff --git a/cbc.h b/cbc.h new file mode 100644 index 0000000..81a0525 --- /dev/null +++ b/cbc.h @@ -0,0 +1,75 @@ +/* cbc.h + * + * Cipher block chaining mode. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_CBC_H_INCLUDED +#define NETTLE_CBC_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define cbc_encrypt nettle_cbc_encrypt +#define cbc_decrypt nettle_cbc_decrypt + +void +cbc_encrypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *iv, + unsigned length, uint8_t *dst, + const uint8_t *src); + +void +cbc_decrypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *iv, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#define CBC_CTX(type, size) \ +{ type ctx; uint8_t iv[size]; } + +#define CBC_SET_IV(ctx, data) \ +memcpy((ctx)->iv, (data), sizeof((ctx)->iv)) + +#define CBC_ENCRYPT(self, f, length, dst, src) \ +(0 ? ((f)(&(self)->ctx, 0, NULL, NULL)) \ + : cbc_encrypt((void *) &(self)->ctx, \ + (nettle_crypt_func *) (f), \ + sizeof((self)->iv), (self)->iv, \ + (length), (dst), (src))) + +#define CBC_DECRYPT(self, f, length, dst, src) \ +(0 ? ((f)(&(self)->ctx, 0, NULL, NULL)) \ + : cbc_decrypt((void *) &(self)->ctx, \ + (nettle_crypt_func *) (f), \ + sizeof((self)->iv), (self)->iv, \ + (length), (dst), (src))) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CBC_H_INCLUDED */ diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..c3bae20 --- /dev/null +++ b/config.guess @@ -0,0 +1,1439 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2005-03-17' + +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 to . Submit a context +# diff and a properly formatted 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. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +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 ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 -q "$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 ;' + +# 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 ;; + *) 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 __ELF__ >/dev/null + 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 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pegasos:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # 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 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/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + 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 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + 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 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + case "`optisa \`isainfo\``" in + amd64) + echo x86_64-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + ;; + *) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + ;; + esac + exit 0 ;; + 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 0 ;; + 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 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + 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 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # 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 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* 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 \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + 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 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????: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 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + 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 0 ;; + *: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 + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + 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 0 ;; + *:AIX:*:[45]) + 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 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 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 + #include + + 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 + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + 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 && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + 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 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/KFreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [x3456]86:Windows_95:* | [x3456]86:Windows_98:* | [x3456]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + 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 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *: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 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #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 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #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 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + 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 ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + 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 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + 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 0 ;; + 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 0 ;; + 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 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + 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 0 ;; + i*86:*:5:[78]*) + 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 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /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 0 ;; + 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 i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + 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 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 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) + 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 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *: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 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + 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 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DRAGONFLY:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly${UNAME_RELEASE} + exit 0 ;; +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 < +# include +#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 + 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"); 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 +# 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 && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# 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 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < 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: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..a45ad2a --- /dev/null +++ b/config.h.in @@ -0,0 +1,180 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define if fcntl file locking is available */ +#undef HAVE_FCNTL_LOCKING + +/* Define if the compiler understands __attribute__ */ +#undef HAVE_GCC_ATTRIBUTE + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `gmp' library (-lgmp). */ +#undef HAVE_LIBGMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memxor' function. */ +#undef HAVE_MEMXOR + +/* Define if mpz_powm_sec is available (appeared in GMP-5) */ +#undef HAVE_MPZ_POWM_SEC + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_AES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_BLOWFISH_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_CAST_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_DES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* 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 version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `void*', as computed by sizeof. */ +#undef SIZEOF_VOIDP + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Defined if public key features are enabled */ +#undef WITH_HOGWEED + +/* Define if you have openssl's libcrypto (used for benchmarking) */ +#undef WITH_OPENSSL + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* 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 `unsigned int' if does not define. */ +#undef size_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* AIX requires this to be the first thing in the file. */ +#ifndef __GNUC__ +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +/* Needed for alloca on windows */ +# if HAVE_MALLOC_H +# include +# endif +# endif +#else /* defined __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# endif +#endif + + +#if __GNUC__ && HAVE_GCC_ATTRIBUTE +# define NORETURN __attribute__ ((__noreturn__)) +# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) +# define UNUSED __attribute__ ((__unused__)) +#else +# define NORETURN +# define PRINTF_STYLE(f, a) +# define UNUSED +#endif + diff --git a/config.m4.in b/config.m4.in new file mode 100644 index 0000000..ec62573 --- /dev/null +++ b/config.m4.in @@ -0,0 +1,8 @@ +define(, <<@srcdir@>>)dnl +define(, <@ASM_SYMBOL_PREFIX@><$1>)dnl +define(, <@ASM_ELF_STYLE@>)dnl +define(, <@ASM_TYPE_FUNCTION@>)dnl +define(, <@ASM_ALIGN_LOG@>)dnl +divert(1) +@ASM_MARK_NOEXEC_STACK@ +divert diff --git a/config.make.in b/config.make.in new file mode 100644 index 0000000..152b42e --- /dev/null +++ b/config.make.in @@ -0,0 +1,93 @@ +# Makefile settings shared between Makefiles. + +CC = @CC@ +CXX = @CXX@ +CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ +CCPIC = @CCPIC@ +CCPIC_MAYBE = @CCPIC_MAYBE@ +CPPFLAGS = @CPPFLAGS@ +DEFS = @DEFS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +LIBOBJS = @LIBOBJS@ + +OBJEXT = @OBJEXT@ +EXEEXT = @EXEEXT@ + +DEP_FLAGS = @DEP_FLAGS@ +DEP_PROCESS = @DEP_PROCESS@ + +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + +SHLIBCFLAGS = @SHLIBCFLAGS@ + +LIBNETTLE_MAJOR = @LIBNETTLE_MAJOR@ +LIBNETTLE_MINOR = @LIBNETTLE_MINOR@ +LIBNETTLE_SONAME = @LIBNETTLE_SONAME@ +LIBNETTLE_FILE = @LIBNETTLE_FILE@ +LIBNETTLE_FORLINK = @LIBNETTLE_FORLINK@ +LIBNETTLE_LIBS = @LIBNETTLE_LIBS@ +LIBNETTLE_LINK = @LIBNETTLE_LINK@ + +LIBHOGWEED_MAJOR = @LIBHOGWEED_MAJOR@ +LIBHOGWEED_MINOR = @LIBHOGWEED_MINOR@ +LIBHOGWEED_SONAME = @LIBHOGWEED_SONAME@ +LIBHOGWEED_FILE = @LIBHOGWEED_FILE@ +LIBHOGWEED_FORLINK = @LIBHOGWEED_FORLINK@ +LIBHOGWEED_LIBS = @LIBHOGWEED_LIBS@ +LIBHOGWEED_LINK = @LIBHOGWEED_LINK@ + +AR = ar +ARFLAGS = cru +AUTOCONF = autoconf +AUTOHEADER = autoheader +M4 = @M4@ +MAKEINFO = makeinfo +RANLIB = @RANLIB@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +bindir = @bindir@ +libdir = @libdir@ +includedir = @includedir@ +infodir = @infodir@ + +# PRE_CPPFLAGS and PRE_LDFLAGS lets each Makefile.in prepend its own +# flags before CPPFLAGS and LDFLAGS. + +COMPILE = $(CC) $(PRE_CPPFLAGS) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(CCPIC) $(DEP_FLAGS) +COMPILE_CXX = $(CXX) $(PRE_CPPFLAGS) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(CCPIC) $(DEP_FLAGS) +LINK = $(CC) $(CFLAGS) $(PRE_LDFLAGS) $(LDFLAGS) +LINK_CXX = $(CXX) $(CXXFLAGS) $(PRE_LDFLAGS) $(LDFLAGS) + +# Default rule. Must be here, since config.make is included before the +# usual targets. +default: all + +# For some reason the suffixes list must be set before the rules. +# Otherwise BSD make won't build binaries e.g. aesdata. On the other +# hand, AIX make has the opposite idiosyncrasies to BSD, and the AIX +# compile was broken when .SUFFIXES was moved here from Makefile.in. + +.SUFFIXES: +.SUFFIXES: .asm .c .$(OBJEXT) .p$(OBJEXT) .html .dvi .info .exe .pdf .ps .texinfo + +# Disable builtin rule +%$(EXEEXT) : %.c +.c: + +# Keep object files +.PRECIOUS: %.o + +.PHONY: all check install uninstall clean distclean mostlyclean maintainer-clean distdir \ + all-here check-here install-here clean-here distclean-here mostlyclean-here \ + maintainer-clean-here distdir-here \ + install-shared install-info install-headers \ + uninstall-shared uninstall-info uninstall-headers \ + dist distcleancheck diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..ba33103 --- /dev/null +++ b/config.sub @@ -0,0 +1,1549 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2004-03-12' + +# 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, 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 . Submit a context +# diff and a properly formatted 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. + +# 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 ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 0;; + + * ) + 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-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-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) + os= + basic_machine=$1 + ;; + -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 + ;; + -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/'` + ;; + -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 \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # 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-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + 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 + ;; + 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + 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 + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + 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 + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + 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 + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + 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) basic_machine=powerpc-unknown + ;; + ppc-*) 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 + ;; + 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 + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + 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 + ;; + 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 + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + 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 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-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 + ;; + 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 + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + 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. + -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* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -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* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -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*) + # 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* \ + | -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 + ;; + -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 + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + 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 + ;; + 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 + ;; + *-ibm) + os=-aix + ;; + *-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 + ;; + -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 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..f7d6767 --- /dev/null +++ b/configure @@ -0,0 +1,11909 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for nettle 2.1. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 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=: + # 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 + + + + +# PATH needs CR +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +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.) +as_nl=' +' +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 + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +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 + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +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 + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +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 + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. 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" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); 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 +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +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 +fi +echo >conf$$.file +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 +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=: +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 7<&0 &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= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='nettle' +PACKAGE_TARNAME='nettle' +PACKAGE_VERSION='2.1' +PACKAGE_STRING='nettle 2.1' +PACKAGE_BUGREPORT='nettle-bugs@lists.lysator.liu.se' + +ac_unique_file="arcfour.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CXX +CXXFLAGS +ac_ct_CXX +CXX_TESTS +SET_MAKE +RANLIB +NM +OBJDUMP +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +DEP_INCLUDE +DEP_FLAGS +DEP_PROCESS +CCPIC +CCPIC_MAYBE +ASM_SYMBOL_PREFIX +ASM_ELF_STYLE +ASM_TYPE_FUNCTION +ASM_MARK_NOEXEC_STACK +ASM_ALIGN_LOG +SHLIBCFLAGS +LIBNETTLE_MAJOR +LIBNETTLE_MINOR +LIBNETTLE_FORLINK +LIBNETTLE_SONAME +LIBNETTLE_FILE +LIBNETTLE_LINK +LIBNETTLE_LIBS +LIBHOGWEED_MAJOR +LIBHOGWEED_MINOR +LIBHOGWEED_FORLINK +LIBHOGWEED_SONAME +LIBHOGWEED_FILE +LIBHOGWEED_LINK +LIBHOGWEED_LIBS +M4 +CPP +GREP +EGREP +ALLOCA +LIBOBJS +IF_HOGWEED +IF_SHARED +OPENSSL_LIBFLAGS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# 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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=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 ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +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 + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +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 + 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 .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# 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 -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + 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 .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + 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 nettle 2.1 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/nettle] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +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 nettle 2.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-public-key Disable public key algorithms + --disable-assembler Disable assembler code + --enable-shared Build a shared library + --disable-pic Do not try to compile library files as position + independent code + --disable-openssl Do not include openssl glue in the benchmark program + --disable-dependency-tracking + Disable dependency tracking. Dependency tracking + doesn't work with BSD make + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-include-path A colon-separated list of directories to search for + include files + --with-lib-path A colon-separated list of directories to search for + libraries + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + +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 . +_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" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`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 + 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 +nettle configure 2.1 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 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 +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 nettle $as_me 2.1, which was +generated by GNU Autoconf 2.61. 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=. + 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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$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 + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_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=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + 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=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + 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 && + echo "$as_me: caught signal $ac_signal" + 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'; { (exit 1); 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 + +# 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 + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +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 + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +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,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`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. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +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 + + + + +# Needed to stop autoconf from looking for files in parent directories. +ac_aux_dir= +for ac_dir in . "$srcdir"/.; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in . \"$srcdir\"/." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in . \"$srcdir\"/." >&2;} + { (exit 1); exit 1; }; } +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. + + + +ac_config_headers="$ac_config_headers config.h" + + +LIBNETTLE_MAJOR=4 +LIBNETTLE_MINOR=0 + +LIBHOGWEED_MAJOR=2 +LIBHOGWEED_MINOR=0 + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +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 + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +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 + + + +# Command line options + +# Check whether --with-include-path was given. +if test "${with_include_path+set}" = set; then + withval=$with_include_path; +else + with_include_path='' +fi + + +if test x$with_include_path != x ; then + CPPFLAGS="$CPPFLAGS -I`echo $with_include_path | sed 's/:/ -I/g'`" +fi + + +# Check whether --with-lib-path was given. +if test "${with_lib_path+set}" = set; then + withval=$with_lib_path; +else + with_lib_path='' +fi + + +if test x$with_lib_path != x ; then + LDFLAGS="$LDFLAGS -L`echo $with_lib_path | sed 's/:/ -L/g'`" +fi + +# Check whether --enable-public-key was given. +if test "${enable_public_key+set}" = set; then + enableval=$enable_public_key; +else + enable_public_key=yes +fi + + +# Check whether --enable-assembler was given. +if test "${enable_assembler+set}" = set; then + enableval=$enable_assembler; +else + enable_assembler=yes +fi + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then + enableval=$enable_shared; +else + enable_shared=no +fi + + +# Check whether --enable-pic was given. +if test "${enable_pic+set}" = set; then + enableval=$enable_pic; +else + enable_pic=yes +fi + + +# Check whether --enable-openssl was given. +if test "${enable_openssl+set}" = set; then + enableval=$enable_openssl; +else + enable_openssl=yes +fi + + +{ echo "$as_me:$LINENO: checking for -R flag" >&5 +echo $ECHO_N "checking for -R flag... $ECHO_C" >&6; } +RPATHFLAG='' +case "$host_os" in + osf1*) RPATHFLAG="-rpath " ;; + irix6.*|irix5.*) RPATHFLAG="-rpath " ;; + solaris*) + if test "$TCC" = "yes"; then + # tcc doesn't know about -R + RPATHFLAG="-Wl,-R," + else + RPATHFLAG=-R + fi + ;; + linux*) RPATHFLAG="-Wl,-rpath," ;; + *) RPATHFLAG="" ;; +esac + +if test x$RPATHFLAG = x ; then + { echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6; } +else + { echo "$as_me:$LINENO: result: using $RPATHFLAG" >&5 +echo "${ECHO_T}using $RPATHFLAG" >&6; } +fi + +RPATH_CANDIDATE_REAL_DIRS='' +RPATH_CANDIDATE_DIRS='' + +{ echo "$as_me:$LINENO: result: Searching for libraries" >&5 +echo "${ECHO_T}Searching for libraries" >&6; } + +for d in `echo $with_lib_path | sed 's/:/ /g'` \ + `echo $exec_prefix | sed "s@^NONE@$prefix/lib@g" | sed "s@^NONE@$ac_default_prefix/lib@g"` \ + /usr/local/lib /sw/local/lib /sw/lib \ + /usr/gnu/lib /opt/gnu/lib /sw/gnu/lib /usr/freeware/lib /usr/pkg/lib ; do + { echo "$as_me:$LINENO: checking $d" >&5 +echo $ECHO_N "checking $d... $ECHO_C" >&6; } +ac_exists=no +if test -d "$d/." ; then + ac_real_dir=`cd $d && pwd` + if test -n "$ac_real_dir" ; then + ac_exists=yes + for old in RPATH_CANDIDATE_REAL_DIRS ; do + ac_found=no + if test x$ac_real_dir = x$old ; then + ac_found=yes; + break; + fi + done + if test $ac_found = yes ; then + { echo "$as_me:$LINENO: result: already added" >&5 +echo "${ECHO_T}already added" >&6; } + else + { echo "$as_me:$LINENO: result: added" >&5 +echo "${ECHO_T}added" >&6; } + # LDFLAGS="$LDFLAGS -L $d" + RPATH_CANDIDATE_REAL_DIRS="$ac_real_dir $RPATH_CANDIDATE_REAL_DIRS" + RPATH_CANDIDATE_DIRS="$d $RPATH_CANDIDATE_DIRS" + fi + fi +fi +if test $ac_exists = no ; then + { echo "$as_me:$LINENO: result: not found" >&5 +echo "${ECHO_T}not found" >&6; } +fi + +done + + +# Checks for programs. +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.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. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.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 + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +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. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.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. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* 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" + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +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) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +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 + + +# When $CC foo.c -o foo creates both foo and foo.exe, autoconf picks +# up the foo.exe and sets exeext to .exe. That is correct for cygwin, +# which has some kind of magic link from foo to foo.exe, but not for +# rntcl. A better check for the cygwin case would check if the +# contents of foo and foo.exe are equal; in the rntcl case, foo is a +# sh script, and foo.exe is a windows executable. + +if test "x$CC" = xrntcl ; then + { echo "$as_me:$LINENO: Compiling with rntcl; clearing EXEEXT and disabling assembler" >&5 +echo "$as_me: Compiling with rntcl; clearing EXEEXT and disabling assembler" >&6;} + ac_exeext='' + ac_cv_exeext='' + EXEEXT='' + enable_assembler=no +fi + +# Used by the testsuite only +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + 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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # 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_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +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_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +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 + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + CXX_TESTS='cxx-test$(EXEEXT)' +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXX_TESTS='' +fi + +rm -f core conftest.err conftest.$ac_objext 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 + + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`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 + echo $ECHO_N "(cached) $ECHO_C" >&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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # 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_NM="${ac_tool_prefix}nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # 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_NM="nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { echo "$as_me:$LINENO: result: $ac_ct_NM" >&5 +echo "${ECHO_T}$ac_ct_NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="strings" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +else + NM="$ac_cv_prog_NM" +fi + +# Used only for the GNU-stack configure test. +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $OBJDUMP" >&5 +echo "${ECHO_T}$OBJDUMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + echo "$as_me:$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 + { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 +echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + +if test "x$ac_cv_prog_cc_stdc" = xno ; then + { { echo "$as_me:$LINENO: error: the C compiler doesn't handle ANSI-C" >&5 +echo "$as_me: error: the C compiler doesn't handle ANSI-C" >&2;} + { (exit 1); exit 1; }; } #' +fi + +# 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. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +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 +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + + +# According to the autoconf manual, needs install-sh from +# autoconf-2.60 or automake-1.10 to avoid races. +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$MKDIR_P" >&6; } + + +# Check whether --enable-dependency_tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +else + enable_dependency_tracking=yes +fi + + +DEP_FLAGS='' +DEP_PROCESS='true' +if test x$enable_dependency_tracking = xyes ; then + if test x$GCC = xyes ; then + gcc_version=`gcc --version | head -1` + case "$gcc_version" in + 2.*|*[!0-9.]2.*) + enable_dependency_tracking=no + { echo "$as_me:$LINENO: WARNING: Dependency tracking disabled, gcc-3.x is needed" >&5 +echo "$as_me: WARNING: Dependency tracking disabled, gcc-3.x is needed" >&2;} + ;; + *) + DEP_FLAGS='-MT $@ -MD -MP -MF $@.d' + DEP_PROCESS='true' + ;; + esac + else + enable_dependency_tracking=no + { echo "$as_me:$LINENO: WARNING: Dependency tracking disabled" >&5 +echo "$as_me: WARNING: Dependency tracking disabled" >&2;} + fi +fi + +if test x$enable_dependency_tracking = xyes ; then + DEP_INCLUDE='include ' +else + DEP_INCLUDE='# ' +fi + + + + + +if test x$enable_dependency_tracking = xyes ; then + # Since the makefiles use include to get the dependency files, we must + # make sure that the files exist. We generate some more files than are + # actually needed. + + ac_config_commands="$ac_config_commands dummy-dep-files" + +fi + +# Figure out ABI. Currently, configurable only be setting CFLAGS. +ABI=standard + +case "$host_cpu" in + x86_64 | amd64) + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if defined(__x86_64__) || defined(__arch64__) +#error 64-bit x86 +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + ABI=32 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + ABI=64 + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + *sparc*) + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if defined(__sparcv9) || defined(__arch64__) +#error 64-bit sparc +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + ABI=32 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + ABI=64 + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; +esac + +if test "x$ABI" != xstandard ; then + { echo "$as_me:$LINENO: Compiler uses $ABI-bit ABI. To change, set CC." >&5 +echo "$as_me: Compiler uses $ABI-bit ABI. To change, set CC." >&6;} + if test "$libdir" = '${exec_prefix}/lib' ; then + # Try setting a better default + case "$host_cpu:$host_os:$ABI" in + *:solaris*:32|*:sunos*:32) + libdir='${exec_prefix}/lib' + ;; + *:solaris*:64|*:sunos*:64) + libdir='${exec_prefix}/lib/64' + ;; + # According to the fhs, all architectures except IA64 + # puts 32-bit libraries in lib, and 64-bit in lib64. + *:linux*:32) + libdir='${exec_prefix}/lib' + ;; + *:linux*:64) + libdir='${exec_prefix}/lib64' + ;; + # On freebsd, it seems 32-bit libraries are in lib32, + # and 64-bit in lib. Don't know about "kfreebsd", does + # it follow the Linux fhs conventions? + *:freebsd*:32) + libdir='${exec_prefix}/lib32' + ;; + *:freebsd*:64) + libdir='${exec_prefix}/lib' + ;; + *) + { echo "$as_me:$LINENO: WARNING: Don't know where to install $ABI-bit libraries on this system." >&5 +echo "$as_me: WARNING: Don't know where to install $ABI-bit libraries on this system." >&2;}; #' + + esac + { echo "$as_me:$LINENO: Libraries to be installed in $libdir." >&5 +echo "$as_me: Libraries to be installed in $libdir." >&6;} + fi +fi + +# Select assembler code +asm_path= +case "$host_cpu" in + i?86* | k[5-8]* | pentium* | athlon) + asm_path=x86 + ;; + x86_64 | amd64) + if test "$ABI" = 64 ; then + asm_path=x86_64 + else + asm_path=x86 + fi + ;; + *sparc*) + if test "$ABI" = 64 ; then + asm_path=sparc64 + else + asm_path=sparc32 + fi + ;; + *) + enable_assembler=no + ;; +esac + +# echo "enable_assembler: $enable_assembler, asm_path: $asm_path" + +if test "x$enable_assembler" = xyes ; then + if test -n "$asm_path"; then + { echo "$as_me:$LINENO: Looking for assembler files in $asm_path/." >&5 +echo "$as_me: Looking for assembler files in $asm_path/." >&6;} + found=no + for tmp_f in aes-encrypt-internal.asm aes-decrypt-internal.asm \ + arcfour-crypt.asm camellia-crypt-internal.asm \ + md5-compress.asm sha1-compress.asm machine.m4; do +# echo "Looking for $srcdir/$asm_path/$tmp_f" + if test -f "$srcdir/$asm_path/$tmp_f"; then +# echo found + found=yes + ac_config_links="$ac_config_links $tmp_f:$asm_path/$tmp_f" + + fi + done + if test "$found" = no; then + enable_assembler=no + { echo "$as_me:$LINENO: WARNING: No assembler files found." >&5 +echo "$as_me: WARNING: No assembler files found." >&2;} + fi + fi +fi + +{ echo "$as_me:$LINENO: checking CCPIC" >&5 +echo $ECHO_N "checking CCPIC... $ECHO_C" >&6; } +if test "${lsh_cv_sys_ccpic+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test -z "$CCPIC" ; then + if test "$GCC" = yes ; then + case "$host_os" in + bsdi4.*) CCPIC="-fPIC" ;; + bsdi*) CCPIC="" ;; + darwin*) CCPIC="-fPIC" ;; + # Could also use -fpic, depending on the number of symbol references + solaris*) CCPIC="-fPIC" ;; + cygwin*) CCPIC="" ;; + mingw32*) CCPIC="" ;; + *) CCPIC="-fpic" ;; + esac + else + case "$host_os" in + darwin*) CCPIC="-fPIC" ;; + irix*) CCPIC="-share" ;; + hpux*) CCPIC="+z"; ;; + *freebsd*) CCPIC="-fpic" ;; + sco*|sysv4.*) CCPIC="-KPIC -dy -Bdynamic" ;; + solaris*) CCPIC="-KPIC -Bdynamic" ;; + winnt*) CCPIC="-shared" ;; + *) CCPIC="" ;; + esac + fi + fi + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $CCPIC" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +exit(0); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + lsh_cv_sys_ccpic="$CCPIC" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lsh_cv_sys_ccpic='' +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$OLD_CFLAGS" + +fi + +CCPIC="$lsh_cv_sys_ccpic" +{ echo "$as_me:$LINENO: result: $CCPIC" >&5 +echo "${ECHO_T}$CCPIC" >&6; } + + +SHLIBCFLAGS="$CCPIC" + +case "$host_os" in + cygwin*) + LIBNETTLE_FORLINK='cygnettle-$(LIBNETTLE_MAJOR)-$(LIBNETTLE_MINOR).dll' + LIBNETTLE_SONAME='' + LIBNETTLE_FILE='libnettle.dll.a' + LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_LIBFILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' + LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)' + + LIBHOGWEED_FORLINK='cyghogweed-$(LIBHOGWEED_MAJOR)-$(LIBHOGWEED_MINOR).dll' + LIBHOGWEED_SONAME='' + LIBHOGWEED_FILE='libhogweed.dll.a' + LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_LIBFILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' + LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS)' + ;; + darwin*) + LIBNETTLE_FORLINK=libnettle.dylib + LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)' + LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)' + LIBNETTLE_LINK='$(CC) -dynamiclib $(LDFLAGS)' + LIBNETTLE_LIBS='' + + LIBHOGWEED_FORLINK=libhogweed.dylib + LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)' + LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)' + LIBHOGWEED_LINK='$(CC) -dynamiclib $(LDFLAGS)' + LIBHOGWEED_LIBS='' + ;; + *) + LIBNETTLE_FORLINK=libnettle.so + LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)' + LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)' + LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,-soname=$(LIBNETTLE_SONAME)' + LIBNETTLE_LIBS='' + + LIBHOGWEED_FORLINK=libhogweed.so + LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)' + LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)' + LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -L. -shared -Wl,-soname=$(LIBHOGWEED_SONAME)' + # Requested by debian, to make linking with only -lhogweed work + # (does not work in general, e.g., with static linking all of + # -lhogweed -lgmp -lnettle are still required). Also makes dlopen + # of libhogweed.so work, without having to use RTLD_GLOBAL. + # Depends on -L. above, to locate nettle.so. + LIBHOGWEED_LIBS='-lnettle -lgmp' + ;; +esac + +if test "x$enable_pic" = xyes; then + CCPIC_MAYBE="$CCPIC" +else + CCPIC_MAYBE='' +fi + + +ASM_SYMBOL_PREFIX='' +ASM_ELF_STYLE='no' +ASM_TYPE_FUNCTION='' +ASM_MARK_NOEXEC_STACK='' +ASM_ALIGN_LOG='' + +if test x$enable_assembler = xyes ; then + { echo "$as_me:$LINENO: checking if globals are prefixed by underscore" >&5 +echo $ECHO_N "checking if globals are prefixed by underscore... $ECHO_C" >&6; } +if test "${nettle_cv_asm_underscore+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Default is no underscore + nettle_cv_asm_underscore=no + cat >conftest.$ac_ext <<_ACEOF +int a_global_symbol; +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + $NM conftest.$OBJEXT >conftest.out + if grep _a_global_symbol conftest.out >/dev/null ; then + nettle_cv_asm_underscore=yes + elif grep a_global_symbol conftest.out >/dev/null ; then + nettle_cv_asm_underscore=no + else + { echo "$as_me:$LINENO: WARNING: nm doesn't list a_global_symbol at all" >&5 +echo "$as_me: WARNING: nm doesn't list a_global_symbol at all" >&2;} + fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: WARNING: test program with a single global could not be compiled!?" >&5 +echo "$as_me: WARNING: test program with a single global could not be compiled!?" >&2;} +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_underscore" >&5 +echo "${ECHO_T}$nettle_cv_asm_underscore" >&6; } + if test x$nettle_cv_asm_underscore = xyes ; then + ASM_SYMBOL_PREFIX='_' + fi + + { echo "$as_me:$LINENO: checking if we should use a .note.GNU-stack section" >&5 +echo $ECHO_N "checking if we should use a .note.GNU-stack section... $ECHO_C" >&6; } +if test "${nettle_cv_asm_gnu_stack+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Default + nettle_cv_asm_gnu_stack=no + + cat >conftest.c <&5 + (eval $nettle_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + cat conftest.out >&5 + $OBJDUMP -x conftest.o | grep '\.note\.GNU-stack' > /dev/null \ + && nettle_cv_asm_gnu_stack=yes + else + cat conftest.out >&5 + echo "configure: failed program was:" >&5 + cat conftest.s >&5 + fi + rm -f conftest.* +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_gnu_stack" >&5 +echo "${ECHO_T}$nettle_cv_asm_gnu_stack" >&6; } + if test x$nettle_cv_asm_gnu_stack = xyes ; then + ASM_MARK_NOEXEC_STACK='.section .note.GNU-stack,"",@progbits' + fi + + { echo "$as_me:$LINENO: checking for ELF-style .type,%function pseudo-ops" >&5 +echo $ECHO_N "checking for ELF-style .type,%function pseudo-ops... $ECHO_C" >&6; } +if test "${nettle_cv_asm_type_percent_function+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + cat conftest.out >&5 + nettle_cv_asm_type_percent_function=yes +else + cat conftest.out >&5 + echo "configure: failed program was:" >&5 + cat conftest.s >&5 + nettle_cv_asm_type_percent_function=no +fi +rm -f conftest* + +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_type_percent_function" >&5 +echo "${ECHO_T}$nettle_cv_asm_type_percent_function" >&6; } + + { echo "$as_me:$LINENO: checking for ELF-style .type,#function pseudo-ops" >&5 +echo $ECHO_N "checking for ELF-style .type,#function pseudo-ops... $ECHO_C" >&6; } +if test "${nettle_cv_asm_type_hash_function+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + cat conftest.out >&5 + nettle_cv_asm_type_hash_function=yes +else + cat conftest.out >&5 + echo "configure: failed program was:" >&5 + cat conftest.s >&5 + nettle_cv_asm_type_hash_function=no +fi +rm -f conftest* + +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_type_hash_function" >&5 +echo "${ECHO_T}$nettle_cv_asm_type_hash_function" >&6; } + + if test x$nettle_cv_asm_type_percent_function = xyes ; then + ASM_ELF_STYLE='yes' + ASM_TYPE_FUNCTION='%function' + else + if test x$nettle_cv_asm_type_hash_function = xyes ; then + ASM_ELF_STYLE='yes' + ASM_TYPE_FUNCTION='#function' + fi + fi + { echo "$as_me:$LINENO: checking if .align assembly directive is logarithmic" >&5 +echo $ECHO_N "checking if .align assembly directive is logarithmic... $ECHO_C" >&6; } +if test "${nettle_cv_asm_align_log+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + cat conftest.out >&5 + nettle_cv_asm_align_log=yes +else + cat conftest.out >&5 + echo "configure: failed program was:" >&5 + cat conftest.s >&5 + nettle_cv_asm_align_log=no +fi +rm -f conftest* + +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_asm_align_log" >&5 +echo "${ECHO_T}$nettle_cv_asm_align_log" >&6; } + if test x$nettle_cv_asm_align_log = xyes ; then + ASM_ALIGN_LOG='yes' + fi +fi + + + + + + + + + + + + + + + + + + + + + + + + + +# Extract the first word of "m4", so it can be a program name with args. +set dummy m4; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_M4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $M4 in + [\\/]* | ?:[\\/]*) + ac_cv_path_M4="$M4" # 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_M4="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_M4" && ac_cv_path_M4="m4" + ;; +esac +fi +M4=$ac_cv_path_M4 +if test -n "$M4"; then + { echo "$as_me:$LINENO: result: $M4" >&5 +echo "${ECHO_T}$M4" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + +# Checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$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_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 +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&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 + echo $ECHO_N "(cached) $ECHO_C" >&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 to if __STDC__ is defined, since + # 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # 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 +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$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 to if __STDC__ is defined, since + # 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # 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 + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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 + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + 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 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + 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 + ac_count=`expr $ac_count + 1` + 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 + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + 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 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + 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 + ac_count=`expr $ac_count + 1` + 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 + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define uid_t int +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define gid_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#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 +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +# Used by eratosthenes.c +{ echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6; } +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef long ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6; } + +# 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. +{ echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + + + + + +for ac_header in openssl/blowfish.h openssl/des.h openssl/cast.h openssl/aes.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------- ## +## Report this to nettle-bugs@lists.lysator.liu.se ## +## ----------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + enable_openssl=no + break +fi + +done + + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ echo "$as_me:$LINENO: checking for working alloca.h" >&5 +echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; } +if test "${ac_cv_working_alloca_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_working_alloca_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_working_alloca_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA_H 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for alloca" >&5 +echo $ECHO_N "checking for alloca... $ECHO_C" >&6; } +if test "${ac_cv_func_alloca_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_alloca_works=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_alloca_works=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA 1 +_ACEOF + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +cat >>confdefs.h <<\_ACEOF +#define C_ALLOCA 1 +_ACEOF + + +{ echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; } +if test "${ac_cv_os_cray+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +echo "${ECHO_T}$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* 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_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; } +if test "${ac_cv_c_stack_direction+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + return find_stack_direction () < 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_stack_direction=1 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +echo "${ECHO_T}$ac_cv_c_stack_direction" >&6; } + +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + +for ac_header in malloc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------- ## +## Report this to nettle-bugs@lists.lysator.liu.se ## +## ----------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + +# Needed by the supplied memcmp.c +{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +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 +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_bigendian=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; 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 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +for ac_func in memxor +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* 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_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `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 + + + +{ echo "$as_me:$LINENO: checking for __attribute__" >&5 +echo $ECHO_N "checking for __attribute__... $ECHO_C" >&6; } +if test "${lsh_cv_c_attribute+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +static void foo(void) __attribute__ ((noreturn)); + +static void __attribute__ ((noreturn)) +foo(void) +{ + exit(1); +} + +int +main () +{ + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + lsh_cv_c_attribute=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lsh_cv_c_attribute=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $lsh_cv_c_attribute" >&5 +echo "${ECHO_T}$lsh_cv_c_attribute" >&6; } + + + +if test "x$lsh_cv_c_attribute" = "xyes"; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_GCC_ATTRIBUTE 1 +_ACEOF + +fi + + + + +# According to Simon Josefsson, looking for uint32_t and friends in +# sys/types.h is needed on some systems, in particular cygwin. +# ------ AX CREATE STDINT H ------------------------------------- +{ echo "$as_me:$LINENO: checking for stdint types" >&5 +echo $ECHO_N "checking for stdint types... $ECHO_C" >&6; } +ac_stdint_h=`echo nettle-stdint.h` +# try to shortcircuit - if the default include path of the compiler +# can find a "stdint.h" header then we assume that all compilers can. +if test "${ac_cv_header_stdint_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +int_least32_t v = 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h"; +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdint_t="" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CXXFLAGS="$old_CXXFLAGS" +CPPFLAGS="$old_CPPFLAGS" +CFLAGS="$old_CFLAGS" +fi + + +v="... $ac_cv_header_stdint_h" +if test "$ac_stdint_h" = "stdint.h" ; then + { echo "$as_me:$LINENO: result: (are you sure you want them in ./stdint.h?)" >&5 +echo "${ECHO_T}(are you sure you want them in ./stdint.h?)" >&6; } +elif test "$ac_stdint_h" = "inttypes.h" ; then + { echo "$as_me:$LINENO: result: (are you sure you want them in ./inttypes.h?)" >&5 +echo "${ECHO_T}(are you sure you want them in ./inttypes.h?)" >&6; } +elif test "_$ac_cv_header_stdint_t" = "_" ; then + { echo "$as_me:$LINENO: result: (putting them into $ac_stdint_h)$v" >&5 +echo "${ECHO_T}(putting them into $ac_stdint_h)$v" >&6; } +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + { echo "$as_me:$LINENO: result: $ac_cv_header_stdint (shortcircuit)" >&5 +echo "${ECHO_T}$ac_cv_header_stdint (shortcircuit)" >&6; } +fi + +if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit.. + + +inttype_headers=`echo sys/types.h | sed -e 's/,/ /g'` + +ac_cv_stdint_result="(no helpful system typedefs seen)" +{ echo "$as_me:$LINENO: checking for stdint uintptr_t" >&5 +echo $ECHO_N "checking for stdint uintptr_t... $ECHO_C" >&6; } +if test "${ac_cv_header_stdint_x+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&6; } + for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do + unset ac_cv_type_uintptr_t + unset ac_cv_type_uint64_t + { echo "$as_me:$LINENO: checking for uintptr_t" >&5 +echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uintptr_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$i> + +typedef uintptr_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uintptr_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uintptr_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5 +echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6; } +if test $ac_cv_type_uintptr_t = yes; then + ac_cv_header_stdint_x=$i +else + continue +fi + + { echo "$as_me:$LINENO: checking for uint64_t" >&5 +echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uint64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$i> + +typedef uint64_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uint64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint64_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint64_t" >&6; } +if test $ac_cv_type_uint64_t = yes; then + and64="/uint64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" + break; + done + { echo "$as_me:$LINENO: checking for stdint uintptr_t" >&5 +echo $ECHO_N "checking for stdint uintptr_t... $ECHO_C" >&6; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdint_x" >&5 +echo "${ECHO_T}$ac_cv_header_stdint_x" >&6; } + +if test "_$ac_cv_header_stdint_x" = "_" ; then +{ echo "$as_me:$LINENO: checking for stdint uint32_t" >&5 +echo $ECHO_N "checking for stdint uint32_t... $ECHO_C" >&6; } +if test "${ac_cv_header_stdint_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&6; } + for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do + unset ac_cv_type_uint32_t + unset ac_cv_type_uint64_t + { echo "$as_me:$LINENO: checking for uint32_t" >&5 +echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uint32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$i> + +typedef uint32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uint32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint32_t" >&6; } +if test $ac_cv_type_uint32_t = yes; then + ac_cv_header_stdint_o=$i +else + continue +fi + + { echo "$as_me:$LINENO: checking for uint64_t" >&5 +echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uint64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$i> + +typedef uint64_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uint64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uint64_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5 +echo "${ECHO_T}$ac_cv_type_uint64_t" >&6; } +if test $ac_cv_type_uint64_t = yes; then + and64="/uint64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen uint32_t$and64 in $i)" + break; + done + { echo "$as_me:$LINENO: checking for stdint uint32_t" >&5 +echo $ECHO_N "checking for stdint uint32_t... $ECHO_C" >&6; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdint_o" >&5 +echo "${ECHO_T}$ac_cv_header_stdint_o" >&6; } +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +{ echo "$as_me:$LINENO: checking for stdint u_int32_t" >&5 +echo $ECHO_N "checking for stdint u_int32_t... $ECHO_C" >&6; } +if test "${ac_cv_header_stdint_u+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&6; } + for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do + unset ac_cv_type_u_int32_t + unset ac_cv_type_u_int64_t + { echo "$as_me:$LINENO: checking for u_int32_t" >&5 +echo $ECHO_N "checking for u_int32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_u_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$i> + +typedef u_int32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_u_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_u_int32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_u_int32_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int32_t" >&6; } +if test $ac_cv_type_u_int32_t = yes; then + ac_cv_header_stdint_u=$i +else + continue +fi + + { echo "$as_me:$LINENO: checking for u_int64_t" >&5 +echo $ECHO_N "checking for u_int64_t... $ECHO_C" >&6; } +if test "${ac_cv_type_u_int64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$i> + +typedef u_int64_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_u_int64_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_u_int64_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_u_int64_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int64_t" >&6; } +if test $ac_cv_type_u_int64_t = yes; then + and64="/u_int64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" + break; + done + { echo "$as_me:$LINENO: checking for stdint u_int32_t" >&5 +echo $ECHO_N "checking for stdint u_int32_t... $ECHO_C" >&6; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdint_u" >&5 +echo "${ECHO_T}$ac_cv_header_stdint_u" >&6; } +fi fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then + { echo "$as_me:$LINENO: checking for stdint datatype model" >&5 +echo $ECHO_N "checking for stdint datatype model... $ECHO_C" >&6; } + { echo "$as_me:$LINENO: result: (..)" >&5 +echo "${ECHO_T}(..)" >&6; } + { echo "$as_me:$LINENO: checking for char" >&5 +echo $ECHO_N "checking for char... $ECHO_C" >&6; } +if test "${ac_cv_type_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef char ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_char=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_char=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_char" >&5 +echo "${ECHO_T}$ac_cv_type_char" >&6; } + +# 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. +{ echo "$as_me:$LINENO: checking size of char" >&5 +echo $ECHO_N "checking size of char... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_char=$ac_lo;; +'') if test "$ac_cv_type_char" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (char) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (char) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_char=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef char ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_char=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_char" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (char) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (char) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_char=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5 +echo "${ECHO_T}$ac_cv_sizeof_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + + { echo "$as_me:$LINENO: checking for short" >&5 +echo $ECHO_N "checking for short... $ECHO_C" >&6; } +if test "${ac_cv_type_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef short ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_short=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_short=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 +echo "${ECHO_T}$ac_cv_type_short" >&6; } + +# 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. +{ echo "$as_me:$LINENO: checking size of short" >&5 +echo $ECHO_N "checking size of short... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_short=$ac_lo;; +'') if test "$ac_cv_type_short" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_short=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_short=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_short" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_short=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 +echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + { echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6; } +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef int ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_int=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&6; } + +# 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. +{ echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') if test "$ac_cv_type_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_int=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_int=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + + { echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6; } +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef long ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6; } + +# 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. +{ echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + { echo "$as_me:$LINENO: checking for void*" >&5 +echo $ECHO_N "checking for void*... $ECHO_C" >&6; } +if test "${ac_cv_type_voidp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef void* ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_voidp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_voidp=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_voidp" >&5 +echo "${ECHO_T}$ac_cv_type_voidp" >&6; } + +# 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. +{ echo "$as_me:$LINENO: checking size of void*" >&5 +echo $ECHO_N "checking size of void*... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_voidp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_voidp=$ac_lo;; +'') if test "$ac_cv_type_voidp" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_voidp=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void* ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_voidp=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_voidp" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_voidp=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5 +echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOIDP $ac_cv_sizeof_voidp +_ACEOF + + + ac_cv_stdint_char_model="" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short" + ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int" + ac_cv_stdint_long_model="" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long" + ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp" + name="$ac_cv_stdint_long_model" + case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in + 122/242) name="$name, IP16 (standard 16bit machine)" ;; + 122/244) name="$name, LP32 (standard 32bit mac/win)" ;; + 122/*) name="$name (unusual int16 model)" ;; + 124/444) name="$name, ILP32 (standard 32bit unixish)" ;; + 124/488) name="$name, LP64 (standard 64bit unixish)" ;; + 124/448) name="$name, LLP64 (unusual 64bit unixish)" ;; + 124/*) name="$name (unusual int32 model)" ;; + 128/888) name="$name, ILP64 (unusual 64bit numeric)" ;; + 128/*) name="$name (unusual int64 model)" ;; + 222/*|444/*) name="$name (unusual dsptype)" ;; + *) name="$name (very unusal model)" ;; + esac + { echo "$as_me:$LINENO: result: combined for stdint datatype model... $name" >&5 +echo "${ECHO_T}combined for stdint datatype model... $name" >&6; } +fi + +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_x" +elif test "_$ac_cv_header_stdint_o" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_o" +elif test "_$ac_cv_header_stdint_u" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_u" +else + ac_cv_header_stdint="stddef.h" +fi + +{ echo "$as_me:$LINENO: checking for extra inttypes in chosen header" >&5 +echo $ECHO_N "checking for extra inttypes in chosen header... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: ($ac_cv_header_stdint)" >&5 +echo "${ECHO_T}($ac_cv_header_stdint)" >&6; } +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +{ echo "$as_me:$LINENO: checking for int_least32_t" >&5 +echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_int_least32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_cv_header_stdint> + +typedef int_least32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_int_least32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int_least32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6; } + +{ echo "$as_me:$LINENO: checking for int_fast32_t" >&5 +echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6; } +if test "${ac_cv_type_int_fast32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include<$ac_cv_header_stdint> + +typedef int_fast32_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_int_fast32_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int_fast32_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5 +echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6; } + +{ echo "$as_me:$LINENO: checking for intmax_t" >&5 +echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6; } +if test "${ac_cv_type_intmax_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_cv_header_stdint> + +typedef intmax_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_intmax_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_intmax_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5 +echo "${ECHO_T}$ac_cv_type_intmax_t" >&6; } + + +fi # shortcircut to system "stdint.h" +# ------------------ PREPARE VARIABLES ------------------------------ +if test "$GCC" = "yes" ; then +ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` +else +ac_cv_stdint_message="using $CC" +fi + +{ echo "$as_me:$LINENO: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5 +echo "${ECHO_T}make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6; } + +# ----------------- DONE inttypes.h checks START header ------------- +ac_config_commands="$ac_config_commands $ac_stdint_h" + + + +# Check for file locking. We (AC_PROG_CC?) have already checked for +# sys/types.h and unistd.h. +{ echo "$as_me:$LINENO: checking for fcntl file locking" >&5 +echo $ECHO_N "checking for fcntl file locking... $ECHO_C" >&6; } +if test "${nettle_cv_fcntl_locking+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +#include + +int +main () +{ + +int op = F_SETLKW; +struct flock fl; + + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + nettle_cv_fcntl_locking=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + nettle_cv_fcntl_locking=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $nettle_cv_fcntl_locking" >&5 +echo "${ECHO_T}$nettle_cv_fcntl_locking" >&6; } + + + +if test "x$nettle_cv_fcntl_locking" = "xyes" ; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_FCNTL_LOCKING 1 +_ACEOF + +fi + +# Checks for libraries + +{ echo "$as_me:$LINENO: checking for __gmpz_getlimbn in -lgmp" >&5 +echo $ECHO_N "checking for __gmpz_getlimbn in -lgmp... $ECHO_C" >&6; } +if test "${ac_cv_lib_gmp___gmpz_getlimbn+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgmp $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 __gmpz_getlimbn (); +int +main () +{ +return __gmpz_getlimbn (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_gmp___gmpz_getlimbn=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_gmp___gmpz_getlimbn=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_gmp___gmpz_getlimbn" >&5 +echo "${ECHO_T}$ac_cv_lib_gmp___gmpz_getlimbn" >&6; } +if test $ac_cv_lib_gmp___gmpz_getlimbn = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGMP 1 +_ACEOF + + LIBS="-lgmp $LIBS" + +else + { echo "$as_me:$LINENO: WARNING: GNU MP not found, or not 3.1 or up, see http://www.swox.com/gmp. +Support for public key algorithms will be unavailable." >&5 +echo "$as_me: WARNING: GNU MP not found, or not 3.1 or up, see http://www.swox.com/gmp. +Support for public key algorithms will be unavailable." >&2;} + enable_public_key=no +fi + + +# Add -R flags needed to run programs linked with gmp +if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then + ac_success=no + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_success=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_success=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + + if test $ac_success = no ; then + { echo "$as_me:$LINENO: checking Running simple test program failed. Trying -R flags" >&5 +echo $ECHO_N "checking Running simple test program failed. Trying -R flags... $ECHO_C" >&6; } + ac_remaining_dirs='' + ac_rpath_save_LDFLAGS="$LDFLAGS" + for d in $RPATH_CANDIDATE_DIRS ; do + if test $ac_success = yes ; then + ac_remaining_dirs="$ac_remaining_dirs $d" + else + LDFLAGS="$RPATHFLAG$d $LDFLAGS" + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_success=yes + ac_rpath_save_LDFLAGS="$LDFLAGS" + { echo "$as_me:$LINENO: result: adding $RPATHFLAG$d" >&5 +echo "${ECHO_T}adding $RPATHFLAG$d" >&6; } + +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_remaining_dirs="$ac_remaining_dirs $d" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + LDFLAGS="$ac_rpath_save_LDFLAGS" + fi + done + RPATH_CANDIDATE_DIRS=$ac_remaining_dirs + fi + if test $ac_success = no ; then + { echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6; } + fi +fi + + + + +{ echo "$as_me:$LINENO: checking for __gmpz_powm_sec" >&5 +echo $ECHO_N "checking for __gmpz_powm_sec... $ECHO_C" >&6; } +if test "${ac_cv_func___gmpz_powm_sec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define __gmpz_powm_sec to an innocuous variant, in case declares __gmpz_powm_sec. + For example, HP-UX 11i declares gettimeofday. */ +#define __gmpz_powm_sec innocuous___gmpz_powm_sec + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char __gmpz_powm_sec (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef __gmpz_powm_sec + +/* 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 __gmpz_powm_sec (); +/* 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___gmpz_powm_sec || defined __stub_____gmpz_powm_sec +choke me +#endif + +int +main () +{ +return __gmpz_powm_sec (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func___gmpz_powm_sec=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func___gmpz_powm_sec=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func___gmpz_powm_sec" >&5 +echo "${ECHO_T}$ac_cv_func___gmpz_powm_sec" >&6; } +if test $ac_cv_func___gmpz_powm_sec = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_MPZ_POWM_SEC 1 +_ACEOF + +fi + + + + + +if test "x$enable_public_key" = xyes ; then + cat >>confdefs.h <<\_ACEOF +#define WITH_HOGWEED 1 +_ACEOF + + IF_HOGWEED='' +else + IF_HOGWEED='#' +fi + +if test "x$enable_shared" = xyes ; then + IF_SHARED='' +else + IF_SHARED='#' +fi + + + + +OPENSSL_LIBFLAGS='' + +# Check for openssl's libcrypto (used only for benchmarking) +if test x$enable_openssl = xyes ; then + { echo "$as_me:$LINENO: checking for BF_ecb_encrypt in -lcrypto" >&5 +echo $ECHO_N "checking for BF_ecb_encrypt in -lcrypto... $ECHO_C" >&6; } +if test "${ac_cv_lib_crypto_BF_ecb_encrypt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 BF_ecb_encrypt (); +int +main () +{ +return BF_ecb_encrypt (); + ; + return 0; +} +_ACEOF +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_crypto_BF_ecb_encrypt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_crypto_BF_ecb_encrypt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_BF_ecb_encrypt" >&5 +echo "${ECHO_T}$ac_cv_lib_crypto_BF_ecb_encrypt" >&6; } +if test $ac_cv_lib_crypto_BF_ecb_encrypt = yes; then + OPENSSL_LIBFLAGS='-lcrypto' +else + enable_openssl=no +fi + +fi + + + + +if test x$enable_openssl = xyes ; then + cat >>confdefs.h <<\_ACEOF +#define WITH_OPENSSL 1 +_ACEOF + +fi + + + +# Set these flags *last*, or else the test programs won't compile +if test x$GCC = xyes ; then + # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core + if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then + true + else + CFLAGS="$CFLAGS -ggdb3" + fi + # FIXME: It would be better to actually test if this option works and/or is needed. + # Or perhaps use -funsigned-char. + if "$CC" --version | grep 'gcc.* 4\.' 1>/dev/null 2>&1; then + CFLAGS="$CFLAGS -Wno-pointer-sign" + fi + CFLAGS="$CFLAGS -Wall -W \ + -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ + -Wpointer-arith -Wbad-function-cast -Wnested-externs" + +# Don't enable -Wcast-align as it results in tons of warnings in the +# DES code. And when using stdio. +# Don't enable -Waggregate-return, as that causes warnings for glibc +# inttypes.h. +fi + +ac_config_files="$ac_config_files config.make config.m4 Makefile" + +ac_config_files="$ac_config_files tools/Makefile testsuite/Makefile examples/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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_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" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +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=`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. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $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} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## 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=: + # 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 + + + + +# PATH needs CR +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +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.) +as_nl=' +' +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 + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +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 + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. 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" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); 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 +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +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 +fi +echo >conf$$.file +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 +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=: +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 + +# 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 nettle $as_me 2.1, which was +generated by GNU Autoconf 2.61. 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 + +cat >>$CONFIG_STATUS <<_ACEOF +# 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_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet 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 ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +nettle config.status 2.1 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 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' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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 ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + 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. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$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 +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=`echo "_$PACKAGE-$ac_stdint_h" | $as_tr_cpp` +ac_cv_stdint_message="$ac_cv_stdint_message" +ac_cv_header_stdint_t="$ac_cv_header_stdint_t" +ac_cv_header_stdint_x="$ac_cv_header_stdint_x" +ac_cv_header_stdint_o="$ac_cv_header_stdint_o" +ac_cv_header_stdint_u="$ac_cv_header_stdint_u" +ac_cv_type_uint64_t="$ac_cv_type_uint64_t" +ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" +ac_cv_stdint_char_model="$ac_cv_stdint_char_model" +ac_cv_stdint_long_model="$ac_cv_stdint_long_model" +ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" +ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" +ac_cv_type_intmax_t="$ac_cv_type_intmax_t" + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# 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" ;; + "dummy-dep-files") CONFIG_COMMANDS="$CONFIG_COMMANDS dummy-dep-files" ;; + "$tmp_f") CONFIG_LINKS="$CONFIG_LINKS $tmp_f:$asm_path/$tmp_f" ;; + "$ac_stdint_h") CONFIG_COMMANDS="$CONFIG_COMMANDS $ac_stdint_h" ;; + "config.make") CONFIG_FILES="$CONFIG_FILES config.make" ;; + "config.m4") CONFIG_FILES="$CONFIG_FILES config.m4" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; + "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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 '{ (exit 1); 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") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CXX_TESTS!$CXX_TESTS$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +RANLIB!$RANLIB$ac_delim +NM!$NM$ac_delim +OBJDUMP!$OBJDUMP$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +DEP_INCLUDE!$DEP_INCLUDE$ac_delim +DEP_FLAGS!$DEP_FLAGS$ac_delim +DEP_PROCESS!$DEP_PROCESS$ac_delim +CCPIC!$CCPIC$ac_delim +CCPIC_MAYBE!$CCPIC_MAYBE$ac_delim +ASM_SYMBOL_PREFIX!$ASM_SYMBOL_PREFIX$ac_delim +ASM_ELF_STYLE!$ASM_ELF_STYLE$ac_delim +ASM_TYPE_FUNCTION!$ASM_TYPE_FUNCTION$ac_delim +ASM_MARK_NOEXEC_STACK!$ASM_MARK_NOEXEC_STACK$ac_delim +ASM_ALIGN_LOG!$ASM_ALIGN_LOG$ac_delim +SHLIBCFLAGS!$SHLIBCFLAGS$ac_delim +LIBNETTLE_MAJOR!$LIBNETTLE_MAJOR$ac_delim +LIBNETTLE_MINOR!$LIBNETTLE_MINOR$ac_delim +LIBNETTLE_FORLINK!$LIBNETTLE_FORLINK$ac_delim +LIBNETTLE_SONAME!$LIBNETTLE_SONAME$ac_delim +LIBNETTLE_FILE!$LIBNETTLE_FILE$ac_delim +LIBNETTLE_LINK!$LIBNETTLE_LINK$ac_delim +LIBNETTLE_LIBS!$LIBNETTLE_LIBS$ac_delim +LIBHOGWEED_MAJOR!$LIBHOGWEED_MAJOR$ac_delim +LIBHOGWEED_MINOR!$LIBHOGWEED_MINOR$ac_delim +LIBHOGWEED_FORLINK!$LIBHOGWEED_FORLINK$ac_delim +LIBHOGWEED_SONAME!$LIBHOGWEED_SONAME$ac_delim +LIBHOGWEED_FILE!$LIBHOGWEED_FILE$ac_delim +LIBHOGWEED_LINK!$LIBHOGWEED_LINK$ac_delim +LIBHOGWEED_LIBS!$LIBHOGWEED_LIBS$ac_delim +M4!$M4$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +ALLOCA!$ALLOCA$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +IF_HOGWEED!$IF_HOGWEED$ac_delim +IF_SHARED!$IF_SHARED$ac_delim +OPENSSL_LIBFLAGS!$OPENSSL_LIBFLAGS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 1; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_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 +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[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 || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$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 "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + 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 || +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" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`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 || +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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`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 +# 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= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + 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 + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;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 +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +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"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +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 + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then 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. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + :L) + # + # CONFIG_LINK + # + + { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_file" >&5 +echo "$as_me: linking $srcdir/$ac_source to $ac_file" >&6;} + + if test ! -r "$srcdir/$ac_source"; then + { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5 +echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;} + { (exit 1); exit 1; }; } + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $srcdir in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$srcdir/$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$srcdir/$ac_source" "$ac_file" 2>/dev/null || + cp -p "$srcdir/$ac_source" "$ac_file" || + { { echo "$as_me:$LINENO: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&5 +echo "$as_me: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "dummy-dep-files":C) (cd "$srcdir" && find . -name '*.c' -print) \ + | sed 's/\.c$//' | (while read f; do echo > "$f.o.d"; echo > "$f.po.d"; done) + ;; + "$ac_stdint_h":C) +{ echo "$as_me:$LINENO: creating $ac_stdint_h : $_ac_stdint_h" >&5 +echo "$as_me: creating $ac_stdint_h : $_ac_stdint_h" >&6;} +ac_stdint=$tmp/_stdint.h + +echo "#ifndef" $_ac_stdint_h >$ac_stdint +echo "#define" $_ac_stdint_h "1" >>$ac_stdint +echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint +echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint +echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint +if test "_$ac_cv_header_stdint_t" != "_" ; then +echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint +fi + +cat >>$ac_stdint < +#else +#include + +/* .................... configured part ............................ */ + +STDINT_EOF + +echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_header="$ac_cv_header_stdint_x" + echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint +fi + +echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_o" != "_" ; then + ac_header="$ac_cv_header_stdint_o" + echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint +fi + +echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint +if test "_$ac_cv_header_stdint_u" != "_" ; then + ac_header="$ac_cv_header_stdint_u" + echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint +fi + +echo "" >>$ac_stdint + +if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then + echo "#include <$ac_header>" >>$ac_stdint + echo "" >>$ac_stdint +fi fi + +echo "/* which 64bit typedef has been found */" >>$ac_stdint +if test "$ac_cv_type_uint64_t" = "yes" ; then +echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint +fi +if test "$ac_cv_type_u_int64_t" = "yes" ; then +echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* which type model has been detected */" >>$ac_stdint +if test "_$ac_cv_stdint_char_model" != "_" ; then +echo "#define _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint +echo "#define _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint +else +echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint +echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* whether int_least types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_least32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint +fi +echo "/* whether int_fast types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_fast32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint +fi +echo "/* whether intmax_t type was detected */" >>$ac_stdint +if test "$ac_cv_type_intmax_t" = "yes"; then +echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + + cat >>$ac_stdint <= 199901L +#define _HAVE_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif !defined __STRICT_ANSI__ +#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ +#define _HAVE_UINT64_T +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ +/* note: all ELF-systems seem to have loff-support which needs 64-bit */ +#if !defined _NO_LONGLONG +#define _HAVE_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif + +#elif defined __alpha || (defined __mips && defined _ABIN32) +#if !defined _NO_LONGLONG +typedef long int64_t; +typedef unsigned long uint64_t; +#endif + /* compiler/cpu type to define int64_t */ +#endif +#endif +#endif + +#if defined _STDINT_HAVE_U_INT_TYPES +/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; + +/* glibc compatibility */ +#ifndef __int8_t_defined +#define __int8_t_defined +#endif +#endif + +#ifdef _STDINT_NEED_INT_MODEL_T +/* we must guess all the basic types. Apart from byte-adressable system, */ +/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ +/* (btw, those nibble-addressable systems are way off, or so we assume) */ + + +#if defined _STDINT_BYTE_MODEL +#if _STDINT_LONG_MODEL+0 == 242 +/* 2:4:2 = IP16 = a normal 16-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 +/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ +/* 4:4:4 = ILP32 = a normal 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 +/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ +/* 4:8:8 = LP64 = a normal 64-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* this system has a "long" of 64bit */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long uint64_t; +typedef long int64_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 448 +/* LLP64 a 64-bit system derived from a 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* assuming the system has a "long long" */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#else +#define _STDINT_NO_INT32_T +#endif +#else +#define _STDINT_NO_INT8_T +#define _STDINT_NO_INT32_T +#endif +#endif + +/* + * quote from SunOS-5.8 sys/inttypes.h: + * Use at your own risk. As of February 1996, the committee is squarely + * behind the fixed sized types; the "least" and "fast" types are still being + * discussed. The probability that the "fast" types may be removed before + * the standard is finalized is high enough that they are not currently + * implemented. + */ + +#if defined _STDINT_NEED_INT_LEAST_T +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_least64_t; +#endif + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_least64_t; +#endif + /* least types */ +#endif + +#if defined _STDINT_NEED_INT_FAST_T +typedef int8_t int_fast8_t; +typedef int int_fast16_t; +typedef int32_t int_fast32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_fast64_t; +#endif + +typedef uint8_t uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef uint32_t uint_fast32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_fast64_t; +#endif + /* fast types */ +#endif + +#ifdef _STDINT_NEED_INTMAX_T +#ifdef _HAVE_UINT64_T +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#else +typedef long intmax_t; +typedef unsigned long uintmax_t; +#endif +#endif + +#ifdef _STDINT_NEED_INTPTR_T +#ifndef __intptr_t_defined +#define __intptr_t_defined +/* we encourage using "long" to store pointer values, never use "int" ! */ +#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 +typedef unsinged int uintptr_t; +typedef int intptr_t; +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 +typedef unsigned long uintptr_t; +typedef long intptr_t; +#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; +#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ +typedef unsigned long uintptr_t; +typedef long intptr_t; +#endif +#endif +#endif + + /* shortcircuit*/ +#endif + /* once */ +#endif +#endif +STDINT_EOF + if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then + { echo "$as_me:$LINENO: $ac_stdint_h is unchanged" >&5 +echo "$as_me: $ac_stdint_h is unchanged" >&6;} + else + ac_dir=`$as_dirname -- "$ac_stdint_h" || +$as_expr X"$ac_stdint_h" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_stdint_h" : 'X\(//\)[^/]' \| \ + X"$ac_stdint_h" : 'X\(//\)$' \| \ + X"$ac_stdint_h" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_stdint_h" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`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 || +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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# 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 || { (exit 1); exit 1; } +fi + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..0251ffa --- /dev/null +++ b/configure.ac @@ -0,0 +1,539 @@ +dnl -*- mode: shell-script; sh-indentation: 2; -*- + +dnl Process this file with autoconf to produce a configure script. + +AC_INIT([nettle], [2.1], [nettle-bugs@lists.lysator.liu.se]) +AC_PREREQ(2.61) +AC_CONFIG_SRCDIR([arcfour.c]) +# Needed to stop autoconf from looking for files in parent directories. +AC_CONFIG_AUX_DIR([.]) + +AC_CONFIG_HEADER([config.h]) + +LIBNETTLE_MAJOR=4 +LIBNETTLE_MINOR=0 + +LIBHOGWEED_MAJOR=2 +LIBHOGWEED_MINOR=0 + +AC_CANONICAL_HOST + +# Command line options +AC_ARG_WITH(include-path, + AC_HELP_STRING([--with-include-path], [A colon-separated list of directories to search for include files]),, + [with_include_path='']) + +if test x$with_include_path != x ; then + CPPFLAGS="$CPPFLAGS -I`echo $with_include_path | sed 's/:/ -I/g'`" +fi + +AC_ARG_WITH(lib-path, + AC_HELP_STRING([--with-lib-path], [A colon-separated list of directories to search for libraries]),, + [with_lib_path='']) + +if test x$with_lib_path != x ; then + LDFLAGS="$LDFLAGS -L`echo $with_lib_path | sed 's/:/ -L/g'`" +fi + +AC_ARG_ENABLE(public-key, + AC_HELP_STRING([--disable-public-key], [Disable public key algorithms]),, + [enable_public_key=yes]) + +AC_ARG_ENABLE(assembler, + AC_HELP_STRING([--disable-assembler],[Disable assembler code]),, + [enable_assembler=yes]) + +AC_ARG_ENABLE(shared, + AC_HELP_STRING([--enable-shared], [Build a shared library]),, + [enable_shared=no]) + +AC_ARG_ENABLE(pic, + AC_HELP_STRING([--disable-pic], + [Do not try to compile library files as position independent code]),, + [enable_pic=yes]) + +AC_ARG_ENABLE(openssl, + AC_HELP_STRING([--disable-openssl], [Do not include openssl glue in the benchmark program]),, + [enable_openssl=yes]) + +LSH_RPATH_INIT([`echo $with_lib_path | sed 's/:/ /g'` \ + `echo $exec_prefix | sed "s@^NONE@$prefix/lib@g" | sed "s@^NONE@$ac_default_prefix/lib@g"` \ + /usr/local/lib /sw/local/lib /sw/lib \ + /usr/gnu/lib /opt/gnu/lib /sw/gnu/lib /usr/freeware/lib /usr/pkg/lib]) + +# Checks for programs. +AC_PROG_CC + +# When $CC foo.c -o foo creates both foo and foo.exe, autoconf picks +# up the foo.exe and sets exeext to .exe. That is correct for cygwin, +# which has some kind of magic link from foo to foo.exe, but not for +# rntcl. A better check for the cygwin case would check if the +# contents of foo and foo.exe are equal; in the rntcl case, foo is a +# sh script, and foo.exe is a windows executable. + +if test "x$CC" = xrntcl ; then + AC_MSG_NOTICE([Compiling with rntcl; clearing EXEEXT and disabling assembler]) + ac_exeext='' + ac_cv_exeext='' + EXEEXT='' + enable_assembler=no +fi + +# Used by the testsuite only +AC_PROG_CXX + +AC_LANG_PUSH(C++) +AC_TRY_COMPILE([],[return 0;],[CXX_TESTS='cxx-test$(EXEEXT)'], [CXX_TESTS='']) +AC_SUBST([CXX_TESTS]) +AC_LANG_POP + +AC_PROG_MAKE_SET +AC_PROG_RANLIB +AC_CHECK_TOOL(NM, nm, strings) +# Used only for the GNU-stack configure test. +AC_CHECK_TOOL(OBJDUMP, objdump, false) + +if test "x$ac_cv_prog_cc_stdc" = xno ; then + AC_ERROR([the C compiler doesn't handle ANSI-C]) #' +fi + +AC_PROG_INSTALL + +# According to the autoconf manual, needs install-sh from +# autoconf-2.60 or automake-1.10 to avoid races. +AC_PROG_MKDIR_P + +LSH_DEPENDENCY_TRACKING + +if test x$enable_dependency_tracking = xyes ; then + # Since the makefiles use include to get the dependency files, we must + # make sure that the files exist. We generate some more files than are + # actually needed. + + AC_CONFIG_COMMANDS([dummy-dep-files], + [(cd "$srcdir" && find . -name '*.c' -print) \ + | sed 's/\.c$//' | (while read f; do echo > "$f.o.d"; echo > "$f.po.d"; done) +]) +fi + +# Figure out ABI. Currently, configurable only be setting CFLAGS. +ABI=standard + +case "$host_cpu" in + [x86_64 | amd64]) + AC_TRY_COMPILE([ +#if defined(__x86_64__) || defined(__arch64__) +#error 64-bit x86 +#endif + ], [], [ + ABI=32 + ], [ + ABI=64 + ]) + ;; + *sparc*) + AC_TRY_COMPILE([ +#if defined(__sparcv9) || defined(__arch64__) +#error 64-bit sparc +#endif + ], [], [ + ABI=32 + ], [ + ABI=64 + ]) + ;; +esac + +if test "x$ABI" != xstandard ; then + AC_MSG_NOTICE([Compiler uses $ABI-bit ABI. To change, set CC.]) + if test "$libdir" = '${exec_prefix}/lib' ; then + # Try setting a better default + case "$host_cpu:$host_os:$ABI" in + *:solaris*:32|*:sunos*:32) + libdir='${exec_prefix}/lib' + ;; + *:solaris*:64|*:sunos*:64) + libdir='${exec_prefix}/lib/64' + ;; + # According to the fhs, all architectures except IA64 + # puts 32-bit libraries in lib, and 64-bit in lib64. + *:linux*:32) + libdir='${exec_prefix}/lib' + ;; + *:linux*:64) + libdir='${exec_prefix}/lib64' + ;; + # On freebsd, it seems 32-bit libraries are in lib32, + # and 64-bit in lib. Don't know about "kfreebsd", does + # it follow the Linux fhs conventions? + *:freebsd*:32) + libdir='${exec_prefix}/lib32' + ;; + *:freebsd*:64) + libdir='${exec_prefix}/lib' + ;; + *) + AC_MSG_WARN([Don't know where to install $ABI-bit libraries on this system.]); #' + + esac + AC_MSG_NOTICE([Libraries to be installed in $libdir.]) + fi +fi + +# Select assembler code +asm_path= +case "$host_cpu" in + [i?86* | k[5-8]* | pentium* | athlon]) + asm_path=x86 + ;; + [x86_64 | amd64]) + if test "$ABI" = 64 ; then + asm_path=x86_64 + else + asm_path=x86 + fi + ;; + *sparc*) + if test "$ABI" = 64 ; then + asm_path=sparc64 + else + asm_path=sparc32 + fi + ;; + *) + enable_assembler=no + ;; +esac + +# echo "enable_assembler: $enable_assembler, asm_path: $asm_path" + +if test "x$enable_assembler" = xyes ; then + if test -n "$asm_path"; then + AC_MSG_NOTICE([Looking for assembler files in $asm_path/.]) + found=no + for tmp_f in aes-encrypt-internal.asm aes-decrypt-internal.asm \ + arcfour-crypt.asm camellia-crypt-internal.asm \ + md5-compress.asm sha1-compress.asm machine.m4; do +# echo "Looking for $srcdir/$asm_path/$tmp_f" + if test -f "$srcdir/$asm_path/$tmp_f"; then +# echo found + found=yes + AC_CONFIG_LINKS($tmp_f:$asm_path/$tmp_f) + fi + done + if test "$found" = no; then + enable_assembler=no + AC_MSG_WARN([No assembler files found.]) + fi + fi +fi + +LSH_CCPIC + +SHLIBCFLAGS="$CCPIC" + +case "$host_os" in + cygwin*) + LIBNETTLE_FORLINK='cygnettle-$(LIBNETTLE_MAJOR)-$(LIBNETTLE_MINOR).dll' + LIBNETTLE_SONAME='' + LIBNETTLE_FILE='libnettle.dll.a' + LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_LIBFILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' + LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)' + + LIBHOGWEED_FORLINK='cyghogweed-$(LIBHOGWEED_MAJOR)-$(LIBHOGWEED_MINOR).dll' + LIBHOGWEED_SONAME='' + LIBHOGWEED_FILE='libhogweed.dll.a' + LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_LIBFILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' + LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS)' + ;; + darwin*) + LIBNETTLE_FORLINK=libnettle.dylib + LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)' + LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)' + LIBNETTLE_LINK='$(CC) -dynamiclib $(LDFLAGS)' + LIBNETTLE_LIBS='' + + LIBHOGWEED_FORLINK=libhogweed.dylib + LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)' + LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)' + LIBHOGWEED_LINK='$(CC) -dynamiclib $(LDFLAGS)' + LIBHOGWEED_LIBS='' + ;; + *) + LIBNETTLE_FORLINK=libnettle.so + LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)' + LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)' + LIBNETTLE_LINK='$(CC) $(LDFLAGS) -shared -Wl,-soname=$(LIBNETTLE_SONAME)' + LIBNETTLE_LIBS='' + + LIBHOGWEED_FORLINK=libhogweed.so + LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)' + LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)' + LIBHOGWEED_LINK='$(CC) $(LDFLAGS) -L. -shared -Wl,-soname=$(LIBHOGWEED_SONAME)' + # Requested by debian, to make linking with only -lhogweed work + # (does not work in general, e.g., with static linking all of + # -lhogweed -lgmp -lnettle are still required). Also makes dlopen + # of libhogweed.so work, without having to use RTLD_GLOBAL. + # Depends on -L. above, to locate nettle.so. + LIBHOGWEED_LIBS='-lnettle -lgmp' + ;; +esac + +if test "x$enable_pic" = xyes; then + CCPIC_MAYBE="$CCPIC" +else + CCPIC_MAYBE='' +fi +AC_SUBST([CCPIC_MAYBE]) + +ASM_SYMBOL_PREFIX='' +ASM_ELF_STYLE='no' +ASM_TYPE_FUNCTION='' +ASM_MARK_NOEXEC_STACK='' +ASM_ALIGN_LOG='' + +if test x$enable_assembler = xyes ; then + AC_CACHE_CHECK([if globals are prefixed by underscore], + nettle_cv_asm_underscore, + [ # Default is no underscore + nettle_cv_asm_underscore=no + AC_COMPILE_IFELSE( + [int a_global_symbol;], + [ $NM conftest.$OBJEXT >conftest.out + if grep _a_global_symbol conftest.out >/dev/null ; then + nettle_cv_asm_underscore=yes + elif grep a_global_symbol conftest.out >/dev/null ; then + nettle_cv_asm_underscore=no + else + AC_MSG_WARN([nm doesn't list a_global_symbol at all]) + fi], + [AC_MSG_WARN([test program with a single global could not be compiled!?])])]) + if test x$nettle_cv_asm_underscore = xyes ; then + ASM_SYMBOL_PREFIX='_' + fi + + AC_CACHE_CHECK([if we should use a .note.GNU-stack section], + nettle_cv_asm_gnu_stack, + [ # Default + nettle_cv_asm_gnu_stack=no + + cat >conftest.c <&AC_FD_CC + $OBJDUMP -x conftest.o | grep '\.note\.GNU-stack' > /dev/null \ + && nettle_cv_asm_gnu_stack=yes + else + cat conftest.out >&AC_FD_CC + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.s >&AC_FD_CC + fi + rm -f conftest.*]) + if test x$nettle_cv_asm_gnu_stack = xyes ; then + ASM_MARK_NOEXEC_STACK='.section .note.GNU-stack,"",@progbits' + fi + + AC_CACHE_CHECK([for ELF-style .type,%function pseudo-ops], + [nettle_cv_asm_type_percent_function], + [GMP_TRY_ASSEMBLE([ +.text +.globl foo +.type foo,%function +foo: +.Lend: + +.size foo, .Lend - foo +], + [nettle_cv_asm_type_percent_function=yes], + [nettle_cv_asm_type_percent_function=no])]) + +dnl Needs double quote for the # character + AC_CACHE_CHECK([[for ELF-style .type,#function pseudo-ops]], + [nettle_cv_asm_type_hash_function], + [GMP_TRY_ASSEMBLE([ +.text +.globl foo +.type foo,#function +foo: +.Lend: + +.size foo, .Lend - foo +], + [nettle_cv_asm_type_hash_function=yes], + [nettle_cv_asm_type_hash_function=no])]) + + if test x$nettle_cv_asm_type_percent_function = xyes ; then + ASM_ELF_STYLE='yes' + ASM_TYPE_FUNCTION='%function' + else + if test x$nettle_cv_asm_type_hash_function = xyes ; then + ASM_ELF_STYLE='yes' + ASM_TYPE_FUNCTION='#function' + fi + fi + AC_CACHE_CHECK([if .align assembly directive is logarithmic], + [nettle_cv_asm_align_log], + [GMP_TRY_ASSEMBLE([ +.align 3 +], + [nettle_cv_asm_align_log=yes], + [nettle_cv_asm_align_log=no])]) + if test x$nettle_cv_asm_align_log = xyes ; then + ASM_ALIGN_LOG='yes' + fi +fi + +AC_SUBST(ASM_SYMBOL_PREFIX) +AC_SUBST(ASM_ELF_STYLE) +AC_SUBST(ASM_TYPE_FUNCTION) +AC_SUBST(ASM_MARK_NOEXEC_STACK) +AC_SUBST(ASM_ALIGN_LOG) + +AC_SUBST(SHLIBCFLAGS) + +AC_SUBST(LIBNETTLE_MAJOR) +AC_SUBST(LIBNETTLE_MINOR) +AC_SUBST(LIBNETTLE_FORLINK) +AC_SUBST(LIBNETTLE_SONAME) +AC_SUBST(LIBNETTLE_FILE) +AC_SUBST(LIBNETTLE_LINK) +AC_SUBST(LIBNETTLE_LIBS) + +AC_SUBST(LIBHOGWEED_MAJOR) +AC_SUBST(LIBHOGWEED_MINOR) +AC_SUBST(LIBHOGWEED_FORLINK) +AC_SUBST(LIBHOGWEED_SONAME) +AC_SUBST(LIBHOGWEED_FILE) +AC_SUBST(LIBHOGWEED_LINK) +AC_SUBST(LIBHOGWEED_LIBS) + +AC_PATH_PROG(M4, m4, m4) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_UID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +# Used by eratosthenes.c +AC_CHECK_SIZEOF(long) + +AC_CHECK_HEADERS([openssl/blowfish.h openssl/des.h openssl/cast.h openssl/aes.h],, +[enable_openssl=no + break]) + +LSH_FUNC_ALLOCA + +# Needed by the supplied memcmp.c +AC_C_BIGENDIAN +AC_REPLACE_FUNCS(memxor) + +LSH_GCC_ATTRIBUTES + +# According to Simon Josefsson, looking for uint32_t and friends in +# sys/types.h is needed on some systems, in particular cygwin. +AX_CREATE_STDINT_H([nettle-stdint.h], [sys/types.h]) + +# Check for file locking. We (AC_PROG_CC?) have already checked for +# sys/types.h and unistd.h. +AC_CACHE_CHECK([for fcntl file locking], + nettle_cv_fcntl_locking, +[AC_TRY_COMPILE([ +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +#include +],[ +int op = F_SETLKW; +struct flock fl; +], +nettle_cv_fcntl_locking=yes, +nettle_cv_fcntl_locking=no)]) + +AH_TEMPLATE([HAVE_FCNTL_LOCKING], [Define if fcntl file locking is available]) +if test "x$nettle_cv_fcntl_locking" = "xyes" ; then + AC_DEFINE(HAVE_FCNTL_LOCKING) +fi + +# Checks for libraries +AC_CHECK_LIB(gmp, __gmpz_getlimbn,, + [AC_MSG_WARN( +[GNU MP not found, or not 3.1 or up, see http://www.swox.com/gmp. +Support for public key algorithms will be unavailable.])] + enable_public_key=no) + +# Add -R flags needed to run programs linked with gmp +LSH_RPATH_FIX + +AH_TEMPLATE([HAVE_MPZ_POWM_SEC], [Define if mpz_powm_sec is available (appeared in GMP-5)]) +AC_CHECK_FUNC(__gmpz_powm_sec, [AC_DEFINE(HAVE_MPZ_POWM_SEC)]) + +AH_TEMPLATE([WITH_HOGWEED], [Defined if public key features are enabled]) + +if test "x$enable_public_key" = xyes ; then + AC_DEFINE(WITH_HOGWEED) + IF_HOGWEED='' +else + IF_HOGWEED='#' +fi + +if test "x$enable_shared" = xyes ; then + IF_SHARED='' +else + IF_SHARED='#' +fi + +AC_SUBST(IF_HOGWEED) +AC_SUBST(IF_SHARED) + +OPENSSL_LIBFLAGS='' + +# Check for openssl's libcrypto (used only for benchmarking) +if test x$enable_openssl = xyes ; then + AC_CHECK_LIB(crypto, BF_ecb_encrypt, + [OPENSSL_LIBFLAGS='-lcrypto'], + [enable_openssl=no]) +fi + +AH_TEMPLATE([WITH_OPENSSL], + [Define if you have openssl's libcrypto (used for benchmarking)]) + +if test x$enable_openssl = xyes ; then + AC_DEFINE(WITH_OPENSSL) +fi + +AC_SUBST(OPENSSL_LIBFLAGS) + +# Set these flags *last*, or else the test programs won't compile +if test x$GCC = xyes ; then + # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core + if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then + true + else + CFLAGS="$CFLAGS -ggdb3" + fi + # FIXME: It would be better to actually test if this option works and/or is needed. + # Or perhaps use -funsigned-char. + if "$CC" --version | grep 'gcc.* 4\.' 1>/dev/null 2>&1; then + CFLAGS="$CFLAGS -Wno-pointer-sign" + fi + CFLAGS="$CFLAGS -Wall -W \ + -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ + -Wpointer-arith -Wbad-function-cast -Wnested-externs" + +# Don't enable -Wcast-align as it results in tons of warnings in the +# DES code. And when using stdio. +# Don't enable -Waggregate-return, as that causes warnings for glibc +# inttypes.h. +fi + +AC_CONFIG_FILES([config.make config.m4 Makefile]) +AC_CONFIG_FILES([tools/Makefile testsuite/Makefile examples/Makefile]) + +AC_OUTPUT + diff --git a/ctr.c b/ctr.c new file mode 100644 index 0000000..25ce7f8 --- /dev/null +++ b/ctr.c @@ -0,0 +1,84 @@ +/* ctr.c + * + * Cipher counter mode. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "ctr.h" + +#include "memxor.h" +#include "nettle-internal.h" + +#define INCREMENT(size, counter, i) \ +do { \ + if (++(ctr)[(size) - 1] == 0) \ + { \ + unsigned i = size - 1; \ + while (i > 0 && ++(ctr)[--i] == 0) \ + ; \ + } \ +} while (0) + +void +ctr_crypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *ctr, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + TMP_ALLOC(buffer, block_size); + + if (src != dst) + { + for (; length >= block_size; length -= block_size, src += block_size, dst += block_size) + { + f(ctx, block_size, dst, ctr); + memxor(dst, src, block_size); + INCREMENT(block_size, ctr, i); + } + } + else + { + for (; length >= block_size; length -= block_size, src += block_size, dst += block_size) + { + f(ctx, block_size, buffer, ctr); + memxor3(dst, src, buffer, block_size); + INCREMENT(block_size, ctr, i); + } + } + if (length > 0) + { + /* A final partial block */ + + f(ctx, block_size, buffer, ctr); + memxor3(dst, src, buffer, length); + INCREMENT(block_size, ctr, i); + } +} diff --git a/ctr.h b/ctr.h new file mode 100644 index 0000000..80abb6e --- /dev/null +++ b/ctr.h @@ -0,0 +1,62 @@ +/* ctr.h + * + * Counter mode, using an network byte order incremented counter, + * matching the testcases of NIST 800-38A. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_CTR_H_INCLUDED +#define NETTLE_CTR_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define ctr_crypt nettle_ctr_crypt + +void +ctr_crypt(void *ctx, nettle_crypt_func f, + unsigned block_size, uint8_t *ctr, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#define CTR_CTX(type, size) \ +{ type ctx; uint8_t ctr[size]; } + +#define CTR_SET_COUNTER(ctx, data) \ +memcpy((ctx)->ctr, (data), sizeof((ctx)->ctr)) + +#define CTR_CRYPT(self, f, length, dst, src) \ +(0 ? ((f)(&(self)->ctx, 0, NULL, NULL)) \ + : ctr_crypt((void *) &(self)->ctx, \ + (nettle_crypt_func) (f), \ + sizeof((self)->ctr), (self)->ctr, \ + (length), (dst), (src))) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CTR_H_INCLUDED */ diff --git a/der-iterator.c b/der-iterator.c new file mode 100644 index 0000000..a724471 --- /dev/null +++ b/der-iterator.c @@ -0,0 +1,272 @@ +/* der-iterator.c + * + * Parses DER encoded objects. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#if HAVE_LIBGMP +#include "bignum.h" +#endif + +#include "asn1.h" + +#include "macros.h" + +/* Basic DER syntax: (reference: A Layman's Guide to a Subset of ASN.1, BER, and DER, + http://luca.ntop.org/Teaching/Appunti/asn1.html) + + The DER header contains a tag and a length. First, the tag. cls is + the class number, c is one if the object is "constructed" and zero + if it is primitive. The tag is represented either using a single + byte, + + 7 6 5 4 3 2 1 0 + _____________________ + |_cls_|_c_|_______tag_| 0 <= tag <= 30 + + or multiple bytes + + 7 6 5 4 3 2 1 0 + _____________________ + |_cls_|_c_|_1_1_1_1_1_| + + followed by the real tag number, in base 128, with all but the + final byte having the most significant bit set. The tag must be + represented with as few bytes as possible. High tag numbers are + currently *not* supported. + + Next, the length, either a single byte with the most significant bit clear, or + + 7 6 5 4 3 2 1 0 + _________________ + |_1_|___________k_| + + followed by k additional bytes that give the length, in network + byte order. The length must be encoded using as few bytes as + possible, and k = 0 is reserved for the "indefinite length form" + which is not supported. + + After the length comes the contets. For primitive objects (c == 0), + it's depends on the type. For constructed objects, it's a + concatenation of the DER encodings of zero or more other objects. +*/ + +enum { + TAG_MASK = 0x1f, + CLASS_MASK = 0xc0, + CONSTRUCTED_MASK = 0x20, +}; + +/* Initializes the iterator, but one has to call next to get to the + * first element. */ +static void +asn1_der_iterator_init(struct asn1_der_iterator *iterator, + unsigned length, const uint8_t *input) +{ + iterator->buffer_length = length; + iterator->buffer = input; + iterator->pos = 0; + iterator->type = 0; + iterator->length = 0; + iterator->data = NULL; +} + +#define LEFT(i) ((i)->buffer_length - (i)->pos) +#define NEXT(i) ((i)->buffer[(i)->pos++]) + +/* Gets type and length of the next object. */ +enum asn1_iterator_result +asn1_der_iterator_next(struct asn1_der_iterator *i) +{ + uint8_t tag; + + if (!LEFT(i)) + return ASN1_ITERATOR_END; + + tag = NEXT(i); + if (!LEFT(i)) + return ASN1_ITERATOR_ERROR; + + if ( (tag & TAG_MASK) == TAG_MASK) + { + /* FIXME: Long tags not supported */ + return ASN1_ITERATOR_ERROR; + } + + i->length = NEXT(i); + if (i->length & 0x80) + { + unsigned k = i->length & 0x7f; + unsigned j; + const uint8_t *data = i->buffer + i->pos; + + if (k == 0) + /* Indefinite encoding. Not supported. */ + return ASN1_ITERATOR_ERROR; + + if (LEFT(i) < k) + return ASN1_ITERATOR_ERROR; + + if (k > sizeof(unsigned)) + return ASN1_ITERATOR_ERROR; + + i->pos += k; + i->length = data[0]; + if (i->length == 0 + || (k == 1 && i->length < 0x80)) + return ASN1_ITERATOR_ERROR; + + for (j = 1; j < k; j++) + i->length = (i->length << 8) | data[j]; + } + if (LEFT(i) < i->length) + return ASN1_ITERATOR_ERROR; + + i->data = i->buffer + i->pos; + i->pos += i->length; + + i->type = tag & TAG_MASK; + i->type |= (tag & CLASS_MASK) << (ASN1_CLASS_SHIFT - 6); + if (tag & CONSTRUCTED_MASK) + { + i->type |= ASN1_TYPE_CONSTRUCTED; + return ASN1_ITERATOR_CONSTRUCTED; + } + else + return ASN1_ITERATOR_PRIMITIVE; +} + +enum asn1_iterator_result +asn1_der_iterator_first(struct asn1_der_iterator *i, + unsigned length, const uint8_t *input) +{ + asn1_der_iterator_init(i, length, input); + return asn1_der_iterator_next(i); +} + +enum asn1_iterator_result +asn1_der_decode_constructed(struct asn1_der_iterator *i, + struct asn1_der_iterator *contents) +{ + assert(i->type & ASN1_TYPE_CONSTRUCTED); + return asn1_der_iterator_first(contents, i->length, i->data); +} + +enum asn1_iterator_result +asn1_der_decode_constructed_last(struct asn1_der_iterator *i) +{ + if (LEFT(i) > 0) + return ASN1_ITERATOR_ERROR; + + return asn1_der_decode_constructed(i, i); +} + +/* Decoding a DER object which is wrapped in a bit string. */ +enum asn1_iterator_result +asn1_der_decode_bitstring(struct asn1_der_iterator *i, + struct asn1_der_iterator *contents) +{ + assert(i->type == ASN1_BITSTRING); + /* First byte is the number of padding bits, which must be zero. */ + if (i->length == 0 || i->data[0] != 0) + return ASN1_ITERATOR_ERROR; + + return asn1_der_iterator_first(contents, i->length - 1, i->data + 1); +} + +enum asn1_iterator_result +asn1_der_decode_bitstring_last(struct asn1_der_iterator *i) +{ + if (LEFT(i) > 0) + return ASN1_ITERATOR_ERROR; + + return asn1_der_decode_bitstring(i, i); +} + +int +asn1_der_get_uint32(struct asn1_der_iterator *i, + uint32_t *x) +{ + /* Big endian, two's complement, minimum number of octets (except 0, + which is encoded as a single octet */ + uint32_t value = 0; + unsigned length = i->length; + unsigned k; + + if (!length || length > 5) + return 0; + + if (i->data[length - 1] >= 0x80) + /* Signed number */ + return 0; + + if (length > 1 + && i->data[length -1] == 0 + && i->data[length -2] < 0x80) + /* Non-minimal number of digits */ + return 0; + + if (length == 5) + { + if (i->data[4]) + return 0; + length--; + } + + for (value = k = 0; k < length; k++) + value = (value << 8) | i->data[k]; + + *x = value; + return 1; +} + +#if HAVE_LIBGMP +int +asn1_der_get_bignum(struct asn1_der_iterator *i, + mpz_t x, unsigned max_bits) +{ + if (i->length > 1 + && ((i->data[0] == 0 && i->data[1] < 0x80) + || (i->data[0] == 0xff && i->data[1] >= 0x80))) + /* Non-minimal number of digits */ + return 0; + + /* Allow some extra here, for leading sign octets. */ + if (max_bits && (8 * i->length > (16 + max_bits))) + return 0; + + nettle_mpz_set_str_256_s(x, i->length, i->data); + + /* FIXME: How to interpret a max_bits for negative numbers? */ + if (max_bits && mpz_sizeinbase(x, 2) > max_bits) + return 0; + + return 1; +} +#endif /* HAVE_LIBGMP */ diff --git a/der2dsa.c b/der2dsa.c new file mode 100644 index 0000000..206c714 --- /dev/null +++ b/der2dsa.c @@ -0,0 +1,119 @@ +/* der2dsa.c + * + * Decoding of DSA keys in OpenSSL and X509.1 format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +#include "bignum.h" +#include "asn1.h" + +#define GET(i, x, l) \ +(asn1_der_iterator_next((i)) == ASN1_ITERATOR_PRIMITIVE \ + && (i)->type == ASN1_INTEGER \ + && asn1_der_get_bignum((i), (x), (l)) \ + && mpz_sgn((x)) > 0) + +int +dsa_params_from_der_iterator(struct dsa_public_key *pub, + unsigned p_max_bits, + struct asn1_der_iterator *i) +{ + /* Dss-Parms ::= SEQUENCE { + p INTEGER, + q INTEGER, + g INTEGER + } + */ + return (i->type == ASN1_INTEGER + && asn1_der_get_bignum(i, pub->p, p_max_bits) + && mpz_sgn(pub->p) > 0 + && GET(i, pub->q, DSA_SHA1_Q_BITS) + && GET(i, pub->g, p_max_bits) + && asn1_der_iterator_next(i) == ASN1_ITERATOR_END); +} + +int +dsa_public_key_from_der_iterator(struct dsa_public_key *pub, + unsigned p_max_bits, + struct asn1_der_iterator *i) +{ + /* DSAPublicKey ::= INTEGER + */ + + return (i->type == ASN1_INTEGER + && asn1_der_get_bignum(i, pub->y, p_max_bits) + && mpz_sgn(pub->y) > 0); +} + +/* FIXME: Rename this and the next function to something + openssl-specific? */ +int +dsa_openssl_private_key_from_der_iterator(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + struct asn1_der_iterator *i) +{ + /* DSAPrivateKey ::= SEQUENCE { + version Version, + p INTEGER, + q INTEGER, + g INTEGER, + pub_key INTEGER, -- y + priv_key INTEGER, -- x + } + */ + + uint32_t version; + + return (i->type == ASN1_SEQUENCE + && asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE + && i->type == ASN1_INTEGER + && asn1_der_get_uint32(i, &version) + && version == 0 + && GET(i, pub->p, p_max_bits) + && GET(i, pub->q, DSA_SHA1_Q_BITS) + && GET(i, pub->g, p_max_bits) + && GET(i, pub->y, p_max_bits) + && GET(i, priv->x, DSA_SHA1_Q_BITS) + && asn1_der_iterator_next(i) == ASN1_ITERATOR_END); +} + +int +dsa_openssl_private_key_from_der(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned length, const uint8_t *data) +{ + struct asn1_der_iterator i; + enum asn1_iterator_result res; + + res = asn1_der_iterator_first(&i, length, data); + + return (res == ASN1_ITERATOR_CONSTRUCTED + && dsa_openssl_private_key_from_der_iterator(pub, priv, p_max_bits, &i)); +} diff --git a/der2rsa.c b/der2rsa.c new file mode 100644 index 0000000..679b336 --- /dev/null +++ b/der2rsa.c @@ -0,0 +1,133 @@ +/* der2rsa.c + * + * Decoding of keys in PKCS#1 format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa.h" + +#include "bignum.h" +#include "asn1.h" + +#define GET(i, x, l) \ +(asn1_der_iterator_next((i)) == ASN1_ITERATOR_PRIMITIVE \ + && (i)->type == ASN1_INTEGER \ + && asn1_der_get_bignum((i), (x), (l)) \ + && mpz_sgn((x)) > 0) + +int +rsa_public_key_from_der_iterator(struct rsa_public_key *pub, + unsigned limit, + struct asn1_der_iterator *i) +{ + /* RSAPublicKey ::= SEQUENCE { + modulus INTEGER, -- n + publicExponent INTEGER -- e + } + */ + + return (i->type == ASN1_SEQUENCE + && asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE + && asn1_der_get_bignum(i, pub->n, limit) + && mpz_sgn(pub->n) > 0 + && GET(i, pub->e, limit) + && asn1_der_iterator_next(i) == ASN1_ITERATOR_END + && rsa_public_key_prepare(pub)); +} + +int +rsa_private_key_from_der_iterator(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + struct asn1_der_iterator *i) +{ + /* RSAPrivateKey ::= SEQUENCE { + version Version, + modulus INTEGER, -- n + publicExponent INTEGER, -- e + privateExponent INTEGER, -- d + prime1 INTEGER, -- p + prime2 INTEGER, -- q + exponent1 INTEGER, -- d mod (p-1) + exponent2 INTEGER, -- d mod (q-1) + coefficient INTEGER, -- (inverse of q) mod p + otherPrimeInfos OtherPrimeInfos OPTIONAL + } + */ + + uint32_t version; + + if (i->type != ASN1_SEQUENCE) + return 0; + + if (asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE + && i->type == ASN1_INTEGER + && asn1_der_get_uint32(i, &version) + && version <= 1 + && GET(i, pub->n, limit) + && GET(i, pub->e, limit) + && rsa_public_key_prepare(pub) + && GET(i, priv->d, limit) + && GET(i, priv->p, limit) + && GET(i, priv->q, limit) + && GET(i, priv->a, limit) + && GET(i, priv->b, limit) + && GET(i, priv->c, limit) + && rsa_private_key_prepare(priv)) + { + if (version == 1) + { + /* otherPrimeInfos must be present. We ignore the contents */ + if (!(asn1_der_iterator_next(i) == ASN1_ITERATOR_CONSTRUCTED + && i->type == ASN1_SEQUENCE)) + return 0; + } + + return (asn1_der_iterator_next(i) == ASN1_ITERATOR_END); + } + + return 0; +} + +int +rsa_keypair_from_der(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + unsigned length, const uint8_t *data) +{ + struct asn1_der_iterator i; + enum asn1_iterator_result res; + + res = asn1_der_iterator_first(&i, length, data); + + if (res != ASN1_ITERATOR_CONSTRUCTED) + return 0; + + if (priv) + return rsa_private_key_from_der_iterator(pub, priv, limit, &i); + else + return rsa_public_key_from_der_iterator(pub, limit, &i); +} diff --git a/des-compat.c b/des-compat.c new file mode 100644 index 0000000..cd8cd1d --- /dev/null +++ b/des-compat.c @@ -0,0 +1,222 @@ +/* des-compat.h + * + * The des block cipher, libdes/openssl-style interface. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "des-compat.h" + +#include "cbc.h" +#include "macros.h" +#include "memxor.h" + +struct des_compat_des3 { const struct des_ctx *keys[3]; }; + +static void +des_compat_des3_encrypt(struct des_compat_des3 *ctx, + uint32_t length, uint8_t *dst, const uint8_t *src) +{ + nettle_des_encrypt(ctx->keys[0], length, dst, src); + nettle_des_decrypt(ctx->keys[1], length, dst, dst); + nettle_des_encrypt(ctx->keys[2], length, dst, dst); +} + +static void +des_compat_des3_decrypt(struct des_compat_des3 *ctx, + uint32_t length, uint8_t *dst, const uint8_t *src) +{ + nettle_des_decrypt(ctx->keys[2], length, dst, src); + nettle_des_encrypt(ctx->keys[1], length, dst, dst); + nettle_des_decrypt(ctx->keys[0], length, dst, dst); +} + +void +des_ecb3_encrypt(const_des_cblock *src, des_cblock *dst, + des_key_schedule k1, + des_key_schedule k2, + des_key_schedule k3, int enc) +{ + struct des_compat_des3 keys; + keys.keys[0] = k1; + keys.keys[1] = k2; + keys.keys[2] = k3; + + ((enc == DES_ENCRYPT) ? des_compat_des3_encrypt : des_compat_des3_decrypt) + (&keys, DES_BLOCK_SIZE, *dst, *src); +} + +/* If input is not a integral number of blocks, the final block is + padded with zeros, no length field or anything like that. That's + pretty broken, since it means that "$100" and "$100\0" always have + the same checksum, but I think that's how it's supposed to work. */ +uint32_t +des_cbc_cksum(const uint8_t *src, des_cblock *dst, + long length, des_key_schedule ctx, + const_des_cblock *iv) +{ + /* FIXME: I'm not entirely sure how this function is supposed to + * work, in particular what it should return, and if iv can be + * modified. */ + uint8_t block[DES_BLOCK_SIZE]; + + memcpy(block, *iv, DES_BLOCK_SIZE); + + while (length >= DES_BLOCK_SIZE) + { + memxor(block, src, DES_BLOCK_SIZE); + nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block); + + src += DES_BLOCK_SIZE; + length -= DES_BLOCK_SIZE; + } + if (length > 0) + { + memxor(block, src, length); + nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block); + } + memcpy(*dst, block, DES_BLOCK_SIZE); + + return LE_READ_UINT32(block + 4); +} + +void +des_ncbc_encrypt(const_des_cblock *src, des_cblock *dst, long length, + des_key_schedule ctx, des_cblock *iv, + int enc) +{ + switch (enc) + { + case DES_ENCRYPT: + nettle_cbc_encrypt(ctx, (nettle_crypt_func *) des_encrypt, + DES_BLOCK_SIZE, *iv, + length, *dst, *src); + break; + case DES_DECRYPT: + nettle_cbc_decrypt(ctx, + (nettle_crypt_func *) des_decrypt, + DES_BLOCK_SIZE, *iv, + length, *dst, *src); + break; + default: + abort(); + } +} + +void +des_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length, + des_key_schedule ctx, const_des_cblock *civ, + int enc) +{ + des_cblock iv; + + memcpy(iv, civ, DES_BLOCK_SIZE); + + des_ncbc_encrypt(src, dst, length, ctx, &iv, enc); +} + + +void +des_ecb_encrypt(const_des_cblock *src, des_cblock *dst, + des_key_schedule ctx, + int enc) +{ + ((enc == DES_ENCRYPT) ? nettle_des_encrypt : nettle_des_decrypt) + (ctx, DES_BLOCK_SIZE, *dst, *src); +} + +void +des_ede3_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length, + des_key_schedule k1, + des_key_schedule k2, + des_key_schedule k3, + des_cblock *iv, + int enc) +{ + struct des_compat_des3 keys; + keys.keys[0] = k1; + keys.keys[1] = k2; + keys.keys[2] = k3; + + switch (enc) + { + case DES_ENCRYPT: + nettle_cbc_encrypt(&keys, (nettle_crypt_func *) des_compat_des3_encrypt, + DES_BLOCK_SIZE, *iv, + length, *dst, *src); + break; + case DES_DECRYPT: + nettle_cbc_decrypt(&keys, (nettle_crypt_func *) des_compat_des3_decrypt, + DES_BLOCK_SIZE, *iv, + length, *dst, *src); + break; + default: + abort(); + } +} + +int +des_set_odd_parity(des_cblock *key) +{ + nettle_des_fix_parity(DES_KEY_SIZE, *key, *key); + + /* FIXME: What to return? */ + return 0; +} + + +/* If des_check_key is non-zero, returns + * + * 0 for ok, -1 for bad parity, and -2 for weak keys. + * + * If des_check_key is zero (the default), always returns zero. + */ + +int des_check_key = 0; + +int +des_key_sched(const_des_cblock *key, des_key_schedule ctx) +{ + if (des_check_key && !des_check_parity (DES_KEY_SIZE, *key)) + /* Bad parity */ + return -1; + + if (!nettle_des_set_key(ctx, *key) && des_check_key) + /* Weak key */ + return -2; + + return 0; +} + +int +des_is_weak_key(const_des_cblock *key) +{ + struct des_ctx ctx; + + return !nettle_des_set_key(&ctx, *key); +} diff --git a/des-compat.h b/des-compat.h new file mode 100644 index 0000000..8aab3bc --- /dev/null +++ b/des-compat.h @@ -0,0 +1,154 @@ +/* des-compat.h + * + * The des block cipher, libdes/openssl-style interface. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_DES_COMPAT_H_INCLUDED +#define NETTLE_DES_COMPAT_H_INCLUDED + +/* According to Assar, des_set_key, des_set_key_odd_parity, + * des_is_weak_key, plus the encryption functions (des_*_encrypt and + * des_cbc_cksum) would be a pretty useful subset. */ + +/* NOTE: This is quite experimental, and not all functions are + * implemented. Contributions, in particular test cases are welcome. */ + +#include "des.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* We use some name mangling, to avoid collisions with either other + * nettle functions or with libcrypto. */ + +#define des_ecb3_encrypt nettle_openssl_des_ecb3_encrypt +#define des_cbc_cksum nettle_openssl_des_cbc_cksum +#define des_ncbc_encrypt nettle_openssl_des_ncbc_encrypt +#define des_cbc_encrypt nettle_openssl_des_cbc_encrypt +#define des_ecb_encrypt nettle_openssl_des_ecb_encrypt +#define des_ede3_cbc_encrypt nettle_openssl_des_ede3_cbc_encrypt +#define des_set_odd_parity nettle_openssl_des_set_odd_parity +#define des_check_key nettle_openssl_des_check_key +#define des_key_sched nettle_openssl_des_key_sched +#define des_is_weak_key nettle_openssl_des_is_weak_key + +/* An extra alias */ +#undef des_set_key +#define des_set_key nettle_openssl_des_key_sched + +enum { DES_DECRYPT = 0, DES_ENCRYPT = 1 }; + +/* Types */ +typedef uint32_t DES_LONG; + +/* Note: Typedef:ed arrays should be avoided, but they're used here + * for compatibility. */ +typedef struct des_ctx des_key_schedule[1]; + +typedef uint8_t des_cblock[DES_BLOCK_SIZE]; +/* Note: The proper definition, + + typedef const uint8_t const_des_cblock[DES_BLOCK_SIZE]; + + would have worked, *if* all the prototypes had used arguments like + foo(const_des_cblock src, des_cblock dst), letting argument arrays + "decay" into pointers of type uint8_t * and const uint8_t *. + + But since openssl's prototypes use *pointers* const_des_cblock *src, + des_cblock *dst, this ends up in type conflicts, and the workaround + is to not use const at all. +*/ +#define const_des_cblock des_cblock + +/* Aliases */ +#define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +/* Global flag */ +extern int des_check_key; + +/* Prototypes */ + +/* Typing is a little confusing. Since both des_cblock and + des_key_schedule are typedef:ed arrays, it automatically decay to + a pointers. + + But the functions are declared taking pointers to des_cblock, i.e. + pointers to arrays. And on the other hand, they take plain + des_key_schedule arguments, which is equivalent to pointers to + struct des_ctx. */ +void +des_ecb3_encrypt(const_des_cblock *src, des_cblock *dst, + des_key_schedule k1, + des_key_schedule k2, + des_key_schedule k3, int enc); + +/* des_cbc_cksum in libdes returns a 32 bit integer, representing the + * latter half of the output block, using little endian byte order. */ +uint32_t +des_cbc_cksum(const uint8_t *src, des_cblock *dst, + long length, des_key_schedule ctx, + const_des_cblock *iv); + +/* NOTE: Doesn't update iv. */ +void +des_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length, + des_key_schedule ctx, const_des_cblock *iv, + int enc); + +/* Similar, but updates iv. */ +void +des_ncbc_encrypt(const_des_cblock *src, des_cblock *dst, long length, + des_key_schedule ctx, des_cblock *iv, + int enc); + +void +des_ecb_encrypt(const_des_cblock *src, des_cblock *dst, + des_key_schedule ctx, int enc); + +void +des_ede3_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length, + des_key_schedule k1, + des_key_schedule k2, + des_key_schedule k3, + des_cblock *iv, + int enc); + +int +des_set_odd_parity(des_cblock *key); + +int +des_key_sched(const_des_cblock *key, des_key_schedule ctx); + +int +des_is_weak_key(const_des_cblock *key); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DES_COMPAT_H_INCLUDED */ diff --git a/des.c b/des.c new file mode 100644 index 0000000..7faadd0 --- /dev/null +++ b/des.c @@ -0,0 +1,296 @@ +/* des.c + * + * The des block cipher. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* des - fast & portable DES encryption & decryption. + * Copyright (C) 1992 Dana L. How + * Please see the file `descore.README' for the complete copyright notice. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "des.h" + +#include "desCode.h" + +/* various tables */ + +static const uint32_t +des_keymap[] = { +#include "keymap.h" +}; + +static const uint8_t +rotors[] = { +#include "rotors.h" +}; + +static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS) +static DECRYPT(DesSmallFipsDecrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS) + +/* If parity bits are used, keys should have odd parity. We use a + small table, to not waste any memory on this fairly obscure DES + feature. */ + +static const unsigned +parity_16[16] = +{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + +#define PARITY(x) (parity_16[(x)&0xf] ^ parity_16[((x)>>4) & 0xf]) + +int +des_check_parity(unsigned length, const uint8_t *key) +{ + unsigned i; + for (i = 0; i> 1; + int8_t k1 = key[1] >> 1; + + unsigned hash = asso_values[k1 + 1] + asso_values[k0]; + const int8_t *candidate = weak_key_hash[hash]; + + if (hash > 25) + return 0; + if (k0 != candidate[0] + || k1 != candidate[1]) + return 0; + + if ( (key[2] >> 1) != k0 + || (key[3] >> 1) != k1) + return 0; + + k0 = key[4] >> 1; + k1 = key[5] >> 1; + if (k0 != candidate[2] + || k1 != candidate[3]) + return 0; + if ( (key[6] >> 1) != k0 + || (key[7] >> 1) != k1) + return 0; + + return 1; +} + +int +des_set_key(struct des_ctx *ctx, const uint8_t *key) +{ + register uint32_t n, w; + register char * b0, * b1; + char bits0[56], bits1[56]; + uint32_t *method; + const uint8_t *k; + + /* explode the bits */ + n = 56; + b0 = bits0; + b1 = bits1; + k = key; + do { + w = (256 | *k++) << 2; + do { + --n; + b1[n] = 8 & w; + w >>= 1; + b0[n] = 4 & w; + } while ( w >= 16 ); + } while ( n ); + + /* put the bits in the correct places */ + n = 16; + k = rotors; + method = ctx->key; + + do { + w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4; + w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2; + w |= b1[k[ 4 ]] | b0[k[ 5 ]]; + w <<= 8; + w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4; + w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2; + w |= b1[k[10 ]] | b0[k[11 ]]; + w <<= 8; + w |= (b1[k[12 ]] | b0[k[13 ]]) << 4; + w |= (b1[k[14 ]] | b0[k[15 ]]) << 2; + w |= b1[k[16 ]] | b0[k[17 ]]; + w <<= 8; + w |= (b1[k[18 ]] | b0[k[19 ]]) << 4; + w |= (b1[k[20 ]] | b0[k[21 ]]) << 2; + w |= b1[k[22 ]] | b0[k[23 ]]; + + method[0] = w; + + w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4; + w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2; + w |= b1[k[ 4+24]] | b0[k[ 5+24]]; + w <<= 8; + w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4; + w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2; + w |= b1[k[10+24]] | b0[k[11+24]]; + w <<= 8; + w |= (b1[k[12+24]] | b0[k[13+24]]) << 4; + w |= (b1[k[14+24]] | b0[k[15+24]]) << 2; + w |= b1[k[16+24]] | b0[k[17+24]]; + w <<= 8; + w |= (b1[k[18+24]] | b0[k[19+24]]) << 4; + w |= (b1[k[20+24]] | b0[k[21+24]]) << 2; + w |= b1[k[22+24]] | b0[k[23+24]]; + + ROR(w, 4, 28); /* could be eliminated */ + method[1] = w; + + k += 48; + method += 2; + } while ( --n ); + + return !des_weak_p (key); +} + +void +des_encrypt(const struct des_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % DES_BLOCK_SIZE)); + + while (length) + { + DesSmallFipsEncrypt(dst, ctx->key, src); + length -= DES_BLOCK_SIZE; + src += DES_BLOCK_SIZE; + dst += DES_BLOCK_SIZE; + } +} + +void +des_decrypt(const struct des_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % DES_BLOCK_SIZE)); + + while (length) + { + DesSmallFipsDecrypt(dst, ctx->key, src); + length -= DES_BLOCK_SIZE; + src += DES_BLOCK_SIZE; + dst += DES_BLOCK_SIZE; + } +} diff --git a/des.h b/des.h new file mode 100644 index 0000000..3f0f9ef --- /dev/null +++ b/des.h @@ -0,0 +1,111 @@ +/* des.h + * + * The des block cipher. And triple des. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 1992, 2001, Dana L. How, Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* + * des - fast & portable DES encryption & decryption. + * Copyright (C) 1992 Dana L. How + * Please see the file `../lib/descore.README' for the complete copyright + * notice. + * + * Slightly edited by Niels Möller, 1997 + */ + +#ifndef NETTLE_DES_H_INCLUDED +#define NETTLE_DES_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Namespace mangling */ +#define des_set_key nettle_des_set_key +#define des_encrypt nettle_des_encrypt +#define des_decrypt nettle_des_decrypt +#define des_check_parity nettle_des_check_parity +#define des_fix_parity nettle_des_fix_parity +#define des3_set_key nettle_des3_set_key +#define des3_encrypt nettle_des3_encrypt +#define des3_decrypt nettle_des3_decrypt + +#define DES_KEY_SIZE 8 +#define DES_BLOCK_SIZE 8 + +/* Expanded key length */ +#define _DES_KEY_LENGTH 32 + +struct des_ctx +{ + uint32_t key[_DES_KEY_LENGTH]; +}; + +/* Returns 1 for good keys and 0 for weak keys. */ +int +des_set_key(struct des_ctx *ctx, const uint8_t *key); + +void +des_encrypt(const struct des_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +des_decrypt(const struct des_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +int +des_check_parity(unsigned length, const uint8_t *key); + +void +des_fix_parity(unsigned length, uint8_t *dst, + const uint8_t *src); + +#define DES3_KEY_SIZE 24 +#define DES3_BLOCK_SIZE DES_BLOCK_SIZE + +struct des3_ctx +{ + struct des_ctx des[3]; +}; + + +/* Returns 1 for good keys and 0 for weak keys. */ +int +des3_set_key(struct des3_ctx *ctx, const uint8_t *key); + +void +des3_encrypt(const struct des3_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +des3_decrypt(const struct des3_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DES_H_INCLUDED */ diff --git a/des3.c b/des3.c new file mode 100644 index 0000000..e574abf --- /dev/null +++ b/des3.c @@ -0,0 +1,74 @@ +/* des3.h + * + * Triple DES cipher. Three key encrypt-decrypt-encrypt. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "des.h" + +/* It's possible to make some more general pipe construction, like the + * lsh/src/cascade.c, but as in practice it's never used for anything + * like triple DES, it's not worth the effort. */ + +/* Returns 1 for good keys and 0 for weak keys. */ +int +des3_set_key(struct des3_ctx *ctx, const uint8_t *key) +{ + unsigned i; + int is_good = 1; + + for (i = 0; i<3; i++, key += DES_KEY_SIZE) + if (!des_set_key(&ctx->des[i], key)) + is_good = 0; + + return is_good; +} + +void +des3_encrypt(const struct des3_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + des_encrypt(&ctx->des[0], + length, dst, src); + des_decrypt(&ctx->des[1], + length, dst, dst); + des_encrypt(&ctx->des[2], + length, dst, dst); +} + +void +des3_decrypt(const struct des3_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src) +{ + des_decrypt(&ctx->des[2], + length, dst, src); + des_encrypt(&ctx->des[1], + length, dst, dst); + des_decrypt(&ctx->des[0], + length, dst, dst); +} diff --git a/desCode.h b/desCode.h new file mode 100644 index 0000000..2559548 --- /dev/null +++ b/desCode.h @@ -0,0 +1,412 @@ +/* desCode.h + * + * $Id: desCode.h,v 1.1 2007/04/05 14:20:35 nisse Exp $ */ + +/* des - fast & portable DES encryption & decryption. + * Copyright (C) 1992 Dana L. How + * Please see the file `descore.README' for the complete copyright notice. + */ + +#include "des.h" + +/* optional customization: + * the idea here is to alter the code so it will still run correctly + * on any machine, but the quickest on the specific machine in mind. + * note that these silly tweaks can give you a 15%-20% speed improvement + * on the sparc -- it's probably even more significant on the 68000. */ + +/* take care of machines with incredibly few registers */ +#if defined(i386) +#define REGISTER /* only x, y, z will be declared register */ +#else +#define REGISTER register +#endif /* i386 */ + +/* is auto inc/dec faster than 7bit unsigned indexing? */ +#if defined(vax) || defined(mc68000) +#define FIXR r += 32; +#define FIXS s += 8; +#define PREV(v,o) *--v +#define NEXT(v,o) *v++ +#else +#define FIXR +#define FIXS +#define PREV(v,o) v[o] +#define NEXT(v,o) v[o] +#endif + +/* if no machine type, default is indexing, 6 registers and cheap literals */ +#if !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc) +#define vax +#endif + + +/* handle a compiler which can't reallocate registers */ +/* The BYTE type is used as parameter for the encrypt/decrypt functions. + * It's pretty bad to have the function prototypes depend on + * a macro definition that the users of the function doesn't + * know about. /Niels */ +#if 0 /* didn't feel like deleting */ +#define SREGFREE ; s = (uint8_t *) D +#define DEST s +#define D m0 +#define BYTE uint32_t +#else +#define SREGFREE +#define DEST d +#define D d +#define BYTE uint8_t +#endif + +/* handle constants in the optimal way for 386 & vax */ +/* 386: we declare 3 register variables (see above) and use 3 more variables; + * vax: we use 6 variables, all declared register; + * we assume address literals are cheap & unrestricted; + * we assume immediate constants are cheap & unrestricted. */ +#if defined(i386) || defined(vax) +#define MQ0 des_bigmap +#define MQ1 (des_bigmap + 64) +#define MQ2 (des_bigmap + 128) +#define MQ3 (des_bigmap + 192) +#define HQ0(z) /* z |= 0x01000000L; */ +#define HQ2(z) /* z |= 0x03000200L; */ +#define LQ0(z) 0xFCFC & z +#define LQ1(z) 0xFCFC & z +#define LQ2(z) 0xFCFC & z +#define LQ3(z) 0xFCFC & z +#define SQ 16 +#define MS0 des_keymap +#define MS1 (des_keymap + 64) +#define MS2 (des_keymap + 128) +#define MS3 (des_keymap + 192) +#define MS4 (des_keymap + 256) +#define MS5 (des_keymap + 320) +#define MS6 (des_keymap + 384) +#define MS7 (des_keymap + 448) +#define HS(z) +#define LS0(z) 0xFC & z +#define LS1(z) 0xFC & z +#define LS2(z) 0xFC & z +#define LS3(z) 0xFC & z +#define REGQUICK +#define SETQUICK +#define REGSMALL +#define SETSMALL +#endif /* defined(i386) || defined(vax) */ + +/* handle constants in the optimal way for mc68000 */ +/* in addition to the core 6 variables, we declare 3 registers holding constants + * and 4 registers holding address literals. + * at most 6 data values and 5 address values are actively used at once. + * we assume address literals are so expensive we never use them; + * we assume constant index offsets > 127 are expensive, so they are not used. + * we assume all constants are expensive and put them in registers, + * including shift counts greater than 8. */ +#if defined(mc68000) +#define MQ0 m0 +#define MQ1 m1 +#define MQ2 m2 +#define MQ3 m3 +#define HQ0(z) +#define HQ2(z) +#define LQ0(z) k0 & z +#define LQ1(z) k0 & z +#define LQ2(z) k0 & z +#define LQ3(z) k0 & z +#define SQ k1 +#define MS0 m0 +#define MS1 m0 +#define MS2 m1 +#define MS3 m1 +#define MS4 m2 +#define MS5 m2 +#define MS6 m3 +#define MS7 m3 +#define HS(z) z |= k0; +#define LS0(z) k1 & z +#define LS1(z) k2 & z +#define LS2(z) k1 & z +#define LS3(z) k2 & z +#define REGQUICK \ + register uint32_t k0, k1; \ + register uint32_t *m0, *m1, *m2, *m3; +#define SETQUICK \ + ; k0 = 0xFCFC \ + ; k1 = 16 \ + /*k2 = 28 to speed up ROL */ \ + ; m0 = des_bigmap \ + ; m1 = m0 + 64 \ + ; m2 = m1 + 64 \ + ; m3 = m2 + 64 +#define REGSMALL \ + register uint32_t k0, k1, k2; \ + register uint32_t *m0, *m1, *m2, *m3; +#define SETSMALL \ + ; k0 = 0x01000100L \ + ; k1 = 0x0FC \ + ; k2 = 0x1FC \ + ; m0 = des_keymap \ + ; m1 = m0 + 128 \ + ; m2 = m1 + 128 \ + ; m3 = m2 + 128 +#endif /* defined(mc68000) */ + +/* handle constants in the optimal way for sparc */ +/* in addition to the core 6 variables, we either declare: + * 4 registers holding address literals and 1 register holding a constant, or + * 8 registers holding address literals. + * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7). + * we assume address literals are so expensive we never use them; + * we assume any constant with >10 bits is expensive and put it in a register, + * and any other is cheap and is coded in-line. */ +#if defined(sparc) +#define MQ0 m0 +#define MQ1 m1 +#define MQ2 m2 +#define MQ3 m3 +#define HQ0(z) +#define HQ2(z) +#define LQ0(z) k0 & z +#define LQ1(z) k0 & z +#define LQ2(z) k0 & z +#define LQ3(z) k0 & z +#define SQ 16 +#define MS0 m0 +#define MS1 m1 +#define MS2 m2 +#define MS3 m3 +#define MS4 m4 +#define MS5 m5 +#define MS6 m6 +#define MS7 m7 +#define HS(z) +#define LS0(z) 0xFC & z +#define LS1(z) 0xFC & z +#define LS2(z) 0xFC & z +#define LS3(z) 0xFC & z +#define REGQUICK \ + register uint32_t k0; \ + register uint32_t *m0, *m1, *m2, *m3; +#define SETQUICK \ + ; k0 = 0xFCFC \ + ; m0 = des_bigmap \ + ; m1 = m0 + 64 \ + ; m2 = m1 + 64 \ + ; m3 = m2 + 64 +#define REGSMALL \ + register uint32_t *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7; +#define SETSMALL \ + ; m0 = des_keymap \ + ; m1 = m0 + 64 \ + ; m2 = m1 + 64 \ + ; m3 = m2 + 64 \ + ; m4 = m3 + 64 \ + ; m5 = m4 + 64 \ + ; m6 = m5 + 64 \ + ; m7 = m6 + 64 +#endif /* defined(sparc) */ + + +/* some basic stuff */ + +/* generate addresses from a base and an index */ +/* FIXME: This is used only as *ADD(msi,lsi(z)) or *ADD(mqi,lqi(z)). + * Why not use plain indexing instead? /Niels */ +#define ADD(b,x) (uint32_t *) ((uint8_t *)b + (x)) + +/* low level rotate operations */ +#define NOP(d,c,o) +#define ROL(d,c,o) d = d << c | d >> o +#define ROR(d,c,o) d = d >> c | d << o +#define ROL1(d) ROL(d, 1, 31) +#define ROR1(d) ROR(d, 1, 31) + +/* elementary swap for doing IP/FP */ +#define SWAP(x,y,m,b) \ + z = ((x >> b) ^ y) & m; \ + x ^= z << b; \ + y ^= z + + +/* the following macros contain all the important code fragments */ + +/* load input data, then setup special registers holding constants */ +#define TEMPQUICK(LOAD) \ + REGQUICK \ + LOAD() \ + SETQUICK +#define TEMPSMALL(LOAD) \ + REGSMALL \ + LOAD() \ + SETSMALL + +/* load data */ +#define LOADDATA(x,y) \ + FIXS \ + y = PREV(s, 7); y<<= 8; \ + y |= PREV(s, 6); y<<= 8; \ + y |= PREV(s, 5); y<<= 8; \ + y |= PREV(s, 4); \ + x = PREV(s, 3); x<<= 8; \ + x |= PREV(s, 2); x<<= 8; \ + x |= PREV(s, 1); x<<= 8; \ + x |= PREV(s, 0) \ + SREGFREE +/* load data without initial permutation and put into efficient position */ +#define LOADCORE() \ + LOADDATA(x, y); \ + ROR1(x); \ + ROR1(y) +/* load data, do the initial permutation and put into efficient position */ +#define LOADFIPS() \ + LOADDATA(y, x); \ + SWAP(x, y, 0x0F0F0F0FL, 004); \ + SWAP(y, x, 0x0000FFFFL, 020); \ + SWAP(x, y, 0x33333333L, 002); \ + SWAP(y, x, 0x00FF00FFL, 010); \ + ROR1(x); \ + z = (x ^ y) & 0x55555555L; \ + y ^= z; \ + x ^= z; \ + ROR1(y) + + +/* core encryption/decryption operations */ +/* S box mapping and P perm */ +#define KEYMAPSMALL(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\ + hs(z) \ + x ^= *ADD(ms3, ls3(z)); \ + z>>= 8; \ + x ^= *ADD(ms2, ls2(z)); \ + z>>= 8; \ + x ^= *ADD(ms1, ls1(z)); \ + z>>= 8; \ + x ^= *ADD(ms0, ls0(z)) +/* alternate version: use 64k of tables */ +#define KEYMAPQUICK(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\ + hq(z) \ + x ^= *ADD(mq0, lq0(z)); \ + z>>= sq; \ + x ^= *ADD(mq1, lq1(z)) +/* apply 24 key bits and do the odd s boxes */ +#define S7S1(x,y,z,r,m,KEYMAP,LOAD) \ + z = LOAD(r, m); \ + z ^= y; \ + KEYMAP(x,z,MQ0,MQ1,HQ0,LQ0,LQ1,SQ,MS0,MS1,MS2,MS3,HS,LS0,LS1,LS2,LS3) +/* apply 24 key bits and do the even s boxes */ +#define S6S0(x,y,z,r,m,KEYMAP,LOAD) \ + z = LOAD(r, m); \ + z ^= y; \ + ROL(z, 4, 28); \ + KEYMAP(x,z,MQ2,MQ3,HQ2,LQ2,LQ3,SQ,MS4,MS5,MS6,MS7,HS,LS0,LS1,LS2,LS3) +/* actual iterations. equivalent except for UPDATE & swapping m and n */ +#define ENCR(x,y,z,r,m,n,KEYMAP) \ + S7S1(x,y,z,r,m,KEYMAP,NEXT); \ + S6S0(x,y,z,r,n,KEYMAP,NEXT) +#define DECR(x,y,z,r,m,n,KEYMAP) \ + S6S0(x,y,z,r,m,KEYMAP,PREV); \ + S7S1(x,y,z,r,n,KEYMAP,PREV) + +/* write out result in correct byte order */ +#define SAVEDATA(x,y) \ + NEXT(DEST, 0) = x; x>>= 8; \ + NEXT(DEST, 1) = x; x>>= 8; \ + NEXT(DEST, 2) = x; x>>= 8; \ + NEXT(DEST, 3) = x; \ + NEXT(DEST, 4) = y; y>>= 8; \ + NEXT(DEST, 5) = y; y>>= 8; \ + NEXT(DEST, 6) = y; y>>= 8; \ + NEXT(DEST, 7) = y +/* write out result */ +#define SAVECORE() \ + ROL1(x); \ + ROL1(y); \ + SAVEDATA(y, x) +/* do final permutation and write out result */ +#define SAVEFIPS() \ + ROL1(x); \ + z = (x ^ y) & 0x55555555L; \ + y ^= z; \ + x ^= z; \ + ROL1(y); \ + SWAP(x, y, 0x00FF00FFL, 010); \ + SWAP(y, x, 0x33333333L, 002); \ + SWAP(x, y, 0x0000FFFFL, 020); \ + SWAP(y, x, 0x0F0F0F0FL, 004); \ + SAVEDATA(x, y) + + +/* the following macros contain the encryption/decryption skeletons */ + +#define ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \ + \ +void \ +NAME(REGISTER BYTE *D, \ + REGISTER const uint32_t *r, \ + REGISTER const uint8_t *s) \ +{ \ + register uint32_t x, y, z; \ + \ + /* declare temps & load data */ \ + TEMP(LOAD); \ + \ + /* do the 16 iterations */ \ + ENCR(x,y,z,r, 0, 1,KEYMAP); \ + ENCR(y,x,z,r, 2, 3,KEYMAP); \ + ENCR(x,y,z,r, 4, 5,KEYMAP); \ + ENCR(y,x,z,r, 6, 7,KEYMAP); \ + ENCR(x,y,z,r, 8, 9,KEYMAP); \ + ENCR(y,x,z,r,10,11,KEYMAP); \ + ENCR(x,y,z,r,12,13,KEYMAP); \ + ENCR(y,x,z,r,14,15,KEYMAP); \ + ENCR(x,y,z,r,16,17,KEYMAP); \ + ENCR(y,x,z,r,18,19,KEYMAP); \ + ENCR(x,y,z,r,20,21,KEYMAP); \ + ENCR(y,x,z,r,22,23,KEYMAP); \ + ENCR(x,y,z,r,24,25,KEYMAP); \ + ENCR(y,x,z,r,26,27,KEYMAP); \ + ENCR(x,y,z,r,28,29,KEYMAP); \ + ENCR(y,x,z,r,30,31,KEYMAP); \ + \ + /* save result */ \ + SAVE(); \ + \ + return; \ +} + +#define DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \ + \ +void \ +NAME(REGISTER BYTE *D, \ + REGISTER const uint32_t *r, \ + REGISTER const uint8_t *s) \ +{ \ + register uint32_t x, y, z; \ + \ + /* declare temps & load data */ \ + TEMP(LOAD); \ + \ + /* do the 16 iterations */ \ + FIXR \ + DECR(x,y,z,r,31,30,KEYMAP); \ + DECR(y,x,z,r,29,28,KEYMAP); \ + DECR(x,y,z,r,27,26,KEYMAP); \ + DECR(y,x,z,r,25,24,KEYMAP); \ + DECR(x,y,z,r,23,22,KEYMAP); \ + DECR(y,x,z,r,21,20,KEYMAP); \ + DECR(x,y,z,r,19,18,KEYMAP); \ + DECR(y,x,z,r,17,16,KEYMAP); \ + DECR(x,y,z,r,15,14,KEYMAP); \ + DECR(y,x,z,r,13,12,KEYMAP); \ + DECR(x,y,z,r,11,10,KEYMAP); \ + DECR(y,x,z,r, 9, 8,KEYMAP); \ + DECR(x,y,z,r, 7, 6,KEYMAP); \ + DECR(y,x,z,r, 5, 4,KEYMAP); \ + DECR(x,y,z,r, 3, 2,KEYMAP); \ + DECR(y,x,z,r, 1, 0,KEYMAP); \ + \ + /* save result */ \ + SAVE(); \ + \ + return; \ +} diff --git a/descore.README b/descore.README new file mode 100644 index 0000000..65a54fb --- /dev/null +++ b/descore.README @@ -0,0 +1,313 @@ +des - fast & portable DES encryption & decryption. +Copyright (C) 1992 Dana L. How + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This 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 Library General Public License for more details. + +You should have received a copy of the GNU Library 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 + +Author's address: how@isl.stanford.edu + +$Id: descore.README,v 1.1 2007/04/05 14:20:35 nisse Exp $ + + +==>> To compile after untarring/unsharring, just `make' <<== + + +This package was designed with the following goals: +1. Highest possible encryption/decryption PERFORMANCE. +2. PORTABILITY to any byte-addressable machine with a 32bit unsigned C type +3. Plug-compatible replacement for KERBEROS's low-level routines. + + +performance comparison to other available des code which i could +compile on a SPARCStation 1 (cc -O4): + +this code (byte-order independent): + 30us per encryption (options: 64k tables, no IP/FP) + 33us per encryption (options: 64k tables, FIPS standard bit ordering) + 45us per encryption (options: 2k tables, no IP/FP) + 49us per encryption (options: 2k tables, FIPS standard bit ordering) + 275us to set a new key (uses 1k of key tables) + this has the quickest encryption/decryption routines i've seen. + since i was interested in fast des filters rather than crypt(3) + and password cracking, i haven't really bothered yet to speed up + the key setting routine. also, i have no interest in re-implementing + all the other junk in the mit kerberos des library, so i've just + provided my routines with little stub interfaces so they can be + used as drop-in replacements with mit's code or any of the mit- + compatible packages below. (note that the first two timings above + are highly variable because of cache effects). + +kerberos des replacement from australia: + 68us per encryption (uses 2k of tables) + 96us to set a new key (uses 2.25k of key tables) + this is a very nice package which implements the most important + of the optimizations which i did in my encryption routines. + it's a bit weak on common low-level optimizations which is why + it's 39%-106% slower. because he was interested in fast crypt(3) and + password-cracking applications, he also used the same ideas to + speed up the key-setting routines with impressive results. + (at some point i may do the same in my package). he also implements + the rest of the mit des library. + (code from eay@psych.psy.uq.oz.au via comp.sources.misc) + +fast crypt(3) package from denmark: + the des routine here is buried inside a loop to do the + crypt function and i didn't feel like ripping it out and measuring + performance. his code takes 26 sparc instructions to compute one + des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37. + he claims to use 280k of tables but the iteration calculation seems + to use only 128k. his tables and code are machine independent. + (code from glad@daimi.aau.dk via alt.sources or comp.sources.misc) + +swedish reimplementation of Kerberos des library + 108us per encryption (uses 34k worth of tables) + 134us to set a new key (uses 32k of key tables to get this speed!) + the tables used seem to be machine-independent; + he seems to have included a lot of special case code + so that, e.g., `long' loads can be used instead of 4 `char' loads + when the machine's architecture allows it. + (code obtained from chalmers.se:pub/des) + +crack 3.3c package from england: + as in crypt above, the des routine is buried in a loop. it's + also very modified for crypt. his iteration code uses 16k + of tables and appears to be slow. + (code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc) + +``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent): + 165us per encryption (uses 6k worth of tables) + 478us to set a new key (uses <1k of key tables) + so despite the comments in this code, it was possible to get + faster code AND smaller tables, as well as making the tables + machine-independent. + (code obtained from prep.ai.mit.edu) + +UC Berkeley code (depends on machine-endedness): + 226us per encryption +10848us to set a new key + table sizes are unclear, but they don't look very small + (code obtained from wuarchive.wustl.edu) + + +motivation and history + +a while ago i wanted some des routines and the routines documented on sun's +man pages either didn't exist or dumped core. i had heard of kerberos, +and knew that it used des, so i figured i'd use its routines. but once +i got it and looked at the code, it really set off a lot of pet peeves - +it was too convoluted, the code had been written without taking +advantage of the regular structure of operations such as IP, E, and FP +(i.e. the author didn't sit down and think before coding), +it was excessively slow, the author had attempted to clarify the code +by adding MORE statements to make the data movement more `consistent' +instead of simplifying his implementation and cutting down on all data +movement (in particular, his use of L1, R1, L2, R2), and it was full of +idiotic `tweaks' for particular machines which failed to deliver significant +speedups but which did obfuscate everything. so i took the test data +from his verification program and rewrote everything else. + +a while later i ran across the great crypt(3) package mentioned above. +the fact that this guy was computing 2 sboxes per table lookup rather +than one (and using a MUCH larger table in the process) emboldened me to +do the same - it was a trivial change from which i had been scared away +by the larger table size. in his case he didn't realize you don't need to keep +the working data in TWO forms, one for easy use of half the sboxes in +indexing, the other for easy use of the other half; instead you can keep +it in the form for the first half and use a simple rotate to get the other +half. this means i have (almost) half the data manipulation and half +the table size. in fairness though he might be encoding something particular +to crypt(3) in his tables - i didn't check. + +i'm glad that i implemented it the way i did, because this C version is +portable (the ifdef's are performance enhancements) and it is faster +than versions hand-written in assembly for the sparc! + + +porting notes + +one thing i did not want to do was write an enormous mess +which depended on endedness and other machine quirks, +and which necessarily produced different code and different lookup tables +for different machines. see the kerberos code for an example +of what i didn't want to do; all their endedness-specific `optimizations' +obfuscate the code and in the end were slower than a simpler machine +independent approach. however, there are always some portability +considerations of some kind, and i have included some options +for varying numbers of register variables. +perhaps some will still regard the result as a mess! + +1) i assume everything is byte addressable, although i don't actually + depend on the byte order, and that bytes are 8 bits. + i assume word pointers can be freely cast to and from char pointers. + note that 99% of C programs make these assumptions. + i always use unsigned char's if the high bit could be set. +2) the typedef `word' means a 32 bit unsigned integral type. + if `unsigned long' is not 32 bits, change the typedef in desCore.h. + i assume sizeof(word) == 4 EVERYWHERE. + +the (worst-case) cost of my NOT doing endedness-specific optimizations +in the data loading and storing code surrounding the key iterations +is less than 12%. also, there is the added benefit that +the input and output work areas do not need to be word-aligned. + + +OPTIONAL performance optimizations + +1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,' + whichever one is closest to the capabilities of your machine. + see the start of desCode.h to see exactly what this selection implies. + note that if you select the wrong one, the des code will still work; + these are just performance tweaks. +2) for those with functional `asm' keywords: you should change the + ROR and ROL macros to use machine rotate instructions if you have them. + this will save 2 instructions and a temporary per use, + or about 32 to 40 instructions per en/decryption. + +these optimizations are all rather persnickety, yet with them you should +be able to get performance equal to assembly-coding, except that: +1) with the lack of a bit rotate operator in C, rotates have to be synthesized + from shifts. so access to `asm' will speed things up if your machine + has rotates, as explained above in (3). +2) if your machine has less than 12 32-bit registers i doubt your compiler will + generate good code. + `i386' tries to configure the code for a 386 by only declaring 3 registers + (it appears that gcc can use ebx, esi and edi to hold register variables). + however, if you like assembly coding, the 386 does have 7 32-bit registers, + and if you use ALL of them, use `scaled by 8' address modes with displacement + and other tricks, you can get reasonable routines for DesQuickCore... with + about 250 instructions apiece. For DesSmall... it will help to rearrange + des_keymap, i.e., now the sbox # is the high part of the index and + the 6 bits of data is the low part; it helps to exchange these. + since i have no way to conveniently test it i have not provided my + shoehorned 386 version. + +coding notes + +the en/decryption routines each use 6 necessary register variables, +with 4 being actively used at once during the inner iterations. +if you don't have 4 register variables get a new machine. +up to 8 more registers are used to hold constants in some configurations. + +i assume that the use of a constant is more expensive than using a register: +a) additionally, i have tried to put the larger constants in registers. + registering priority was by the following: + anything more than 12 bits (bad for RISC and CISC) + greater than 127 in value (can't use movq or byte immediate on CISC) + 9-127 (may not be able to use CISC shift immediate or add/sub quick), + 1-8 were never registered, being the cheapest constants. +b) the compiler may be too stupid to realize table and table+256 should + be assigned to different constant registers and instead repetitively + do the arithmetic, so i assign these to explicit `m' register variables + when possible and helpful. + +i assume that indexing is cheaper or equivalent to auto increment/decrement, +where the index is 7 bits unsigned or smaller. +this assumption is reversed for 68k and vax. + +i assume that addresses can be cheaply formed from two registers, +or from a register and a small constant. i never use the `two registers +and offset' form you see in some CISC machines. +all index scaling is done explicitly - no hidden shifts by log2(sizeof). + +the code is written so that even a dumb compiler +should never need more than one hidden temporary, +increasing the chance that everything will fit in the registers. +KEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING. + + +special efficient data format + +bits are manipulated in this arrangement most of the time (S7 S5 S3 S1): + 003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx +(the x bits are still there, i'm just emphasizing where the S boxes are). +bits are rotated left 4 when computing S6 S4 S2 S0: + 282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx +the rightmost two bits are usually cleared so the lower byte can be used +as an index into an sbox mapping table. the next two x'd bits are set +to various values to access different parts of the tables. + + +how to use the routines + +datatypes: + pointer to 8 byte area of type DesData + used to hold keys and input/output blocks to des. + + pointer to 128 byte area of type DesKeys + used to hold full 768-bit key. + must be long-aligned. + +DesQuickInit() + call this before using any other routine with `Quick' in its name. + it generates the special 64k table these routines need. +DesQuickDone() + frees this table + +DesMethod(m, k) + m points to a 128byte block, k points to an 8 byte des key + which must have odd parity (or -1 is returned) and which must + not be a (semi-)weak key (or -2 is returned). + normally DesMethod() returns 0. + m is filled in from k so that when one of the routines below + is called with m, the routine will act like standard des + en/decryption with the key k. if you use DesMethod, + you supply a standard 56bit key; however, if you fill in + m yourself, you will get a 768bit key - but then it won't + be standard. it's 768bits not 1024 because the least significant + two bits of each byte are not used. and yes, each byte controls + a specific sbox during a specific iteration. + NOTE: actually, every other word has been rotated right 4 bits + to reduce the number of temporaries needed when the key is used. + you really shouldn't use the 768bit format directly; i should + provide a routine that converts 128 6-bit bytes (specified in + S-box mapping order or something) into the right format for you. + this would entail some byte concatenation and rotation. + +Des{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s) + performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *). + uses m as a 768bit key as explained above. + the Encrypt|Decrypt choice is obvious. + Fips|Core determines whether a completely standard FIPS initial + and final permutation is done; if not, then the data is loaded + and stored in a nonstandard bit order (FIPS w/o IP/FP). + Fips slows down Quick by 10%, Small by 9%. + Small|Quick determines whether you use the normal routine + or the crazy quick one which gobbles up 64k more of memory. + Small is 50% slower then Quick, but Quick needs 32 times as much + memory. Quick is included for programs that do nothing but DES, + e.g., encryption filters, etc. + + +Getting it to compile on your machine + +there are no machine-dependencies in the code (see porting), +except perhaps the `now()' macro in desTest.c. +ALL generated tables are machine independent. +you should edit the Makefile with the appropriate optimization flags +for your compiler (MAX optimization). + + +Speeding up kerberos (and/or its des library) + +note that i have included a kerberos-compatible interface in desUtil.c +through the functions des_key_sched() and des_ecb_encrypt(). +to use these with kerberos or kerberos-compatible code put desCore.a +ahead of the kerberos-compatible library on your linker's command line. +you should not need to #include desCore.h; just include the header +file provided with the kerberos library. + +Other uses + +the macros in desCode.h would be very useful for putting inline des +functions in more complicated encryption routines. diff --git a/desdata.c b/desdata.c new file mode 100644 index 0000000..0f7aecb --- /dev/null +++ b/desdata.c @@ -0,0 +1,198 @@ +/* desdata.c + * + * Generate tables used by des.c and desCode.h. + * + * $Id: desdata.c,v 1.1 2007/04/05 14:20:35 nisse Exp $ */ + +/* + * des - fast & portable DES encryption & decryption. + * Copyright (C) 1992 Dana L. How + * Please see the file `descore.README' for the complete copyright notice. + * + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "desinfo.h" + +#include "desCode.h" + + +/* list of weak and semi-weak keys + + +0 +1 +2 +3 +4 +5 +6 +7 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e + 0x01 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1 + 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe + 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e 0x01 + 0x1f 0x1f 0x1f 0x1f 0x0e 0x0e 0x0e 0x0e + 0x1f 0xe0 0x1f 0xe0 0x0e 0xf1 0x0e 0xf1 + 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e 0xfe + 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1 0x01 + 0xe0 0x1f 0xe0 0x1f 0xf1 0x0e 0xf1 0x0e + 0xe0 0xe0 0xe0 0xe0 0xf1 0xf1 0xf1 0xf1 + 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1 0xfe + 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01 + 0xfe 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e + 0xfe 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1 + 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe + */ + +/* key bit order in each method pair: bits 31->00 of 1st, bits 31->00 of 2nd */ +/* this does not reflect the rotate of the 2nd word */ + +#define S(box,bit) (box*6+bit) +int korder[] = { + S(7, 5), S(7, 4), S(7, 3), S(7, 2), S(7, 1), S(7, 0), + S(5, 5), S(5, 4), S(5, 3), S(5, 2), S(5, 1), S(5, 0), + S(3, 5), S(3, 4), S(3, 3), S(3, 2), S(3, 1), S(3, 0), + S(1, 5), S(1, 4), S(1, 3), S(1, 2), S(1, 1), S(1, 0), + S(6, 5), S(6, 4), S(6, 3), S(6, 2), S(6, 1), S(6, 0), + S(4, 5), S(4, 4), S(4, 3), S(4, 2), S(4, 1), S(4, 0), + S(2, 5), S(2, 4), S(2, 3), S(2, 2), S(2, 1), S(2, 0), + S(0, 5), S(0, 4), S(0, 3), S(0, 2), S(0, 1), S(0, 0), +}; + +/* the order in which the algorithm accesses the s boxes */ + +int sorder[] = { + 7, 5, 3, 1, 6, 4, 2, 0, +}; + +int printf(const char *, ...); + +int +main(int argc UNUSED, char **argv UNUSED) +{ + uint32_t d, i, j, k, l, m, n, s; + char b[256], ksr[56]; + + switch ( argv[1][0] ) { + + /* + * <<< make the key parity table >>> + */ + +case 'p': + (void)printf( +"/* automagically produced - do not fuss with this information */\n\n"); + + /* store parity information */ + for ( i = 0; i < 256; i++ ) { + j = i; + j ^= j >> 4; /* bits 3-0 have pairs */ + j ^= j << 2; /* bits 3-2 have quads */ + j ^= j << 1; /* bit 3 has the entire eight (no cox) */ + b[i] = 8 & ~j; /* 0 is okay and 8 is bad parity */ + } + + /* only these characters can appear in a weak key */ + b[0x01] = 1; + b[0x0e] = 2; + b[0x1f] = 3; + b[0xe0] = 4; + b[0xf1] = 5; + b[0xfe] = 6; + + /* print it out */ + for ( i = 0; i < 256; i++ ) { + (void)printf("%d,", b[i]); + if ( (i & 31) == 31 ) + (void)printf("\n"); + } + + break; + + + /* + * <<< make the key usage table >>> + */ + +case 'r': + (void)printf("/* automagically made - do not fuss with this */\n\n"); + + /* KL specifies the initial key bit positions */ + for (i = 0; i < 56; i++) + ksr[i] = (KL[i] - 1) ^ 7; + + for (i = 0; i < 16; i++) { + + /* apply the appropriate number of left shifts */ + for (j = 0; j < KS[i]; j++) { + m = ksr[ 0]; + n = ksr[28]; + for (k = 0; k < 27; k++) + ksr[k ] = ksr[k + 1], + ksr[k + 28] = ksr[k + 29]; + ksr[27] = m; + ksr[55] = n; + } + + /* output the key bit numbers */ + for (j = 0; j < 48; j++) { + m = ksr[KC[korder[j]] - 1]; + m = (m / 8) * 7 + (m % 8) - 1; + m = 55 - m; + (void)printf(" %2ld,", (long) m); + if ((j % 12) == 11) + (void)printf("\n"); + } + (void)printf("\n"); + } + + break; + + + /* + * <<< make the keymap table >>> + */ + +case 'k': + (void)printf("/* automagically made - do not fuss with this */\n\n"); + + for ( i = 0; i <= 7 ; i++ ) { + s = sorder[i]; + for ( d = 0; d <= 63; d++ ) { + /* flip bits */ + k = ((d << 5) & 32) | + ((d << 3) & 16) | + ((d << 1) & 8) | + ((d >> 1) & 4) | + ((d >> 3) & 2) | + ((d >> 5) & 1) ; + /* more bit twiddling */ + l = ((k << 0) & 32) | /* overlap bit */ + ((k << 4) & 16) | /* overlap bit */ + ((k >> 1) & 15) ; /* unique bits */ + /* look up s box value */ + m = SB[s][l]; + /* flip bits */ + n = ((m << 3) & 8) | + ((m << 1) & 4) | + ((m >> 1) & 2) | + ((m >> 3) & 1) ; + /* put in correct nybble */ + n <<= (s << 2); + /* perform p permutation */ + for ( m = j = 0; j < 32; j++ ) + if ( n & (1 << (SP[j] - 1)) ) + m |= (1 << j); + /* rotate right (alg keeps everything rotated by 1) */ + ROR(m, 1, 31); + /* print it out */ + (void)printf(" 0x%08lx,", (long) m); + if ( ( d & 3 ) == 3 ) + (void)printf("\n"); + } + (void)printf("\n"); + } + + break; + + } + + return 0; +} diff --git a/desinfo.h b/desinfo.h new file mode 100644 index 0000000..0bff551 --- /dev/null +++ b/desinfo.h @@ -0,0 +1,96 @@ +/* desinfo.h + * + * Tables describing DES rather than just this implementation. + * These are used in desdata but NOT in runtime code. + * + * $Id: desinfo.h,v 1.1 2007/04/05 14:20:35 nisse Exp $ */ + +/* des - fast & portable DES encryption & decryption. + * Copyright (C) 1992 Dana L. How + * Please see the file `descore.README' for the complete copyright notice. + */ + +/* the initial permutation, E selection, and final permutation are hardwired */ + +/* Key Load: how to load the shift register from the user key */ + +unsigned char KL[] = { + + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4, +}; + +/* Key Shift: how many times to shift the key shift register */ + +unsigned char KS[] = { + + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, +}; + +/* Key Choose: which key bits from shift reg are used in the key schedule */ + +unsigned char KC[] = { + + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32, +}; + +/* S Boxes */ + +unsigned char SB[8][64] = { + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + },{ + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + },{ + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + },{ + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + },{ + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + },{ + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + },{ + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + },{ + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +/* Sbox Permutation */ + +char SP[] = { + + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25, +}; diff --git a/dsa-keygen.c b/dsa-keygen.c new file mode 100644 index 0000000..be17771 --- /dev/null +++ b/dsa-keygen.c @@ -0,0 +1,125 @@ +/* dsa-keygen.c + * + * Generation of DSA keypairs + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "dsa.h" + +#include "bignum.h" +#include "nettle-internal.h" + + +/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048. 224), + (2048, 256), (3072, 256). Currenty, we use only q_bits of 160 or + 256. */ +int +dsa_generate_keypair(struct dsa_public_key *pub, + struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + void *progress_ctx, nettle_progress_func progress, + unsigned p_bits, unsigned q_bits) +{ + mpz_t p0, p0q, r; + unsigned p0_bits; + unsigned a; + + switch (q_bits) + { + case 160: + if (p_bits < DSA_SHA1_MIN_P_BITS) + return 0; + break; + case 256: + if (p_bits < DSA_SHA256_MIN_P_BITS) + return 0; + break; + default: + return 0; + } + + mpz_init (p0); + mpz_init (p0q); + mpz_init (r); + + nettle_random_prime (pub->q, q_bits, 0, random_ctx, random, + progress_ctx, progress); + + p0_bits = (p_bits + 3)/2; + + nettle_random_prime (p0, p0_bits, 0, + random_ctx, random, + progress_ctx, progress); + + if (progress) + progress (progress_ctx, 'q'); + + /* Generate p = 2 r q p0 + 1, such that 2^{n-1} < p < 2^n. + * + * We select r in the range i + 1 < r <= 2i, with i = floor (2^{n-2} / (p0 q). */ + + mpz_mul (p0q, p0, pub->q); + + _nettle_generate_pocklington_prime (pub->p, r, p_bits, 0, + random_ctx, random, + p0, pub->q, p0q); + + if (progress) + progress (progress_ctx, 'p'); + + mpz_mul (r, r, p0); + + for (a = 2; ; a++) + { + mpz_set_ui (pub->g, a); + mpz_powm (pub->g, pub->g, r, pub->p); + if (mpz_cmp_ui (pub->g, 1) != 0) + break; + } + + if (progress) + progress (progress_ctx, 'g'); + + mpz_init_set(r, pub->q); + mpz_sub_ui(r, r, 2); + nettle_mpz_random(key->x, random_ctx, random, r); + + mpz_add_ui(key->x, key->x, 1); + + mpz_powm(pub->y, pub->g, key->x, pub->p); + + if (progress) + progress (progress_ctx, '\n'); + + mpz_clear (p0); + mpz_clear (p0q); + mpz_clear (r); + + return 1; +} diff --git a/dsa-sha1-sign.c b/dsa-sha1-sign.c new file mode 100644 index 0000000..5654c49 --- /dev/null +++ b/dsa-sha1-sign.c @@ -0,0 +1,56 @@ +/* dsa-sha1-sign.c + * + * The original DSA publickey algorithm, using SHA-1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +int +dsa_sha1_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature) +{ + return _dsa_sign(pub, key, random_ctx, random, + SHA1_DIGEST_SIZE, digest, signature); +} + + +int +dsa_sha1_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha1_ctx *hash, + struct dsa_signature *signature) +{ + uint8_t digest[SHA1_DIGEST_SIZE]; + sha1_digest(hash, sizeof(digest), digest); + + return _dsa_sign(pub, key, random_ctx, random, + sizeof(digest), digest, signature); +} diff --git a/dsa-sha1-verify.c b/dsa-sha1-verify.c new file mode 100644 index 0000000..73e948c --- /dev/null +++ b/dsa-sha1-verify.c @@ -0,0 +1,51 @@ +/* dsa-sha1-verify.c + * + * The original DSA publickey algorithm, using SHA-1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "dsa.h" + +int +dsa_sha1_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return _dsa_verify(key, SHA1_DIGEST_SIZE, digest, signature); +} + +int +dsa_sha1_verify(const struct dsa_public_key *key, + struct sha1_ctx *hash, + const struct dsa_signature *signature) +{ + uint8_t digest[SHA1_DIGEST_SIZE]; + sha1_digest(hash, sizeof(digest), digest); + + return _dsa_verify(key, sizeof(digest), digest, signature); +} diff --git a/dsa-sha256-sign.c b/dsa-sha256-sign.c new file mode 100644 index 0000000..ea82022 --- /dev/null +++ b/dsa-sha256-sign.c @@ -0,0 +1,55 @@ +/* dsa-sha256-sign.c + * + * The DSA publickey algorithm, using SHA-256 (FIPS186-3). + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +int +dsa_sha256_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature) +{ + return _dsa_sign(pub, key, random_ctx, random, + SHA256_DIGEST_SIZE, digest, signature); +} + +int +dsa_sha256_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha256_ctx *hash, + struct dsa_signature *signature) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + sha256_digest(hash, sizeof(digest), digest); + + return _dsa_sign(pub, key, random_ctx, random, + sizeof(digest), digest, signature); +} diff --git a/dsa-sha256-verify.c b/dsa-sha256-verify.c new file mode 100644 index 0000000..ed79a86 --- /dev/null +++ b/dsa-sha256-verify.c @@ -0,0 +1,51 @@ +/* dsa-sha256-verify.c + * + * The DSA publickey algorithm, using SHA-256 (FIPS186-3). + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "dsa.h" + +int +dsa_sha256_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return _dsa_verify(key, SHA256_DIGEST_SIZE, digest, signature); +} + +int +dsa_sha256_verify(const struct dsa_public_key *key, + struct sha256_ctx *hash, + const struct dsa_signature *signature) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + sha256_digest(hash, sizeof(digest), digest); + + return _dsa_verify(key, sizeof(digest), digest, signature); +} diff --git a/dsa-sign.c b/dsa-sign.c new file mode 100644 index 0000000..9c5a29c --- /dev/null +++ b/dsa-sign.c @@ -0,0 +1,90 @@ +/* dsa-sign.c + * + * The DSA publickey algorithm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "dsa.h" + +#include "bignum.h" + + +int +_dsa_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + unsigned digest_size, + const uint8_t *digest, + struct dsa_signature *signature) +{ + mpz_t k; + mpz_t h; + mpz_t tmp; + + /* Require precise match of bitsize of q and hash size. The general + description of DSA in FIPS186-3 allows both larger and smaller q; + in the the latter case, the hash must be truncated to the right + number of bits. */ + if (mpz_sizeinbase(pub->q, 2) != 8 * digest_size) + return 0; + + /* Select k, 0q); + mpz_sub_ui(tmp, tmp, 1); + + mpz_init(k); + nettle_mpz_random(k, random_ctx, random, tmp); + mpz_add_ui(k, k, 1); + + /* Compute r = (g^k (mod p)) (mod q) */ + mpz_powm(tmp, pub->g, k, pub->p); + mpz_fdiv_r(signature->r, tmp, pub->q); + + /* Compute hash */ + mpz_init(h); + nettle_mpz_set_str_256_u(h, digest_size, digest); + + /* Compute k^-1 (mod q) */ + if (!mpz_invert(k, k, pub->q)) + /* What do we do now? The key is invalid. */ + return 0; + + /* Compute signature s = k^-1 (h + xr) (mod q) */ + mpz_mul(tmp, signature->r, key->x); + mpz_fdiv_r(tmp, tmp, pub->q); + mpz_add(tmp, tmp, h); + mpz_mul(tmp, tmp, k); + mpz_fdiv_r(signature->s, tmp, pub->q); + + mpz_clear(k); + mpz_clear(h); + mpz_clear(tmp); + + return 1; +} diff --git a/dsa-verify.c b/dsa-verify.c new file mode 100644 index 0000000..faea0a0 --- /dev/null +++ b/dsa-verify.c @@ -0,0 +1,101 @@ +/* dsa-verify.c + * + * The DSA publickey algorithm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "dsa.h" + +#include "bignum.h" + +int +_dsa_verify(const struct dsa_public_key *key, + unsigned digest_size, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + mpz_t w; + mpz_t tmp; + mpz_t v; + + int res; + + if (mpz_sizeinbase(key->q, 2) != 8 * digest_size) + return 0; + + /* Check that r and s are in the proper range */ + if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, key->q) >= 0) + return 0; + + if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, key->q) >= 0) + return 0; + + mpz_init(w); + + /* Compute w = s^-1 (mod q) */ + + /* NOTE: In gmp-2, mpz_invert sometimes generates negative inverses, + * so we need gmp-3 or better. */ + if (!mpz_invert(w, signature->s, key->q)) + { + mpz_clear(w); + return 0; + } + + mpz_init(tmp); + mpz_init(v); + + /* The message digest */ + nettle_mpz_set_str_256_u(tmp, digest_size, digest); + + /* v = g^{w * h (mod q)} (mod p) */ + mpz_mul(tmp, tmp, w); + mpz_fdiv_r(tmp, tmp, key->q); + + mpz_powm(v, key->g, tmp, key->p); + + /* y^{w * r (mod q) } (mod p) */ + mpz_mul(tmp, signature->r, w); + mpz_fdiv_r(tmp, tmp, key->q); + + mpz_powm(tmp, key->y, tmp, key->p); + + /* v = (g^{w * h} * y^{w * r} (mod p) ) (mod q) */ + mpz_mul(v, v, tmp); + mpz_fdiv_r(v, v, key->p); + + mpz_fdiv_r(v, v, key->q); + + res = !mpz_cmp(v, signature->r); + + mpz_clear(w); + mpz_clear(tmp); + mpz_clear(v); + + return res; +} diff --git a/dsa.c b/dsa.c new file mode 100644 index 0000000..02cc785 --- /dev/null +++ b/dsa.c @@ -0,0 +1,78 @@ +/* dsa.h + * + * The DSA publickey algorithm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +#include "bignum.h" + +void +dsa_public_key_init(struct dsa_public_key *key) +{ + mpz_init(key->p); + mpz_init(key->q); + mpz_init(key->g); + mpz_init(key->y); +} + +void +dsa_public_key_clear(struct dsa_public_key *key) +{ + mpz_clear(key->p); + mpz_clear(key->q); + mpz_clear(key->g); + mpz_clear(key->y); +} + + +void +dsa_private_key_init(struct dsa_private_key *key) +{ + mpz_init(key->x); +} + +void +dsa_private_key_clear(struct dsa_private_key *key) +{ + mpz_clear(key->x); +} + + +void +dsa_signature_init(struct dsa_signature *signature) +{ + mpz_init(signature->r); + mpz_init(signature->s); +} + +void +dsa_signature_clear(struct dsa_signature *signature) +{ + mpz_clear(signature->r); + mpz_clear(signature->s); +} diff --git a/dsa.h b/dsa.h new file mode 100644 index 0000000..412178b --- /dev/null +++ b/dsa.h @@ -0,0 +1,295 @@ +/* dsa.h + * + * The DSA publickey algorithm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_DSA_H_INCLUDED +#define NETTLE_DSA_H_INCLUDED + +#include + +#include "nettle-types.h" + +#include "sha.h" + +/* For nettle_random_func */ +#include "nettle-meta.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define dsa_public_key_init nettle_dsa_public_key_init +#define dsa_public_key_clear nettle_dsa_public_key_clear +#define dsa_private_key_init nettle_dsa_private_key_init +#define dsa_private_key_clear nettle_dsa_private_key_clear +#define dsa_signature_init nettle_dsa_signature_init +#define dsa_signature_clear nettle_dsa_signature_clear +#define dsa_sha1_sign nettle_dsa_sha1_sign +#define dsa_sha1_verify nettle_dsa_sha1_verify +#define dsa_sha256_sign nettle_dsa_sha256_sign +#define dsa_sha256_verify nettle_dsa_sha256_verify +#define dsa_sha1_sign_digest nettle_dsa_sha1_sign_digest +#define dsa_sha1_verify_digest nettle_dsa_sha1_verify_digest +#define dsa_sha256_sign_digest nettle_dsa_sha256_sign_digest +#define dsa_sha256_verify_digest nettle_dsa_sha256_verify_digest +#define dsa_generate_keypair nettle_dsa_generate_keypair +#define dsa_signature_from_sexp nettle_dsa_signature_from_sexp +#define dsa_keypair_to_sexp nettle_dsa_keypair_to_sexp +#define dsa_keypair_from_sexp_alist nettle_dsa_keypair_from_sexp_alist +#define dsa_sha1_keypair_from_sexp nettle_dsa_sha1_keypair_from_sexp +#define dsa_sha256_keypair_from_sexp nettle_dsa_sha256_keypair_from_sexp +#define dsa_params_from_der_iterator nettle_dsa_params_from_der_iterator +#define dsa_public_key_from_der_iterator nettle_dsa_public_key_from_der_iterator +#define dsa_openssl_private_key_from_der_iterator nettle_dsa_openssl_private_key_from_der_iterator +#define dsa_openssl_private_key_from_der nettle_openssl_provate_key_from_der +#define _dsa_sign _nettle_dsa_sign +#define _dsa_verify _nettle_dsa_verify + +#define DSA_SHA1_MIN_P_BITS 512 +#define DSA_SHA1_Q_OCTETS 20 +#define DSA_SHA1_Q_BITS 160 + +#define DSA_SHA256_MIN_P_BITS 1024 +#define DSA_SHA256_Q_OCTETS 32 +#define DSA_SHA256_Q_BITS 256 + +struct dsa_public_key +{ + /* Modulo */ + mpz_t p; + + /* Group order */ + mpz_t q; + + /* Generator */ + mpz_t g; + + /* Public value */ + mpz_t y; +}; + +struct dsa_private_key +{ + /* Unlike an rsa public key, private key operations will need both + * the private and the public information. */ + mpz_t x; +}; + +struct dsa_signature +{ + mpz_t r; + mpz_t s; +}; + +/* Signing a message works as follows: + * + * Store the private key in a dsa_private_key struct. + * + * Initialize a hashing context, by callling + * sha1_init + * + * Hash the message by calling + * sha1_update + * + * Create the signature by calling + * dsa_sha1_sign + * + * The signature is represented as a struct dsa_signature. This call also + * resets the hashing context. + * + * When done with the key and signature, don't forget to call + * dsa_signature_clear. + */ + +/* Calls mpz_init to initialize bignum storage. */ +void +dsa_public_key_init(struct dsa_public_key *key); + +/* Calls mpz_clear to deallocate bignum storage. */ +void +dsa_public_key_clear(struct dsa_public_key *key); + + +/* Calls mpz_init to initialize bignum storage. */ +void +dsa_private_key_init(struct dsa_private_key *key); + +/* Calls mpz_clear to deallocate bignum storage. */ +void +dsa_private_key_clear(struct dsa_private_key *key); + +/* Calls mpz_init to initialize bignum storage. */ +void +dsa_signature_init(struct dsa_signature *signature); + +/* Calls mpz_clear to deallocate bignum storage. */ +void +dsa_signature_clear(struct dsa_signature *signature); + + +int +dsa_sha1_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha1_ctx *hash, + struct dsa_signature *signature); + +int +dsa_sha256_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha256_ctx *hash, + struct dsa_signature *signature); + +int +dsa_sha1_verify(const struct dsa_public_key *key, + struct sha1_ctx *hash, + const struct dsa_signature *signature); + +int +dsa_sha256_verify(const struct dsa_public_key *key, + struct sha256_ctx *hash, + const struct dsa_signature *signature); + +int +dsa_sha1_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature); +int +dsa_sha256_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature); + +int +dsa_sha1_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature); + +int +dsa_sha256_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature); + +/* Key generation */ + +int +dsa_generate_keypair(struct dsa_public_key *pub, + struct dsa_private_key *key, + + void *random_ctx, nettle_random_func random, + + void *progress_ctx, nettle_progress_func progress, + unsigned p_bits, unsigned q_bits); + +/* Keys in sexp form. */ + +struct nettle_buffer; + +/* Generates a public-key expression if PRIV is NULL .*/ +int +dsa_keypair_to_sexp(struct nettle_buffer *buffer, + const char *algorithm_name, /* NULL means "dsa" */ + const struct dsa_public_key *pub, + const struct dsa_private_key *priv); + +struct sexp_iterator; + +int +dsa_signature_from_sexp(struct dsa_signature *rs, + struct sexp_iterator *i, + unsigned q_bits); + +int +dsa_keypair_from_sexp_alist(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned q_bits, + struct sexp_iterator *i); + +/* If PRIV is NULL, expect a public-key expression. If PUB is NULL, + * expect a private key expression and ignore the parts not needed for + * the public key. */ +/* Keys must be initialized before calling this function, as usual. */ +int +dsa_sha1_keypair_from_sexp(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned length, const uint8_t *expr); + +int +dsa_sha256_keypair_from_sexp(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned length, const uint8_t *expr); + +/* Keys in X.509 andd OpenSSL format. */ +struct asn1_der_iterator; + +int +dsa_params_from_der_iterator(struct dsa_public_key *pub, + unsigned p_max_bits, + struct asn1_der_iterator *i); +int +dsa_public_key_from_der_iterator(struct dsa_public_key *pub, + unsigned p_max_bits, + struct asn1_der_iterator *i); + +int +dsa_openssl_private_key_from_der_iterator(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + struct asn1_der_iterator *i); + +int +dsa_openssl_private_key_from_der(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned length, const uint8_t *data); + + +/* Internal functions. */ +int +_dsa_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + unsigned digest_size, + const uint8_t *digest, + struct dsa_signature *signature); + +int +_dsa_verify(const struct dsa_public_key *key, + unsigned digest_size, + const uint8_t *digest, + const struct dsa_signature *signature); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DSA_H_INCLUDED */ diff --git a/dsa2sexp.c b/dsa2sexp.c new file mode 100644 index 0000000..213903d --- /dev/null +++ b/dsa2sexp.c @@ -0,0 +1,54 @@ +/* dsa2sexp.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2009 Niels Möller, Magnus Holmgren + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +#include "sexp.h" + +int +dsa_keypair_to_sexp(struct nettle_buffer *buffer, + const char *algorithm_name, + const struct dsa_public_key *pub, + const struct dsa_private_key *priv) +{ + if (!algorithm_name) + algorithm_name = "dsa"; + + if (priv) + return sexp_format(buffer, + "(private-key(%0s(p%b)(q%b)" + "(g%b)(y%b)(x%b)))", + algorithm_name, pub->p, pub->q, + pub->g, pub->y, priv->x); + else + return sexp_format(buffer, + "(public-key(%0s(p%b)(q%b)" + "(g%b)(y%b)))", + algorithm_name, pub->p, pub->q, + pub->g, pub->y); +} diff --git a/examples/Makefile.in b/examples/Makefile.in new file mode 100644 index 0000000..2a6632d --- /dev/null +++ b/examples/Makefile.in @@ -0,0 +1,98 @@ +@SET_MAKE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +top_srcdir = @top_srcdir@ + +include ../config.make + +PRE_CPPFLAGS = -I.. -I$(top_srcdir) +PRE_LDFLAGS = -L.. + +OPENSSL_LIBFLAGS = @OPENSSL_LIBFLAGS@ +RSA_TARGETS = rsa-keygen$(EXEEXT) rsa-sign$(EXEEXT) \ + rsa-verify$(EXEEXT) rsa-encrypt$(EXEEXT) rsa-decrypt$(EXEEXT) +TARGETS = nettle-benchmark$(EXEEXT) eratosthenes$(EXEEXT) @IF_HOGWEED@ $(RSA_TARGETS) next-prime$(EXEEXT) random-prime$(EXEEXT) +SOURCES = nettle-benchmark.c eratosthenes.c next-prime.c random-prime.c \ + nettle-openssl.c \ + io.c read_rsa_key.c getopt.c getopt1.c \ + rsa-encrypt.c rsa-decrypt.c rsa-keygen.c rsa-sign.c rsa-verify.c + +GETOPT_OBJS = getopt.$(OBJEXT) getopt1.$(OBJEXT) + +TS_ALL = rsa-sign-test rsa-verify-test rsa-encrypt-test + +DISTFILES= $(SOURCES) Makefile.in $(TS_ALL) run-tests setup-env teardown-env \ + io.h rsa-session.h getopt.h + +all: $(TARGETS) + +.c.$(OBJEXT): + $(COMPILE) -c $< && $(DEP_PROCESS) + +# For Solaris and BSD make, we have to use an explicit rule for each executable +next-prime$(EXEEXT): next-prime.$(OBJEXT) $(GETOPT_OBJS) ../libhogweed.a + $(LINK) next-prime.$(OBJEXT) $(GETOPT_OBJS) \ + -lhogweed -lnettle $(LIBS) -o next-prime$(EXEEXT) + +random-prime$(EXEEXT): random-prime.$(OBJEXT) $(GETOPT_OBJS) ../libhogweed.a + $(LINK) random-prime.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \ + -lhogweed -lnettle $(LIBS) -o random-prime$(EXEEXT) + +rsa-keygen$(EXEEXT): rsa-keygen.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) rsa-keygen.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \ + -lhogweed -lnettle $(LIBS) -o rsa-keygen$(EXEEXT) + +rsa-sign$(EXEEXT): rsa-sign.$(OBJEXT) read_rsa_key.$(OBJEXT) + $(LINK) rsa-sign.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \ + -lhogweed -lnettle $(LIBS) -o rsa-sign$(EXEEXT) + +rsa-verify$(EXEEXT): rsa-verify.$(OBJEXT) read_rsa_key.$(OBJEXT) + $(LINK) rsa-verify.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \ + -lhogweed -lnettle $(LIBS) -o rsa-verify$(EXEEXT) + +rsa-encrypt$(EXEEXT): rsa-encrypt.$(OBJEXT) read_rsa_key.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) rsa-encrypt.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \ + $(GETOPT_OBJS) \ + -lhogweed -lnettle $(LIBS) -o rsa-encrypt$(EXEEXT) + +rsa-decrypt$(EXEEXT): rsa-decrypt.$(OBJEXT) read_rsa_key.$(OBJEXT) + $(LINK) rsa-decrypt.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \ + -lhogweed -lnettle $(LIBS) -o rsa-decrypt$(EXEEXT) + +eratosthenes$(EXEEXT): eratosthenes.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) eratosthenes.$(OBJEXT) $(GETOPT_OBJS) -o eratosthenes$(EXEEXT) + +nettle-benchmark$(EXEEXT): nettle-benchmark.$(OBJEXT) nettle-openssl.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) nettle-benchmark.$(OBJEXT) nettle-openssl.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \ + -lnettle $(LIBS) $(OPENSSL_LIBFLAGS) -o nettle-benchmark$(EXEEXT) + +$(TARGETS) : io.$(OBJEXT) ../libnettle.a + + +check: $(TS_ALL) + LD_LIBRARY_PATH=../.lib srcdir="$(srcdir)" \ + "$(srcdir)"/run-tests $(TS_ALL) + +Makefile: $(srcdir)/Makefile.in ../config.status + cd .. && $(SHELL) ./config.status examples/$@ + +install uninstall: + true + +# NOTE: I'd like to use $^, but that's a GNU extension. $? should be +# more portable, equivalent for phony targets. +distdir: $(DISTFILES) + cp $? $(distdir) + +clean: + -rm -f $(TARGETS) *.$(OBJEXT) + +distclean: clean + -rm -f Makefile *.d + +tags: + etags -o $(srcdir)/TAGS --include $(top_srcdir) $(srcdir)/*.c $(srcdir)/*.h + +@DEP_INCLUDE@ $(SOURCES:.c=.$(OBJEXT).d) diff --git a/examples/eratosthenes.c b/examples/eratosthenes.c new file mode 100644 index 0000000..287aaa3 --- /dev/null +++ b/examples/eratosthenes.c @@ -0,0 +1,388 @@ +/* eratosthenes.c + * + * An implementation of the sieve of Eratosthenes, to generate a list of primes. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2007 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "getopt.h" + +#ifdef SIZEOF_LONG +# define BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG) +# if BITS_PER_LONG > 32 +# define NEED_HANDLE_LARGE_LONG 1 +# else +# define NEED_HANDLE_LARGE_LONG 0 +# endif +#else +# define BITS_PER_LONG (CHAR_BIT * sizeof(unsigned long)) +# define NEED_HANDLE_LARGE_LONG 1 +#endif + + +static void +usage(void) +{ + fprintf(stderr, "Usage: erathostenes [OPTIONS] [LIMIT]\n\n" + "Options:\n" + " -? Display this message.\n" + " -b SIZE Block size.\n" + " -v Verbose output.\n" + " -s No output.\n"); +} + +static unsigned +isqrt(unsigned long n) +{ + unsigned long x; + + /* FIXME: Better initialization. */ + if (n < ULONG_MAX) + x = n; + else + /* Must avoid overflow in the first step. */ + x = n-1; + + for (;;) + { + unsigned long y = (x + n/x) / 2; + if (y >= x) + return x; + + x = y; + } +} + +/* Size is in bits */ +static unsigned long * +vector_alloc(unsigned long size) +{ + unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG; + unsigned long *vector = malloc (end * sizeof(long)); + + if (!vector) + { + fprintf(stderr, "Insufficient memory.\n"); + exit(EXIT_FAILURE); + } + return vector; +} + +static void +vector_init(unsigned long *vector, unsigned long size) +{ + unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG; + unsigned long i; + + for (i = 0; i < end; i++) + vector[i] = ~0; +} + +static void +vector_clear_bits (unsigned long *vector, unsigned long step, + unsigned long start, unsigned long size) +{ + unsigned long bit; + + for (bit = start; bit < size; bit += step) + { + unsigned long i = bit / BITS_PER_LONG; + unsigned long mask = 1L << (bit % BITS_PER_LONG); + + vector[i] &= ~mask; + } +} + +static unsigned +find_first_one (unsigned long x) +{ + unsigned table[0x101] = + { + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0,11, 0, 0, 0,10, 0, 9, 8, + 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, + }; + + /* Isolate least significant bit */ + x &= -x; + + unsigned i = 0; +#if NEED_HANDLE_LARGE_LONG +#ifndef SIZEOF_LONG + /* Can not be tested by the preprocessor. May generate warnings + when long is 32 bits. */ + if (BITS_PER_LONG > 32) +#endif + while (x >= 0x100000000L) + { + x >>= 32; + i += 32; + } +#endif /* NEED_HANDLE_LARGE_LONG */ + + if (x >= 0x10000) + { + x >>= 16; + i += 16; + } + return i + table[128 + (x & 0xff) - (x >> 8)]; +} + +/* Returns size if there's no more bits set */ +static unsigned long +vector_find_next (const unsigned long *vector, unsigned long bit, unsigned long size) +{ + unsigned long end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG; + unsigned long i = bit / BITS_PER_LONG; + unsigned long mask = 1L << (bit % BITS_PER_LONG); + unsigned long word; + + if (i >= end) + return size; + + for (word = vector[i] & ~(mask - 1); !word; word = vector[i]) + if (++i >= end) + return size; + + /* Next bit is the least significant bit of word */ + return i * BITS_PER_LONG + find_first_one(word); +} + +/* For benchmarking, define to do nothing (otherwise, most of the time + will be spent converting the output to decimal). */ +#define OUTPUT(n) printf("%lu\n", (n)) + +static long +atosize(const char *s) +{ + char *end; + long value = strtol(s, &end, 10); + + if (value <= 0) + return 0; + + /* FIXME: Doesn't check for overflow. */ + switch(*end) + { + default: + return 0; + case '\0': + break; + case 'k': case 'K': + value <<= 10; + break; + case 'M': + value <<= 20; + break; + } + return value; +} + +int +main (int argc, char **argv) +{ + /* Generate all primes p <= limit */ + unsigned long limit; + unsigned long root; + + unsigned long limit_nbits; + + /* Represents numbers up to sqrt(limit) */ + unsigned long sieve_nbits; + unsigned long *sieve; + /* Block for the rest of the sieving. Size should match the cache, + the default value corresponds to 64 KB. */ + unsigned long block_nbits = 64L << 13; + unsigned long block_start_bit; + unsigned long *block; + + unsigned long bit; + int silent = 0; + int verbose = 0; + int c; + + while ( (c = getopt(argc, argv, "?svb:")) != -1) + switch (c) + { + case '?': + usage(); + return EXIT_FAILURE; + case 'b': + block_nbits = CHAR_BIT * atosize(optarg); + if (!block_nbits) + { + usage(); + return EXIT_FAILURE; + } + break; + + case 's': + silent = 1; + break; + + case 'v': + verbose++; + break; + + default: + abort(); + } + + argc -= optind; + argv += optind; + + if (argc == 0) + limit = 1000; + else if (argc == 1) + { + limit = atol(argv[0]); + if (limit < 2) + return EXIT_SUCCESS; + } + else + { + usage(); + return EXIT_FAILURE; + } + + root = isqrt(limit); + /* Round down to odd */ + root = (root - 1) | 1; + /* Represents odd numbers from 3 up. */ + sieve_nbits = (root - 1) / 2; + sieve = vector_alloc(sieve_nbits ); + vector_init(sieve, sieve_nbits); + + if (verbose) + fprintf(stderr, "Initial sieve using %lu bits.\n", sieve_nbits); + + if (!silent) + printf("2\n"); + + if (limit == 2) + return EXIT_SUCCESS; + + for (bit = 0; + bit < sieve_nbits; + bit = vector_find_next(sieve, bit + 1, sieve_nbits)) + { + unsigned long n = 3 + 2 * bit; + /* First bit to clear corresponds to n^2, which is bit + + (n^2 - 3) / 2 = (n + 3) * bit + 3 + */ + unsigned long n2_bit = (n+3)*bit + 3; + + if (!silent) + printf("%lu\n", n); + + vector_clear_bits (sieve, n, n2_bit, sieve_nbits); + } + + limit_nbits = (limit - 1) / 2; + + if (sieve_nbits + block_nbits > limit_nbits) + block_nbits = limit_nbits - sieve_nbits; + + if (verbose) + { + double storage = block_nbits / 8.0; + unsigned shift = 0; + const char prefix[] = " KMG"; + + while (storage > 1024 && shift < 3) + { + storage /= 1024; + shift++; + } + fprintf(stderr, "Blockwise sieving using blocks of %lu bits (%.3g %cByte)\n", + block_nbits, storage, prefix[shift]); + } + + block = vector_alloc(block_nbits); + + for (block_start_bit = bit; block_start_bit < limit_nbits; block_start_bit += block_nbits) + { + unsigned long block_start; + + if (block_start_bit + block_nbits > limit_nbits) + block_nbits = limit_nbits - block_start_bit; + + vector_init(block, block_nbits); + + block_start = 3 + 2*block_start_bit; + + if (verbose > 1) + fprintf(stderr, "Next block, n = %lu\n", block_start); + + /* Sieve */ + for (bit = 0; bit < sieve_nbits; + bit = vector_find_next(sieve, bit + 1, sieve_nbits)) + { + unsigned long n = 3 + 2 * bit; + unsigned long sieve_start_bit = (n + 3) * bit + 3; + + if (sieve_start_bit < block_start_bit) + { + unsigned long k = (block_start + n - 1) / (2*n); + sieve_start_bit = n * k + bit; + + assert(sieve_start_bit < block_start_bit + n); + } + assert(sieve_start_bit >= block_start_bit); + + vector_clear_bits(block, n, sieve_start_bit - block_start_bit, block_nbits); + } + for (bit = vector_find_next(block, 0, block_nbits); + bit < block_nbits; + bit = vector_find_next(block, bit + 1, block_nbits)) + { + unsigned long n = block_start + 2 * bit; + if (!silent) + printf("%lu\n", n); + } + } + return EXIT_SUCCESS; +} diff --git a/examples/getopt.c b/examples/getopt.c new file mode 100644 index 0000000..ed32692 --- /dev/null +++ b/examples/getopt.c @@ -0,0 +1,1067 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifndef _ +# define _(msgid) gettext (msgid) +# endif +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +#ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; +#endif + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/examples/getopt.h b/examples/getopt.h new file mode 100644 index 0000000..76cf5ee --- /dev/null +++ b/examples/getopt.h @@ -0,0 +1,179 @@ +/* Declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if (defined __STDC__ && __STDC__) || defined __cplusplus + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if (defined __STDC__ && __STDC__) || defined __cplusplus +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/examples/getopt1.c b/examples/getopt1.c new file mode 100644 index 0000000..62c55cf --- /dev/null +++ b/examples/getopt1.c @@ -0,0 +1,187 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/examples/io.c b/examples/io.c new file mode 100644 index 0000000..689e0f6 --- /dev/null +++ b/examples/io.c @@ -0,0 +1,189 @@ +/* io.c + * + * Miscellaneous functions used by the example programs. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +/* For errno and strerror */ +#include +#include + +#include "io.h" + +#define RANDOM_DEVICE "/dev/urandom" +#define BUFSIZE 1000 + +int quiet_flag = 0; + +void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + +void +werror(const char *format, ...) +{ + if (!quiet_flag) + { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + } +} + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +unsigned +read_file(const char *name, unsigned max_size, char **contents) +{ + unsigned size; + unsigned done; + char *buffer; + FILE *f; + + f = fopen(name, "rb"); + if (!f) + { + werror("Opening `%s' failed: %s\n", name, strerror(errno)); + return 0; + } + buffer = NULL; + + if (max_size && max_size < 100) + size = max_size; + else + size = 100; + + for (size = 100, done = 0; + (!max_size || done < max_size) && !feof(f); + size *= 2) + { + char *p; + + if (max_size && size > max_size) + size = max_size; + + /* Space for terminating NUL */ + p = realloc(buffer, size + 1); + + if (!p) + { + fail: + fclose(f); + free(buffer); + *contents = NULL; + return 0; + } + + buffer = p; + done += fread(buffer + done, 1, size - done, f); + + if (ferror(f)) + goto fail; + } + + fclose(f); + + /* NUL-terminate the data. */ + buffer[done] = '\0'; + *contents = buffer; + + return done; +} + +int +write_file(const char *name, unsigned size, const char *buffer) +{ + FILE *f = fopen(name, "wb"); + unsigned res; + + if (!f) + return 0; + + res = fwrite(buffer, 1, size, f); + + if (res < size) + res = 0; + + return fclose(f) == 0 && res > 0; +} + +int +write_string(FILE *f, unsigned size, const char *buffer) +{ + size_t res = fwrite(buffer, 1, size, f); + + return res == size; +} + +int +simple_random(struct yarrow256_ctx *ctx, const char *name) +{ + unsigned length; + char *buffer; + + if (name) + length = read_file(name, 0, &buffer); + else + length = read_file(RANDOM_DEVICE, 20, &buffer); + + if (!length) + return 0; + + yarrow256_seed(ctx, length, buffer); + + free(buffer); + + return 1; +} + +int +hash_file(const struct nettle_hash *hash, void *ctx, FILE *f) +{ + for (;;) + { + char buffer[BUFSIZE]; + size_t res = fread(buffer, 1, sizeof(buffer), f); + if (ferror(f)) + return 0; + + hash->update(ctx, res, buffer); + if (feof(f)) + return 1; + } +} diff --git a/examples/io.h b/examples/io.h new file mode 100644 index 0000000..e85dc5f --- /dev/null +++ b/examples/io.h @@ -0,0 +1,73 @@ +/* io.c + * + * Miscellaneous functions used by the example programs. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_EXAMPLES_IO_H_INCLUDED +#define NETTLE_EXAMPLES_IO_H_INCLUDED + +#include "nettle-meta.h" +#include "yarrow.h" + +#include + +extern int quiet_flag; + +void * +xalloc(size_t size); + +void +werror(const char *format, ...) +#if __GNUC___ + __attribute__((__format__ (__printf__,1, 2))) +#endif + ; + +/* If size is > 0, read at most that many bytes. If size == 0, + * read until EOF. Allocates the buffer dynamically. */ +unsigned +read_file(const char *name, unsigned size, char **buffer); + +int +write_file(const char *name, unsigned size, const char *buffer); + +int +write_string(FILE *f, unsigned size, const char *buffer); + +int +simple_random(struct yarrow256_ctx *ctx, const char *name); + +int +hash_file(const struct nettle_hash *hash, void *ctx, FILE *f); + +#if WITH_HOGWEED +struct rsa_public_key; +struct rsa_private_key; + +int +read_rsa_key(const char *name, + struct rsa_public_key *pub, + struct rsa_private_key *priv); +#endif /* WITH_HOGWEED */ + +#endif /* NETTLE_EXAMPLES_IO_H_INCLUDED */ diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c new file mode 100644 index 0000000..95296ba --- /dev/null +++ b/examples/nettle-benchmark.c @@ -0,0 +1,440 @@ +/* nettle-benchmark.c + * + * Tries the performance of the various algorithms. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "aes.h" +#include "arcfour.h" +#include "blowfish.h" +#include "cast128.h" +#include "cbc.h" +#include "des.h" +#include "serpent.h" +#include "sha.h" +#include "twofish.h" + +#include "nettle-meta.h" +#include "nettle-internal.h" + +#include "getopt.h" + +static double frequency = 0.0; + +/* Process BENCH_BLOCK bytes at a time, for BENCH_INTERVAL clocks. */ +#define BENCH_BLOCK 10240 +#define BENCH_INTERVAL (CLOCKS_PER_SEC / 4) + +/* Total MB:s, for MB/s figures. */ +#define BENCH_TOTAL 10.0 + +/* FIXME: Proper configure test for rdtsc? */ +#ifndef WITH_CYCLE_COUNTER +# if defined(__GNUC__) && defined(__i386__) +# define WITH_CYCLE_COUNTER 1 +# else +# define WITH_CYCLE_COUNTER 0 +# endif +#endif + +#if WITH_CYCLE_COUNTER +#define GET_CYCLE_COUNTER(hi, lo) \ + __asm__("xorl %%eax,%%eax\n" \ + "movl %%ebx, %%edi\n" \ + "cpuid\n" \ + "rdtsc\n" \ + "movl %%edi, %%ebx\n" \ + : "=a" (lo), "=d" (hi) \ + : /* No inputs. */ \ + : "%edi", "%ecx", "cc") +#define BENCH_ITERATIONS 10 +#endif + +/* Returns second per function call */ +static double +time_function(void (*f)(void *arg), void *arg) +{ + clock_t before; + clock_t after; + clock_t done; + unsigned ncalls; + + before = clock(); + done = before + BENCH_INTERVAL; + ncalls = 0; + + do + { + f(arg); + after = clock(); + ncalls++; + } + while (after < done); + + return ((double)(after - before)) / CLOCKS_PER_SEC / ncalls; +} + +struct bench_hash_info +{ + void *ctx; + nettle_hash_update_func *update; + const uint8_t *data; +}; + +static void +bench_hash(void *arg) +{ + struct bench_hash_info *info = arg; + info->update(info->ctx, BENCH_BLOCK, info->data); +} + +struct bench_cipher_info +{ + void *ctx; + nettle_crypt_func *crypt; + uint8_t *data; +}; + +static void +bench_cipher(void *arg) +{ + struct bench_cipher_info *info = arg; + info->crypt(info->ctx, BENCH_BLOCK, info->data, info->data); +} + +struct bench_cbc_info +{ + void *ctx; + nettle_crypt_func *crypt; + + uint8_t *data; + + unsigned block_size; + uint8_t *iv; +}; + +static void +bench_cbc_encrypt(void *arg) +{ + struct bench_cbc_info *info = arg; + cbc_encrypt(info->ctx, info->crypt, + info->block_size, info->iv, + BENCH_BLOCK, info->data, info->data); +} + +static void +bench_cbc_decrypt(void *arg) +{ + struct bench_cbc_info *info = arg; + cbc_decrypt(info->ctx, info->crypt, + info->block_size, info->iv, + BENCH_BLOCK, info->data, info->data); +} + +/* Set data[i] = floor(sqrt(i)) */ +static void +init_data(uint8_t *data) +{ + unsigned i,j; + for (i = j = 0; i 0.0 ? " cycles/byte cycles/block" : ""); +} + +static void +display(const char *name, const char *mode, unsigned block_size, + double time) +{ + printf("%18s %11s %7.2f", + name, mode, + BENCH_BLOCK / (time * 1048576.0)); + if (frequency > 0.0) + { + printf(" %11.2f", time * frequency / BENCH_BLOCK); + if (block_size > 0) + printf(" %12.2f", time * frequency * block_size / BENCH_BLOCK); + } + printf("\n"); +} + +static void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + +static void +time_hash(const struct nettle_hash *hash) +{ + static uint8_t data[BENCH_BLOCK]; + struct bench_hash_info info; + info.ctx = xalloc(hash->context_size); + info.update = hash->update; + info.data = data; + + init_data(data); + hash->init(info.ctx); + + display(hash->name, "update", hash->block_size, + time_function(bench_hash, &info)); + + free(info.ctx); +} + +static void +time_cipher(const struct nettle_cipher *cipher) +{ + void *ctx = xalloc(cipher->context_size); + uint8_t *key = xalloc(cipher->key_size); + + static uint8_t data[BENCH_BLOCK]; + + printf("\n"); + + init_data(data); + + { + /* Decent initializers are a GNU extension, so don't use it here. */ + struct bench_cipher_info info; + info.ctx = ctx; + info.crypt = cipher->encrypt; + info.data = data; + + init_key(cipher->key_size, key); + cipher->set_encrypt_key(ctx, cipher->key_size, key); + + display(cipher->name, "ECB encrypt", cipher->block_size, + time_function(bench_cipher, &info)); + } + + { + struct bench_cipher_info info; + info.ctx = ctx; + info.crypt = cipher->decrypt; + info.data = data; + + init_key(cipher->key_size, key); + cipher->set_decrypt_key(ctx, cipher->key_size, key); + + display(cipher->name, "ECB decrypt", cipher->block_size, + time_function(bench_cipher, &info)); + } + + /* Don't use nettle cbc to benchmark openssl ciphers */ + if (cipher->block_size && cipher->name[0] != 'o') + { + uint8_t *iv = xalloc(cipher->block_size); + + /* Do CBC mode */ + { + struct bench_cbc_info info; + info.ctx = ctx; + info.crypt = cipher->encrypt; + info.data = data; + info.block_size = cipher->block_size; + info.iv = iv; + + memset(iv, 0, sizeof(iv)); + + cipher->set_encrypt_key(ctx, cipher->key_size, key); + + display(cipher->name, "CBC encrypt", cipher->block_size, + time_function(bench_cbc_encrypt, &info)); + } + + { + struct bench_cbc_info info; + info.ctx = ctx; + info.crypt = cipher->decrypt; + info.data = data; + info.block_size = cipher->block_size; + info.iv = iv; + + memset(iv, 0, sizeof(iv)); + + cipher->set_decrypt_key(ctx, cipher->key_size, key); + + display(cipher->name, "CBC decrypt", cipher->block_size, + time_function(bench_cbc_decrypt, &info)); + } + free(iv); + } + free(ctx); + free(key); +} + +static int +compare_double(const void *ap, const void *bp) +{ + double a = *(const double *) ap; + double b = *(const double *) bp; + if (a < b) + return -1; + else if (a > b) + return 1; + else + return 0; +} + +/* Try to get accurate cycle times for assembler functions. */ +static void +bench_sha1_compress(void) +{ +#if WITH_CYCLE_COUNTER + uint32_t state[_SHA1_DIGEST_LENGTH]; + uint8_t data[BENCH_ITERATIONS * SHA1_DATA_SIZE]; + uint32_t start_lo, start_hi, end_lo, end_hi; + + double count[5]; + + uint8_t *p; + unsigned i, j; + + for (j = 0; j < 5; j++) + { + i = 0; + p = data; + GET_CYCLE_COUNTER(start_hi, start_lo); + for (; i < BENCH_ITERATIONS; i++, p += SHA1_DATA_SIZE) + _nettle_sha1_compress(state, p); + + GET_CYCLE_COUNTER(end_hi, end_lo); + + end_hi -= (start_hi + (start_lo > end_lo)); + end_lo -= start_lo; + + count[j] = ldexp(end_hi, 32) + end_lo; + } + + qsort(count, 5, sizeof(double), compare_double); + printf("sha1_compress: %.2f cycles\n\n", count[2] / BENCH_ITERATIONS); +#endif +} + +#if WITH_OPENSSL +# define OPENSSL(x) x, +#else +# define OPENSSL(x) +#endif + +int +main(int argc, char **argv) +{ + unsigned i; + int c; + + const struct nettle_hash *hashes[] = + { + &nettle_md2, &nettle_md4, &nettle_md5, + OPENSSL(&nettle_openssl_md5) + &nettle_sha1, OPENSSL(&nettle_openssl_sha1) + &nettle_sha224, &nettle_sha256, + &nettle_sha384, &nettle_sha512, + NULL + }; + + const struct nettle_cipher *ciphers[] = + { + &nettle_aes128, &nettle_aes192, &nettle_aes256, + OPENSSL(&nettle_openssl_aes128) + OPENSSL(&nettle_openssl_aes192) + OPENSSL(&nettle_openssl_aes256) + &nettle_arcfour128, OPENSSL(&nettle_openssl_arcfour128) + &nettle_blowfish128, OPENSSL(&nettle_openssl_blowfish128) + &nettle_camellia128, &nettle_camellia192, &nettle_camellia256, + &nettle_cast128, OPENSSL(&nettle_openssl_cast128) + &nettle_des, OPENSSL(&nettle_openssl_des) + &nettle_des3, + &nettle_serpent256, + &nettle_twofish128, &nettle_twofish192, &nettle_twofish256, + NULL + }; + + while ( (c = getopt(argc, argv, "f:")) != -1) + switch (c) + { + case 'f': + frequency = atof(optarg); + if (frequency > 0.0) + break; + + case ':': case '?': + fprintf(stderr, "Usage: nettle-benchmark [-f clock frequency]\n"); + return EXIT_FAILURE; + + default: + abort(); + } + + bench_sha1_compress(); + + header(); + + for (i = 0; hashes[i]; i++) + time_hash(hashes[i]); + + for (i = 0; ciphers[i]; i++) + time_cipher(ciphers[i]); + + return 0; +} diff --git a/examples/nettle-openssl.c b/examples/nettle-openssl.c new file mode 100644 index 0000000..5f5f2b1 --- /dev/null +++ b/examples/nettle-openssl.c @@ -0,0 +1,372 @@ +/* nettle-openssl.c + * + * Glue that's used only by the benchmark, and subject to change. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +/* Openssl glue, for comparative benchmarking only */ + +#if WITH_OPENSSL + +/* No ancient ssleay compatibility */ +#define NCOMPAT +#define OPENSSL_DISABLE_OLD_DES_SUPPORT + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "nettle-internal.h" + + +/* AES */ +static nettle_set_key_func openssl_aes_set_encrypt_key; +static void +openssl_aes_set_encrypt_key(void *ctx, unsigned length, const uint8_t *key) +{ + AES_set_encrypt_key(key, length * 8, ctx); +} + +static nettle_set_key_func openssl_aes_set_decrypt_key; +static void +openssl_aes_set_decrypt_key(void *ctx, unsigned length, const uint8_t *key) +{ + AES_set_decrypt_key(key, length * 8, ctx); +} + +static nettle_crypt_func openssl_aes_encrypt; +static void +openssl_aes_encrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % AES_BLOCK_SIZE)); + while (length) + { + AES_ecb_encrypt(src, dst, ctx, AES_ENCRYPT); + length -= AES_BLOCK_SIZE; + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } +} + +static nettle_crypt_func openssl_aes_decrypt; +static void +openssl_aes_decrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % AES_BLOCK_SIZE)); + while (length) + { + AES_ecb_encrypt(src, dst, ctx, AES_DECRYPT); + length -= AES_BLOCK_SIZE; + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } +} + +const struct nettle_cipher +nettle_openssl_aes128 = { + "openssl aes128", sizeof(AES_KEY), + 16, 16, + openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key, + openssl_aes_encrypt, openssl_aes_decrypt +}; + +const struct nettle_cipher +nettle_openssl_aes192 = { + "openssl aes192", sizeof(AES_KEY), + /* Claim no block size, so that the benchmark doesn't try CBC mode + * (as openssl cipher + nettle cbc is somewhat pointless to + * benchmark). */ + 16, 24, + openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key, + openssl_aes_encrypt, openssl_aes_decrypt +}; + +const struct nettle_cipher +nettle_openssl_aes256 = { + "openssl aes256", sizeof(AES_KEY), + /* Claim no block size, so that the benchmark doesn't try CBC mode + * (as openssl cipher + nettle cbc is somewhat pointless to + * benchmark). */ + 16, 32, + openssl_aes_set_encrypt_key, openssl_aes_set_decrypt_key, + openssl_aes_encrypt, openssl_aes_decrypt +}; + +/* Arcfour */ +static nettle_set_key_func openssl_arcfour_set_key; +static void +openssl_arcfour_set_key(void *ctx, unsigned length, const uint8_t *key) +{ + RC4_set_key(ctx, length, key); +} + +static nettle_crypt_func openssl_arcfour_crypt; +static void +openssl_arcfour_crypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + RC4(ctx, length, src, dst); +} + +const struct nettle_cipher +nettle_openssl_arcfour128 = { + "openssl arcfour128", sizeof(RC4_KEY), + 0, 16, + openssl_arcfour_set_key, openssl_arcfour_set_key, + openssl_arcfour_crypt, openssl_arcfour_crypt +}; + +/* Blowfish */ +static nettle_set_key_func openssl_bf_set_key; +static void +openssl_bf_set_key(void *ctx, unsigned length, const uint8_t *key) +{ + BF_set_key(ctx, length, key); +} + +static nettle_crypt_func openssl_bf_encrypt; +static void +openssl_bf_encrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % BF_BLOCK)); + while (length) + { + BF_ecb_encrypt(src, dst, ctx, BF_ENCRYPT); + length -= BF_BLOCK; + dst += BF_BLOCK; + src += BF_BLOCK; + } +} + +static nettle_crypt_func openssl_bf_decrypt; +static void +openssl_bf_decrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % BF_BLOCK)); + while (length) + { + BF_ecb_encrypt(src, dst, ctx, BF_DECRYPT); + length -= BF_BLOCK; + dst += BF_BLOCK; + src += BF_BLOCK; + } +} + +const struct nettle_cipher +nettle_openssl_blowfish128 = { + "openssl bf128", sizeof(BF_KEY), + 8, 16, + openssl_bf_set_key, openssl_bf_set_key, + openssl_bf_encrypt, openssl_bf_decrypt +}; + + +/* DES */ +static nettle_set_key_func openssl_des_set_key; +static void +openssl_des_set_key(void *ctx, unsigned length, const uint8_t *key) +{ + assert(length == 8); + /* Not sure what "unchecked" means. We want to ignore parity bits, + but it would still make sense to check for weak keys. */ + /* Explicit cast used as I don't want to care about openssl's broken + array typedefs DES_cblock and const_DES_cblock. */ + DES_set_key_unchecked( (void *) key, ctx); +} + +#define DES_BLOCK_SIZE 8 + +static nettle_crypt_func openssl_des_encrypt; +static void +openssl_des_encrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % DES_BLOCK_SIZE)); + while (length) + { + DES_ecb_encrypt((void *) src, (void *) dst, ctx, DES_ENCRYPT); + length -= DES_BLOCK_SIZE; + dst += DES_BLOCK_SIZE; + src += DES_BLOCK_SIZE; + } +} + +static nettle_crypt_func openssl_des_decrypt; +static void +openssl_des_decrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % DES_BLOCK_SIZE)); + while (length) + { + DES_ecb_encrypt((void *) src, (void *) dst, ctx, DES_DECRYPT); + length -= DES_BLOCK_SIZE; + dst += DES_BLOCK_SIZE; + src += DES_BLOCK_SIZE; + } +} + +const struct nettle_cipher +nettle_openssl_des = { + "openssl des", sizeof(DES_key_schedule), + 8, 8, + openssl_des_set_key, openssl_des_set_key, + openssl_des_encrypt, openssl_des_decrypt +}; + + +/* Cast128 */ +static nettle_set_key_func openssl_cast_set_key; +static void +openssl_cast_set_key(void *ctx, unsigned length, const uint8_t *key) +{ + CAST_set_key(ctx, length, key); +} + +static nettle_crypt_func openssl_cast_encrypt; +static void +openssl_cast_encrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % CAST_BLOCK)); + while (length) + { + CAST_ecb_encrypt(src, dst, ctx, CAST_ENCRYPT); + length -= CAST_BLOCK; + dst += CAST_BLOCK; + src += CAST_BLOCK; + } +} + +static nettle_crypt_func openssl_cast_decrypt; +static void +openssl_cast_decrypt(void *ctx, unsigned length, + uint8_t *dst, const uint8_t *src) +{ + assert (!(length % CAST_BLOCK)); + while (length) + { + CAST_ecb_encrypt(src, dst, ctx, CAST_DECRYPT); + length -= CAST_BLOCK; + dst += CAST_BLOCK; + src += CAST_BLOCK; + } +} + +const struct nettle_cipher +nettle_openssl_cast128 = { + "openssl cast128", sizeof(CAST_KEY), + 8, CAST_KEY_LENGTH, + openssl_cast_set_key, openssl_cast_set_key, + openssl_cast_encrypt, openssl_cast_decrypt +}; + +/* Hash functions */ + +/* md5 */ +static nettle_hash_init_func openssl_md5_init; +static void +openssl_md5_init(void *ctx) +{ + MD5_Init(ctx); +} + +static nettle_hash_update_func openssl_md5_update; +static void +openssl_md5_update(void *ctx, + unsigned length, + const uint8_t *src) +{ + MD5_Update(ctx, src, length); +} + +static nettle_hash_digest_func openssl_md5_digest; +static void +openssl_md5_digest(void *ctx, + unsigned length, uint8_t *dst) +{ + assert(length == SHA_DIGEST_LENGTH); + MD5_Final(dst, ctx); + MD5_Init(ctx); +} + +const struct nettle_hash +nettle_openssl_md5 = { + "openssl md5", sizeof(SHA_CTX), + SHA_DIGEST_LENGTH, SHA_CBLOCK, + openssl_md5_init, + openssl_md5_update, + openssl_md5_digest +}; + +/* sha1 */ +static nettle_hash_init_func openssl_sha1_init; +static void +openssl_sha1_init(void *ctx) +{ + SHA1_Init(ctx); +} + +static nettle_hash_update_func openssl_sha1_update; +static void +openssl_sha1_update(void *ctx, + unsigned length, + const uint8_t *src) +{ + SHA1_Update(ctx, src, length); +} + +static nettle_hash_digest_func openssl_sha1_digest; +static void +openssl_sha1_digest(void *ctx, + unsigned length, uint8_t *dst) +{ + assert(length == SHA_DIGEST_LENGTH); + SHA1_Final(dst, ctx); + SHA1_Init(ctx); +} + +const struct nettle_hash +nettle_openssl_sha1 = { + "openssl sha1", sizeof(SHA_CTX), + SHA_DIGEST_LENGTH, SHA_CBLOCK, + openssl_sha1_init, + openssl_sha1_update, + openssl_sha1_digest +}; + +#endif /* WITH_OPENSSL */ diff --git a/examples/next-prime.c b/examples/next-prime.c new file mode 100644 index 0000000..5283ecc --- /dev/null +++ b/examples/next-prime.c @@ -0,0 +1,158 @@ +/* next-prime.c + * + * Command line tool for prime search. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2007 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "bignum.h" + +#include "getopt.h" + +static void +usage(void) +{ + fprintf(stderr, "Usage: next-prime [OPTIONS] number\n\n" + "Options:\n" + " --help Display this message.\n" + " -v, --verbose Display timing information.\n" + " --factorial Use factorial of input number.\n" + " -s --sieve-limit Number of primes to use for sieving.\n"); +} + +int +main(int argc, char **argv) +{ + mpz_t n; + mpz_t p; + + int c; + int verbose = 0; + int factorial = 0; + int prime_limit = 200; + + clock_t start; + clock_t end; + + enum { OPT_FACTORIAL = -100 }; + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "verbose", no_argument, NULL, 'v' }, + { "factorial", no_argument, NULL, 'f' }, + { "sieve-limit", required_argument, NULL, 's' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "v?s:", options, NULL)) != -1) + switch (c) + { + case 'v': + verbose = 1; + break; + case '?': + usage(); + return EXIT_FAILURE; + case 'f': + factorial = 1; + break; + case 's': + prime_limit = atoi(optarg); + if (prime_limit < 0) + { + usage(); + return EXIT_FAILURE; + } + break; + default: + abort(); + + } + + argc -= optind; + argv += optind; + + if (argc != 1) + { + usage(); + return EXIT_FAILURE; + } + + mpz_init(n); + + if (factorial) + { + long arg; + char *end; + arg = strtol(argv[0], &end, 0); + if (*end || arg < 0) + { + fprintf(stderr, "Invalid number.\n"); + return EXIT_FAILURE; + } + mpz_fac_ui(n, arg); + } + else if (mpz_set_str(n, argv[0], 0)) + { + fprintf(stderr, "Invalid number.\n"); + return EXIT_FAILURE; + } + + if (mpz_cmp_ui(n, 2) <= 0) + { + printf("2\n"); + return EXIT_SUCCESS; + } + + mpz_init(p); + + start = clock(); + nettle_next_prime(p, n, 25, prime_limit, NULL, NULL); + end = clock(); + + mpz_out_str(stdout, 10, p); + printf("\n"); + + if (verbose) + { + mpz_t d; + + mpz_init(d); + mpz_sub(d, p, n); + + /* Avoid using gmp_fprintf, to stay compatible with gmp-3.1. */ + fprintf(stderr, "bit size: %lu, diff: ", (unsigned long) mpz_sizeinbase(p, 2)); + mpz_out_str(stderr, 10, d); + fprintf(stderr, ", total time: %.3g s\n", + (double)(end - start) / CLOCKS_PER_SEC); + } + return EXIT_SUCCESS; +} diff --git a/examples/random-prime.c b/examples/random-prime.c new file mode 100644 index 0000000..1ed4fcd --- /dev/null +++ b/examples/random-prime.c @@ -0,0 +1,143 @@ +/* random-prime.c + * + * Command line tool for prime generation. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "bignum.h" +#include "yarrow.h" + +#include "io.h" + +#include "getopt.h" + +static void +usage(void) +{ + fprintf(stderr, "Usage: random-prime [OPTIONS] bits\n\n" + "Options:\n" + " --help Display this message.\n" + " -v, --verbose Display timing information.\n" + " -r, --random FILE Random data to use for seeding.\n"); +} + +int +main(int argc, char **argv) +{ + long bits; + mpz_t p; + struct yarrow256_ctx yarrow; + + int verbose = 0; + const char *random_file = NULL; + + int c; + char *arg_end; + + clock_t start; + clock_t end; + + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "verbose", no_argument, NULL, 'v' }, + { "random", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "v?r:", options, NULL)) != -1) + switch (c) + { + case 'v': + verbose = 1; + break; + case 'r': + random_file = optarg; + break; + case '?': + usage(); + return EXIT_FAILURE; + default: + abort(); + } + + argc -= optind; + argv += optind; + + if (argc != 1) + { + usage(); + return EXIT_FAILURE; + } + + bits = strtol(argv[0], &arg_end, 0); + if (*arg_end || bits < 0) + { + fprintf(stderr, "Invalid number.\n"); + return EXIT_FAILURE; + } + + if (bits < 3) + { + fprintf(stderr, "Bitsize must be at least 3.\n"); + return EXIT_FAILURE; + } + + /* NOTE: No sources */ + yarrow256_init(&yarrow, 0, NULL); + + /* Read some data to seed the generator */ + if (!simple_random(&yarrow, random_file)) + { + werror("Initialization of randomness generator failed.\n"); + return EXIT_FAILURE; + } + + mpz_init(p); + + start = clock(); + + nettle_random_prime(p, bits, 0, + &yarrow, (nettle_random_func *) yarrow256_random, + NULL, NULL); + + end = clock(); + + mpz_out_str(stdout, 10, p); + printf("\n"); + + if (verbose) + fprintf(stderr, "time: %.3g s\n", + (double)(end - start) / CLOCKS_PER_SEC); + + return EXIT_SUCCESS; +} diff --git a/examples/read_rsa_key.c b/examples/read_rsa_key.c new file mode 100644 index 0000000..1d092e7 --- /dev/null +++ b/examples/read_rsa_key.c @@ -0,0 +1,50 @@ +/* Used by the rsa example programs. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2007 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "io.h" +#include "rsa.h" + +/* Split out from io.c, since it depends on hogweed. */ +int +read_rsa_key(const char *name, + struct rsa_public_key *pub, + struct rsa_private_key *priv) +{ + unsigned length; + char *buffer; + int res; + + length = read_file(name, 0, &buffer); + if (!length) + return 0; + + res = rsa_keypair_from_sexp(pub, priv, 0, length, buffer); + free(buffer); + + return res; +} diff --git a/examples/rsa-decrypt.c b/examples/rsa-decrypt.c new file mode 100644 index 0000000..5e0ee79 --- /dev/null +++ b/examples/rsa-decrypt.c @@ -0,0 +1,243 @@ +/* rsa-decrypt.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +/* string.h must be included before gmp.h */ +#include "aes.h" +#include "bignum.h" +#include "buffer.h" +#include "cbc.h" +#include "hmac.h" +#include "macros.h" +#include "rsa.h" +#include "yarrow.h" + +#include "io.h" +#include "rsa-session.h" + +void +rsa_session_set_decrypt_key(struct rsa_session *ctx, + const struct rsa_session_info *key) +{ + const uint8_t *aes_key = SESSION_AES_KEY(key); + const uint8_t *iv = SESSION_IV(key); + const uint8_t *hmac_key = SESSION_HMAC_KEY(key); + + aes_set_decrypt_key(&ctx->aes.ctx, AES_KEY_SIZE, aes_key); + CBC_SET_IV(&ctx->aes, iv); + hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key); +} + +static int +read_uint32(FILE *f, uint32_t *n) +{ + uint8_t buf[4]; + if (fread(buf, 1, sizeof(buf), f) != sizeof(buf)) + return 0; + + *n = READ_UINT32(buf); + return 1; +} + +static int +read_version(FILE *f) +{ + uint32_t version; + return read_uint32(f, &version) && version == RSA_VERSION; +} + +static int +read_bignum(FILE *f, mpz_t x) +{ + uint32_t size; + if (read_uint32(f, &size) + && size < 1000) + { + uint8_t *p = xalloc(size); + if (fread(p, 1, size, f) != size) + { + free(p); + return 0; + } + + nettle_mpz_set_str_256_u(x, size, p); + free(p); + + return 1; + } + return 0; +} + +struct process_ctx +{ + struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes; + struct hmac_sha1_ctx hmac; + struct yarrow256_ctx yarrow; +}; + +#define BUF_SIZE (100 * AES_BLOCK_SIZE) + +/* Trailing data that needs special processing */ +#define BUF_FINAL (AES_BLOCK_SIZE + SHA1_DIGEST_SIZE) + +static int +process_file(struct rsa_session *ctx, + FILE *in, FILE *out) +{ + uint8_t buffer[BUF_SIZE + BUF_FINAL]; + uint8_t digest[SHA1_DIGEST_SIZE]; + size_t size; + unsigned padding; + + size = fread(buffer, 1, BUF_FINAL, in); + if (size < BUF_FINAL || ferror(in)) + { + werror("Reading input failed: %s\n", strerror(errno)); + return 0; + } + + do + { + size = fread(buffer + BUF_FINAL, 1, BUF_SIZE, in); + + if (ferror(in)) + { + werror("Reading input failed: %s\n", strerror(errno)); + return 0; + } + + if (size % AES_BLOCK_SIZE != 0) + { + werror("Unexpected EOF on input.\n"); + return 0; + } + + if (size) + { + CBC_DECRYPT(&ctx->aes, aes_decrypt, size, buffer, buffer); + hmac_sha1_update(&ctx->hmac, size, buffer); + if (!write_string(out, size, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + memmove(buffer, buffer + size, BUF_FINAL); + } + } + while (size == BUF_SIZE); + + /* Decrypt final block */ + CBC_DECRYPT(&ctx->aes, aes_decrypt, AES_BLOCK_SIZE, buffer, buffer); + padding = buffer[AES_BLOCK_SIZE - 1]; + if (padding > AES_BLOCK_SIZE) + { + werror("Decryption failed: Invalid padding.\n"); + return 0; + } + + if (padding < AES_BLOCK_SIZE) + { + unsigned leftover = AES_BLOCK_SIZE - padding; + hmac_sha1_update(&ctx->hmac, leftover, buffer); + if (!write_string(out, leftover, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + } + hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, digest); + if (memcmp(digest, buffer + AES_BLOCK_SIZE, SHA1_DIGEST_SIZE) != 0) + { + werror("Decryption failed: Invalid mac.\n"); + return 0; + } + + return 1; +} + +int +main(int argc, char **argv) +{ + struct rsa_private_key key; + struct rsa_session ctx; + struct rsa_session_info session; + + unsigned length; + mpz_t x; + + mpz_init(x); + + if (argc != 2) + { + werror("Usage: rsa-decrypt PRIVATE-KEY < ciphertext\n"); + return EXIT_FAILURE; + } + + rsa_private_key_init(&key); + + if (!read_rsa_key(argv[1], NULL, &key)) + { + werror("Invalid key\n"); + return EXIT_FAILURE; + } + + if (!read_version(stdin)) + { + werror("Bad version number in input file.\n"); + return EXIT_FAILURE; + } + + if (!read_bignum(stdin, x)) + { + werror("Bad rsa header in input file.\n"); + return EXIT_FAILURE; + } + + length = sizeof(session.key); + if (!rsa_decrypt(&key, &length, session.key, x) || length != sizeof(session.key)) + { + werror("Failed to decrypt rsa header in input file.\n"); + return EXIT_FAILURE; + } + mpz_clear(x); + + rsa_session_set_decrypt_key(&ctx, &session); + + if (!process_file(&ctx, + stdin, stdout)) + return EXIT_FAILURE; + + rsa_private_key_clear(&key); + + return EXIT_SUCCESS; +} diff --git a/examples/rsa-encrypt-test b/examples/rsa-encrypt-test new file mode 100755 index 0000000..08b7a44 --- /dev/null +++ b/examples/rsa-encrypt-test @@ -0,0 +1,27 @@ +#! /bin/sh + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +data="$srcdir/nettle-benchmark.c" + +if [ -x rsa-encrypt ] ; then + if ./rsa-encrypt -r rsa-decrypt testkey.pub < "$data" > testciphertext ; then + : + else + exit 1 + fi + if ./rsa-decrypt testkey < testciphertext > testcleartext ; then + : + else + exit 1 + fi + if cmp "$data" testcleartext ; then + exit 0 + else + exit 1 + fi +else + exit 77 +fi diff --git a/examples/rsa-encrypt.c b/examples/rsa-encrypt.c new file mode 100644 index 0000000..e87dcb6 --- /dev/null +++ b/examples/rsa-encrypt.c @@ -0,0 +1,240 @@ +/* rsa-encrypt.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +/* string.h must be included before gmp.h */ +#include "bignum.h" +#include "buffer.h" +#include "macros.h" +#include "rsa.h" +#include "yarrow.h" + +#include "io.h" +#include "rsa-session.h" + +#include "getopt.h" + +void +rsa_session_set_encrypt_key(struct rsa_session *ctx, + const struct rsa_session_info *key) +{ + const uint8_t *aes_key = SESSION_AES_KEY(key); + const uint8_t *iv = SESSION_IV(key); + const uint8_t *hmac_key = SESSION_HMAC_KEY(key); + + aes_set_encrypt_key(&ctx->aes.ctx, AES_KEY_SIZE, aes_key); + CBC_SET_IV(&ctx->aes, iv); + hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key); +} + +static int +write_uint32(FILE *f, uint32_t n) +{ + uint8_t buffer[4]; + WRITE_UINT32(buffer, n); + + return write_string(f, sizeof(buffer), buffer); +} + +static int +write_version(FILE *f) +{ + return write_uint32(f, 1); +} + +static int +write_bignum(FILE *f, mpz_t x) +{ + unsigned size = nettle_mpz_sizeinbase_256_u(x); + uint8_t *p; + int res; + + if (!write_uint32(f, size)) + return 0; + + p = xalloc(size); + nettle_mpz_get_str_256(size, p, x); + + res = write_string(f, size, p); + free(p); + return res; +} + +static int +process_file(struct rsa_session *ctx, + FILE *in, FILE *out) +{ + uint8_t buffer[AES_BLOCK_SIZE * 100]; + unsigned leftover; + unsigned padding; + + padding = leftover = 0; + + for (;;) + { + size_t size = fread(buffer, 1, sizeof(buffer), in); + if (ferror(in)) + { + werror("Reading input failed: %s\n", strerror(errno)); + return 0; + } + + hmac_sha1_update(&ctx->hmac, size, buffer); + if (size < sizeof(buffer)) + { + /* Setting padding != ends the loop */ + leftover = size % AES_BLOCK_SIZE; + padding = AES_BLOCK_SIZE - leftover; + size -= leftover; + + if (!size) + break; + } + + CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer); + if (!write_string(out, size, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + + if (padding) + { + if (leftover) + memcpy(buffer, buffer + size, leftover); + + break; + } + } + if (padding > 1) + yarrow256_random(&ctx->yarrow, padding - 1, buffer + leftover); + + buffer[AES_BLOCK_SIZE - 1] = padding; + CBC_ENCRYPT(&ctx->aes, aes_encrypt, AES_BLOCK_SIZE, buffer, buffer); + hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, buffer + AES_BLOCK_SIZE); + + if (!write_string(out, AES_BLOCK_SIZE + SHA1_DIGEST_SIZE, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + + return 1; +} + +int +main(int argc, char **argv) +{ + struct rsa_session ctx; + struct rsa_session_info info; + + struct rsa_public_key key; + mpz_t x; + + int c; + const char *random_name = NULL; + + while ( (c = getopt(argc, argv, "o:r:")) != -1) + switch (c) + { + case 'r': + random_name = optarg; + break; + + case '?': + if (isprint (optopt)) + werror("Unknown option `-%c'.\n", optopt); + else + werror("Unknown option character `\\x%x'.\n", + optopt); + return EXIT_FAILURE; + default: + abort(); + } + + argv += optind; + argc -= optind; + + if (argc != 1) + { + werror("Usage: rsa-encrypt [-r random-file] PUBLIC-KEY < cleartext\n"); + return EXIT_FAILURE; + } + + rsa_public_key_init(&key); + + if (!read_rsa_key(argv[0], &key, NULL)) + { + werror("Invalid key\n"); + return EXIT_FAILURE; + } + + /* NOTE: No sources */ + yarrow256_init(&ctx.yarrow, 0, NULL); + + /* Read some data to seed the generator */ + if (!simple_random(&ctx.yarrow, random_name)) + { + werror("Initialization of randomness generator failed.\n"); + return EXIT_FAILURE; + } + + WRITE_UINT32(SESSION_VERSION(&info), RSA_VERSION); + + yarrow256_random(&ctx.yarrow, sizeof(info.key) - 4, info.key + 4); + + rsa_session_set_encrypt_key(&ctx, &info); + + write_version(stdout); + + mpz_init(x); + + if (!rsa_encrypt(&key, + &ctx.yarrow, (nettle_random_func *) yarrow256_random, + sizeof(info.key), info.key, + x)) + { + werror("RSA encryption failed.\n"); + return EXIT_FAILURE; + } + + write_bignum(stdout, x); + + if (!process_file(&ctx, + stdin, stdout)) + return EXIT_FAILURE; + + rsa_public_key_clear(&key); + + return EXIT_SUCCESS; +} diff --git a/examples/rsa-keygen.c b/examples/rsa-keygen.c new file mode 100644 index 0000000..2f70e55 --- /dev/null +++ b/examples/rsa-keygen.c @@ -0,0 +1,156 @@ +/* rsa-keygen.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "buffer.h" +#include "rsa.h" +#include "sexp.h" +#include "yarrow.h" + +#include "io.h" + +#include "getopt.h" + +#define KEYSIZE 900 +#define ESIZE 30 + +static void +progress(void *ctx, int c) +{ + (void) ctx; + fputc(c, stderr); +} + + +int +main(int argc, char **argv) +{ + struct yarrow256_ctx yarrow; + struct rsa_public_key pub; + struct rsa_private_key priv; + + int c; + char *pub_name = NULL; + const char *priv_name = NULL; + const char *random_name = NULL; + + struct nettle_buffer pub_buffer; + struct nettle_buffer priv_buffer; + + while ( (c = getopt(argc, argv, "o:r:")) != -1) + switch (c) + { + case 'o': + priv_name = optarg; + break; + + case 'r': + random_name = optarg; + break; + + case '?': + if (isprint (optopt)) + werror("Unknown option `-%c'.\n", optopt); + else + werror("Unknown option character `\\x%x'.\n", + optopt); + return EXIT_FAILURE; + default: + abort(); + } + + if (!priv_name) + { + werror("No filename provided.\n"); + return EXIT_FAILURE; + } + + pub_name = xalloc(strlen(priv_name) + 5); + sprintf(pub_name, "%s.pub", priv_name); + + /* NOTE: No sources */ + yarrow256_init(&yarrow, 0, NULL); + + /* Read some data to seed the generator */ + if (!simple_random(&yarrow, random_name)) + { + werror("Initialization of randomness generator failed.\n"); + return EXIT_FAILURE; + } + + rsa_public_key_init(&pub); + rsa_private_key_init(&priv); + + if (!rsa_generate_keypair + (&pub, &priv, + (void *) &yarrow, (nettle_random_func *) yarrow256_random, + NULL, progress, + KEYSIZE, ESIZE)) + { + werror("Key generation failed.\n"); + return EXIT_FAILURE; + } + + nettle_buffer_init(&priv_buffer); + nettle_buffer_init(&pub_buffer); + + if (!rsa_keypair_to_sexp(&pub_buffer, "rsa-pkcs1-sha1", &pub, NULL)) + { + werror("Formatting public key failed.\n"); + return EXIT_FAILURE; + } + + if (!rsa_keypair_to_sexp(&priv_buffer, "rsa-pkcs1-sha1", &pub, &priv)) + { + werror("Formatting private key failed.\n"); + return EXIT_FAILURE; + } + + if (!write_file(pub_name, pub_buffer.size, pub_buffer.contents)) + { + werror("Failed to write public key: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + /* NOTE: This doesn't set up paranoid access restrictions on the + * private key file, like a serious key generation tool would do. */ + if (!write_file(priv_name, priv_buffer.size, priv_buffer.contents)) + { + werror("Failed to write private key: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/examples/rsa-session.h b/examples/rsa-session.h new file mode 100644 index 0000000..44b85ec --- /dev/null +++ b/examples/rsa-session.h @@ -0,0 +1,66 @@ +/* Session key definitions for the rsa-encrypt and rsa-decrypt programs. + */ + +#ifndef NETTLE_EXAMPLES_RSA_SESSION_H_INCLUDED +#define NETTLE_EXAMPLES_RSA_SESSION_H_INCLUDED + +#include "aes.h" +#include "cbc.h" +#include "hmac.h" + +#define RSA_VERSION 1 + +/* Encryption program using the following file format: + + uint32_t version = 1; + uint32_t nsize; + uint8_t x[nsize]; + uint8_t encrypted[n]; + uint8_t hmac[SHA1_DIGEST_SIZE]; + + where x is the data + + uint32_t version = 1; + uint8_t aes_key[AES_KEY_SIZE]; + uint8_t iv[AES_BLOCK_SIZE]; + uint8_t hmac_key[SHA1_DIGEST_SIZE]; + + of size (4 + AES_KEY_SIZE + AES_BLOCK_SIZE + SHA1_DIGEST_SIZE) = 72 + bytes, encrypted using rsa-pkcs1. + + The cleartext input is encrypted using aes-cbc. The final block is + padded as + + | data | random octets | padding length | + + where the last octet is the padding length, a number between 1 and + AES_BLOCK_SIZE (inclusive). +*/ + +struct rsa_session +{ + struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes; + struct hmac_sha1_ctx hmac; + struct yarrow256_ctx yarrow; +}; + +struct rsa_session_info +{ + /* Version followed by aes key, iv and mac key */ + uint8_t key[4 + AES_KEY_SIZE + AES_BLOCK_SIZE + SHA1_DIGEST_SIZE]; +}; + +#define SESSION_VERSION(s) ((s)->key) +#define SESSION_AES_KEY(s) ((s)->key + 4) +#define SESSION_IV(s) ((s)->key + 4 + AES_KEY_SIZE) +#define SESSION_HMAC_KEY(s) ((s)->key + 4 + AES_KEY_SIZE + AES_BLOCK_SIZE) + +void +rsa_session_set_encrypt_key(struct rsa_session *ctx, + const struct rsa_session_info *key); + +void +rsa_session_set_decrypt_key(struct rsa_session *ctx, + const struct rsa_session_info *key); + +#endif /* NETTLE_EXAMPLES_RSA_SESSION_H_INCLUDED */ diff --git a/examples/rsa-sign-test b/examples/rsa-sign-test new file mode 100755 index 0000000..1621226 --- /dev/null +++ b/examples/rsa-sign-test @@ -0,0 +1,17 @@ +#! /bin/sh + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +data="$srcdir/nettle-benchmark.c" + +if [ -x rsa-sign ] ; then + if ./rsa-sign testkey < "$data" > testsignature ; then + exit 0; + else + exit 1 + fi +else + exit 77 +fi diff --git a/examples/rsa-sign.c b/examples/rsa-sign.c new file mode 100644 index 0000000..c480761 --- /dev/null +++ b/examples/rsa-sign.c @@ -0,0 +1,87 @@ +/* rsa-sign.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +/* string.h must be included before gmp.h */ +#include "rsa.h" +#include "io.h" + +int +main(int argc, char **argv) +{ + struct rsa_private_key key; + struct sha1_ctx hash; + mpz_t s; + + if (argc != 2) + { + werror("Usage: rsa-sign PRIVATE-KEY < file\n"); + return EXIT_FAILURE; + } + + rsa_private_key_init(&key); + + if (!read_rsa_key(argv[1], NULL, &key)) + { + werror("Invalid key\n"); + return EXIT_FAILURE; + } + + sha1_init(&hash); + if (!hash_file(&nettle_sha1, &hash, stdin)) + { + werror("Failed reading stdin: %s\n", + strerror(errno)); + return 0; + } + + mpz_init(s); + if (!rsa_sha1_sign(&key, &hash, s)) + { + werror("RSA key too small\n"); + return 0; + } + + if (!mpz_out_str(stdout, 16, s)) + { + werror("Failed writing signature: %s\n", + strerror(errno)); + return 0; + } + + putchar('\n'); + + mpz_clear(s); + rsa_private_key_clear(&key); + + return EXIT_SUCCESS; +} diff --git a/examples/rsa-verify-test b/examples/rsa-verify-test new file mode 100755 index 0000000..765b61f --- /dev/null +++ b/examples/rsa-verify-test @@ -0,0 +1,29 @@ +#! /bin/sh + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +data="$srcdir/nettle-benchmark.c" + +if [ -x rsa-verify ] ; then + ./rsa-sign testkey < "$data" > testsignature \ + && ./rsa-verify testkey.pub testsignature < "$data" \ + || exit 1; + + # Try modifying the data + sed s/128/129/ < "$data" >testdata + + if ./rsa-verify testkey.pub testsignature < testdata 2>/dev/null; then + exit 1 + fi + + # Try modifying the signature + sed s/1/2/ testsignature2 + if ./rsa-verify testkey.pub testsignature2 < "$data" 2>/dev/null; then + exit 1; + fi + exit 0 +else + exit 77 +fi diff --git a/examples/rsa-verify.c b/examples/rsa-verify.c new file mode 100644 index 0000000..8781812 --- /dev/null +++ b/examples/rsa-verify.c @@ -0,0 +1,102 @@ +/* rsa-verify.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "rsa.h" +#include "io.h" + +static int +read_signature(const char *name, mpz_t s) +{ + char *buffer; + unsigned length; + int res; + + length = read_file(name, 0, &buffer); + if (!length) + return 0; + + res = (mpz_set_str(s, buffer, 16) == 0); + free(buffer); + + return res; +} + +int +main(int argc, char **argv) +{ + struct rsa_public_key key; + struct sha1_ctx hash; + mpz_t s; + + if (argc != 3) + { + werror("Usage: rsa-verify PUBLIC-KEY SIGNATURE-FILE < FILE\n"); + return EXIT_FAILURE; + } + + rsa_public_key_init(&key); + + if (!read_rsa_key(argv[1], &key, NULL)) + { + werror("Invalid key\n"); + return EXIT_FAILURE; + } + + mpz_init(s); + + if (!read_signature(argv[2], s)) + { + werror("Failed to read signature file `%s'\n", + argv[2]); + return EXIT_FAILURE; + } + + sha1_init(&hash); + if (!hash_file(&nettle_sha1, &hash, stdin)) + { + werror("Failed reading stdin: %s\n", + strerror(errno)); + return 0; + } + + if (!rsa_sha1_verify(&key, &hash, s)) + { + werror("Invalid signature!\n"); + return EXIT_FAILURE; + } + + mpz_clear(s); + rsa_public_key_clear(&key); + + return EXIT_SUCCESS; +} diff --git a/examples/run-tests b/examples/run-tests new file mode 100755 index 0000000..f240599 --- /dev/null +++ b/examples/run-tests @@ -0,0 +1,104 @@ +#! /bin/sh + +failed=0 +all=0 + +debug='no' +testflags='' + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +export srcdir + +# When used in make rules, we sometimes get the filenames VPATH +# expanded, but usually not. +find_program () { + case "$1" in + */*) + echo "$1" + ;; + *) + if [ -x "$1" ] ; then + echo "./$1" + else + echo "$srcdir/$1" + fi + ;; + esac +} + +env_program () { + if [ -x "$1" ] ; then + if "$1"; then : ; else + echo FAIL: $1 + exit 1 + fi + fi +} + +test_program () { + testname=`basename "$1" .exe` + testname=`basename "$testname" -test` + "$1" $testflags + case "$?" in + 0) + echo PASS: $testname + all=`expr $all + 1` + ;; + 77) + echo SKIP: $testname + ;; + *) + echo FAIL: $testname + failed=`expr $failed + 1` + all=`expr $all + 1` + ;; + esac +} + +env_program `find_program setup-env` + +while test $# != 0 +do + case "$1" in + --debug) + debug=yes + ;; + -v) + testflags='-v' + ;; + -*) + echo >&2 'Unknown option `'"$1'" + exit 1 + ;; + *) + break + ;; + esac + shift +done + +if [ $# -eq 0 ] ; then + for f in *-test; do test_program "./$f"; done +else + for f in "$@" ; do test_program `find_program "$f"`; done +fi + +if [ $failed -eq 0 ] ; then + banner="All $all tests passed" +else + banner="$failed of $all tests failed" +fi +dashes=`echo "$banner" | sed s/./=/g` +echo "$dashes" +echo "$banner" +echo "$dashes" + +if [ "x$debug" = xno ] ; then + env_program `find_program teardown-env` +fi + +[ "$failed" -eq 0 ] + diff --git a/examples/setup-env b/examples/setup-env new file mode 100755 index 0000000..7588d6f --- /dev/null +++ b/examples/setup-env @@ -0,0 +1,7 @@ +#! /bin/sh + +set -e + +if [ -x rsa-keygen ] ; then + ./rsa-keygen -r rsa-decrypt -o testkey || exit 1 +fi diff --git a/examples/teardown-env b/examples/teardown-env new file mode 100755 index 0000000..ce1a157 --- /dev/null +++ b/examples/teardown-env @@ -0,0 +1,6 @@ +#! /bin/sh + +rm -rf testkey testkey.pub testsignature testsignature2 testdata \ + testciphertext testcleartext + + diff --git a/hmac-md5.c b/hmac-md5.c new file mode 100644 index 0000000..99ce1f9 --- /dev/null +++ b/hmac-md5.c @@ -0,0 +1,51 @@ +/* hmac-md5.c + * + * HMAC-MD5 message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_md5_set_key(struct hmac_md5_ctx *ctx, + unsigned key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_md5, key_length, key); +} + +void +hmac_md5_update(struct hmac_md5_ctx *ctx, + unsigned length, const uint8_t *data) +{ + md5_update(&ctx->state, length, data); +} + +void +hmac_md5_digest(struct hmac_md5_ctx *ctx, + unsigned length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_md5, length, digest); +} diff --git a/hmac-sha1.c b/hmac-sha1.c new file mode 100644 index 0000000..64c079e --- /dev/null +++ b/hmac-sha1.c @@ -0,0 +1,51 @@ +/* hmac-sha1.c + * + * HMAC-SHA1 message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha1_set_key(struct hmac_sha1_ctx *ctx, + unsigned key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha1, key_length, key); +} + +void +hmac_sha1_update(struct hmac_sha1_ctx *ctx, + unsigned length, const uint8_t *data) +{ + sha1_update(&ctx->state, length, data); +} + +void +hmac_sha1_digest(struct hmac_sha1_ctx *ctx, + unsigned length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_sha1, length, digest); +} diff --git a/hmac-sha224.c b/hmac-sha224.c new file mode 100644 index 0000000..580509e --- /dev/null +++ b/hmac-sha224.c @@ -0,0 +1,44 @@ +/* hmac-sha224.c + * + * HMAC-SHA224 message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha224_set_key(struct hmac_sha224_ctx *ctx, + unsigned key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha224, key_length, key); +} + +void +hmac_sha224_digest(struct hmac_sha224_ctx *ctx, + unsigned length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_sha224, length, digest); +} diff --git a/hmac-sha256.c b/hmac-sha256.c new file mode 100644 index 0000000..9ead853 --- /dev/null +++ b/hmac-sha256.c @@ -0,0 +1,51 @@ +/* hmac-sha256.c + * + * HMAC-SHA256 message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha256_set_key(struct hmac_sha256_ctx *ctx, + unsigned key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha256, key_length, key); +} + +void +hmac_sha256_update(struct hmac_sha256_ctx *ctx, + unsigned length, const uint8_t *data) +{ + sha256_update(&ctx->state, length, data); +} + +void +hmac_sha256_digest(struct hmac_sha256_ctx *ctx, + unsigned length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_sha256, length, digest); +} diff --git a/hmac-sha384.c b/hmac-sha384.c new file mode 100644 index 0000000..f39705f --- /dev/null +++ b/hmac-sha384.c @@ -0,0 +1,44 @@ +/* hmac-sha384.c + * + * HMAC-SHA384 message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha384_set_key(struct hmac_sha512_ctx *ctx, + unsigned key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha384, key_length, key); +} + +void +hmac_sha384_digest(struct hmac_sha512_ctx *ctx, + unsigned length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_sha384, length, digest); +} diff --git a/hmac-sha512.c b/hmac-sha512.c new file mode 100644 index 0000000..c09e9f5 --- /dev/null +++ b/hmac-sha512.c @@ -0,0 +1,51 @@ +/* hmac-sha512.c + * + * HMAC-SHA512 message authentication code. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha512_set_key(struct hmac_sha512_ctx *ctx, + unsigned key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha512, key_length, key); +} + +void +hmac_sha512_update(struct hmac_sha512_ctx *ctx, + unsigned length, const uint8_t *data) +{ + sha512_update(&ctx->state, length, data); +} + +void +hmac_sha512_digest(struct hmac_sha512_ctx *ctx, + unsigned length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_sha512, length, digest); +} diff --git a/hmac.c b/hmac.c new file mode 100644 index 0000000..dc77e94 --- /dev/null +++ b/hmac.c @@ -0,0 +1,109 @@ +/* hmac.c + * + * HMAC message authentication code (RFC-2104). + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +/* Needed for alloca on freebsd */ +#include +#include + +#include "hmac.h" + +#include "memxor.h" +#include "nettle-internal.h" + +#define IPAD 0x36 +#define OPAD 0x5c + +void +hmac_set_key(void *outer, void *inner, void *state, + const struct nettle_hash *hash, + unsigned key_length, const uint8_t *key) +{ + TMP_DECL(pad, uint8_t, NETTLE_MAX_HASH_BLOCK_SIZE); + TMP_ALLOC(pad, hash->block_size); + + hash->init(outer); + hash->init(inner); + + if (key_length > hash->block_size) + { + /* Reduce key to the algorithm's hash size. Use the area pointed + * to by state for the temporary state. */ + + TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_ALLOC(digest, hash->digest_size); + + hash->init(state); + hash->update(state, key_length, key); + hash->digest(state, hash->digest_size, digest); + + key = digest; + key_length = hash->digest_size; + } + + assert(key_length <= hash->block_size); + + memset(pad, OPAD, hash->block_size); + memxor(pad, key, key_length); + + hash->update(outer, hash->block_size, pad); + + memset(pad, IPAD, hash->block_size); + memxor(pad, key, key_length); + + hash->update(inner, hash->block_size, pad); + + memcpy(state, inner, hash->context_size); +} + +void +hmac_update(void *state, + const struct nettle_hash *hash, + unsigned length, const uint8_t *data) +{ + hash->update(state, length, data); +} + +void +hmac_digest(const void *outer, const void *inner, void *state, + const struct nettle_hash *hash, + unsigned length, uint8_t *dst) +{ + TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_ALLOC(digest, hash->digest_size); + + hash->digest(state, hash->digest_size, digest); + + memcpy(state, outer, hash->context_size); + + hash->update(state, hash->digest_size, digest); + hash->digest(state, length, dst); + + memcpy(state, inner, hash->context_size); +} diff --git a/hmac.h b/hmac.h new file mode 100644 index 0000000..0142e6e --- /dev/null +++ b/hmac.h @@ -0,0 +1,181 @@ +/* hmac.h + * + * HMAC message authentication code (RFC-2104). + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_HMAC_H_INCLUDED +#define NETTLE_HMAC_H_INCLUDED + +#include "nettle-meta.h" + +#include "md5.h" +#include "sha.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Namespace mangling */ +#define hmac_set_key nettle_hmac_set_key +#define hmac_update nettle_hmac_update +#define hmac_digest nettle_hmac_digest +#define hmac_md5_set_key nettle_hmac_md5_set_key +#define hmac_md5_update nettle_hmac_md5_update +#define hmac_md5_digest nettle_hmac_md5_digest +#define hmac_sha1_set_key nettle_hmac_sha1_set_key +#define hmac_sha1_update nettle_hmac_sha1_update +#define hmac_sha1_digest nettle_hmac_sha1_digest +#define hmac_sha224_set_key nettle_hmac_sha224_set_key +#define hmac_sha224_digest nettle_hmac_sha224_digest +#define hmac_sha256_set_key nettle_hmac_sha256_set_key +#define hmac_sha256_update nettle_hmac_sha256_update +#define hmac_sha256_digest nettle_hmac_sha256_digest +#define hmac_sha384_set_key nettle_hmac_sha384_set_key +#define hmac_sha384_digest nettle_hmac_sha384_digest +#define hmac_sha512_set_key nettle_hmac_sha512_set_key +#define hmac_sha512_update nettle_hmac_sha512_update +#define hmac_sha512_digest nettle_hmac_sha512_digest + +void +hmac_set_key(void *outer, void *inner, void *state, + const struct nettle_hash *hash, + unsigned length, const uint8_t *key); + +/* This function is not strictly needed, it's s just the same as the + * hash update function. */ +void +hmac_update(void *state, + const struct nettle_hash *hash, + unsigned length, const uint8_t *data); + +void +hmac_digest(const void *outer, const void *inner, void *state, + const struct nettle_hash *hash, + unsigned length, uint8_t *digest); + + +#define HMAC_CTX(type) \ +{ type outer; type inner; type state; } + +#define HMAC_SET_KEY(ctx, hash, length, key) \ + hmac_set_key( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \ + (hash), (length), (key) ) + +#define HMAC_DIGEST(ctx, hash, length, digest) \ + hmac_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \ + (hash), (length), (digest) ) + +/* HMAC using specific hash functions */ + +/* hmac-md5 */ +struct hmac_md5_ctx HMAC_CTX(struct md5_ctx); + +void +hmac_md5_set_key(struct hmac_md5_ctx *ctx, + unsigned key_length, const uint8_t *key); + +void +hmac_md5_update(struct hmac_md5_ctx *ctx, + unsigned length, const uint8_t *data); + +void +hmac_md5_digest(struct hmac_md5_ctx *ctx, + unsigned length, uint8_t *digest); + + +/* hmac-sha1 */ +struct hmac_sha1_ctx HMAC_CTX(struct sha1_ctx); + +void +hmac_sha1_set_key(struct hmac_sha1_ctx *ctx, + unsigned key_length, const uint8_t *key); + +void +hmac_sha1_update(struct hmac_sha1_ctx *ctx, + unsigned length, const uint8_t *data); + +void +hmac_sha1_digest(struct hmac_sha1_ctx *ctx, + unsigned length, uint8_t *digest); + +/* hmac-sha256 */ +struct hmac_sha256_ctx HMAC_CTX(struct sha256_ctx); + +void +hmac_sha256_set_key(struct hmac_sha256_ctx *ctx, + unsigned key_length, const uint8_t *key); + +void +hmac_sha256_update(struct hmac_sha256_ctx *ctx, + unsigned length, const uint8_t *data); + +void +hmac_sha256_digest(struct hmac_sha256_ctx *ctx, + unsigned length, uint8_t *digest); + +/* hmac-sha224 */ +#define hmac_sha224_ctx hmac_sha256_ctx + +void +hmac_sha224_set_key(struct hmac_sha224_ctx *ctx, + unsigned key_length, const uint8_t *key); + +#define hmac_sha224_update nettle_hmac_sha256_update + +void +hmac_sha224_digest(struct hmac_sha224_ctx *ctx, + unsigned length, uint8_t *digest); + +/* hmac-sha512 */ +struct hmac_sha512_ctx HMAC_CTX(struct sha512_ctx); + +void +hmac_sha512_set_key(struct hmac_sha512_ctx *ctx, + unsigned key_length, const uint8_t *key); + +void +hmac_sha512_update(struct hmac_sha512_ctx *ctx, + unsigned length, const uint8_t *data); + +void +hmac_sha512_digest(struct hmac_sha512_ctx *ctx, + unsigned length, uint8_t *digest); + +/* hmac-sha384 */ +#define hmac_sha384_ctx hmac_sha512_ctx + +void +hmac_sha384_set_key(struct hmac_sha512_ctx *ctx, + unsigned key_length, const uint8_t *key); + +#define hmac_sha384_update nettle_hmac_sha512_update + +void +hmac_sha384_digest(struct hmac_sha512_ctx *ctx, + unsigned length, uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_HMAC_H_INCLUDED */ diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..4fbbae7 --- /dev/null +++ b/install-sh @@ -0,0 +1,507 @@ +#!/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: diff --git a/keymap.h b/keymap.h new file mode 100644 index 0000000..5600c32 --- /dev/null +++ b/keymap.h @@ -0,0 +1,138 @@ +/* automagically made - do not fuss with this */ + + 0x02080008, 0x02082000, 0x00002008, 0x00000000, + 0x02002000, 0x00080008, 0x02080000, 0x02082008, + 0x00000008, 0x02000000, 0x00082000, 0x00002008, + 0x00082008, 0x02002008, 0x02000008, 0x02080000, + 0x00002000, 0x00082008, 0x00080008, 0x02002000, + 0x02082008, 0x02000008, 0x00000000, 0x00082000, + 0x02000000, 0x00080000, 0x02002008, 0x02080008, + 0x00080000, 0x00002000, 0x02082000, 0x00000008, + 0x00080000, 0x00002000, 0x02000008, 0x02082008, + 0x00002008, 0x02000000, 0x00000000, 0x00082000, + 0x02080008, 0x02002008, 0x02002000, 0x00080008, + 0x02082000, 0x00000008, 0x00080008, 0x02002000, + 0x02082008, 0x00080000, 0x02080000, 0x02000008, + 0x00082000, 0x00002008, 0x02002008, 0x02080000, + 0x00000008, 0x02082000, 0x00082008, 0x00000000, + 0x02000000, 0x02080008, 0x00002000, 0x00082008, + + 0x08000004, 0x00020004, 0x00000000, 0x08020200, + 0x00020004, 0x00000200, 0x08000204, 0x00020000, + 0x00000204, 0x08020204, 0x00020200, 0x08000000, + 0x08000200, 0x08000004, 0x08020000, 0x00020204, + 0x00020000, 0x08000204, 0x08020004, 0x00000000, + 0x00000200, 0x00000004, 0x08020200, 0x08020004, + 0x08020204, 0x08020000, 0x08000000, 0x00000204, + 0x00000004, 0x00020200, 0x00020204, 0x08000200, + 0x00000204, 0x08000000, 0x08000200, 0x00020204, + 0x08020200, 0x00020004, 0x00000000, 0x08000200, + 0x08000000, 0x00000200, 0x08020004, 0x00020000, + 0x00020004, 0x08020204, 0x00020200, 0x00000004, + 0x08020204, 0x00020200, 0x00020000, 0x08000204, + 0x08000004, 0x08020000, 0x00020204, 0x00000000, + 0x00000200, 0x08000004, 0x08000204, 0x08020200, + 0x08020000, 0x00000204, 0x00000004, 0x08020004, + + 0x80040100, 0x01000100, 0x80000000, 0x81040100, + 0x00000000, 0x01040000, 0x81000100, 0x80040000, + 0x01040100, 0x81000000, 0x01000000, 0x80000100, + 0x81000000, 0x80040100, 0x00040000, 0x01000000, + 0x81040000, 0x00040100, 0x00000100, 0x80000000, + 0x00040100, 0x81000100, 0x01040000, 0x00000100, + 0x80000100, 0x00000000, 0x80040000, 0x01040100, + 0x01000100, 0x81040000, 0x81040100, 0x00040000, + 0x81040000, 0x80000100, 0x00040000, 0x81000000, + 0x00040100, 0x01000100, 0x80000000, 0x01040000, + 0x81000100, 0x00000000, 0x00000100, 0x80040000, + 0x00000000, 0x81040000, 0x01040100, 0x00000100, + 0x01000000, 0x81040100, 0x80040100, 0x00040000, + 0x81040100, 0x80000000, 0x01000100, 0x80040100, + 0x80040000, 0x00040100, 0x01040000, 0x81000100, + 0x80000100, 0x01000000, 0x81000000, 0x01040100, + + 0x04010801, 0x00000000, 0x00010800, 0x04010000, + 0x04000001, 0x00000801, 0x04000800, 0x00010800, + 0x00000800, 0x04010001, 0x00000001, 0x04000800, + 0x00010001, 0x04010800, 0x04010000, 0x00000001, + 0x00010000, 0x04000801, 0x04010001, 0x00000800, + 0x00010801, 0x04000000, 0x00000000, 0x00010001, + 0x04000801, 0x00010801, 0x04010800, 0x04000001, + 0x04000000, 0x00010000, 0x00000801, 0x04010801, + 0x00010001, 0x04010800, 0x04000800, 0x00010801, + 0x04010801, 0x00010001, 0x04000001, 0x00000000, + 0x04000000, 0x00000801, 0x00010000, 0x04010001, + 0x00000800, 0x04000000, 0x00010801, 0x04000801, + 0x04010800, 0x00000800, 0x00000000, 0x04000001, + 0x00000001, 0x04010801, 0x00010800, 0x04010000, + 0x04010001, 0x00010000, 0x00000801, 0x04000800, + 0x04000801, 0x00000001, 0x04010000, 0x00010800, + + 0x00000400, 0x00000020, 0x00100020, 0x40100000, + 0x40100420, 0x40000400, 0x00000420, 0x00000000, + 0x00100000, 0x40100020, 0x40000020, 0x00100400, + 0x40000000, 0x00100420, 0x00100400, 0x40000020, + 0x40100020, 0x00000400, 0x40000400, 0x40100420, + 0x00000000, 0x00100020, 0x40100000, 0x00000420, + 0x40100400, 0x40000420, 0x00100420, 0x40000000, + 0x40000420, 0x40100400, 0x00000020, 0x00100000, + 0x40000420, 0x00100400, 0x40100400, 0x40000020, + 0x00000400, 0x00000020, 0x00100000, 0x40100400, + 0x40100020, 0x40000420, 0x00000420, 0x00000000, + 0x00000020, 0x40100000, 0x40000000, 0x00100020, + 0x00000000, 0x40100020, 0x00100020, 0x00000420, + 0x40000020, 0x00000400, 0x40100420, 0x00100000, + 0x00100420, 0x40000000, 0x40000400, 0x40100420, + 0x40100000, 0x00100420, 0x00100400, 0x40000400, + + 0x00800000, 0x00001000, 0x00000040, 0x00801042, + 0x00801002, 0x00800040, 0x00001042, 0x00801000, + 0x00001000, 0x00000002, 0x00800002, 0x00001040, + 0x00800042, 0x00801002, 0x00801040, 0x00000000, + 0x00001040, 0x00800000, 0x00001002, 0x00000042, + 0x00800040, 0x00001042, 0x00000000, 0x00800002, + 0x00000002, 0x00800042, 0x00801042, 0x00001002, + 0x00801000, 0x00000040, 0x00000042, 0x00801040, + 0x00801040, 0x00800042, 0x00001002, 0x00801000, + 0x00001000, 0x00000002, 0x00800002, 0x00800040, + 0x00800000, 0x00001040, 0x00801042, 0x00000000, + 0x00001042, 0x00800000, 0x00000040, 0x00001002, + 0x00800042, 0x00000040, 0x00000000, 0x00801042, + 0x00801002, 0x00801040, 0x00000042, 0x00001000, + 0x00001040, 0x00801002, 0x00800040, 0x00000042, + 0x00000002, 0x00001042, 0x00801000, 0x00800002, + + 0x10400000, 0x00404010, 0x00000010, 0x10400010, + 0x10004000, 0x00400000, 0x10400010, 0x00004010, + 0x00400010, 0x00004000, 0x00404000, 0x10000000, + 0x10404010, 0x10000010, 0x10000000, 0x10404000, + 0x00000000, 0x10004000, 0x00404010, 0x00000010, + 0x10000010, 0x10404010, 0x00004000, 0x10400000, + 0x10404000, 0x00400010, 0x10004010, 0x00404000, + 0x00004010, 0x00000000, 0x00400000, 0x10004010, + 0x00404010, 0x00000010, 0x10000000, 0x00004000, + 0x10000010, 0x10004000, 0x00404000, 0x10400010, + 0x00000000, 0x00404010, 0x00004010, 0x10404000, + 0x10004000, 0x00400000, 0x10404010, 0x10000000, + 0x10004010, 0x10400000, 0x00400000, 0x10404010, + 0x00004000, 0x00400010, 0x10400010, 0x00004010, + 0x00400010, 0x00000000, 0x10404000, 0x10000010, + 0x10400000, 0x10004010, 0x00000010, 0x00404000, + + 0x00208080, 0x00008000, 0x20200000, 0x20208080, + 0x00200000, 0x20008080, 0x20008000, 0x20200000, + 0x20008080, 0x00208080, 0x00208000, 0x20000080, + 0x20200080, 0x00200000, 0x00000000, 0x20008000, + 0x00008000, 0x20000000, 0x00200080, 0x00008080, + 0x20208080, 0x00208000, 0x20000080, 0x00200080, + 0x20000000, 0x00000080, 0x00008080, 0x20208000, + 0x00000080, 0x20200080, 0x20208000, 0x00000000, + 0x00000000, 0x20208080, 0x00200080, 0x20008000, + 0x00208080, 0x00008000, 0x20000080, 0x00200080, + 0x20208000, 0x00000080, 0x00008080, 0x20200000, + 0x20008080, 0x20000000, 0x20200000, 0x00208000, + 0x20208080, 0x00008080, 0x00208000, 0x20200080, + 0x00200000, 0x20000080, 0x20008000, 0x00000000, + 0x00008000, 0x00200000, 0x20200080, 0x00208080, + 0x20000000, 0x20208000, 0x00000080, 0x20008080, + diff --git a/knuth-lfib.c b/knuth-lfib.c new file mode 100644 index 0000000..e12688c --- /dev/null +++ b/knuth-lfib.c @@ -0,0 +1,162 @@ +/* knuth-lfib.c + * + * A "lagged fibonacci" pseudorandomness generator. + * + * Described in Knuth, TAOCP, 3.6 + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * Includes code copied verbatim from Knuth's TAOCP. + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* NOTE: This generator is totally inappropriate for cryptographic + * applications. It is useful for generating deterministic but + * random-looking test data, and is used by the Nettle testsuite. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "knuth-lfib.h" + +#include "macros.h" + +#define KK _KNUTH_LFIB_KK +#define LL 37 +#define MM (1UL << 30) +#define TT 70 + +void +knuth_lfib_init(struct knuth_lfib_ctx *ctx, uint32_t seed) +{ + uint32_t t,j; + uint32_t x[2*KK - 1]; + uint32_t ss = (seed + 2) & (MM-2); + + for (j = 0; j= MM) ss -= (MM-2); + } + for (;j< 2*KK-1; j++) + x[j] = 0; + + x[1]++; + + ss = seed & (MM-1); + for (t = TT-1; t; ) + { + for (j = KK-1; j>0; j--) + x[j+j] = x[j]; + for (j = 2*KK-2; j > KK-LL; j-= 2) + x[2*KK-1-j] = x[j] & ~1; + for (j = 2*KK-2; j>=KK; j--) + if (x[j] & 1) + { + x[j-(KK-LL)] = (x[j - (KK-LL)] - x[j]) & (MM-1); + x[j-KK] = (x[j-KK] - x[j]) & (MM-1); + } + if (ss & 1) + { + for (j=KK; j>0; j--) + x[j] = x[j-1]; + x[0] = x[KK]; + if (x[KK] & 1) + x[LL] = (x[LL] - x[KK]) & (MM-1); + } + if (ss) + ss >>= 1; + else + t--; + } + for (j=0; jx[j+KK-LL] = x[j]; + for (; jx[j-LL] = x[j]; + + ctx->index = 0; +} + +/* Get's a single number in the range 0 ... 2^30-1 */ +uint32_t +knuth_lfib_get(struct knuth_lfib_ctx *ctx) +{ + uint32_t value; + assert(ctx->index < KK); + + value = ctx->x[ctx->index]; + ctx->x[ctx->index] -= ctx->x[(ctx->index + KK - LL) % KK]; + ctx->x[ctx->index] &= (MM-1); + + ctx->index = (ctx->index + 1) % KK; + + return value; +} + +/* NOTE: Not at all optimized. */ +void +knuth_lfib_get_array(struct knuth_lfib_ctx *ctx, + unsigned n, uint32_t *a) +{ + unsigned i; + + for (i = 0; i= 3; n-=3, dst += 3) + { + uint32_t value = knuth_lfib_get(ctx); + + /* Xor the most significant octet (containing 6 significant bits) + * into the lower octet. */ + value ^= (value >> 24); + + WRITE_UINT24(dst, value); + } + if (n) + { + /* We need one or two octets more */ + uint32_t value = knuth_lfib_get(ctx); + switch (n) + { + case 1: + *dst++ = value & 0xff; + break; + case 2: + WRITE_UINT16(dst, value); + break; + default: + abort(); + } + } +} diff --git a/knuth-lfib.h b/knuth-lfib.h new file mode 100644 index 0000000..b52393e --- /dev/null +++ b/knuth-lfib.h @@ -0,0 +1,75 @@ +/* knuth-lfib.h + * + * A "lagged fibonacci" pseudorandomness generator. + * + * Described in Knuth, TAOCP, 3.6 + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* NOTE: This generator is totally inappropriate for cryptographic + * applications. It is useful for generating deterministic but + * random-looking test data, and is used by the Nettle testsuite. */ +#ifndef NETTLE_KNUTH_LFIB_H_INCLUDED +#define NETTLE_KNUTH_LFIB_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Namespace mangling */ +#define knuth_lfib_init nettle_knuth_lfib_init +#define knuth_lfib_get nettle_knuth_lfib_get +#define knuth_lfib_get_array nettle_knuth_lfib_get_array +#define knuth_lfib_random nettle_knuth_lfib_random + +#define _KNUTH_LFIB_KK 100 + +struct knuth_lfib_ctx +{ + uint32_t x[_KNUTH_LFIB_KK]; + unsigned index; +}; + +void +knuth_lfib_init(struct knuth_lfib_ctx *ctx, uint32_t seed); + +/* Get's a single number in the range 0 ... 2^30-1 */ +uint32_t +knuth_lfib_get(struct knuth_lfib_ctx *ctx); + +/* Get an array of numbers */ +void +knuth_lfib_get_array(struct knuth_lfib_ctx *ctx, + unsigned n, uint32_t *a); + +/* Get an array of octets. */ +void +knuth_lfib_random(struct knuth_lfib_ctx *ctx, + unsigned n, uint8_t *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_KNUTH_LFIB_H_INCLUDED */ diff --git a/macros.h b/macros.h new file mode 100644 index 0000000..2cc69cb --- /dev/null +++ b/macros.h @@ -0,0 +1,122 @@ +/* macros.h + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_MACROS_H_INCLUDED +#define NETTLE_MACROS_H_INCLUDED + +/* Reads a 64-bit integer, in network, big-endian, byte order */ +#define READ_UINT64(p) \ +( (((uint64_t) (p)[0]) << 56) \ + | (((uint64_t) (p)[1]) << 48) \ + | (((uint64_t) (p)[2]) << 40) \ + | (((uint64_t) (p)[3]) << 32) \ + | (((uint64_t) (p)[4]) << 24) \ + | (((uint64_t) (p)[5]) << 16) \ + | (((uint64_t) (p)[6]) << 8) \ + | ((uint64_t) (p)[7])) + +#define WRITE_UINT64(p, i) \ +do { \ + (p)[0] = ((i) >> 56) & 0xff; \ + (p)[1] = ((i) >> 48) & 0xff; \ + (p)[2] = ((i) >> 40) & 0xff; \ + (p)[3] = ((i) >> 32) & 0xff; \ + (p)[4] = ((i) >> 24) & 0xff; \ + (p)[5] = ((i) >> 16) & 0xff; \ + (p)[6] = ((i) >> 8) & 0xff; \ + (p)[7] = (i) & 0xff; \ +} while(0) + +/* Reads a 32-bit integer, in network, big-endian, byte order */ +#define READ_UINT32(p) \ +( (((uint32_t) (p)[0]) << 24) \ + | (((uint32_t) (p)[1]) << 16) \ + | (((uint32_t) (p)[2]) << 8) \ + | ((uint32_t) (p)[3])) + +#define WRITE_UINT32(p, i) \ +do { \ + (p)[0] = ((i) >> 24) & 0xff; \ + (p)[1] = ((i) >> 16) & 0xff; \ + (p)[2] = ((i) >> 8) & 0xff; \ + (p)[3] = (i) & 0xff; \ +} while(0) + +/* Analogous macros, for 24 and 16 bit numbers */ +#define READ_UINT24(p) \ +( (((uint32_t) (p)[0]) << 16) \ + | (((uint32_t) (p)[1]) << 8) \ + | ((uint32_t) (p)[2])) + +#define WRITE_UINT24(p, i) \ +do { \ + (p)[0] = ((i) >> 16) & 0xff; \ + (p)[1] = ((i) >> 8) & 0xff; \ + (p)[2] = (i) & 0xff; \ +} while(0) + +#define READ_UINT16(p) \ +( (((uint32_t) (p)[0]) << 8) \ + | ((uint32_t) (p)[1])) + +#define WRITE_UINT16(p, i) \ +do { \ + (p)[0] = ((i) >> 8) & 0xff; \ + (p)[1] = (i) & 0xff; \ +} while(0) + +/* And the other, little-endian, byteorder */ +#define LE_READ_UINT32(p) \ +( (((uint32_t) (p)[3]) << 24) \ + | (((uint32_t) (p)[2]) << 16) \ + | (((uint32_t) (p)[1]) << 8) \ + | ((uint32_t) (p)[0])) + +#define LE_WRITE_UINT32(p, i) \ +do { \ + (p)[3] = ((i) >> 24) & 0xff; \ + (p)[2] = ((i) >> 16) & 0xff; \ + (p)[1] = ((i) >> 8) & 0xff; \ + (p)[0] = (i) & 0xff; \ +} while(0) + +/* Analogous macros, for 16 bit numbers */ +#define LE_READ_UINT16(p) \ + ( (((uint32_t) (p)[1]) << 8) \ + | ((uint32_t) (p)[0])) + +#define LE_WRITE_UINT16(p, i) \ + do { \ + (p)[1] = ((i) >> 8) & 0xff; \ + (p)[0] = (i) & 0xff; \ + } while(0) + +/* Macro to make it easier to loop over several blocks. */ +#define FOR_BLOCKS(length, dst, src, blocksize) \ + assert( !((length) % (blocksize))); \ + for (; (length); ((length) -= (blocksize), \ + (dst) += (blocksize), \ + (src) += (blocksize)) ) + +#endif /* NETTLE_MACROS_H_INCLUDED */ diff --git a/md2-meta.c b/md2-meta.c new file mode 100644 index 0000000..0ed0b47 --- /dev/null +++ b/md2-meta.c @@ -0,0 +1,32 @@ +/* md2-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "md2.h" + +const struct nettle_hash nettle_md2 += _NETTLE_HASH(md2, MD2); diff --git a/md2.c b/md2.c new file mode 100644 index 0000000..ae2abb5 --- /dev/null +++ b/md2.c @@ -0,0 +1,167 @@ +/* md2.h + * + * The MD2 hash function, described in RFC 1319. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller, Andreas Sigfridsson + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* This code originates from the Python Cryptography Toolkit, version 1.0.1. + Further hacked by Andreas Sigfridsson and Niels Möller. Original license: + + =================================================================== + Distribute and use freely; there are no restrictions on further + dissemination and usage except those imposed by the laws of your + country of residence. This software is provided "as is" without + warranty of fitness for use or suitability for any purpose, express + or implied. Use at your own risk or not at all. + =================================================================== + + Incorporating the code into commercial products is permitted; you do + not have to make source available or contribute your changes back + (though that would be nice). + + --amk (www.amk.ca) */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "md2.h" + +#include "macros.h" + +static const uint8_t +S[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +static void +md2_transform(struct md2_ctx *ctx, const uint8_t *data) +{ + unsigned i; + uint8_t t; + + memcpy(ctx->X + 16, data, MD2_DATA_SIZE); + + for (i = 0, t = ctx->C[15]; + iX[2 * MD2_DATA_SIZE + i] + = ctx->X[i] ^ ctx->X[MD2_DATA_SIZE + i]; + t = (ctx->C[i] ^= S[data[i]^t]); + } + for (i = t = 0; + i< MD2_DATA_SIZE + 2; + t = (t + i) & 0xff, i++) + { + unsigned j; + for (j = 0; j < 3 * MD2_DATA_SIZE; j++) + t = (ctx->X[j] ^= S[t]); + } +} + +#if 0 +static void +md2_final(struct md2_ctx *ctx) +{ + unsigned left = MD2_DATA_SIZE - ctx->index; + memset(ctx->block + ctx->index, left, left); + md2_transform(ctx, ctx->block); +} +#endif + +void +md2_init(struct md2_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +void +md2_update(struct md2_ctx *ctx, + unsigned length, + const uint8_t *data) +{ + if (ctx->index) + { + /* Try to fill partial block */ + unsigned left = MD2_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, data, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, data, left); + md2_transform(ctx, ctx->block); + data += left; + length -= left; + } + } + while (length >= MD2_DATA_SIZE) + { + md2_transform(ctx, data); + data += MD2_DATA_SIZE; + length -= MD2_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, data, length); +} + +void +md2_digest(struct md2_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned left; + + assert(length <= MD2_DIGEST_SIZE); + + left = MD2_DATA_SIZE - ctx->index; + memset(ctx->block + ctx->index, left, left); + md2_transform(ctx, ctx->block); + + md2_transform(ctx, ctx->C); + memcpy(digest, ctx->X, length); + md2_init(ctx); +} diff --git a/md2.h b/md2.h new file mode 100644 index 0000000..ac1cf33 --- /dev/null +++ b/md2.h @@ -0,0 +1,69 @@ +/* md2.h + * + * The MD2 hash function, described in RFC 1319. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_MD2_H_INCLUDED +#define NETTLE_MD2_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define md2_init nettle_md2_init +#define md2_update nettle_md2_update +#define md2_digest nettle_md2_digest + +#define MD2_DIGEST_SIZE 16 +#define MD2_DATA_SIZE 16 + +struct md2_ctx +{ + uint8_t C[MD2_DATA_SIZE]; + uint8_t X[3 * MD2_DATA_SIZE]; + uint8_t block[MD2_DATA_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ +}; + +void +md2_init(struct md2_ctx *ctx); + +void +md2_update(struct md2_ctx *ctx, + unsigned length, + const uint8_t *data); + +void +md2_digest(struct md2_ctx *ctx, + unsigned length, + uint8_t *digest); + + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MD2_H_INCLUDED */ diff --git a/md4-meta.c b/md4-meta.c new file mode 100644 index 0000000..2d74f79 --- /dev/null +++ b/md4-meta.c @@ -0,0 +1,32 @@ +/* md4-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "md4.h" + +const struct nettle_hash nettle_md4 += _NETTLE_HASH(md4, MD4); diff --git a/md4.c b/md4.c new file mode 100644 index 0000000..544ce0d --- /dev/null +++ b/md4.c @@ -0,0 +1,272 @@ +/* md4.h + * + * The MD4 hash function, described in RFC 1320. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller, Marcus Comstedt + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Based on the public domain md5 code, and modified by Marcus + Comstedt */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "md4.h" + +#include "macros.h" + +/* A block, treated as a sequence of 32-bit words. */ +#define MD4_DATA_LENGTH 16 + +static void +md4_transform(uint32_t *digest, const uint32_t *data); + +static void +md4_block(struct md4_ctx *ctx, const uint8_t *block); + +static void +md4_final(struct md4_ctx *ctx); + +void +md4_init(struct md4_ctx *ctx) +{ + /* Same constants as for md5. */ + ctx->digest[0] = 0x67452301; + ctx->digest[1] = 0xefcdab89; + ctx->digest[2] = 0x98badcfe; + ctx->digest[3] = 0x10325476; + + ctx->count_l = ctx->count_h = 0; + ctx->index = 0; +} + +void +md4_update(struct md4_ctx *ctx, + unsigned length, + const uint8_t *data) +{ + if (ctx->index) + { + /* Try to fill partial block */ + unsigned left = MD4_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, data, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, data, left); + md4_block(ctx, ctx->block); + data += left; + length -= left; + } + } + while (length >= MD4_DATA_SIZE) + { + md4_block(ctx, data); + data += MD4_DATA_SIZE; + length -= MD4_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, data, length); +} + +void +md4_digest(struct md4_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned i; + unsigned words; + unsigned leftover; + + assert(length <= MD4_DIGEST_SIZE); + + md4_final(ctx); + + words = length / 4; + leftover = length % 4; + + /* Little endian order */ + for (i = 0; i < words; i++, digest += 4) + LE_WRITE_UINT32(digest, ctx->digest[i]); + + if (leftover) + { + uint32_t word; + unsigned j; + + assert(i < _MD4_DIGEST_LENGTH); + + /* Still least significant byte first. */ + for (word = ctx->digest[i], j = 0; j < leftover; + j++, word >>= 8) + digest[j] = word & 0xff; + } + md4_init(ctx); +} + +/* MD4 functions */ +#define F(x, y, z) (((y) & (x)) | ((z) & ~(x))) +#define G(x, y, z) (((y) & (x)) | ((z) & (x)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +#define ROUND(f, w, x, y, z, data, s) \ +( w += f(x, y, z) + data, w = w<>(32-s) ) + +/* Perform the MD4 transformation on one full block of 16 32-bit words. */ + +static void +md4_transform(uint32_t *digest, const uint32_t *data) +{ + uint32_t a, b, c, d; + a = digest[0]; + b = digest[1]; + c = digest[2]; + d = digest[3]; + + ROUND(F, a, b, c, d, data[ 0], 3); + ROUND(F, d, a, b, c, data[ 1], 7); + ROUND(F, c, d, a, b, data[ 2], 11); + ROUND(F, b, c, d, a, data[ 3], 19); + ROUND(F, a, b, c, d, data[ 4], 3); + ROUND(F, d, a, b, c, data[ 5], 7); + ROUND(F, c, d, a, b, data[ 6], 11); + ROUND(F, b, c, d, a, data[ 7], 19); + ROUND(F, a, b, c, d, data[ 8], 3); + ROUND(F, d, a, b, c, data[ 9], 7); + ROUND(F, c, d, a, b, data[10], 11); + ROUND(F, b, c, d, a, data[11], 19); + ROUND(F, a, b, c, d, data[12], 3); + ROUND(F, d, a, b, c, data[13], 7); + ROUND(F, c, d, a, b, data[14], 11); + ROUND(F, b, c, d, a, data[15], 19); + + ROUND(G, a, b, c, d, data[ 0] + 0x5a827999, 3); + ROUND(G, d, a, b, c, data[ 4] + 0x5a827999, 5); + ROUND(G, c, d, a, b, data[ 8] + 0x5a827999, 9); + ROUND(G, b, c, d, a, data[12] + 0x5a827999, 13); + ROUND(G, a, b, c, d, data[ 1] + 0x5a827999, 3); + ROUND(G, d, a, b, c, data[ 5] + 0x5a827999, 5); + ROUND(G, c, d, a, b, data[ 9] + 0x5a827999, 9); + ROUND(G, b, c, d, a, data[13] + 0x5a827999, 13); + ROUND(G, a, b, c, d, data[ 2] + 0x5a827999, 3); + ROUND(G, d, a, b, c, data[ 6] + 0x5a827999, 5); + ROUND(G, c, d, a, b, data[10] + 0x5a827999, 9); + ROUND(G, b, c, d, a, data[14] + 0x5a827999, 13); + ROUND(G, a, b, c, d, data[ 3] + 0x5a827999, 3); + ROUND(G, d, a, b, c, data[ 7] + 0x5a827999, 5); + ROUND(G, c, d, a, b, data[11] + 0x5a827999, 9); + ROUND(G, b, c, d, a, data[15] + 0x5a827999, 13); + + ROUND(H, a, b, c, d, data[ 0] + 0x6ed9eba1, 3); + ROUND(H, d, a, b, c, data[ 8] + 0x6ed9eba1, 9); + ROUND(H, c, d, a, b, data[ 4] + 0x6ed9eba1, 11); + ROUND(H, b, c, d, a, data[12] + 0x6ed9eba1, 15); + ROUND(H, a, b, c, d, data[ 2] + 0x6ed9eba1, 3); + ROUND(H, d, a, b, c, data[10] + 0x6ed9eba1, 9); + ROUND(H, c, d, a, b, data[ 6] + 0x6ed9eba1, 11); + ROUND(H, b, c, d, a, data[14] + 0x6ed9eba1, 15); + ROUND(H, a, b, c, d, data[ 1] + 0x6ed9eba1, 3); + ROUND(H, d, a, b, c, data[ 9] + 0x6ed9eba1, 9); + ROUND(H, c, d, a, b, data[ 5] + 0x6ed9eba1, 11); + ROUND(H, b, c, d, a, data[13] + 0x6ed9eba1, 15); + ROUND(H, a, b, c, d, data[ 3] + 0x6ed9eba1, 3); + ROUND(H, d, a, b, c, data[11] + 0x6ed9eba1, 9); + ROUND(H, c, d, a, b, data[ 7] + 0x6ed9eba1, 11); + ROUND(H, b, c, d, a, data[15] + 0x6ed9eba1, 15); + + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; +} + +static void +md4_block(struct md4_ctx *ctx, const uint8_t *block) +{ + uint32_t data[MD4_DATA_LENGTH]; + unsigned i; + + /* Update block count */ + if (!++ctx->count_l) + ++ctx->count_h; + + /* Endian independent conversion */ + for (i = 0; i<16; i++, block += 4) + data[i] = LE_READ_UINT32(block); + + md4_transform(ctx->digest, data); +} + +/* Final wrapup - pad to MD4_DATA_SIZE-byte boundary with the bit + * pattern 1 0* (64-bit count of bits processed, LSB-first) */ + +static void +md4_final(struct md4_ctx *ctx) +{ + uint32_t data[MD4_DATA_LENGTH]; + unsigned i; + unsigned words; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there + * is always at least one byte free */ + assert(i < MD4_DATA_SIZE); + ctx->block[i++] = 0x80; + + /* Fill rest of word */ + for( ; i & 3; i++) + ctx->block[i] = 0; + + /* i is now a multiple of the word size 4 */ + words = i >> 2; + for (i = 0; i < words; i++) + data[i] = LE_READ_UINT32(ctx->block + 4*i); + + if (words > (MD4_DATA_LENGTH-2)) + { /* No room for length in this block. Process it and + * pad with another one */ + for (i = words ; i < MD4_DATA_LENGTH; i++) + data[i] = 0; + md4_transform(ctx->digest, data); + for (i = 0; i < (MD4_DATA_LENGTH-2); i++) + data[i] = 0; + } + else + for (i = words ; i < MD4_DATA_LENGTH - 2; i++) + data[i] = 0; + + /* There are 512 = 2^9 bits in one block + * Little-endian order => Least significant word first */ + + data[MD4_DATA_LENGTH-1] = (ctx->count_h << 9) | (ctx->count_l >> 23); + data[MD4_DATA_LENGTH-2] = (ctx->count_l << 9) | (ctx->index << 3); + md4_transform(ctx->digest, data); +} diff --git a/md4.h b/md4.h new file mode 100644 index 0000000..e9a32b9 --- /dev/null +++ b/md4.h @@ -0,0 +1,72 @@ +/* md4.h + * + * The MD4 hash function, described in RFC 1320. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_MD4_H_INCLUDED +#define NETTLE_MD4_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define md4_init nettle_md4_init +#define md4_update nettle_md4_update +#define md4_digest nettle_md4_digest + +#define MD4_DIGEST_SIZE 16 +#define MD4_DATA_SIZE 64 + +/* Digest is kept internally as 4 32-bit words. */ +#define _MD4_DIGEST_LENGTH 4 + +struct md4_ctx +{ + uint32_t digest[_MD4_DIGEST_LENGTH]; + uint32_t count_l, count_h; /* Block count */ + uint8_t block[MD4_DATA_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ +}; + +void +md4_init(struct md4_ctx *ctx); + +void +md4_update(struct md4_ctx *ctx, + unsigned length, + const uint8_t *data); + +void +md4_digest(struct md4_ctx *ctx, + unsigned length, + uint8_t *digest); + + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MD4_H_INCLUDED */ diff --git a/md5-compat.c b/md5-compat.c new file mode 100644 index 0000000..31a2fd5 --- /dev/null +++ b/md5-compat.c @@ -0,0 +1,48 @@ +/* md5-compat.c + * + * The md5 hash function, RFC 1321-style interface. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "md5-compat.h" + +void +MD5Init(MD5_CTX *ctx) +{ + md5_init(ctx); +} + +void +MD5Update(MD5_CTX *ctx, const unsigned char *data, unsigned int length) +{ + md5_update(ctx, length, data); +} + +void +MD5Final(unsigned char *out, MD5_CTX *ctx) +{ + md5_digest(ctx, MD5_DIGEST_SIZE, out); +} diff --git a/md5-compat.h b/md5-compat.h new file mode 100644 index 0000000..8f5f331 --- /dev/null +++ b/md5-compat.h @@ -0,0 +1,50 @@ +/* md5-compat.h + * + * The md5 hash function, RFC 1321-style interface. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_MD5_COMPAT_H_INCLUDED +#define NETTLE_MD5_COMPAT_H_INCLUDED + +#include "md5.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define MD5Init nettle_MD5Init +#define MD5Update nettle_MD5Update +#define MD5Final nettle_MD5Final + +typedef struct md5_ctx MD5_CTX; + +void MD5Init(MD5_CTX *ctx); +void MD5Update(MD5_CTX *ctx, const unsigned char *data, unsigned int length); +void MD5Final(unsigned char *out, MD5_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MD5_COMPAT_H_INCLUDED */ diff --git a/md5-compress.c b/md5-compress.c new file mode 100644 index 0000000..ec949e7 --- /dev/null +++ b/md5-compress.c @@ -0,0 +1,167 @@ +/* md5-compress.c + * + * The compression function for the sha1 hash function. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Based on public domain code hacked by Colin Plumb, Andrew Kuchling, and + * Niels Möller. */ + + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef MD5_DEBUG +# define MD5_DEBUG 0 +#endif + +#if MD5_DEBUG +# include +# define DEBUG(i) \ + fprintf(stderr, "%2d: %8x %8x %8x %8x\n", i, a, b, c, d) +#else +# define DEBUG(i) +#endif + +#include +#include +#include + +#include "md5.h" + +#include "macros.h" + +/* A block, treated as a sequence of 32-bit words. */ +#define MD5_DATA_LENGTH 16 + +/* MD5 functions */ + +#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define F2(x, y, z) F1((z), (x), (y)) +#define F3(x, y, z) ((x) ^ (y) ^ (z)) +#define F4(x, y, z) ((y) ^ ((x) | ~(z))) + +#define ROUND(f, w, x, y, z, data, s) \ +( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* Perform the MD5 transformation on one full block of 16 32-bit + * words. + * + * Compresses 20 (_MD5_DIGEST_LENGTH + MD5_DATA_LENGTH) words into 4 + * (_MD5_DIGEST_LENGTH) words. */ + +void +_nettle_md5_compress(uint32_t *digest, const uint8_t *input) +{ + uint32_t data[MD5_DATA_LENGTH]; + uint32_t a, b, c, d; + unsigned i; + + for (i = 0; i < MD5_DATA_LENGTH; i++, input += 4) + data[i] = LE_READ_UINT32(input); + + a = digest[0]; + b = digest[1]; + c = digest[2]; + d = digest[3]; + + DEBUG(-1); + ROUND(F1, a, b, c, d, data[ 0] + 0xd76aa478, 7); DEBUG(0); + ROUND(F1, d, a, b, c, data[ 1] + 0xe8c7b756, 12); DEBUG(1); + ROUND(F1, c, d, a, b, data[ 2] + 0x242070db, 17); + ROUND(F1, b, c, d, a, data[ 3] + 0xc1bdceee, 22); + ROUND(F1, a, b, c, d, data[ 4] + 0xf57c0faf, 7); + ROUND(F1, d, a, b, c, data[ 5] + 0x4787c62a, 12); + ROUND(F1, c, d, a, b, data[ 6] + 0xa8304613, 17); + ROUND(F1, b, c, d, a, data[ 7] + 0xfd469501, 22); + ROUND(F1, a, b, c, d, data[ 8] + 0x698098d8, 7); + ROUND(F1, d, a, b, c, data[ 9] + 0x8b44f7af, 12); + ROUND(F1, c, d, a, b, data[10] + 0xffff5bb1, 17); + ROUND(F1, b, c, d, a, data[11] + 0x895cd7be, 22); + ROUND(F1, a, b, c, d, data[12] + 0x6b901122, 7); + ROUND(F1, d, a, b, c, data[13] + 0xfd987193, 12); + ROUND(F1, c, d, a, b, data[14] + 0xa679438e, 17); + ROUND(F1, b, c, d, a, data[15] + 0x49b40821, 22); DEBUG(15); + + ROUND(F2, a, b, c, d, data[ 1] + 0xf61e2562, 5); DEBUG(16); + ROUND(F2, d, a, b, c, data[ 6] + 0xc040b340, 9); DEBUG(17); + ROUND(F2, c, d, a, b, data[11] + 0x265e5a51, 14); + ROUND(F2, b, c, d, a, data[ 0] + 0xe9b6c7aa, 20); + ROUND(F2, a, b, c, d, data[ 5] + 0xd62f105d, 5); + ROUND(F2, d, a, b, c, data[10] + 0x02441453, 9); + ROUND(F2, c, d, a, b, data[15] + 0xd8a1e681, 14); + ROUND(F2, b, c, d, a, data[ 4] + 0xe7d3fbc8, 20); + ROUND(F2, a, b, c, d, data[ 9] + 0x21e1cde6, 5); + ROUND(F2, d, a, b, c, data[14] + 0xc33707d6, 9); + ROUND(F2, c, d, a, b, data[ 3] + 0xf4d50d87, 14); + ROUND(F2, b, c, d, a, data[ 8] + 0x455a14ed, 20); + ROUND(F2, a, b, c, d, data[13] + 0xa9e3e905, 5); + ROUND(F2, d, a, b, c, data[ 2] + 0xfcefa3f8, 9); + ROUND(F2, c, d, a, b, data[ 7] + 0x676f02d9, 14); + ROUND(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20); DEBUG(31); + + ROUND(F3, a, b, c, d, data[ 5] + 0xfffa3942, 4); DEBUG(32); + ROUND(F3, d, a, b, c, data[ 8] + 0x8771f681, 11); DEBUG(33); + ROUND(F3, c, d, a, b, data[11] + 0x6d9d6122, 16); + ROUND(F3, b, c, d, a, data[14] + 0xfde5380c, 23); + ROUND(F3, a, b, c, d, data[ 1] + 0xa4beea44, 4); + ROUND(F3, d, a, b, c, data[ 4] + 0x4bdecfa9, 11); + ROUND(F3, c, d, a, b, data[ 7] + 0xf6bb4b60, 16); + ROUND(F3, b, c, d, a, data[10] + 0xbebfbc70, 23); + ROUND(F3, a, b, c, d, data[13] + 0x289b7ec6, 4); + ROUND(F3, d, a, b, c, data[ 0] + 0xeaa127fa, 11); + ROUND(F3, c, d, a, b, data[ 3] + 0xd4ef3085, 16); + ROUND(F3, b, c, d, a, data[ 6] + 0x04881d05, 23); + ROUND(F3, a, b, c, d, data[ 9] + 0xd9d4d039, 4); + ROUND(F3, d, a, b, c, data[12] + 0xe6db99e5, 11); + ROUND(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16); + ROUND(F3, b, c, d, a, data[ 2] + 0xc4ac5665, 23); DEBUG(47); + + ROUND(F4, a, b, c, d, data[ 0] + 0xf4292244, 6); DEBUG(48); + ROUND(F4, d, a, b, c, data[ 7] + 0x432aff97, 10); DEBUG(49); + ROUND(F4, c, d, a, b, data[14] + 0xab9423a7, 15); + ROUND(F4, b, c, d, a, data[ 5] + 0xfc93a039, 21); + ROUND(F4, a, b, c, d, data[12] + 0x655b59c3, 6); + ROUND(F4, d, a, b, c, data[ 3] + 0x8f0ccc92, 10); + ROUND(F4, c, d, a, b, data[10] + 0xffeff47d, 15); + ROUND(F4, b, c, d, a, data[ 1] + 0x85845dd1, 21); + ROUND(F4, a, b, c, d, data[ 8] + 0x6fa87e4f, 6); + ROUND(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10); + ROUND(F4, c, d, a, b, data[ 6] + 0xa3014314, 15); + ROUND(F4, b, c, d, a, data[13] + 0x4e0811a1, 21); + ROUND(F4, a, b, c, d, data[ 4] + 0xf7537e82, 6); + ROUND(F4, d, a, b, c, data[11] + 0xbd3af235, 10); + ROUND(F4, c, d, a, b, data[ 2] + 0x2ad7d2bb, 15); + ROUND(F4, b, c, d, a, data[ 9] + 0xeb86d391, 21); DEBUG(63); + + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; +#if MD5_DEBUG + fprintf(stderr, "99: %8x %8x %8x %8x\n", + digest[0], digest[1], digest[2], digest[3]); +#endif + +} diff --git a/md5-meta.c b/md5-meta.c new file mode 100644 index 0000000..3ea5900 --- /dev/null +++ b/md5-meta.c @@ -0,0 +1,32 @@ +/* md5-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "md5.h" + +const struct nettle_hash nettle_md5 += _NETTLE_HASH(md5, MD5); diff --git a/md5.c b/md5.c new file mode 100644 index 0000000..d398b31 --- /dev/null +++ b/md5.c @@ -0,0 +1,169 @@ +/* md5.c + * + * The MD5 hash function, described in RFC 1321. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Based on public domain code hacked by Colin Plumb, Andrew Kuchling, and + * Niels Möller. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "md5.h" + +#include "macros.h" + +static void +md5_final(struct md5_ctx *ctx); + +void +md5_init(struct md5_ctx *ctx) +{ + ctx->digest[0] = 0x67452301; + ctx->digest[1] = 0xefcdab89; + ctx->digest[2] = 0x98badcfe; + ctx->digest[3] = 0x10325476; + + ctx->count_l = ctx->count_h = 0; + ctx->index = 0; +} + +#define MD5_INCR(ctx) ((ctx)->count_h += !++(ctx)->count_l) + +void +md5_update(struct md5_ctx *ctx, + unsigned length, + const uint8_t *data) +{ + if (ctx->index) + { + /* Try to fill partial block */ + unsigned left = MD5_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, data, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, data, left); + + _nettle_md5_compress(ctx->digest, ctx->block); + MD5_INCR(ctx); + + data += left; + length -= left; + } + } + while (length >= MD5_DATA_SIZE) + { + _nettle_md5_compress(ctx->digest, data); + MD5_INCR(ctx); + + data += MD5_DATA_SIZE; + length -= MD5_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, data, length); +} + +void +md5_digest(struct md5_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned i; + unsigned words; + unsigned leftover; + + assert(length <= MD5_DIGEST_SIZE); + + md5_final(ctx); + + words = length / 4; + leftover = length % 4; + + /* Little endian order */ + for (i = 0; i < words; i++, digest += 4) + LE_WRITE_UINT32(digest, ctx->digest[i]); + + if (leftover) + { + uint32_t word; + unsigned j; + + assert(i < _MD5_DIGEST_LENGTH); + + /* Still least significant byte first. */ + for (word = ctx->digest[i], j = 0; j < leftover; + j++, word >>= 8) + digest[j] = word & 0xff; + } + md5_init(ctx); +} + +/* Final wrapup - pad to MD5_DATA_SIZE-byte boundary with the bit + * pattern 1 0* (64-bit count of bits processed, LSB-first) */ + +static void +md5_final(struct md5_ctx *ctx) +{ + uint32_t bitcount_high; + uint32_t bitcount_low; + unsigned i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there + * is always at least one byte free */ + assert(i < MD5_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (MD5_DATA_SIZE - 8)) + { + /* No room for length in this block. Process it and + pad with another one */ + memset(ctx->block + i, 0, MD5_DATA_SIZE - i); + + _nettle_md5_compress(ctx->digest, ctx->block); + i = 0; + } + if (i < (MD5_DATA_SIZE - 8)) + memset(ctx->block + i, 0, (MD5_DATA_SIZE - 8) - i); + + /* There are 512 = 2^9 bits in one block + * Little-endian order => Least significant word first */ + + bitcount_low = (ctx->count_l << 9) | (ctx->index << 3); + bitcount_high = (ctx->count_h << 9) | (ctx->count_l >> 23); + LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 8), bitcount_low); + LE_WRITE_UINT32(ctx->block + (MD5_DATA_SIZE - 4), bitcount_high); + + _nettle_md5_compress(ctx->digest, ctx->block); +} diff --git a/md5.h b/md5.h new file mode 100644 index 0000000..c936cb2 --- /dev/null +++ b/md5.h @@ -0,0 +1,76 @@ +/* md5.h + * + * The MD5 hash function, described in RFC 1321. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_MD5_H_INCLUDED +#define NETTLE_MD5_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define md5_init nettle_md5_init +#define md5_update nettle_md5_update +#define md5_digest nettle_md5_digest + +#define MD5_DIGEST_SIZE 16 +#define MD5_DATA_SIZE 64 + +/* Digest is kept internally as 4 32-bit words. */ +#define _MD5_DIGEST_LENGTH 4 + +struct md5_ctx +{ + uint32_t digest[_MD5_DIGEST_LENGTH]; + uint32_t count_l, count_h; /* Block count */ + uint8_t block[MD5_DATA_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ +}; + +void +md5_init(struct md5_ctx *ctx); + +void +md5_update(struct md5_ctx *ctx, + unsigned length, + const uint8_t *data); + +void +md5_digest(struct md5_ctx *ctx, + unsigned length, + uint8_t *digest); + +/* Internal compression function. STATE points to 4 uint32_t words, + and DATA points to 64 bytes of input data, possibly unaligned. */ +void +_nettle_md5_compress(uint32_t *state, const uint8_t *data); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MD5_H_INCLUDED */ diff --git a/memxor.c b/memxor.c new file mode 100644 index 0000000..92f14a5 --- /dev/null +++ b/memxor.c @@ -0,0 +1,35 @@ +/* memxor.c + * + * $Id: memxor.c,v 1.1 2007/04/05 14:20:35 nisse Exp $ + */ + +/* XOR LEN bytes starting at SRCADDR onto DESTADDR. Result undefined + if the source overlaps with the destination. + Return DESTADDR. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "memxor.h" + +uint8_t * +memxor(uint8_t *dst, const uint8_t *src, size_t n) +{ + size_t i; + for (i = 0; i +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t *memxor(uint8_t *dst, const uint8_t *src, size_t n); +uint8_t *memxor3(uint8_t *dst, const uint8_t *a, const uint8_t *b, size_t n); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MEMXOR_H_INCLUDED */ diff --git a/nettle-internal.c b/nettle-internal.c new file mode 100644 index 0000000..a4817fa --- /dev/null +++ b/nettle-internal.c @@ -0,0 +1,85 @@ +/* nettle-internal.c + * + * Things that are used only by the testsuite and benchmark, and + * subject to change. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "nettle-internal.h" +#include "des.h" +#include "blowfish.h" + +/* DES uses a different signature for the key set function. + * And we have to adjust parity. */ +static void +des_set_key_hack(void *c, unsigned length, const uint8_t *key) +{ + struct des_ctx *ctx = c; + uint8_t pkey[DES_KEY_SIZE]; + + assert(length == DES_KEY_SIZE); + des_fix_parity(DES_KEY_SIZE, pkey, key); + if (!des_set_key(ctx, pkey)) + abort(); +} + +static void +des3_set_key_hack(void *c, unsigned length, const uint8_t *key) +{ + struct des3_ctx *ctx = c; + uint8_t pkey[DES3_KEY_SIZE]; + + assert(length == DES3_KEY_SIZE); + des_fix_parity(DES3_KEY_SIZE, pkey, key); + if (!des3_set_key(ctx, pkey)) + abort(); +} + +const struct nettle_cipher +nettle_des = { + "des", sizeof(struct des_ctx), + DES_BLOCK_SIZE, DES_KEY_SIZE, + des_set_key_hack, des_set_key_hack, + (nettle_crypt_func *) des_encrypt, + (nettle_crypt_func *) des_decrypt +}; + +const struct nettle_cipher +nettle_des3 = { + "des3", sizeof(struct des3_ctx), + DES3_BLOCK_SIZE, DES3_KEY_SIZE, + des3_set_key_hack, des3_set_key_hack, + (nettle_crypt_func *) des3_encrypt, + (nettle_crypt_func *) des3_decrypt +}; + +/* NOTE: This is not as nice as one might think, as it will crash if + * we try to encrypt something with a weak key. */ +const struct nettle_cipher +nettle_blowfish128 = _NETTLE_CIPHER(blowfish, BLOWFISH, 128); diff --git a/nettle-internal.h b/nettle-internal.h new file mode 100644 index 0000000..c5b1b53 --- /dev/null +++ b/nettle-internal.h @@ -0,0 +1,77 @@ +/* nettle-internal.h + * + * Things that are used only by the testsuite and benchmark, and + * subject to change. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_INTERNAL_H_INCLUDED +#define NETTLE_INTERNAL_H_INCLUDED + +#include "nettle-meta.h" + +/* Temporary allocation, for systems that don't support alloca. Note + * that the allocation requests should always be reasonably small, so + * that they can fit on the stack. For non-alloca systems, we use a + * fix maximum size, and abort if we ever need anything larger. */ + +#if HAVE_ALLOCA +# define TMP_DECL(name, type, max) type *name +# define TMP_ALLOC(name, size) (name = alloca(sizeof (*name) * size)) +#else /* !HAVE_ALLOCA */ +# define TMP_DECL(name, type, max) type name[max] +# define TMP_ALLOC(name, size) \ +do { if (size > (sizeof(name) / sizeof(name[0]))) abort(); } while (0) +#endif + +/* Arbitrary limits which apply to systems that don't have alloca */ +#define NETTLE_MAX_BIGNUM_BITS 10000 +#define NETTLE_MAX_HASH_BLOCK_SIZE 128 +#define NETTLE_MAX_HASH_DIGEST_SIZE 64 +#define NETTLE_MAX_SEXP_ASSOC 17 +#define NETTLE_MAX_CIPHER_BLOCK_SIZE 32 + +/* Doesn't quite fit with the other algorithms, because of the weak + * keys. Weak keys are not reported, the functions will simply crash + * if you try to use a weak key. */ + +extern const struct nettle_cipher nettle_des; +extern const struct nettle_cipher nettle_des3; + +extern const struct nettle_cipher nettle_blowfish128; + +/* Glue to openssl, for comparative benchmarking. The corresponding + * code is not included in the nettle library, as that would make the + * shared library depend on openssl. Instead, look at + * examples/nettle-openssl.c. */ +extern const struct nettle_cipher nettle_openssl_aes128; +extern const struct nettle_cipher nettle_openssl_aes192; +extern const struct nettle_cipher nettle_openssl_aes256; +extern const struct nettle_cipher nettle_openssl_arcfour128; +extern const struct nettle_cipher nettle_openssl_blowfish128; +extern const struct nettle_cipher nettle_openssl_des; +extern const struct nettle_cipher nettle_openssl_cast128; + +extern const struct nettle_hash nettle_openssl_md5; +extern const struct nettle_hash nettle_openssl_sha1; + +#endif /* NETTLE_INTERNAL_H_INCLUDED */ diff --git a/nettle-meta.h b/nettle-meta.h new file mode 100644 index 0000000..e3fb4e2 --- /dev/null +++ b/nettle-meta.h @@ -0,0 +1,217 @@ +/* nettle-meta.h + * + * Information about algorithms. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_META_H_INCLUDED +#define NETTLE_META_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +struct nettle_cipher +{ + const char *name; + + unsigned context_size; + + /* Zero for stream ciphers */ + unsigned block_size; + + /* Suggested key size; other sizes are sometimes possible. */ + unsigned key_size; + + nettle_set_key_func *set_encrypt_key; + nettle_set_key_func *set_decrypt_key; + + nettle_crypt_func *encrypt; + nettle_crypt_func *decrypt; +}; + +#define _NETTLE_CIPHER(name, NAME, keysize) { \ + #name #keysize, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 8, \ + (nettle_set_key_func *) name##_set_key, \ + (nettle_set_key_func *) name##_set_key, \ + (nettle_crypt_func *) name##_encrypt, \ + (nettle_crypt_func *) name##_decrypt, \ +} + +#define _NETTLE_CIPHER_SEP(name, NAME, keysize) { \ + #name #keysize, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 8, \ + (nettle_set_key_func *) name##_set_encrypt_key, \ + (nettle_set_key_func *) name##_set_decrypt_key, \ + (nettle_crypt_func *) name##_encrypt, \ + (nettle_crypt_func *) name##_decrypt, \ +} + +#define _NETTLE_CIPHER_SEP_SET_KEY(name, NAME, keysize) {\ + #name #keysize, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 8, \ + (nettle_set_key_func *) name##_set_encrypt_key, \ + (nettle_set_key_func *) name##_set_decrypt_key, \ + (nettle_crypt_func *) name##_crypt, \ + (nettle_crypt_func *) name##_crypt, \ +} + +#define _NETTLE_CIPHER_FIX(name, NAME, keysize) { \ + #name, \ + sizeof(struct name##_ctx), \ + NAME##_BLOCK_SIZE, \ + keysize / 8, \ + (nettle_set_key_func *) name##_set_key, \ + (nettle_set_key_func *) name##_set_key, \ + (nettle_crypt_func *) name##_encrypt, \ + (nettle_crypt_func *) name##_decrypt, \ +} + +extern const struct nettle_cipher nettle_aes128; +extern const struct nettle_cipher nettle_aes192; +extern const struct nettle_cipher nettle_aes256; + +extern const struct nettle_cipher nettle_arcfour128; + +extern const struct nettle_cipher nettle_camellia128; +extern const struct nettle_cipher nettle_camellia192; +extern const struct nettle_cipher nettle_camellia256; + +extern const struct nettle_cipher nettle_cast128; + +extern const struct nettle_cipher nettle_serpent128; +extern const struct nettle_cipher nettle_serpent192; +extern const struct nettle_cipher nettle_serpent256; + +extern const struct nettle_cipher nettle_twofish128; +extern const struct nettle_cipher nettle_twofish192; +extern const struct nettle_cipher nettle_twofish256; + +extern const struct nettle_cipher nettle_arctwo40; +extern const struct nettle_cipher nettle_arctwo64; +extern const struct nettle_cipher nettle_arctwo128; +extern const struct nettle_cipher nettle_arctwo_gutmann128; + +struct nettle_hash +{ + const char *name; + + /* Size of the context struct */ + unsigned context_size; + + /* Size of digests */ + unsigned digest_size; + + /* Internal block size */ + unsigned block_size; + + nettle_hash_init_func *init; + nettle_hash_update_func *update; + nettle_hash_digest_func *digest; +}; + +#define _NETTLE_HASH(name, NAME) { \ + #name, \ + sizeof(struct name##_ctx), \ + NAME##_DIGEST_SIZE, \ + NAME##_DATA_SIZE, \ + (nettle_hash_init_func *) name##_init, \ + (nettle_hash_update_func *) name##_update, \ + (nettle_hash_digest_func *) name##_digest \ +} + +extern const struct nettle_hash nettle_md2; +extern const struct nettle_hash nettle_md4; +extern const struct nettle_hash nettle_md5; +extern const struct nettle_hash nettle_sha1; +extern const struct nettle_hash nettle_sha224; +extern const struct nettle_hash nettle_sha256; +extern const struct nettle_hash nettle_sha384; +extern const struct nettle_hash nettle_sha512; + +struct nettle_armor +{ + const char *name; + unsigned encode_context_size; + unsigned decode_context_size; + + unsigned encode_final_length; + + nettle_armor_init_func *encode_init; + nettle_armor_length_func *encode_length; + nettle_armor_encode_update_func *encode_update; + nettle_armor_encode_final_func *encode_final; + + nettle_armor_init_func *decode_init; + nettle_armor_length_func *decode_length; + nettle_armor_decode_update_func *decode_update; + nettle_armor_decode_final_func *decode_final; +}; + +#define _NETTLE_ARMOR(name, NAME) { \ + #name, \ + sizeof(struct name##_encode_ctx), \ + sizeof(struct name##_decode_ctx), \ + NAME##_ENCODE_FINAL_LENGTH, \ + (nettle_armor_init_func *) name##_encode_init, \ + (nettle_armor_length_func *) name##_encode_length, \ + (nettle_armor_encode_update_func *) name##_encode_update, \ + (nettle_armor_encode_final_func *) name##_encode_final, \ + (nettle_armor_init_func *) name##_decode_init, \ + (nettle_armor_length_func *) name##_decode_length, \ + (nettle_armor_decode_update_func *) name##_decode_update, \ + (nettle_armor_decode_final_func *) name##_decode_final, \ +} + +#define _NETTLE_ARMOR_0(name, NAME) { \ + #name, \ + 0, \ + sizeof(struct name##_decode_ctx), \ + NAME##_ENCODE_FINAL_LENGTH, \ + (nettle_armor_init_func *) name##_encode_init, \ + (nettle_armor_length_func *) name##_encode_length, \ + (nettle_armor_encode_update_func *) name##_encode_update, \ + (nettle_armor_encode_final_func *) name##_encode_final, \ + (nettle_armor_init_func *) name##_decode_init, \ + (nettle_armor_length_func *) name##_decode_length, \ + (nettle_armor_decode_update_func *) name##_decode_update, \ + (nettle_armor_decode_final_func *) name##_decode_final, \ +} + +extern const struct nettle_armor nettle_base64; +extern const struct nettle_armor nettle_base16; + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_META_H_INCLUDED */ diff --git a/nettle-types.h b/nettle-types.h new file mode 100644 index 0000000..2a97715 --- /dev/null +++ b/nettle-types.h @@ -0,0 +1,87 @@ +/* nettle-types.h */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_TYPES_H +#define NETTLE_TYPES_H + +#include "nettle-stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Randomness. Used by key generation and dsa signature creation. */ +typedef void (nettle_random_func)(void *ctx, + unsigned length, uint8_t *dst); + +/* Progress report function, mainly for key generation. */ +typedef void (nettle_progress_func)(void *ctx, + int c); + +/* Ciphers */ +typedef void (nettle_set_key_func)(void *ctx, + unsigned length, + const uint8_t *key); + +/* Uses a void * for cipher contexts. + + For block ciphers it would make sense with a const void * for the + context, but we use the same typedef for stream ciphers where the + internal state changes during the encryption. */ + +typedef void (nettle_crypt_func)(void *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +/* Hash algorithms */ +typedef void (nettle_hash_init_func)(void *ctx); +typedef void (nettle_hash_update_func)(void *ctx, + unsigned length, + const uint8_t *src); +typedef void (nettle_hash_digest_func)(void *ctx, + unsigned length, uint8_t *dst); + +/* ASCII armor codecs. NOTE: Experimental and subject to change. */ + +typedef unsigned (nettle_armor_length_func)(unsigned length); +typedef void (nettle_armor_init_func)(void *ctx); + +typedef unsigned (nettle_armor_encode_update_func)(void *ctx, + uint8_t *dst, + unsigned src_length, + const uint8_t *src); + +typedef unsigned (nettle_armor_encode_final_func)(void *ctx, uint8_t *dst); + +typedef int (nettle_armor_decode_update_func)(void *ctx, + unsigned *dst_length, + uint8_t *dst, + unsigned src_length, + const uint8_t *src); + +typedef int (nettle_armor_decode_final_func)(void *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_TYPES_H */ diff --git a/nettle-write.h b/nettle-write.h new file mode 100644 index 0000000..7287270 --- /dev/null +++ b/nettle-write.h @@ -0,0 +1,44 @@ +/* nettle-write.h + * + * Prototypes for some internal functions to write out word-sized data + * to byte arrays. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_WRITE_H_INCLUDED +#define NETTLE_WRITE_H_INCLUDED + +#include "nettle-stdint.h" + +/* Write the word array at SRC to the byte array at DST, using little + endian (le) or big endian (be) byte order, and truncating the + result to LENGTH bytes. */ +void +_nettle_write_be32(unsigned length, uint8_t *dst, + uint32_t *src); +void +_nettle_write_le32(unsigned length, uint8_t *dst, + uint32_t *src); +void +_nettle_write_be64(unsigned length, uint8_t *dst, + uint64_t *src); + +#endif /* NETTLE_WRITE_H_INCLUDED */ diff --git a/nettle.html b/nettle.html new file mode 100644 index 0000000..52ef62b --- /dev/null +++ b/nettle.html @@ -0,0 +1,5286 @@ + + +Nettle: a low-level cryptographic library + + + + + + + + +

Nettle: a low-level cryptographic library

+ + + + +
+


+Node: Top, +Next: , +Previous: (dir), +Up: (dir) +
+
+ +

Nettle

+ +

This document describes the Nettle low-level cryptographic library. You +can use the library directly from your C programs, or write or use an +object-oriented wrapper for your favorite language or application. + +This manual is for the Nettle library (version 2.1), a +low-level cryptographic library. + +

Originally written 2001 by Niels Möller, updated 2010. + +

+This manual is placed in the public domain. You may freely copy it, in +whole or in part, with or without modification. Attribution is +appreciated, but not required. +
+ + + +
+


+Node: Introduction, +Next: , +Previous: Top, +Up: Top +
+
+ +

Introduction

+ +

Nettle is a cryptographic library that is designed to fit easily in more +or less any context: In crypto toolkits for object-oriented languages +(C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in +kernel space. In most contexts, you need more than the basic +cryptographic algorithms, you also need some way to keep track of available +algorithms, their properties and variants. You often have some algorithm +selection process, often dictated by a protocol you want to implement. + +

And as the requirements of applications differ in subtle and not so +subtle ways, an API that fits one application well can be a pain to use +in a different context. And that is why there are so many different +cryptographic libraries around. + +

Nettle tries to avoid this problem by doing one thing, the low-level +crypto stuff, and providing a simple but general interface to it. +In particular, Nettle doesn't do algorithm selection. It doesn't do +memory allocation. It doesn't do any I/O. + +

The idea is that one can build several application and context specific +interfaces on top of Nettle, and share the code, test cases, benchmarks, +documentation, etc. Examples are the Nettle module for the Pike +language, and LSH, which both use an object-oriented abstraction on top +of the library. + +

This manual explains how to use the Nettle library. It also tries to +provide some background on the cryptography, and advice on how to best +put it to use. + +

+


+Node: Copyright, +Next: , +Previous: Introduction, +Up: Top +
+
+ +

Copyright

+ +

Nettle is distributed under the GNU General Public License (GPL) (see +the file COPYING for details). However, most of the individual files +are dual licensed under less restrictive licenses like the GNU Lesser +General Public License (LGPL), or are in the public domain. This means +that if you don't use the parts of nettle that are GPL-only, you have +the option to use the Nettle library just as if it were licensed under +the LGPL. To find the current status of particular files, you have to +read the copyright notices at the top of the files. + +

This manual is in the public domain. You may freely copy it in whole or +in part, e.g., into documentation of programs that build on Nettle. +Attribution, as well as contribution of improvements to the text, is of +course appreciated, but it is not required. + +

A list of the supported algorithms, their origins and licenses: + +

+
AES +
The implementation of the AES cipher (also known as rijndael) is written +by Rafael Sevilla. Assembler for x86 by Rafael Sevilla and +Niels Möller, Sparc assembler by Niels Möller. Released under the +LGPL. + +
ARCFOUR +
The implementation of the ARCFOUR (also known as RC4) cipher is written +by Niels Möller. Released under the LGPL. + +
ARCTWO +
The implementation of the ARCTWO (also known as RC2) cipher is written +by Nikos Mavroyanopoulos and modified by Werner Koch and Simon +Josefsson. Released under the LGPL. + +
BLOWFISH +
The implementation of the BLOWFISH cipher is written by Werner Koch, +copyright owned by the Free Software Foundation. Also hacked by Ray +Dassen and Niels Möller. Released under the GPL. + +
CAMELLIA +
The C implementation is by Nippon Telegraph and Telephone Corporation +(NTT), heavily modified by Niels Möller. Assembler for x86 by +Niels Möller. Released under the LGPL. + +
CAST128 +
The implementation of the CAST128 cipher is written by Steve Reid. +Released into the public domain. + +
DES +
The implementation of the DES cipher is written by Dana L. How, and +released under the LGPL. + +
MD2 +
The implementation of MD2 is written by Andrew Kuchling, and hacked +some by Andreas Sigfridsson and Niels Möller. Python Cryptography +Toolkit license (essentially public domain). + +
MD4 +
This is almost the same code as for MD5 below, with modifications by +Marcus Comstedt. Released into the public domain. + +
MD5 +
The implementation of the MD5 message digest is written by Colin Plumb. +It has been hacked some more by Andrew Kuchling and Niels Möller. +Released into the public domain. + +
SERPENT +
The implementation of the SERPENT cipher is written by Ross Anderson, +Eli Biham, and Lars Knudsen, adapted to LSH by Rafael Sevilla, and to +Nettle by Niels Möller. Released under the GPL. + +
SHA1 +
The C implementation of the SHA1 message digest is written by Peter +Gutmann, and hacked some more by Andrew Kuchling and Niels Möller. +Released into the public domain. Assembler for x86 by Niels Möller, +released under the LGPL. + +
SHA224, SHA256, SHA384, and SHA512 +
Written by Niels Möller, using Peter Gutmann's SHA1 code as a model. +Released under the LGPL. + +
TWOFISH +
The implementation of the TWOFISH cipher is written by Ruud de Rooij. +Released under the LGPL. + +
RSA +
Written by Niels Möller, released under the LGPL. Uses the GMP library +for bignum operations. + +
DSA +
Written by Niels Möller, released under the LGPL. Uses the GMP library +for bignum operations. +
+ +
+


+Node: Conventions, +Next: , +Previous: Copyright, +Up: Top +
+
+ +

Conventions

+ +

For each supported algorithm, there is an include file that defines a +context struct, a few constants, and declares functions for +operating on the context. The context struct encapsulates all information +needed by the algorithm, and it can be copied or moved in memory with no +unexpected effects. + +

For consistency, functions for different algorithms are very similar, +but there are some differences, for instance reflecting if the key setup +or encryption function differ for encryption and decryption, and whether +or not key setup can fail. There are also differences between algorithms +that don't show in function prototypes, but which the application must +nevertheless be aware of. There is no big difference between the +functions for stream ciphers and for block ciphers, although they should +be used quite differently by the application. + +

If your application uses more than one algorithm of the same type, you +should probably create an interface that is tailor-made for your needs, +and then write a few lines of glue code on top of Nettle. + +

By convention, for an algorithm named foo, the struct tag for the +context struct is foo_ctx, constants and functions uses prefixes +like FOO_BLOCK_SIZE (a constant) and foo_set_key (a +function). + +

In all functions, strings are represented with an explicit length, of +type unsigned, and a pointer of type uint8_t * or +const uint8_t *. For functions that transform one string to +another, the argument order is length, destination pointer and source +pointer. Source and destination areas are of the same length. Source and +destination may be the same, so that you can process strings in place, +but they must not overlap in any other way. + +

Many of the functions lack return value and can never fail. Those +functions which can fail, return one on success and zero on failure. + +

+


+Node: Example, +Next: , +Previous: Conventions, +Up: Top +
+
+ +

Example

+ +

A simple example program that reads a file from standard input and +writes its SHA1 checksum on standard output should give the flavor of +Nettle. + +

+
+     
#include <stdio.h>
+     #include <stdlib.h>
+     
+     #include <nettle/sha.h>
+     
+     #define BUF_SIZE 1000
+     
+     static void
+     display_hex(unsigned length, uint8_t *data)
+     {
+       unsigned i;
+     
+       for (i = 0; i<length; i++)
+         printf("%02x ", data[i]);
+     
+       printf("\n");
+     }
+     
+     int
+     main(int argc, char **argv)
+     {
+       struct sha1_ctx ctx;
+       uint8_t buffer[BUF_SIZE];
+       uint8_t digest[SHA1_DIGEST_SIZE];
+       
+       sha1_init(&ctx);
+       for (;;)
+       {
+         int done = fread(buffer, 1, sizeof(buffer), stdin);
+         sha1_update(&ctx, done, buffer);
+         if (done < sizeof(buffer))
+           break;
+       }
+       if (ferror(stdin))
+         return EXIT_FAILURE;
+     
+       sha1_digest(&ctx, SHA1_DIGEST_SIZE, digest);
+     
+       display_hex(SHA1_DIGEST_SIZE, digest);
+       return EXIT_SUCCESS;  
+     }
+     
+ +

On a typical Unix system, this program can be compiled and linked with +the command line +

     cc sha-example.c -o sha-example -lnettle
+     
+ +
+


+Node: Linking, +Next: , +Previous: Example, +Up: Top +
+
+ +

Linking

+ +

Nettle actually consists of two libraries, libnettle and +libhogweed. The libhogweed library contains those +functions of Nettle that uses bignum operations, and depends on the GMP +library. With this division, linking works the same for both static and +dynamic libraries. + +

If an application uses only the symmetric crypto algorithms of Nettle +(i.e., block ciphers, hash functions, and the like), it's sufficient to +link with -lnettle. If an application also uses public-key +algorithms, the recommended linker flags are -lhogweed -lnettle +-lgmp. If the involved libraries are installed as dynamic libraries, it +may be sufficient to link with just -lhogweed, and the loader +will resolve the dependencies automatically. + +

+


+Node: Reference, +Next: , +Previous: Linking, +Up: Top +
+
+ +

Reference

+ +

This chapter describes all the Nettle functions, grouped by family. + +

+ +
+


+Node: Hash functions, +Next: , +Previous: Reference, +Up: Reference +
+
+ +

Hash functions

+ +

A cryptographic hash function is a function that takes variable +size strings, and maps them to strings of fixed, short, length. There +are naturally lots of collisions, as there are more possible 1MB files +than 20 byte strings. But the function is constructed such that is hard +to find the collisions. More precisely, a cryptographic hash function +H should have the following properties: + +

+ +
One-way +
Given a hash value H(x) it is hard to find a string x +that hashes to that value. + +
Collision-resistant +
It is hard to find two different strings, x and y, such +that H(x) = H(y). + +
+ +

Hash functions are useful as building blocks for digital signatures, +message authentication codes, pseudo random generators, association of +unique ids to documents, and many other things. + +

The most commonly used hash functions are MD5 and SHA1. Unfortunately, +both these fail the collision-resistance requirement; cryptologists have +found ways to construct colliding inputs. The recommended hash function +for new applications is SHA256, even though it uses a structure similar +to MD5 and SHA1. Constructing better hash functions is an urgent research +problem. + +

MD5

+ +

MD5 is a message digest function constructed by Ronald Rivest, and +described in RFC 1321. It outputs message digests of 128 bits, or +16 octets. Nettle defines MD5 in <nettle/md5.h>. + +

+ + + + + +
struct md5_ctx + Context struct
+ + +
+
+ +

+ + + + + +
MD5_DIGEST_SIZE + Constant
+ + +
+The size of an MD5 digest, i.e. 16. +
+ +

+ + + + + +
MD5_DATA_SIZE + Constant
+ + +
+The internal block size of MD5. Useful for some special constructions, +in particular HMAC-MD5. +
+ +

+ + + + + +
void md5_init (struct md5_ctx *ctx) + Function
+ + +
+Initialize the MD5 state. +
+ +

+ + + + + +
void md5_update (struct md5_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void md5_digest (struct md5_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +MD5_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +md5_init. +

+ +

The normal way to use MD5 is to call the functions in order: First +md5_init, then md5_update zero or more times, and finally +md5_digest. After md5_digest, the context is reset to +its initial state, so you can start over calling md5_update to +hash new data. + +

To start over, you can call md5_init at any time. + +

MD2

+ +

MD2 is another hash function of Ronald Rivest's, described in +RFC 1319. It outputs message digests of 128 bits, or 16 octets. +Nettle defines MD2 in <nettle/md2.h>. + +

+ + + + + +
struct md2_ctx + Context struct
+ + +
+
+ +

+ + + + + +
MD2_DIGEST_SIZE + Constant
+ + +
+The size of an MD2 digest, i.e. 16. +
+ +

+ + + + + +
MD2_DATA_SIZE + Constant
+ + +
+The internal block size of MD2. +
+ +

+ + + + + +
void md2_init (struct md2_ctx *ctx) + Function
+ + +
+Initialize the MD2 state. +
+ +

+ + + + + +
void md2_update (struct md2_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void md2_digest (struct md2_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +MD2_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +md2_init. +

+ +

MD4

+ +

MD4 is a predecessor of MD5, described in RFC 1320. Like MD5, it +is constructed by Ronald Rivest. It outputs message digests of 128 bits, +or 16 octets. Nettle defines MD4 in <nettle/md4.h>. Use of MD4 is +not recommended, but it is sometimes needed for compatibility with +existing applications and protocols. + +

+ + + + + +
struct md4_ctx + Context struct
+ + +
+
+ +

+ + + + + +
MD4_DIGEST_SIZE + Constant
+ + +
+The size of an MD4 digest, i.e. 16. +
+ +

+ + + + + +
MD4_DATA_SIZE + Constant
+ + +
+The internal block size of MD4. +
+ +

+ + + + + +
void md4_init (struct md4_ctx *ctx) + Function
+ + +
+Initialize the MD4 state. +
+ +

+ + + + + +
void md4_update (struct md4_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void md4_digest (struct md4_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +MD4_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +md4_init. +

+ +

SHA1

+ +

SHA1 is a hash function specified by NIST (The U.S. National Institute +for Standards and Technology). It outputs hash values of 160 bits, or 20 +octets. Nettle defines SHA1 in <nettle/sha.h>. + +

The functions are analogous to the MD5 ones. + +

+ + + + + +
struct sha1_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA1_DIGEST_SIZE + Constant
+ + +
+The size of an SHA1 digest, i.e. 20. +
+ +

+ + + + + +
SHA1_DATA_SIZE + Constant
+ + +
+The internal block size of SHA1. Useful for some special constructions, +in particular HMAC-SHA1. +
+ +

+ + + + + +
void sha1_init (struct sha1_ctx *ctx) + Function
+ + +
+Initialize the SHA1 state. +
+ +

+ + + + + +
void sha1_update (struct sha1_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha1_digest (struct sha1_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA1_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +sha1_init. +

+ +

SHA256

+ +

SHA256 is another hash function specified by NIST, intended as a +replacement for SHA1, generating larger digests. It outputs +hash values of 256 bits, or 32 octets. Nettle defines SHA256 in +<nettle/sha.h>. + +

The functions are analogous to the MD5 ones. + +

+ + + + + +
struct sha256_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA256_DIGEST_SIZE + Constant
+ + +
+The size of an SHA256 digest, i.e. 32. +
+ +

+ + + + + +
SHA256_DATA_SIZE + Constant
+ + +
+The internal block size of SHA256. Useful for some special constructions, +in particular HMAC-SHA256. +
+ +

+ + + + + +
void sha256_init (struct sha256_ctx *ctx) + Function
+ + +
+Initialize the SHA256 state. +
+ +

+ + + + + +
void sha256_update (struct sha256_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha256_digest (struct sha256_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA256_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +sha256_init. +

+ +

SHA224

+ +

SHA224 is a variant of SHA256, with a different initial state, and with +the output truncated to 224 bits, or 28 octets. Nettle defines SHA224 in +<nettle/sha.h>. + +

The functions are analogous to the MD5 ones. + +

+ + + + + +
struct sha224_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA224_DIGEST_SIZE + Constant
+ + +
+The size of an SHA224 digest, i.e. 28. +
+ +

+ + + + + +
SHA224_DATA_SIZE + Constant
+ + +
+The internal block size of SHA224. Useful for some special constructions, +in particular HMAC-SHA224. +
+ +

+ + + + + +
void sha224_init (struct sha224_ctx *ctx) + Function
+ + +
+Initialize the SHA224 state. +
+ +

+ + + + + +
void sha224_update (struct sha224_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha224_digest (struct sha224_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA224_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +sha224_init. +

+ +

SHA512

+ +

SHA512 is a larger sibling to SHA256, with a very similar structure but +with both the output and the internal variables of twice the size. The +internal variables are 64 bits rather than 32, making it significantly +slower on 32-bit computers. It outputs hash values of 512 bits, or 64 +octets. Nettle defines SHA512 in <nettle/sha.h>. + +

The functions are analogous to the MD5 ones. + +

+ + + + + +
struct sha512_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA512_DIGEST_SIZE + Constant
+ + +
+The size of an SHA512 digest, i.e. 64. +
+ +

+ + + + + +
SHA512_DATA_SIZE + Constant
+ + +
+The internal block size of SHA512. Useful for some special constructions, +in particular HMAC-SHA512. +
+ +

+ + + + + +
void sha512_init (struct sha512_ctx *ctx) + Function
+ + +
+Initialize the SHA512 state. +
+ +

+ + + + + +
void sha512_update (struct sha512_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha512_digest (struct sha512_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA512_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +sha512_init. +

+ +

SHA384

+ +

SHA384 is a variant of SHA512, with a different initial state, and with +the output truncated to 384 bits, or 48 octets. Nettle defines SHA384 in +<nettle/sha.h>. + +

The functions are analogous to the MD5 ones. + +

+ + + + + +
struct sha384_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SHA384_DIGEST_SIZE + Constant
+ + +
+The size of an SHA384 digest, i.e. 48. +
+ +

+ + + + + +
SHA384_DATA_SIZE + Constant
+ + +
+The internal block size of SHA384. Useful for some special constructions, +in particular HMAC-SHA384. +
+ +

+ + + + + +
void sha384_init (struct sha384_ctx *ctx) + Function
+ + +
+Initialize the SHA384 state. +
+ +

+ + + + + +
void sha384_update (struct sha384_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Hash some more data. +
+ +

+ + + + + +
void sha384_digest (struct sha384_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA384_DIGEST_SIZE, in which case only the first length +octets of the digest are written. + +

This function also resets the context in the same way as +sha384_init. +

+ +

struct nettle_hash

+ +

Nettle includes a struct including information about the supported hash +functions. It is defined in <nettle/nettle-meta.h>, and is used +by Nettle's implementation of HMAC see Keyed hash functions. + +

+ + + + + +
struct nettle_hash name context_size digest_size block_size init update digest + Meta struct
+ + +
+The last three attributes are function pointers, of types +nettle_hash_init_func, nettle_hash_update_func, and +nettle_hash_digest_func. The first argument to these functions is +void * pointer to a context struct, which is of size +context_size. +
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
struct nettle_hash nettle_md2 + Constant Struct
struct nettle_hash nettle_md4 + Constant Struct
struct nettle_hash nettle_md5 + Constant Struct
struct nettle_hash nettle_sha1 + Constant Struct
struct nettle_hash nettle_sha224 + Constant Struct
struct nettle_hash nettle_sha256 + Constant Struct
struct nettle_hash nettle_sha384 + Constant Struct
struct nettle_hash nettle_sha512 + Constant Struct
+ + +
+ +

These are all the hash functions that Nettle implements. +

+ +

+


+Node: Cipher functions, +Next: , +Previous: Hash functions, +Up: Reference +
+
+ +

Cipher functions

+ +

A cipher is a function that takes a message or plaintext +and a secret key and transforms it to a ciphertext. Given +only the ciphertext, but not the key, it should be hard to find the +plaintext. Given matching pairs of plaintext and ciphertext, it should +be hard to find the key. + +

There are two main classes of ciphers: Block ciphers and stream ciphers. + +

A block cipher can process data only in fixed size chunks, called +blocks. Typical block sizes are 8 or 16 octets. To encrypt +arbitrary messages, you usually have to pad it to an integral number of +blocks, split it into blocks, and then process each block. The simplest +way is to process one block at a time, independent of each other. That +mode of operation is called ECB, Electronic Code Book mode. +However, using ECB is usually a bad idea. For a start, plaintext blocks +that are equal are transformed to ciphertext blocks that are equal; that +leaks information about the plaintext. Usually you should apply the +cipher is some "feedback mode", CBC (Cipher Block Chaining) and +CTR (Counter mode) being two of +of the most popular. See See Cipher modes, for information on +how to apply CBC and CTR with Nettle. + +

A stream cipher can be used for messages of arbitrary length. A typical +stream cipher is a keyed pseudo-random generator. To encrypt a plaintext +message of n octets, you key the generator, generate n +octets of pseudo-random data, and XOR it with the plaintext. To decrypt, +regenerate the same stream using the key, XOR it to the ciphertext, and +the plaintext is recovered. + +

Caution: The first rule for this kind of cipher is the +same as for a One Time Pad: never ever use the same key twice. + +

A common misconception is that encryption, by itself, implies +authentication. Say that you and a friend share a secret key, and you +receive an encrypted message. You apply the key, and get a plaintext +message that makes sense to you. Can you then be sure that it really was +your friend that wrote the message you're reading? The answer is no. For +example, if you were using a block cipher in ECB mode, an attacker may +pick up the message on its way, and reorder, delete or repeat some of +the blocks. Even if the attacker can't decrypt the message, he can +change it so that you are not reading the same message as your friend +wrote. If you are using a block cipher in CBC mode rather than +ECB, or are using a stream cipher, the possibilities for this sort of +attack are different, but the attacker can still make predictable +changes to the message. + +

It is recommended to always use an authentication mechanism in +addition to encrypting the messages. Popular choices are Message +Authentication Codes like HMAC-SHA1 see Keyed hash functions, or digital signatures like RSA. + +

Some ciphers have so called "weak keys", keys that results in +undesirable structure after the key setup processing, and should be +avoided. In Nettle, most key setup functions have no return value, but +for ciphers with weak keys, the return value indicates whether or not +the given key is weak. For good keys, key setup returns 1, and for weak +keys, it returns 0. When possible, avoid algorithms that +have weak keys. There are several good ciphers that don't have any weak +keys. + +

To encrypt a message, you first initialize a cipher context for +encryption or decryption with a particular key. You then use the context +to process plaintext or ciphertext messages. The initialization is known +as key setup. With Nettle, it is recommended to use each +context struct for only one direction, even if some of the ciphers use a +single key setup function that can be used for both encryption and +decryption. + +

AES

+ +

AES is a block cipher, specified by NIST as a replacement for +the older DES standard. The standard is the result of a competition +between cipher designers. The winning design, also known as RIJNDAEL, +was constructed by Joan Daemen and Vincent Rijnmen. + +

Like all the AES candidates, the winning design uses a block size of 128 +bits, or 16 octets, and variable key-size, 128, 192 and 256 bits (16, 24 +and 32 octets) being the allowed key sizes. It does not have any weak +keys. Nettle defines AES in <nettle/aes.h>. + +

+ + + + + +
struct aes_ctx + Context struct
+ + +
+
+ +

+ + + + + +
AES_BLOCK_SIZE + Constant
+ + +
+The AES block-size, 16 +
+ +

+ + + + + +
AES_MIN_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
AES_MAX_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
AES_KEY_SIZE + Constant
+ + +
+Default AES key size, 32 +
+ +

+ + + + + + + + + + +
void aes_set_encrypt_key (struct aes_ctx *ctx, unsigned length, const uint8_t *key) + Function
void aes_set_decrypt_key (struct aes_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher, for encryption or decryption, respectively. +
+ +

+ + + + + +
void aes_invert_key (struct aes_ctx *dst, const struct aes_ctx *src) + Function
+ + +
+Given a context src initialized for encryption, initializes the +context struct dst for decryption, using the same key. If the same +context struct is passed for both src and dst, it is +converted in place. Calling aes_set_encrypt_key and +aes_invert_key is more efficient than calling +aes_set_encrypt_key and aes_set_decrypt_key. This function +is mainly useful for applications which needs to both encrypt and +decrypt using the same key. +
+ +

+ + + + + +
void aes_encrypt (struct aes_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void aes_decrypt (struct aes_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to aes_encrypt +
+ +

ARCFOUR

+ +

ARCFOUR is a stream cipher, also known under the trade marked name RC4, +and it is one of the fastest ciphers around. A problem is that the key +setup of ARCFOUR is quite weak, you should never use keys with +structure, keys that are ordinary passwords, or sequences of keys like +"secret:1", "secret:2", ..... If you have keys that don't look +like random bit strings, and you want to use ARCFOUR, always hash the +key before feeding it to ARCFOUR. Furthermore, the initial bytes of the +generated key stream leak information about the key; for this reason, it +is recommended to discard the first 512 bytes of the key stream. + +

     /* A more robust key setup function for ARCFOUR */
+     void
+     arcfour_set_key_hashed(struct arcfour_ctx *ctx,
+                            unsigned length, const uint8_t *key)
+     {
+       struct sha256_ctx hash;
+       uint8_t digest[SHA256_DIGEST_SIZE];
+       uint8_t buffer[0x200];
+     
+       sha256_init(&hash);
+       sha256_update(&hash, length, key);
+       sha256_digest(&hash, SHA256_DIGEST_SIZE, digest);
+     
+       arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest);
+       arcfour_crypt(ctx, sizeof(buffer), buffer, buffer);
+     }
+     
+ +

Nettle defines ARCFOUR in <nettle/arcfour.h>. + +

+ + + + + +
struct arcfour_ctx + Context struct
+ + +
+
+ +

+ + + + + +
ARCFOUR_MIN_KEY_SIZE + Constant
+ + +
+Minimum key size, 1 +
+ +

+ + + + + +
ARCFOUR_MAX_KEY_SIZE + Constant
+ + +
+Maximum key size, 256 +
+ +

+ + + + + +
ARCFOUR_KEY_SIZE + Constant
+ + +
+Default ARCFOUR key size, 16 +
+ +

+ + + + + +
void arcfour_set_key (struct arcfour_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void arcfour_crypt (struct arcfour_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encrypt some data. The same function is used for both encryption and +decryption. Unlike the block ciphers, this function modifies the +context, so you can split the data into arbitrary chunks and encrypt +them one after another. The result is the same as if you had called +arcfour_crypt only once with all the data. +
+ +

ARCTWO

+ +

ARCTWO (also known as the trade marked name RC2) is a block cipher +specified in RFC 2268. Nettle also include a variation of the ARCTWO +set key operation that lack one step, to be compatible with the +reverse engineered RC2 cipher description, as described in a Usenet +post to sci.crypt by Peter Gutmann. + +

ARCTWO uses a block size of 64 bits, and variable key-size ranging +from 1 to 128 octets. Besides the key, ARCTWO also has a second +parameter to key setup, the number of effective key bits, ekb. +This parameter can be used to artificially reduce the key size. In +practice, ekb is usually set equal to the input key size. +Nettle defines ARCTWO in <nettle/arctwo.h>. + +

We do not recommend the use of ARCTWO; the Nettle implementation is +provided primarily for interoperability with existing applications and +standards. + +

+ + + + + +
struct arctwo_ctx + Context struct
+ + +
+
+ +

+ + + + + +
ARCTWO_BLOCK_SIZE + Constant
+ + +
+The AES block-size, 8 +
+ +

+ + + + + +
ARCTWO_MIN_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
ARCTWO_MAX_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
ARCTWO_KEY_SIZE + Constant
+ + +
+Default ARCTWO key size, 8 +
+ +

+ + + + + + + + + + + + + + + +
void arctwo_set_key_ekb (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key, unsigned ekb) + Function
void arctwo_set_key (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key) + Function
void arctwo_set_key_gutmann (struct arctwo_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption +and decryption. The first function is the most general one, which lets +you provide both the variable size key, and the desired effective key +size (in bits). The maximum value for ekb is 1024, and for +convenience, ekb = 0 has the same effect as ekb = 1024. + +

arctwo_set_key(ctx, length, key) is equivalent to +arctwo_set_key_ekb(ctx, length, key, 8*length), and +arctwo_set_key_gutmann(ctx, length, key) is equivalent to +arctwo_set_key_ekb(ctx, length, key, 1024) +

+ +

+ + + + + +
void arctwo_encrypt (struct arctwo_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not +overlap in any other way. +
+ +

+ + + + + +
void arctwo_decrypt (struct arctwo_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to arctwo_encrypt +
+ +

BLOWFISH

+ +

BLOWFISH is a block cipher designed by Bruce Schneier. It uses a block +size of 64 bits (8 octets), and a variable key size, up to 448 bits. It +has some weak keys. Nettle defines BLOWFISH in <nettle/blowfish.h>. + +

+ + + + + +
struct blowfish_ctx + Context struct
+ + +
+
+ +

+ + + + + +
BLOWFISH_BLOCK_SIZE + Constant
+ + +
+The BLOWFISH block-size, 8 +
+ +

+ + + + + +
BLOWFISH_MIN_KEY_SIZE + Constant
+ + +
+Minimum BLOWFISH key size, 8 +
+ +

+ + + + + +
BLOWFISH_MAX_KEY_SIZE + Constant
+ + +
+Maximum BLOWFISH key size, 56 +
+ +

+ + + + + +
BLOWFISH_KEY_SIZE + Constant
+ + +
+Default BLOWFISH key size, 16 +
+ +

+ + + + + +
int blowfish_set_key (struct blowfish_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. Checks for weak keys, returning 1 +for good keys and 0 for weak keys. Applications that don't care about +weak keys can ignore the return value. + +

blowfish_encrypt or blowfish_decrypt with a weak key will +crash with an assert violation. +

+ +

+ + + + + +
void blowfish_encrypt (struct blowfish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void blowfish_decrypt (struct blowfish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to blowfish_encrypt +
+ +

Camellia

+ +

Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph +and Telephone Corporation, described in RFC3713, and recommended +by some Japanese and European authorities as an alternative to AES. The +algorithm is patented. The implementation in Nettle is derived from the +implementation released by NTT under the GNU LGPL (v2.1 or later), and +relies on the implicit patent license of the LGPL. There is also a +statement of royalty-free licensing for Camellia at +<http://www.ntt.co.jp/news/news01e/0104/010417.html>, but this +statement has some limitations which seem problematic for free software. + +

Camellia uses a the same block size and key sizes as AES: The block size +is 128 bits (16 octets), and the supported key sizes are 128, 192, and +256 bits. Nettle defines Camellia in <nettle/camellia.h>. + +

+ + + + + +
struct camellia_ctx + Context struct
+ + +
+
+ +

+ + + + + +
CAMELLIA_BLOCK_SIZE + Constant
+ + +
+The CAMELLIA block-size, 16 +
+ +

+ + + + + +
CAMELLIA_MIN_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
CAMELLIA_MAX_KEY_SIZE + Constant
+ + +
+
+ +

+ + + + + +
CAMELLIA_KEY_SIZE + Constant
+ + +
+Default CAMELLIA key size, 32 +
+ +

+ + + + + + + + + + +
void camellia_set_encrypt_key (struct camellia_ctx *ctx, unsigned length, const uint8_t *key) + Function
void camellia_set_decrypt_key (struct camellia_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher, for encryption or decryption, respectively. +
+ +

+ + + + + +
void camellia_invert_key (struct camellia_ctx *dst, const struct camellia_ctx *src) + Function
+ + +
+Given a context src initialized for encryption, initializes the +context struct dst for decryption, using the same key. If the same +context struct is passed for both src and dst, it is +converted in place. Calling camellia_set_encrypt_key and +camellia_invert_key is more efficient than calling +camellia_set_encrypt_key and camellia_set_decrypt_key. This function +is mainly useful for applications which needs to both encrypt and +decrypt using the same key. +
+ +

+ + + + + +
void camellia_crypt (struct camellia_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+The same function is used for both encryption and decryption. +length must be an integral multiple of the block size. If it is +more than one block, the data is processed in ECB mode. src and +dst may be equal, but they must not overlap in any other way. +
+ +

CAST128

+ +

CAST-128 is a block cipher, specified in RFC 2144. It uses a 64 +bit (8 octets) block size, and a variable key size of up to 128 bits. +Nettle defines cast128 in <nettle/cast128.h>. + +

+ + + + + +
struct cast128_ctx + Context struct
+ + +
+
+ +

+ + + + + +
CAST128_BLOCK_SIZE + Constant
+ + +
+The CAST128 block-size, 8 +
+ +

+ + + + + +
CAST128_MIN_KEY_SIZE + Constant
+ + +
+Minimum CAST128 key size, 5 +
+ +

+ + + + + +
CAST128_MAX_KEY_SIZE + Constant
+ + +
+Maximum CAST128 key size, 16 +
+ +

+ + + + + +
CAST128_KEY_SIZE + Constant
+ + +
+Default CAST128 key size, 16 +
+ +

+ + + + + +
void cast128_set_key (struct cast128_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void cast128_encrypt (struct cast128_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void cast128_decrypt (struct cast128_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to cast128_encrypt +
+ +

DES

+ +

DES is the old Data Encryption Standard, specified by NIST. It uses a +block size of 64 bits (8 octets), and a key size of 56 bits. However, +the key bits are distributed over 8 octets, where the least significant +bit of each octet may be used for parity. A common way to use DES is to +generate 8 random octets in some way, then set the least significant bit +of each octet to get odd parity, and initialize DES with the resulting +key. + +

The key size of DES is so small that keys can be found by brute force, +using specialized hardware or lots of ordinary work stations in +parallel. One shouldn't be using plain DES at all today, if one uses +DES at all one should be using "triple DES", see DES3 below. + +

DES also has some weak keys. Nettle defines DES in <nettle/des.h>. + +

+ + + + + +
struct des_ctx + Context struct
+ + +
+
+ +

+ + + + + +
DES_BLOCK_SIZE + Constant
+ + +
+The DES block-size, 8 +
+ +

+ + + + + +
DES_KEY_SIZE + Constant
+ + +
+DES key size, 8 +
+ +

+ + + + + +
int des_set_key (struct des_ctx *ctx, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. Parity bits are ignored. Checks for weak keys, returning 1 +for good keys and 0 for weak keys. Applications that don't care about +weak keys can ignore the return value. +
+ +

+ + + + + +
void des_encrypt (struct des_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void des_decrypt (struct des_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to des_encrypt +
+ +

+ + + + + +
int des_check_parity (unsigned length, const uint8_t *key); + Function
+ + +
+Checks that the given key has correct, odd, parity. Returns 1 for +correct parity, and 0 for bad parity. +
+ +

+ + + + + +
void des_fix_parity (unsigned length, uint8_t *dst, const uint8_t *src) + Function
+ + +
+Adjusts the parity bits to match DES's requirements. You need this +function if you have created a random-looking string by a key agreement +protocol, and want to use it as a DES key. dst and src may +be equal. +
+ +

DES3

+ +

The inadequate key size of DES has already been mentioned. One way to +increase the key size is to pipe together several DES boxes with +independent keys. It turns out that using two DES ciphers is not as +secure as one might think, even if the key size of the combination is a +respectable 112 bits. + +

The standard way to increase DES's key size is to use three DES boxes. +The mode of operation is a little peculiar: the middle DES box is wired +in the reverse direction. To encrypt a block with DES3, you encrypt it +using the first 56 bits of the key, then decrypt it using the +middle 56 bits of the key, and finally encrypt it again using the last +56 bits of the key. This is known as "ede" triple-DES, for +"encrypt-decrypt-encrypt". + +

The "ede" construction provides some backward compatibility, as you get +plain single DES simply by feeding the same key to all three boxes. That +should help keeping down the gate count, and the price, of hardware +circuits implementing both plain DES and DES3. + +

DES3 has a key size of 168 bits, but just like plain DES, useless parity +bits are inserted, so that keys are represented as 24 octets (192 bits). +As a 112 bit key is large enough to make brute force attacks +impractical, some applications uses a "two-key" variant of triple-DES. +In this mode, the same key bits are used for the first and the last DES +box in the pipe, while the middle box is keyed independently. The +two-key variant is believed to be secure, i.e. there are no known +attacks significantly better than brute force. + +

Naturally, it's simple to implement triple-DES on top of Nettle's DES +functions. Nettle includes an implementation of three-key "ede" +triple-DES, it is defined in the same place as plain DES, +<nettle/des.h>. + +

+ + + + + +
struct des3_ctx + Context struct
+ + +
+
+ +

+ + + + + +
DES3_BLOCK_SIZE + Constant
+ + +
+The DES3 block-size is the same as DES_BLOCK_SIZE, 8 +
+ +

+ + + + + +
DES3_KEY_SIZE + Constant
+ + +
+DES key size, 24 +
+ +

+ + + + + +
int des3_set_key (struct des3_ctx *ctx, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. Parity bits are ignored. Checks for weak keys, returning 1 +if all three keys are good keys, and 0 if one or more key is weak. +Applications that don't care about weak keys can ignore the return +value. +
+ +

For random-looking strings, you can use des_fix_parity to adjust +the parity bits before calling des3_set_key. + +

+ + + + + +
void des3_encrypt (struct des3_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void des3_decrypt (struct des3_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to des_encrypt +
+ +

SERPENT

+ +

SERPENT is one of the AES finalists, designed by Ross Anderson, Eli +Biham and Lars Knudsen. Thus, the interface and properties are similar +to AES'. One peculiarity is that it is quite pointless to use it with +anything but the maximum key size, smaller keys are just padded to +larger ones. Nettle defines SERPENT in <nettle/serpent.h>. + +

+ + + + + +
struct serpent_ctx + Context struct
+ + +
+
+ +

+ + + + + +
SERPENT_BLOCK_SIZE + Constant
+ + +
+The SERPENT block-size, 16 +
+ +

+ + + + + +
SERPENT_MIN_KEY_SIZE + Constant
+ + +
+Minimum SERPENT key size, 16 +
+ +

+ + + + + +
SERPENT_MAX_KEY_SIZE + Constant
+ + +
+Maximum SERPENT key size, 32 +
+ +

+ + + + + +
SERPENT_KEY_SIZE + Constant
+ + +
+Default SERPENT key size, 32 +
+ +

+ + + + + +
void serpent_set_key (struct serpent_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void serpent_encrypt (struct serpent_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void serpent_decrypt (struct serpent_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to serpent_encrypt +
+ +

TWOFISH

+ +

Another AES finalist, this one designed by Bruce Schneier and others. +Nettle defines it in <nettle/twofish.h>. + +

+ + + + + +
struct twofish_ctx + Context struct
+ + +
+
+ +

+ + + + + +
TWOFISH_BLOCK_SIZE + Constant
+ + +
+The TWOFISH block-size, 16 +
+ +

+ + + + + +
TWOFISH_MIN_KEY_SIZE + Constant
+ + +
+Minimum TWOFISH key size, 16 +
+ +

+ + + + + +
TWOFISH_MAX_KEY_SIZE + Constant
+ + +
+Maximum TWOFISH key size, 32 +
+ +

+ + + + + +
TWOFISH_KEY_SIZE + Constant
+ + +
+Default TWOFISH key size, 32 +
+ +

+ + + + + +
void twofish_set_key (struct twofish_ctx *ctx, unsigned length, const uint8_t *key) + Function
+ + +
+Initialize the cipher. The same function is used for both encryption and +decryption. +
+ +

+ + + + + +
void twofish_encrypt (struct twofish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Encryption function. length must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. src and dst may be equal, but they must not overlap +in any other way. +
+ +

+ + + + + +
void twofish_decrypt (struct twofish_ctx *ctx, unsigned length, const uint8_t *dst, uint8_t *src) + Function
+ + +
+Analogous to twofish_encrypt +
+ +

struct nettle_cipher

+ +

Nettle includes a struct including information about some of the more +regular cipher functions. It should be considered a little experimental, +but can be useful for applications that need a simple way to handle +various algorithms. Nettle defines these structs in +<nettle/nettle-meta.h>. + +

+ + + + + +
struct nettle_cipher name context_size block_size key_size set_encrypt_key set_decrypt_key encrypt decrypt + Meta struct
+ + +
+The last four attributes are function pointers, of types +nettle_set_key_func and nettle_crypt_func. The first +argument to these functions is a void * pointer to a context +struct, which is of size context_size. +
+ +

+ + + + + + + + + + + + + + + +
struct nettle_cipher nettle_aes128 + Constant Struct
struct nettle_cipher nettle_aes192 + Constant Struct
struct nettle_cipher nettle_aes256 + Constant Struct
+ + + + + + + + + + + + + + + + + + + + +
+ +
struct nettle_cipher nettle_arctwo40; + Constant Struct
struct nettle_cipher nettle_arctwo64; + Constant Struct
struct nettle_cipher nettle_arctwo128; + Constant Struct
struct nettle_cipher nettle_arctwo_gutmann128; + Constant Struct
+ + + + + +
+ +
struct nettle_cipher nettle_arcfour128 + Constant Struct
+ + + + + + + + + + + + + + + +
+ +
struct nettle_cipher nettle_camellia128 + Constant Struct
struct nettle_cipher nettle_camellia192 + Constant Struct
struct nettle_cipher nettle_camellia256 + Constant Struct
+ + + + + +
+ +
struct nettle_cipher nettle_cast128 + Constant Struct
+ + + + + + + + + + + + + + + +
+ +
struct nettle_cipher nettle_serpent128 + Constant Struct
struct nettle_cipher nettle_serpent192 + Constant Struct
struct nettle_cipher nettle_serpent256 + Constant Struct
+ + + + + + + + + + + + + + + +
+ +
struct nettle_cipher nettle_twofish128 + Constant Struct
struct nettle_cipher nettle_twofish192 + Constant Struct
struct nettle_cipher nettle_twofish256 + Constant Struct
+ + + + + + + + + + + + + + + + + + + + +
+ +
struct nettle_cipher nettle_arctwo40; + Constant Struct
struct nettle_cipher nettle_arctwo64; + Constant Struct
struct nettle_cipher nettle_arctwo128; + Constant Struct
struct nettle_cipher nettle_arctwo_gutmann128; + Constant Struct
+ + +
+ +

Nettle includes such structs for all the regular ciphers, i.e. +ones without weak keys or other oddities. +

+ +

+


+Node: Cipher modes, +Next: , +Previous: Cipher functions, +Up: Reference +
+
+ +

Cipher modes

+ +

Cipher modes of operation specifies the procedure to use when +encrypting a message that is larger than the cipher's block size. As +explained in See Cipher functions, splitting the message into blocks +and processing them independently with the block cipher (Electronic Code +Book mode, ECB) leaks information. Besides ECB, +Nettle provides two other modes of operation: Cipher Block Chaining +(CBC) and Counter mode (CTR). CBC is +widely used, but there are a few subtle issues of information leakage. +CTR was standardized more recently, and is believed to be more +secure. + +

Cipher Block Chaining

+ +

When using CBC mode, plaintext blocks are not encrypted +independently of each other, like in Electronic Cook Book mode. Instead, +when encrypting a block in CBC mode, the previous ciphertext +block is XORed with the plaintext before it is fed to the block cipher. +When encrypting the first block, a random block called an IV, or +Initialization Vector, is used as the "previous ciphertext block". The +IV should be chosen randomly, but it need not be kept secret, and can +even be transmitted in the clear together with the encrypted data. + +

In symbols, if E_k is the encryption function of a block cipher, +and IV is the initialization vector, then n plaintext blocks +M_1,... M_n are transformed into n ciphertext blocks +C_1,... C_n as follows: + +

     C_1 = E_k(IV  XOR M_1)
+     C_2 = E_k(C_1 XOR M_2)
+     
+     ...
+     
+     C_n = E_k(C_(n-1) XOR M_n)
+     
+ +

Nettle's includes two functions for applying a block cipher in Cipher +Block Chaining (CBC) mode, one for encryption and one for +decryption. These functions uses void * to pass cipher contexts +around. + +

+ + + + + + + + + + +
void cbc_encrypt (void *ctx, nettle_crypt_func f, unsigned block_size, uint8_t *iv, unsigned length, uint8_t *dst, const uint8_t *src) + Function
void cbc_decrypt (void *ctx, void (*f)(), unsigned block_size, uint8_t *iv, unsigned length, uint8_t *dst, const uint8_t *src) + Function
+ + +
+ +

Applies the encryption or decryption function f in CBC +mode. The final ciphertext block processed is copied into iv +before returning, so that large message be processed be a sequence of +calls to cbc_encrypt. The function f is of type + +

void f (void *ctx, unsigned length, uint8_t dst, +const uint8_t *src), + +

and the cbc_encrypt and cbc_decrypt functions pass their +argument ctx on to f. +

+ +

There are also some macros to help use these functions correctly. + +

+ + + + + +
CBC_CTX (context_type, block_size) + Macro
+ + +
+Expands into +
          {
+             context_type ctx;
+             uint8_t iv[block_size];
+          }
+          
+
+ +

It can be used to define a CBC context struct, either directly, + +

     struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx;
+     
+ +

or to give it a struct tag, + +

     struct aes_cbc_ctx CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE);
+     
+ +

+ + + + + +
CBC_SET_IV (ctx, iv) + Macro
+ + +
+First argument is a pointer to a context struct as defined by CBC_CTX, +and the second is a pointer to an Initialization Vector (IV) that is +copied into that context. +
+ +

+ + + + + + + + + + +
CBC_ENCRYPT (ctx, f, length, dst, src) + Macro
CBC_DECRYPT (ctx, f, length, dst, src) + Macro
+ + +
+A simpler way to invoke cbc_encrypt and cbc_decrypt. The +first argument is a pointer to a context struct as defined by +CBC_CTX, and the second argument is an encryption or decryption +function following Nettle's conventions. The last three arguments define +the source and destination area for the operation. +
+ +

These macros use some tricks to make the compiler display a warning if +the types of f and ctx don't match, e.g. if you try to use +an struct aes_ctx context with the des_encrypt function. + +

Counter mode

+ +

Counter mode (CTR) uses the block cipher as a keyed +pseudo-random generator. The output of the generator is XORed with the +data to be encrypted. It can be understood as a way to transform a block +cipher to a stream cipher. + +

The message is divided into n blocks M_1,... +M_n, where M_n is of size m which may be smaller +than the block size. Except for the last block, all the message blocks +must be of size equal to the cipher's block size. + +

If E_k is the encryption function of a block cipher, IC is +the initial counter, then the n plaintext blocks are +transformed into n ciphertext blocks C_1,... +C_n as follows: + +

     C_1 = E_k(IC) XOR M_1
+     C_2 = E_k(IC + 1) XOR M_2
+     
+     ...
+     
+     C_(n-1) = E_k(IC + n - 2) XOR M_(n-1)
+     C_n = E_k(IC + n - 1) [1..m] XOR M_n
+     
+ +

The IC is the initial value for the counter, it plays a +similar role as the IV for CBC. When adding, +IC + x, IC is interpreted as an integer, in network +byte order. For the last block, E_k(IC + n - 1) [1..m] means that +the cipher output is truncated to m bytes. + +

+ + + + + +
void ctr_crypt (void *ctx, nettle_crypt_func f, unsigned block_size, uint8_t *ctr, unsigned length, uint8_t *dst, const uint8_t *src) + Function
+ + +
+ +

Applies the encryption function f in CTR mode. Note that +for CTR mode, encryption and decryption is the same operation, +and hence f should always be the encryption function for the +underlying block cipher. + +

When a message is encrypted using a sequence of calls to +ctr_crypt, all but the last call must use a length that is +a multiple of the block size. +

+ +

Like for CBC, there are also a couple of helper macros. + +

+ + + + + +
CTR_CTX (context_type, block_size) + Macro
+ + +
+Expands into +
          {
+             context_type ctx;
+             uint8_t ctr[block_size];
+          }
+          
+
+ +

+ + + + + +
CTR_SET_COUNTER (ctx, iv) + Macro
+ + +
+First argument is a pointer to a context struct as defined by +CTR_CTX, and the second is a pointer to an initial counter that +is copied into that context. +
+ +

+ + + + + +
CTR_CRYPT (ctx, f, length, dst, src) + Macro
+ + +
+A simpler way to invoke ctr_crypt. The first argument is a +pointer to a context struct as defined by CTR_CTX, and the second +argument is an encryption function following Nettle's conventions. The +last three arguments define the source and destination area for the +operation. +
+ +

+


+Node: Keyed hash functions, +Next: , +Previous: Cipher modes, +Up: Reference +
+
+ +

Keyed Hash Functions

+ +

A keyed hash function, or Message Authentication Code +(MAC) is a function that takes a key and a message, and +produces fixed size MAC. It should be hard to compute a +message and a matching MAC without knowledge of the key. It +should also be hard to compute the key given only messages and +corresponding MACs. + +

Keyed hash functions are useful primarily for message authentication, +when Alice and Bob shares a secret: The sender, Alice, computes the +MAC and attaches it to the message. The receiver, Bob, also computes +the MAC of the message, using the same key, and compares that +to Alice's value. If they match, Bob can be assured that +the message has not been modified on its way from Alice. + +

However, unlike digital signatures, this assurance is not transferable. +Bob can't show the message and the MAC to a third party and +prove that Alice sent that message. Not even if he gives away the key to +the third party. The reason is that the same key is used on both +sides, and anyone knowing the key can create a correct MAC for +any message. If Bob believes that only he and Alice knows the key, and +he knows that he didn't attach a MAC to a particular message, +he knows it must be Alice who did it. However, the third party can't +distinguish between a MAC created by Alice and one created by +Bob. + +

Keyed hash functions are typically a lot faster than digital signatures +as well. + +

HMAC

+ +

One can build keyed hash functions from ordinary hash functions. Older +constructions simply concatenate secret key and message and hashes that, but +such constructions have weaknesses. A better construction is +HMAC, described in RFC 2104. + +

For an underlying hash function H, with digest size l and +internal block size b, HMAC-H is constructed as +follows: From a given key k, two distinct subkeys k_i and +k_o are constructed, both of length b. The +HMAC-H of a message m is then computed as H(k_o | +H(k_i | m)), where | denotes string concatenation. + +

HMAC keys can be of any length, but it is recommended to use +keys of length l, the digest size of the underlying hash function +H. Keys that are longer than b are shortened to length +l by hashing with H, so arbitrarily long keys aren't +very useful. + +

Nettle's HMAC functions are defined in <nettle/hmac.h>. +There are abstract functions that use a pointer to a struct +nettle_hash to represent the underlying hash function and void +* pointers that point to three different context structs for that hash +function. There are also concrete functions for HMAC-MD5, +HMAC-SHA1, HMAC-SHA256, and HMAC-SHA512. +First, the abstract functions: + +

+ + + + + +
void hmac_set_key (void *outer, void *inner, void *state, const struct nettle_hash *H, unsigned length, const uint8_t *key) + Function
+ + +
+Initializes the three context structs from the key. The outer and +inner contexts corresponds to the subkeys k_o and +k_i. state is used for hashing the message, and is +initialized as a copy of the inner context. +
+ +

+ + + + + +
void hmac_update (void *state, const struct nettle_hash *H, unsigned length, const uint8_t *data) + Function
+ + +
+This function is called zero or more times to process the message. +Actually, hmac_update(state, H, length, data) is equivalent to +H->update(state, length, data), so if you wish you can use the +ordinary update function of the underlying hash function instead. +
+ +

+ + + + + +
void hmac_digest (const void *outer, const void *inner, void *state, const struct nettle_hash *H, unsigned length, uint8_t *digest) + Function
+ + +
+Extracts the MAC of the message, writing it to digest. +outer and inner are not modified. length is usually +equal to H->digest_size, but if you provide a smaller value, +only the first length octets of the MAC are written. + +

This function also resets the state context so that you can start +over processing a new message (with the same key). +

+ +

Like for CBC, there are some macros to help use these +functions correctly. + +

+ + + + + +
HMAC_CTX (type) + Macro
+ + +
+Expands into +
          {
+             type outer;
+             type inner;
+             type state;
+          }
+          
+
+ +

It can be used to define a HMAC context struct, either +directly, + +

     struct HMAC_CTX(struct md5_ctx) ctx;
+     
+ +

or to give it a struct tag, + +

     struct hmac_md5_ctx HMAC_CTX (struct md5_ctx);
+     
+ +

+ + + + + +
HMAC_SET_KEY (ctx, H, length, key) + Macro
+ + +
+ctx is a pointer to a context struct as defined by +HMAC_CTX, H is a pointer to a const struct +nettle_hash describing the underlying hash function (so it must match +the type of the components of ctx). The last two arguments specify +the secret key. +
+ +

+ + + + + +
HMAC_DIGEST (ctx, H, length, digest) + Macro
+ + +
+ctx is a pointer to a context struct as defined by +HMAC_CTX, H is a pointer to a const struct +nettle_hash describing the underlying hash function. The last two +arguments specify where the digest is written. +
+ +

Note that there is no HMAC_UPDATE macro; simply call +hmac_update function directly, or the update function of the +underlying hash function. + +

Concrete HMAC functions

+ +

Now we come to the specialized HMAC functions, which are +easier to use than the general HMAC functions. + +

HMAC-MD5

+ +

+ + + + + +
struct hmac_md5_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_md5_set_key (struct hmac_md5_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_md5_update (struct hmac_md5_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_md5_digest (struct hmac_md5_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Extracts the MAC, writing it to digest. length may be smaller than +MD5_DIGEST_SIZE, in which case only the first length +octets of the MAC are written. + +

This function also resets the context for processing new messages, with +the same key. +

+ +

HMAC-SHA1

+ +

+ + + + + +
struct hmac_sha1_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_sha1_set_key (struct hmac_sha1_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_sha1_update (struct hmac_sha1_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_sha1_digest (struct hmac_sha1_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Extracts the MAC, writing it to digest. length may be smaller than +SHA1_DIGEST_SIZE, in which case only the first length +octets of the MAC are written. + +

This function also resets the context for processing new messages, with +the same key. +

+ +

HMAC-SHA256

+ +

+ + + + + +
struct hmac_sha256_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_sha256_set_key (struct hmac_sha256_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_sha256_update (struct hmac_sha256_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_sha256_digest (struct hmac_sha256_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Extracts the MAC, writing it to digest. length may be smaller than +SHA256_DIGEST_SIZE, in which case only the first length +octets of the MAC are written. + +

This function also resets the context for processing new messages, with +the same key. +

+ +

HMAC-SHA512

+ +

+ + + + + +
struct hmac_sha512_ctx + Context struct
+ + +
+
+ +

+ + + + + +
void hmac_sha512_set_key (struct hmac_sha512_ctx *ctx, unsigned key_length, const uint8_t *key) + Function
+ + +
+Initializes the context with the key. +
+ +

+ + + + + +
void hmac_sha512_update (struct hmac_sha512_ctx *ctx, unsigned length, const uint8_t *data) + Function
+ + +
+Process some more data. +
+ +

+ + + + + +
void hmac_sha512_digest (struct hmac_sha512_ctx *ctx, unsigned length, uint8_t *digest) + Function
+ + +
+Extracts the MAC, writing it to digest. length may be smaller than +SHA512_DIGEST_SIZE, in which case only the first length +octets of the MAC are written. + +

This function also resets the context for processing new messages, with +the same key. +

+ +

+


+Node: Public-key algorithms, +Next: , +Previous: Keyed hash functions, +Up: Reference +
+
+ +

Public-key algorithms

+ +

Nettle uses GMP, the GNU bignum library, for all calculations +with large numbers. In order to use the public-key features of Nettle, +you must install GMP, at least version 3.0, before compiling +Nettle, and you need to link your programs with -lhogweed -lnettle +-lgmp. + +

The concept of Public-key encryption and digital signatures was +discovered by Whitfield Diffie and Martin E. Hellman and described in a +paper 1976. In traditional, "symmetric", cryptography, sender and +receiver share the same keys, and these keys must be distributed in a +secure way. And if there are many users or entities that need to +communicate, each pair needs a shared secret key known by nobody +else. + +

Public-key cryptography uses trapdoor one-way functions. A +one-way function is a function F such that it is easy to +compute the value F(x) for any x, but given a value +y, it is hard to compute a corresponding x such that +y = F(x). Two examples are cryptographic hash functions, and +exponentiation in certain groups. + +

A trapdoor one-way function is a function F that is +one-way, unless one knows some secret information about F. If one +knows the secret, it is easy to compute both F and it's inverse. +If this sounds strange, look at the RSA example below. + +

Two important uses for one-way functions with trapdoors are public-key +encryption, and digital signatures. The public-key encryption functions +in Nettle are not yet documented; the rest of this chapter is about +digital signatures. + +

To use a digital signature algorithm, one must first create a +key-pair: A public key and a corresponding private key. The private +key is used to sign messages, while the public key is used for verifying +that that signatures and messages match. Some care must be taken when +distributing the public key; it need not be kept secret, but if a bad +guy is able to replace it (in transit, or in some user's list of known +public keys), bad things may happen. + +

There are two operations one can do with the keys. The signature +operation takes a message and a private key, and creates a signature for +the message. A signature is some string of bits, usually at most a few +thousand bits or a few hundred octets. Unlike paper-and-ink signatures, +the digital signature depends on the message, so one can't cut it out of +context and glue it to a different message. + +

The verification operation takes a public key, a message, and a string +that is claimed to be a signature on the message, and returns true or +false. If it returns true, that means that the three input values +matched, and the verifier can be sure that someone went through with the +signature operation on that very message, and that the "someone" also +knows the private key corresponding to the public key. + +

The desired properties of a digital signature algorithm are as follows: +Given the public key and pairs of messages and valid signatures on them, +it should be hard to compute the private key, and it should also be hard +to create a new message and signature that is accepted by the +verification operation. + +

Besides signing meaningful messages, digital signatures can be used for +authorization. A server can be configured with a public key, such that +any client that connects to the service is given a random nonce message. +If the server gets a reply with a correct signature matching the nonce +message and the configured public key, the client is granted access. So +the configuration of the server can be understood as "grant access to +whoever knows the private key corresponding to this particular public +key, and to no others". + +

+ +
+


+Node: RSA, +Next: , +Previous: Public-key algorithms, +Up: Public-key algorithms +
+
+ +

RSA

+ +

The RSA algorithm was the first practical digital signature +algorithm that was constructed. It was described 1978 in a paper by +Ronald Rivest, Adi Shamir and L.M. Adleman, and the technique was also +patented in the USA in 1983. The patent expired on September 20, 2000, and since +that day, RSA can be used freely, even in the USA. + +

It's remarkably simple to describe the trapdoor function behind +RSA. The "one-way"-function used is + +

     F(x) = x^e mod n
+     
+ +

I.e. raise x to the e:th power, while discarding all multiples of +n. The pair of numbers n and e is the public key. +e can be quite small, even e = 3 has been used, although +slightly larger numbers are recommended. n should be about 1000 +bits or larger. + +

If n is large enough, and properly chosen, the inverse of F, +the computation of e:th roots modulo n, is very difficult. +But, where's the trapdoor? + +

Let's first look at how RSA key-pairs are generated. First +n is chosen as the product of two large prime numbers p +and q of roughly the same size (so if n is 1000 bits, +p and q are about 500 bits each). One also computes the +number phi = (p-1)(q-1), in mathematical speak, phi is the +order of the multiplicative group of integers modulo n. + +

Next, e is chosen. It must have no factors in common with phi (in +particular, it must be odd), but can otherwise be chosen more or less +randomly. e = 65537 is a popular choice, because it makes raising +to the e'th power particularly efficient, and being prime, it +usually has no factors common with phi. + +

Finally, a number d, d < n is computed such that e d +mod phi = 1. It can be shown that such a number exists (this is why +e and phi must have no common factors), and that for all x, + +

     (x^e)^d mod n = x^(ed) mod n = (x^d)^e mod n = x
+     
+ +

Using Euclid's algorithm, d can be computed quite easily from +phi and e. But it is still hard to get d without +knowing phi, which depends on the factorization of n. + +

So d is the trapdoor, if we know d and y = F(x), we can +recover x as y^d mod n. d is also the private half of +the RSA key-pair. + +

The most common signature operation for RSA is defined in +PKCS#1, a specification by RSA Laboratories. The message to be +signed is first hashed using a cryptographic hash function, e.g. +MD5 or SHA1. Next, some padding, the ASN.1 +"Algorithm Identifier" for the hash function, and the message digest +itself, are concatenated and converted to a number x. The +signature is computed from x and the private key as s = x^d +mod n1. The signature, s is a +number of about the same size of n, and it usually encoded as a +sequence of octets, most significant octet first. + +

The verification operation is straight-forward, x is computed +from the message in the same way as above. Then s^e mod n is +computed, the operation returns true if and only if the result equals +x. + +

Nettle's RSA support

+ +

Nettle represents RSA keys using two structures that contain +large numbers (of type mpz_t). + +

+ + + + + +
rsa_public_key size n e + Context struct
+ + +
+size is the size, in octets, of the modulo, and is used internally. +n and e is the public key. +
+ +

+ + + + + +
rsa_private_key size d p q a b c + Context struct
+ + +
+size is the size, in octets, of the modulo, and is used internally. +d is the secret exponent, but it is not actually used when +signing. Instead, the factors p and q, and the parameters +a, b and c are used. They are computed from p, +q and e such that a e mod (p - 1) = 1, b e mod (q - +1) = 1, c q mod p = 1. +
+ +

Before use, these structs must be initialized by calling one of + +

+ + + + + + + + + + +
void rsa_public_key_init (struct rsa_public_key *pub) + Function
void rsa_private_key_init (struct rsa_private_key *key) + Function
+ + +
+Calls mpz_init on all numbers in the key struct. +
+ +

and when finished with them, the space for the numbers must be +deallocated by calling one of + +

+ + + + + + + + + + +
void rsa_public_key_clear (struct rsa_public_key *pub) + Function
void rsa_private_key_clear (struct rsa_private_key *key) + Function
+ + +
+Calls mpz_clear on all numbers in the key struct. +
+ +

In general, Nettle's RSA functions deviates from Nettle's "no +memory allocation"-policy. Space for all the numbers, both in the key structs +above, and temporaries, are allocated dynamically. For information on how +to customize allocation, see +See GMP Allocation. + +

When you have assigned values to the attributes of a key, you must call + +

+ + + + + + + + + + +
int rsa_public_key_prepare (struct rsa_public_key *pub) + Function
int rsa_private_key_prepare (struct rsa_private_key *key) + Function
+ + +
+Computes the octet size of the key (stored in the size attribute, +and may also do other basic sanity checks. Returns one if successful, or +zero if the key can't be used, for instance if the modulo is smaller +than the minimum size needed for RSA operations specified by PKCS#1. +
+ +

Before signing or verifying a message, you first hash it with the +appropriate hash function. You pass the hash function's context struct +to the RSA signature function, and it will extract the message +digest and do the rest of the work. There are also alternative functions +that take the hash digest as argument. + +

There is currently no support for using SHA224 or SHA384 with +RSA signatures, since there's no gain in either computation +time nor message size compared to using SHA256 and SHA512, respectively. + +

Creation and verification of signatures is done with the following functions: + +

+ + + + + + + + + + + + + + + + + + + + +
int rsa_md5_sign (const struct rsa_private_key *key, struct md5_ctx *hash, mpz_t signature) + Function
int rsa_sha1_sign (const struct rsa_private_key *key, struct sha1_ctx *hash, mpz_t signature) + Function
int rsa_sha256_sign (const struct rsa_private_key *key, struct sha256_ctx *hash, mpz_t signature) + Function
int rsa_sha512_sign (const struct rsa_private_key *key, struct sha512_ctx *hash, mpz_t signature) + Function
+ + +
+The signature is stored in signature (which must have been +mpz_init'ed earlier). The hash context is reset so that it can be +used for new messages. Returns one on success, or zero on failure. +Signing fails if the key is too small for the given hash size, e.g., +it's not possible to create a signature using SHA512 and a 512-bit +RSA key. +
+ +

+ + + + + + + + + + + + + + + + + + + + +
int rsa_md5_sign_digest (const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature) + Function
int rsa_sha1_sign_digest (const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature); + Function
int rsa_sha256_sign_digest (const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature); + Function
int rsa_sha512_sign_digest (const struct rsa_private_key *key, const uint8_t *digest, mpz_t signature); + Function
+ + +
+Creates a signature from the given hash digest. digest should +point to a digest of size MD5_DIGEST_SIZE, +SHA1_DIGEST_SIZE, or SHA256_DIGEST_SIZE, respectively. The +signature is stored in signature (which must have been +mpz_init:ed earlier). Returns one on success, or zero on failure. +
+ +

+ + + + + + + + + + + + + + + + + + + + +
int rsa_md5_verify (const struct rsa_public_key *key, struct md5_ctx *hash, const mpz_t signature) + Function
int rsa_sha1_verify (const struct rsa_public_key *key, struct sha1_ctx *hash, const mpz_t signature) + Function
int rsa_sha256_verify (const struct rsa_public_key *key, struct sha256_ctx *hash, const mpz_t signature) + Function
int rsa_sha512_verify (const struct rsa_public_key *key, struct sha512_ctx *hash, const mpz_t signature) + Function
+ + +
+Returns 1 if the signature is valid, or 0 if it isn't. In either case, +the hash context is reset so that it can be used for new messages. +
+ +

+ + + + + + + + + + + + + + + + + + + + +
int rsa_md5_verify_digest (const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature) + Function
int rsa_sha1_verify_digest (const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature) + Function
int rsa_sha256_verify_digest (const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature) + Function
int rsa_sha512_verify_digest (const struct rsa_public_key *key, const uint8_t *digest, const mpz_t signature) + Function
+ + +
+Returns 1 if the signature is valid, or 0 if it isn't. digest should +point to a digest of size MD5_DIGEST_SIZE, +SHA1_DIGEST_SIZE, or SHA256_DIGEST_SIZE, respectively. +
+ +

If you need to use the RSA trapdoor, the private key, in a way +that isn't supported by the above functions Nettle also includes a +function that computes x^d mod n and nothing more, using the +CRT optimization. + +

+ + + + + +
void rsa_compute_root (struct rsa_private_key *key, mpz_t x, const mpz_t m) + Function
+ + +
+Computes x = m^d, efficiently. +
+ +

At last, how do you create new keys? + +

+ + + + + +
int rsa_generate_keypair (struct rsa_public_key *pub, struct rsa_private_key *key, void *random_ctx, nettle_random_func random, void *progress_ctx, nettle_progress_func progress, unsigned n_size, unsigned e_size); + Function
+ + +
+There are lots of parameters. pub and key is where the +resulting key pair is stored. The structs should be initialized, but you +don't need to call rsa_public_key_prepare or +rsa_private_key_prepare after key generation. + +

random_ctx and random is a randomness generator. +random(random_ctx, length, dst) should generate length +random octets and store them at dst. For advice, see +See Randomness. + +

progress and progress_ctx can be used to get callbacks +during the key generation process, in order to uphold an illusion of +progress. progress can be NULL, in that case there are no +callbacks. + +

size_n is the desired size of the modulo, in bits. If size_e +is non-zero, it is the desired size of the public exponent and a random +exponent of that size is selected. But if e_size is zero, it is +assumed that the caller has already chosen a value for e, and +stored it in pub. +Returns one on success, and zero on failure. The function can fail for +example if if n_size is too small, or if e_size is zero and +pub->e is an even number. +

+ +

+


+Node: DSA, +Previous: RSA, +Up: Public-key algorithms +
+
+ +

Nettle's DSA support

+ +

The DSA digital signature algorithm is more complex than +RSA. It was specified during the early 1990s, and in 1994 NIST +published FIPS 186 which is the authoritative specification. +Sometimes DSA is referred to using the acronym DSS, +for Digital Signature Standard. The most recent revision of the +specification, FIPS186-3, was issueed in 2009, and it adds support for +larger hash functions than sha1. + +

For DSA, the underlying mathematical problem is the +computation of discreet logarithms. The public key consists of a large +prime p, a small prime q which is a factor of p-1, +a number g which generates a subgroup of order q modulo +p, and an element y in that subgroup. + +

In the original DSA, the size of q is fixed to 160 +bits, to match with the SHA1 hash algorithm. The size of +p is in principle unlimited, but the +standard specifies only nine specific sizes: 512 + l*64, where +l is between 0 and 8. Thus, the maximum size of p is 1024 +bits, and sizes less than 1024 bits are considered obsolete and not +secure. + +

The subgroup requirement means that if you compute + +

     g^t mod p
+     
+ +

for all possible integers t, you will get precisely q +distinct values. + +

The private key is a secret exponent x, such that + +

     g^x = y mod p
+     
+ +

In mathematical speak, x is the discrete logarithm of +y mod p, with respect to the generator g. The size +of x will also be about the same size as q. The security of the +DSA algorithm relies on the difficulty of the discrete +logarithm problem. Current algorithms to compute discrete logarithms in +this setting, and hence crack DSA, are of two types. The first +type works directly in the (multiplicative) group of integers mod +p. The best known algorithm of this type is the Number Field +Sieve, and it's complexity is similar to the complexity of factoring +numbers of the same size as p. The other type works in the +smaller q-sized subgroup generated by g, which has a more +difficult group structure. One good algorithm is Pollard-rho, which has +complexity sqrt(q). + +

The important point is that security depends on the size of both +p and q, and they should be choosen so that the difficulty +of both discrete logarithm methods are comparable. Today, the security +margin of the original DSA may be uncomfortably small. Using a +p of 1024 bits implies that cracking using the number field sieve +is expected to take about the same time as factoring a 1024-bit +RSA modulo, and using a q of size 160 bits implies +that cracking using Pollard-rho will take roughly 2^80 group +operations. With the size of q fixed, tied to the SHA1 +digest size, it may be tempting to increase the size of p to, +say, 4096 bits. This will provide excellent resistance against attacks +like the number field sieve which works in the large group. But it will +do very little to defend against Pollard-rho attacking the small +subgroup; the attacker is slowed down at most by a single factor of 10 +due to the more expensive group operation. And the attacker will surely +choose the latter attack. + +

The signature generation algorithm is randomized; in order to create a +DSA signature, you need a good source for random numbers +(see Randomness). Let us describe the common case of a 160-bit +q. + +

To create a signature, one starts with the hash digest of the message, +h, which is a 160 bit number, and a random number k, +0<k<q, also 160 bits. Next, one computes + +

     r = (g^k mod p) mod q
+     s = k^-1 (h + x r) mod q
+     
+ +

The signature is the pair (r, s), two 160 bit numbers. Note the +two different mod operations when computing r, and the use of the +secret exponent x. + +

To verify a signature, one first checks that 0 < r,s < q, and +then one computes backwards, + +

     w = s^-1 mod q
+     v = (g^(w h) y^(w r) mod p) mod q
+     
+ +

The signature is valid if v = r. This works out because w = +s^-1 mod q = k (h + x r)^-1 mod q, so that + +

     g^(w h) y^(w r) = g^(w h) (g^x)^(w r) = g^(w (h + x r)) = g^k
+     
+ +

When reducing mod q this yields r. Note that when +verifying a signature, we don't know either k or x: those +numbers are secret. + +

If you can choose between RSA and DSA, which one is +best? Both are believed to be secure. DSA gained popularity in +the late 1990s, as a patent free alternative to RSA. Now that +the RSA patents have expired, there's no compelling reason to +want to use DSA. Today, the original DSA key size +does not provide a large security margin, and it should probably be +phased out together with RSA keys of 1024 bits. Using the +revised DSA algorithm with a larger hash function, in +particular, SHA256, a 256-bit q, and p of size +2048 bits or more, should provide for a more comfortable security +margin, but these variants are not yet in wide use. + +

DSA signatures are smaller than RSA signatures, +which is important for some specialized applications. + +

From a practical point of view, DSA's need for a good +randomness source is a serious disadvantage. If you ever use the same +k (and r) for two different message, you leak your private +key. + +

Nettle's DSA support

+ +

Like for RSA, Nettle represents DSA keys using two +structures, containing values of type mpz_t. For information on +how to customize allocation, see See GMP Allocation. + +

Most of the DSA functions are very similar to the +corresponding RSA functions, but there are a few differences +pointed out below. For a start, there are no functions corresponding to +rsa_public_key_prepare and rsa_private_key_prepare. + +

+ + + + + +
dsa_public_key p q g y + Context struct
+ + +
+The public parameters described above. +
+ +

+ + + + + +
dsa_private_key x + Context struct
+ + +
+The private key x. +
+ +

Before use, these structs must be initialized by calling one of + +

+ + + + + + + + + + +
void dsa_public_key_init (struct dsa_public_key *pub) + Function
void dsa_private_key_init (struct dsa_private_key *key) + Function
+ + +
+Calls mpz_init on all numbers in the key struct. +
+ +

When finished with them, the space for the numbers must be +deallocated by calling one of + +

+ + + + + + + + + + +
void dsa_public_key_clear (struct dsa_public_key *pub) + Function
void dsa_private_key_clear (struct dsa_private_key *key) + Function
+ + +
+Calls mpz_clear on all numbers in the key struct. +
+ +

Signatures are represented using the structure below, and need to be +initialized and cleared in the same way as the key structs. + +

+ + + + + +
dsa_signature r s + Context struct
+ + +
+
+ +

+ + + + + + + + + + +
void dsa_signature_init (struct dsa_signature *signature) + Function
void dsa_signature_clear (struct dsa_signature *signature) + Function
+ + +
+You must call dsa_signature_init before creating or using a +signature, and call dsa_signature_clear when you are finished +with it. +
+ +

For signing, you need to provide both the public and the private key +(unlike RSA, where the private key struct includes all +information needed for signing), and a source for random numbers. +Signatures can use the SHA1 or the SHA256 hash +function, although the implementation of DSA with +SHA256 should be considered somewhat experimental due to lack +of official test vectors and interoperability testing. + +

+ + + + + + + + + + + + + + + + + + + + +
int dsa_sha1_sign (const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, struct sha1_ctx *hash, struct dsa_signature *signature) + Function
int dsa_sha1_sign_digest (const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, const uint8_t *digest, struct dsa_signature *signature) + Function
int dsa_sha256_sign (const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, struct sha256_ctx *hash, struct dsa_signature *signature) + Function
int dsa_sha256_sign_digest (const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, const uint8_t *digest, struct dsa_signature *signature) + Function
+ + +
+Creates a signature from the given hash context or digest. +random_ctx and random is a randomness generator. +random(random_ctx, length, dst) should generate length +random octets and store them at dst. For advice, see +See Randomness. Returns one on success, or zero on failure. +Signing fails if the key size and the hash size don't match. +
+ +

Verifying signatures is a little easier, since no randomness generator is +needed. The functions are + +

+ + + + + + + + + + + + + + + + + + + + +
int dsa_sha1_verify (const struct dsa_public_key *key, struct sha1_ctx *hash, const struct dsa_signature *signature) + Function
int dsa_sha1_verify_digest (const struct dsa_public_key *key, const uint8_t *digest, const struct dsa_signature *signature) + Function
int dsa_sha256_verify (const struct dsa_public_key *key, struct sha256_ctx *hash, const struct dsa_signature *signature) + Function
int dsa_sha256_verify_digest (const struct dsa_public_key *key, const uint8_t *digest, const struct dsa_signature *signature) + Function
+ + +
+Verifies a signature. Returns 1 if the signature is valid, otherwise 0. +
+ +

Key generation uses mostly the same parameters as the corresponding +RSA function. + +

+ + + + + +
int dsa_generate_keypair (struct dsa_public_key *pub, struct dsa_private_key *key, void *random_ctx, nettle_random_func random, void *progress_ctx, nettle_progress_func progress, unsigned p_bits, unsigned q_bits) + Function
+ + +
+pub and key is where the resulting key pair is stored. The +structs should be initialized before you call this function. + +

random_ctx and random is a randomness generator. +random(random_ctx, length, dst) should generate length +random octets and store them at dst. For advice, see +See Randomness. + +

progress and progress_ctx can be used to get callbacks +during the key generation process, in order to uphold an illusion of +progress. progress can be NULL, in that case there are no +callbacks. + +

p_bits and q_bits are the desired sizes of p and +q. To generate keys that conform to the original DSA +standard, you must use q_bits = 160 and select p_bits of +the form p_bits = 512 + l*64, for 0 <= l <= 8, where the +smaller sizes are no longer recommended, so you should most likely stick +to p_bits = 1024. Non-standard sizes are possible, in particular +p_bits larger than 1024, although DSA implementations +can not in general be expected to support such keys. Also note that +using very large p_bits, with q_bits fixed at 160, doesn't +make much sense, because the security is also limited by the size of the +smaller prime. Using a larger q_bits requires switchign to a +larger hash function. To generate DSA keys for use with +SHA256, use q_bits = 256 and, e.g., p_bits = +2048. + +

Returns one on success, and zero on failure. The function will fail if +q_bits is neither 160 nor 256, or if p_bits is unreasonably +small. +

+ +

+


+Node: Randomness, +Next: , +Previous: Public-key algorithms, +Up: Reference +
+
+ +

Randomness

+ +

A crucial ingredient in many cryptographic contexts is randomness: Let +p be a random prime, choose a random initialization vector +iv, a random key k and a random exponent e, etc. In +the theories, it is assumed that you have plenty of randomness around. +If this assumption is not true in practice, systems that are otherwise +perfectly secure, can be broken. Randomness has often turned out to be +the weakest link in the chain. + +

In non-cryptographic applications, such as games as well as scientific +simulation, a good randomness generator usually means a generator that +has good statistical properties, and is seeded by some simple function +of things like the current time, process id, and host name. + +

However, such a generator is inadequate for cryptography, for at least +two reasons: + +

    + +
  • It's too easy for an attacker to guess the initial seed. Even if it will +take some 2^32 tries before he guesses right, that's far too easy. For +example, if the process id is 16 bits, the resolution of "current time" +is one second, and the attacker knows what day the generator was seeded, +there are only about 2^32 possibilities to try if all possible values +for the process id and time-of-day are tried. + +
  • The generator output reveals too much. By observing only a small segment +of the generator's output, its internal state can be recovered, and from +there, all previous output and all future output can be computed by the +attacker. +
+ +

A randomness generator that is used for cryptographic purposes must have +better properties. Let's first look at the seeding, as the issues here +are mostly independent of the rest of the generator. The initial state +of the generator (its seed) must be unguessable by the attacker. So +what's unguessable? It depends on what the attacker already knows. The +concept used in information theory to reason about such things is called +"entropy", or "conditional entropy" (not to be confused with the +thermodynamic concept with the same name). A reasonable requirement is +that the seed contains a conditional entropy of at least some 80-100 +bits. This property can be explained as follows: Allow the attacker to +ask n yes-no-questions, of his own choice, about the seed. If +the attacker, using this question-and-answer session, as well as any +other information he knows about the seeding process, still can't guess +the seed correctly, then the conditional entropy is more than n +bits. + +

Let's look at an example. Say information about timing of received +network packets is used in the seeding process. If there is some random +network traffic going on, this will contribute some bits of entropy or +"unguessability" to the seed. However, if the attacker can listen in to +the local network, or if all but a small number of the packets were +transmitted by machines that the attacker can monitor, this additional +information makes the seed easier for the attacker to figure out. Even +if the information is exactly the same, the conditional entropy, or +unguessability, is smaller for an attacker that knows some of it already +before the hypothetical question-and-answer session. + +

Seeding of good generators is usually based on several sources. The key +point here is that the amount of unguessability that each source +contributes, depends on who the attacker is. Some sources that have been +used are: + +

+
High resolution timing of i/o activities +
Such as completed blocks from spinning hard disks, network packets, etc. +Getting access to such information is quite system dependent, and not +all systems include suitable hardware. If available, it's one of the +better randomness source one can find in a digital, mostly predictable, +computer. + +
User activity +
Timing and contents of user interaction events is another popular source +that is available for interactive programs (even if I suspect that it is +sometimes used in order to make the user feel good, not because the +quality of the input is needed or used properly). Obviously, not +available when a machine is unattended. Also beware of networks: User +interaction that happens across a long serial cable, TELNET +session, or even SSH session may be visible to an attacker, in +full or partially. + +
Audio input +
Any room, or even a microphone input that's left unconnected, is a +source of some random background noise, which can be fed into the +seeding process. + +
Specialized hardware +
Hardware devices with the sole purpose of generating random data have +been designed. They range from radioactive samples with an attached +Geiger counter, to amplification of the inherent noise in electronic +components such as diodes and resistors, to low-frequency sampling of +chaotic systems. Hashing successive images of a Lava lamp is a +spectacular example of the latter type. + +
Secret information +
Secret information, such as user passwords or keys, or private files +stored on disk, can provide some unguessability. A problem is that if +the information is revealed at a later time, the unguessability +vanishes. Another problem is that this kind of information tends to be +fairly constant, so if you rely on it and seed your generator regularly, +you risk constructing almost similar seeds or even constructing the same +seed more than once. +
+ +

For all practical sources, it's difficult but important to provide a +reliable lower bound on the amount of unguessability that it provides. +Two important points are to make sure that the attacker can't observe +your sources (so if you like the Lava lamp idea, remember that you have +to get your own lamp, and not put it by a window or anywhere else where +strangers can see it), and that hardware failures are detected. What if +the bulb in the Lava lamp, which you keep locked into a cupboard +following the above advice, breaks after a few months? + +

So let's assume that we have been able to find an unguessable seed, +which contains at least 80 bits of conditional entropy, relative to all +attackers that we care about (typically, we must at the very least +assume that no attacker has root privileges on our machine). + +

How do we generate output from this seed, and how much can we get? Some +generators (notably the Linux /dev/random generator) tries to +estimate available entropy and restrict the amount of output. The goal +is that if you read 128 bits from /dev/random, you should get 128 +"truly random" bits. This is a property that is useful in some +specialized circumstances, for instance when generating key material for +a one time pad, or when working with unconditional blinding, but in most +cases, it doesn't matter much. For most application, there's no limit on +the amount of useful "random" data that we can generate from a small +seed; what matters is that the seed is unguessable and that the +generator has good cryptographic properties. + +

At the heart of all generators lies its internal state. Future output +is determined by the internal state alone. Let's call it the generator's +key. The key is initialized from the unguessable seed. Important +properties of a generator are: + +

+ +
Key-hiding +
An attacker observing the output should not be able to recover the +generator's key. + +
Independence of outputs +
Observing some of the output should not help the attacker to guess +previous or future output. + +
Forward secrecy +
Even if an attacker compromises the generator's key, he should not be +able to guess the generator output before the key compromise. + +
Recovery from key compromise +
If an attacker compromises the generator's key, he can compute +all future output. This is inevitable if the generator is seeded +only once, at startup. However, the generator can provide a reseeding +mechanism, to achieve recovery from key compromise. More precisely: If +the attacker compromises the key at a particular time t_1, there +is another later time t_2, such that if the attacker observes all +output generated between t_1 and t_2, he still can't guess +what output is generated after t_2. + +
+ +

Nettle includes one randomness generator that is believed to have all +the above properties, and two simpler ones. + +

ARCFOUR, like any stream cipher, can be used as a randomness +generator. Its output should be of reasonable quality, if the seed is +hashed properly before it is used with arcfour_set_key. There's +no single natural way to reseed it, but if you need reseeding, you +should be using Yarrow instead. + +

The "lagged Fibonacci" generator in <nettle/knuth-lfib.h> is a +fast generator with good statistical properties, but is not for +cryptographic use, and therefore not documented here. It is included +mostly because the Nettle test suite needs to generate some test data +from a small seed. + +

The recommended generator to use is Yarrow, described below. + +

Yarrow

+ +

Yarrow is a family of pseudo-randomness generators, designed for +cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson. +Yarrow-160 is described in a paper at +<http://www.counterpane.com/yarrow.html>, and it uses SHA1 +and triple-DES, and has a 160-bit internal state. Nettle implements +Yarrow-256, which is similar, but uses SHA256 and +AES to get an internal state of 256 bits. + +

Yarrow was an almost finished project, the paper mentioned above is the +closest thing to a specification for it, but some smaller details are +left out. There is no official reference implementation or test cases. +This section includes an overview of Yarrow, but for the details of +Yarrow-256, as implemented by Nettle, you have to consult the source +code. Maybe a complete specification can be written later. + +

Yarrow can use many sources (at least two are needed for proper +reseeding), and two randomness "pools", referred to as the "slow pool" and +the "fast pool". Input from the sources is fed alternatingly into the +two pools. When one of the sources has contributed 100 bits of entropy +to the fast pool, a "fast reseed" happens and the fast pool is mixed +into the internal state. When at least two of the sources have +contributed at least 160 bits each to the slow pool, a "slow reseed" +takes place. The contents of both pools are mixed into the internal +state. These procedures should ensure that the generator will eventually +recover after a key compromise. + +

The output is generated by using AES to encrypt a counter, +using the generator's current key. After each request for output, +another 256 bits are generated which replace the key. This ensures +forward secrecy. + +

Yarrow can also use a seed file to save state across restarts. +Yarrow is seeded by either feeding it the contents of the previous seed +file, or feeding it input from its sources until a slow reseed happens. + +

Nettle defines Yarrow-256 in <nettle/yarrow.h>. + +

+ + + + + +
struct yarrow256_ctx + Context struct
+ + +
+
+ +

+ + + + + +
struct yarrow_source + Context struct
+ + +
+Information about a single source. +
+ +

+ + + + + +
YARROW256_SEED_FILE_SIZE + Constant
+ + +
+Recommanded size of the Yarrow-256 seed file. +
+ +

+ + + + + +
void yarrow256_init (struct yarrow256_ctx *ctx, unsigned nsources, struct yarrow_source *sources) + Function
+ + +
+Initializes the yarrow context, and its nsources sources. It's +possible to call it with nsources=0 and sources=NULL, if +you don't need the update features. +
+ +

+ + + + + +
void yarrow256_seed (struct yarrow256_ctx *ctx, unsigned length, uint8_t *seed_file) + Function
+ + +
+Seeds Yarrow-256 from a previous seed file. length should be at least +YARROW256_SEED_FILE_SIZE, but it can be larger. + +

The generator will trust you that the seed_file data really is +unguessable. After calling this function, you must overwrite the old +seed file with newly generated data from yarrow256_random. If it's +possible for several processes to read the seed file at about the same +time, access must be coordinated using some locking mechanism. +

+ +

+ + + + + +
int yarrow256_update (struct yarrow256_ctx *ctx, unsigned source, unsigned entropy, unsigned length, const uint8_t *data) + Function
+ + +
+Updates the generator with data from source SOURCE (an index that +must be smaller than the number of sources). entropy is your +estimated lower bound for the entropy in the data, measured in bits. +Calling update with zero entropy is always safe, no matter if the +data is random or not. + +

Returns 1 if a reseed happened, in which case an application using a +seed file may want to generate new seed data with +yarrow256_random and overwrite the seed file. Otherwise, the +function returns 0. +

+ +

+ + + + + +
void yarrow256_random (struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst) + Function
+ + +
+Generates length octets of output. The generator must be seeded +before you call this function. + +

If you don't need forward secrecy, e.g. if you need non-secret +randomness for initialization vectors or padding, you can gain some +efficiency by buffering, calling this function for reasonably large +blocks of data, say 100-1000 octets at a time. +

+ +

+ + + + + +
int yarrow256_is_seeded (struct yarrow256_ctx *ctx) + Function
+ + +
+Returns 1 if the generator is seeded and ready to generate output, +otherwise 0. +
+ +

+ + + + + +
unsigned yarrow256_needed_sources (struct yarrow256_ctx *ctx) + Function
+ + +
+Returns the number of sources that must reach the threshold before a +slow reseed will happen. Useful primarily when the generator is unseeded. +
+ +

+ + + + + + + + + + +
void yarrow256_fast_reseed (struct yarrow256_ctx *ctx) + Function
void yarrow256_slow_reseed (struct yarrow256_ctx *ctx) + Function
+ + +
+Causes a fast or slow reseed to take place immediately, regardless of the +current entropy estimates of the two pools. Use with care. +
+ +

Nettle includes an entropy estimator for one kind of input source: User +keyboard input. + +

+ + + + + +
struct yarrow_key_event_ctx + Context struct
+ + +
+Information about recent key events. +
+ +

+ + + + + +
void yarrow_key_event_init (struct yarrow_key_event_ctx *ctx) + Function
+ + +
+Initializes the context. +
+ +

+ + + + + +
unsigned yarrow_key_event_estimate (struct yarrow_key_event_ctx *ctx, unsigned key, unsigned time) + Function
+ + +
+key is the id of the key (ASCII value, hardware key code, X +keysym, ..., it doesn't matter), and time is the timestamp of +the event. The time must be given in units matching the resolution by +which you read the clock. If you read the clock with microsecond +precision, time should be provided in units of microseconds. But +if you use gettimeofday on a typical Unix system where the clock +ticks 10 or so microseconds at a time, time should be given in +units of 10 microseconds. + +

Returns an entropy estimate, in bits, suitable for calling +yarrow256_update. Usually, 0, 1 or 2 bits. +

+ +

+


+Node: Miscellaneous functions, +Next: , +Previous: Randomness, +Up: Reference +
+
+ +

Miscellaneous functions

+ +

+ + + + + +
uint8_t * memxor (uint8_t *dst, const uint8_t *src, size_t n) + Function
+ + +
+XORs the source area on top of the destination area. The interface +doesn't follow the Nettle conventions, because it is intended to be +similar to the ANSI-C memcpy function. +
+ +

memxor is declared in <nettle/memxor.h>. + +

+


+Node: Compatibility functions, +Previous: Miscellaneous functions, +Up: Reference +
+
+ +

Compatibility functions

+ +

For convenience, Nettle includes alternative interfaces to some +algorithms, for compatibility with some other popular crypto toolkits. +These are not fully documented here; refer to the source or to the +documentation for the original implementation. + +

MD5 is defined in [RFC 1321], which includes a reference implementation. +Nettle defines a compatible interface to MD5 in +<nettle/md5-compat.h>. This file defines the typedef +MD5_CTX, and declares the functions MD5Init, MD5Update and +MD5Final. + +

Eric Young's "libdes" (also part of OpenSSL) is a quite popular DES +implementation. Nettle includes a subset if its interface in +<nettle/des-compat.h>. This file defines the typedefs +des_key_schedule and des_cblock, two constants +DES_ENCRYPT and DES_DECRYPT, and declares one global +variable des_check_key, and the functions des_cbc_cksum +des_cbc_encrypt, des_ecb2_encrypt, +des_ecb3_encrypt, des_ecb_encrypt, +des_ede2_cbc_encrypt, des_ede3_cbc_encrypt, +des_is_weak_key, des_key_sched, des_ncbc_encrypt +des_set_key, and des_set_odd_parity. + +

+


+Node: Nettle soup, +Next: , +Previous: Reference, +Up: Top +
+
+ +

Traditional Nettle Soup

+ +

For the serious nettle hacker, here is a recipe for nettle soup. 4 servings. + +

    +
  • 1 liter fresh nettles (urtica dioica) +
  • 2 tablespoons butter +
  • 3 tablespoons flour +
  • 1 liter stock (meat or vegetable) +
  • 1/2 teaspoon salt +
  • a tad white pepper +
  • some cream or milk +
+ +

Gather 1 liter fresh nettles. Use gloves! Small, tender shoots are +preferable but the tops of larger nettles can also be used. + +

Rinse the nettles very well. Boil them for 10 minutes in lightly salted +water. Strain the nettles and save the water. Hack the nettles. Melt the +butter and mix in the flour. Dilute with stock and the nettle-water you +saved earlier. Add the hacked nettles. If you wish you can add some milk +or cream at this stage. Bring to a boil and let boil for a few minutes. +Season with salt and pepper. + +

Serve with boiled egg-halves. + +

+


+Node: Installation, +Next: , +Previous: Nettle soup, +Up: Top +
+
+ +

Installation

+ +

Nettle uses autoconf. To build it, unpack the source and run + +

     ./configure
+     make
+     make check
+     make install
+     
+ +

to install in the default location, /usr/local. The library files +are installed in /use/local/lib/libnettle.a +/use/local/lib/libhogweed.a and the include files are installed +in /use/local/include/nettle/. + +

To get a list of configure options, use ./configure --help. + +

By default, only static libraries are built and installed. To also build +and install shared libraries, use the --enable-shared option +to ./configure. + +

Using GNU make is recommended. For other make programs, in particular +BSD make, you may have to use the --disable-dependency-tracking +option to ./configure. + +

+


+Node: Index, +Previous: Installation, +Up: Top +
+
+ +

Function and Concept Index

+ + + + +
+
+

Footnotes

+
    +
  1. +

    Actually, the computation is not done like this, it is +done more efficiently using p, q and the Chinese remainder +theorem (CRT). But the result is the same.

    + +

+ + + diff --git a/nettle.info b/nettle.info new file mode 100644 index 0000000..3ffca1f --- /dev/null +++ b/nettle.info @@ -0,0 +1,2768 @@ +This is nettle.info, produced by makeinfo version 4.6 from +nettle.texinfo. + +This manual is for the Nettle library (version 2.1), a low-level +cryptographic library. + + Originally written 2001 by Niels Möller, updated 2010. + + This manual is placed in the public domain. You may freely copy + it, in whole or in part, with or without modification. Attribution + is appreciated, but not required. + +INFO-DIR-SECTION Encryption +START-INFO-DIR-ENTRY +* Nettle: (nettle). A low-level cryptographic library. +END-INFO-DIR-ENTRY + + +File: nettle.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +Nettle +****** + +This document describes the Nettle low-level cryptographic library. You +can use the library directly from your C programs, or write or use an +object-oriented wrapper for your favorite language or application. + +This manual is for the Nettle library (version 2.1), a low-level +cryptographic library. + + Originally written 2001 by Niels Möller, updated 2010. + + This manual is placed in the public domain. You may freely copy + it, in whole or in part, with or without modification. Attribution + is appreciated, but not required. + +* Menu: + +* Introduction:: What is Nettle? +* Copyright:: Your rights. +* Conventions:: General interface conventions. +* Example:: An example program. +* Linking:: Linking with the libnettle and libhogweed. +* Reference:: All Nettle functions and features. +* Nettle soup:: For the serious nettle hacker. +* Installation:: How to install Nettle. +* Index:: Function and concept index. + + +File: nettle.info, Node: Introduction, Next: Copyright, Prev: Top, Up: Top + +Introduction +************ + +Nettle is a cryptographic library that is designed to fit easily in more +or less any context: In crypto toolkits for object-oriented languages +(C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in +kernel space. In most contexts, you need more than the basic +cryptographic algorithms, you also need some way to keep track of +available algorithms, their properties and variants. You often have +some algorithm selection process, often dictated by a protocol you want +to implement. + + And as the requirements of applications differ in subtle and not so +subtle ways, an API that fits one application well can be a pain to use +in a different context. And that is why there are so many different +cryptographic libraries around. + + Nettle tries to avoid this problem by doing one thing, the low-level +crypto stuff, and providing a _simple_ but general interface to it. In +particular, Nettle doesn't do algorithm selection. It doesn't do memory +allocation. It doesn't do any I/O. + + The idea is that one can build several application and context +specific interfaces on top of Nettle, and share the code, test cases, +benchmarks, documentation, etc. Examples are the Nettle module for the +Pike language, and LSH, which both use an object-oriented abstraction +on top of the library. + + This manual explains how to use the Nettle library. It also tries to +provide some background on the cryptography, and advice on how to best +put it to use. + + +File: nettle.info, Node: Copyright, Next: Conventions, Prev: Introduction, Up: Top + +Copyright +********* + +Nettle is distributed under the GNU General Public License (GPL) (see +the file COPYING for details). However, most of the individual files +are dual licensed under less restrictive licenses like the GNU Lesser +General Public License (LGPL), or are in the public domain. This means +that if you don't use the parts of nettle that are GPL-only, you have +the option to use the Nettle library just as if it were licensed under +the LGPL. To find the current status of particular files, you have to +read the copyright notices at the top of the files. + + This manual is in the public domain. You may freely copy it in whole +or in part, e.g., into documentation of programs that build on Nettle. +Attribution, as well as contribution of improvements to the text, is of +course appreciated, but it is not required. + + A list of the supported algorithms, their origins and licenses: + +_AES_ + The implementation of the AES cipher (also known as rijndael) is + written by Rafael Sevilla. Assembler for x86 by Rafael Sevilla and + Niels Möller, Sparc assembler by Niels Möller. Released under the + LGPL. + +_ARCFOUR_ + The implementation of the ARCFOUR (also known as RC4) cipher is + written by Niels Möller. Released under the LGPL. + +_ARCTWO_ + The implementation of the ARCTWO (also known as RC2) cipher is + written by Nikos Mavroyanopoulos and modified by Werner Koch and + Simon Josefsson. Released under the LGPL. + +_BLOWFISH_ + The implementation of the BLOWFISH cipher is written by Werner + Koch, copyright owned by the Free Software Foundation. Also hacked + by Ray Dassen and Niels Möller. Released under the GPL. + +_CAMELLIA_ + The C implementation is by Nippon Telegraph and Telephone + Corporation (NTT), heavily modified by Niels Möller. Assembler for + x86 by Niels Möller. Released under the LGPL. + +_CAST128_ + The implementation of the CAST128 cipher is written by Steve Reid. + Released into the public domain. + +_DES_ + The implementation of the DES cipher is written by Dana L. How, and + released under the LGPL. + +_MD2_ + The implementation of MD2 is written by Andrew Kuchling, and hacked + some by Andreas Sigfridsson and Niels Möller. Python Cryptography + Toolkit license (essentially public domain). + +_MD4_ + This is almost the same code as for MD5 below, with modifications + by Marcus Comstedt. Released into the public domain. + +_MD5_ + The implementation of the MD5 message digest is written by Colin + Plumb. It has been hacked some more by Andrew Kuchling and Niels + Möller. Released into the public domain. + +_SERPENT_ + The implementation of the SERPENT cipher is written by Ross + Anderson, Eli Biham, and Lars Knudsen, adapted to LSH by Rafael + Sevilla, and to Nettle by Niels Möller. Released under the GPL. + +_SHA1_ + The C implementation of the SHA1 message digest is written by Peter + Gutmann, and hacked some more by Andrew Kuchling and Niels Möller. + Released into the public domain. Assembler for x86 by Niels Möller, + released under the LGPL. + +_SHA224, SHA256, SHA384, and SHA512_ + Written by Niels Möller, using Peter Gutmann's SHA1 code as a + model. Released under the LGPL. + +_TWOFISH_ + The implementation of the TWOFISH cipher is written by Ruud de + Rooij. Released under the LGPL. + +_RSA_ + Written by Niels Möller, released under the LGPL. Uses the GMP + library for bignum operations. + +_DSA_ + Written by Niels Möller, released under the LGPL. Uses the GMP + library for bignum operations. + + +File: nettle.info, Node: Conventions, Next: Example, Prev: Copyright, Up: Top + +Conventions +*********** + +For each supported algorithm, there is an include file that defines a +_context struct_, a few constants, and declares functions for operating +on the context. The context struct encapsulates all information needed +by the algorithm, and it can be copied or moved in memory with no +unexpected effects. + + For consistency, functions for different algorithms are very similar, +but there are some differences, for instance reflecting if the key setup +or encryption function differ for encryption and decryption, and whether +or not key setup can fail. There are also differences between algorithms +that don't show in function prototypes, but which the application must +nevertheless be aware of. There is no big difference between the +functions for stream ciphers and for block ciphers, although they should +be used quite differently by the application. + + If your application uses more than one algorithm of the same type, +you should probably create an interface that is tailor-made for your +needs, and then write a few lines of glue code on top of Nettle. + + By convention, for an algorithm named `foo', the struct tag for the +context struct is `foo_ctx', constants and functions uses prefixes like +`FOO_BLOCK_SIZE' (a constant) and `foo_set_key' (a function). + + In all functions, strings are represented with an explicit length, of +type `unsigned', and a pointer of type `uint8_t *' or `const uint8_t +*'. For functions that transform one string to another, the argument +order is length, destination pointer and source pointer. Source and +destination areas are of the same length. Source and destination may be +the same, so that you can process strings in place, but they _must not_ +overlap in any other way. + + Many of the functions lack return value and can never fail. Those +functions which can fail, return one on success and zero on failure. + + +File: nettle.info, Node: Example, Next: Linking, Prev: Conventions, Up: Top + +Example +******* + +A simple example program that reads a file from standard input and +writes its SHA1 checksum on standard output should give the flavor of +Nettle. + + #include + #include + + #include + + #define BUF_SIZE 1000 + + static void + display_hex(unsigned length, uint8_t *data) + { + unsigned i; + + for (i = 0; i'. + + - Context struct: struct md5_ctx + + - Constant: MD5_DIGEST_SIZE + The size of an MD5 digest, i.e. 16. + + - Constant: MD5_DATA_SIZE + The internal block size of MD5. Useful for some special + constructions, in particular HMAC-MD5. + + - Function: void md5_init (struct md5_ctx *CTX) + Initialize the MD5 state. + + - Function: void md5_update (struct md5_ctx *CTX, unsigned LENGTH, + const uint8_t *DATA) + Hash some more data. + + - Function: void md5_digest (struct md5_ctx *CTX, unsigned LENGTH, + uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `MD5_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `md5_init'. + + The normal way to use MD5 is to call the functions in order: First +`md5_init', then `md5_update' zero or more times, and finally +`md5_digest'. After `md5_digest', the context is reset to its initial +state, so you can start over calling `md5_update' to hash new data. + + To start over, you can call `md5_init' at any time. + +MD2 +--- + +MD2 is another hash function of Ronald Rivest's, described in `RFC +1319'. It outputs message digests of 128 bits, or 16 octets. Nettle +defines MD2 in `'. + + - Context struct: struct md2_ctx + + - Constant: MD2_DIGEST_SIZE + The size of an MD2 digest, i.e. 16. + + - Constant: MD2_DATA_SIZE + The internal block size of MD2. + + - Function: void md2_init (struct md2_ctx *CTX) + Initialize the MD2 state. + + - Function: void md2_update (struct md2_ctx *CTX, unsigned LENGTH, + const uint8_t *DATA) + Hash some more data. + + - Function: void md2_digest (struct md2_ctx *CTX, unsigned LENGTH, + uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `MD2_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `md2_init'. + +MD4 +--- + +MD4 is a predecessor of MD5, described in `RFC 1320'. Like MD5, it is +constructed by Ronald Rivest. It outputs message digests of 128 bits, +or 16 octets. Nettle defines MD4 in `'. Use of MD4 is not +recommended, but it is sometimes needed for compatibility with existing +applications and protocols. + + - Context struct: struct md4_ctx + + - Constant: MD4_DIGEST_SIZE + The size of an MD4 digest, i.e. 16. + + - Constant: MD4_DATA_SIZE + The internal block size of MD4. + + - Function: void md4_init (struct md4_ctx *CTX) + Initialize the MD4 state. + + - Function: void md4_update (struct md4_ctx *CTX, unsigned LENGTH, + const uint8_t *DATA) + Hash some more data. + + - Function: void md4_digest (struct md4_ctx *CTX, unsigned LENGTH, + uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `MD4_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `md4_init'. + +SHA1 +---- + +SHA1 is a hash function specified by "NIST" (The U.S. National Institute +for Standards and Technology). It outputs hash values of 160 bits, or 20 +octets. Nettle defines SHA1 in `'. + + The functions are analogous to the MD5 ones. + + - Context struct: struct sha1_ctx + + - Constant: SHA1_DIGEST_SIZE + The size of an SHA1 digest, i.e. 20. + + - Constant: SHA1_DATA_SIZE + The internal block size of SHA1. Useful for some special + constructions, in particular HMAC-SHA1. + + - Function: void sha1_init (struct sha1_ctx *CTX) + Initialize the SHA1 state. + + - Function: void sha1_update (struct sha1_ctx *CTX, unsigned LENGTH, + const uint8_t *DATA) + Hash some more data. + + - Function: void sha1_digest (struct sha1_ctx *CTX, unsigned LENGTH, + uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `SHA1_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `sha1_init'. + +SHA256 +------ + +SHA256 is another hash function specified by "NIST", intended as a +replacement for SHA1, generating larger digests. It outputs hash values +of 256 bits, or 32 octets. Nettle defines SHA256 in `'. + + The functions are analogous to the MD5 ones. + + - Context struct: struct sha256_ctx + + - Constant: SHA256_DIGEST_SIZE + The size of an SHA256 digest, i.e. 32. + + - Constant: SHA256_DATA_SIZE + The internal block size of SHA256. Useful for some special + constructions, in particular HMAC-SHA256. + + - Function: void sha256_init (struct sha256_ctx *CTX) + Initialize the SHA256 state. + + - Function: void sha256_update (struct sha256_ctx *CTX, unsigned + LENGTH, const uint8_t *DATA) + Hash some more data. + + - Function: void sha256_digest (struct sha256_ctx *CTX, unsigned + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `SHA256_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `sha256_init'. + +SHA224 +------ + +SHA224 is a variant of SHA256, with a different initial state, and with +the output truncated to 224 bits, or 28 octets. Nettle defines SHA224 in +`'. + + The functions are analogous to the MD5 ones. + + - Context struct: struct sha224_ctx + + - Constant: SHA224_DIGEST_SIZE + The size of an SHA224 digest, i.e. 28. + + - Constant: SHA224_DATA_SIZE + The internal block size of SHA224. Useful for some special + constructions, in particular HMAC-SHA224. + + - Function: void sha224_init (struct sha224_ctx *CTX) + Initialize the SHA224 state. + + - Function: void sha224_update (struct sha224_ctx *CTX, unsigned + LENGTH, const uint8_t *DATA) + Hash some more data. + + - Function: void sha224_digest (struct sha224_ctx *CTX, unsigned + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `SHA224_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `sha224_init'. + +SHA512 +------ + +SHA512 is a larger sibling to SHA256, with a very similar structure but +with both the output and the internal variables of twice the size. The +internal variables are 64 bits rather than 32, making it significantly +slower on 32-bit computers. It outputs hash values of 512 bits, or 64 +octets. Nettle defines SHA512 in `'. + + The functions are analogous to the MD5 ones. + + - Context struct: struct sha512_ctx + + - Constant: SHA512_DIGEST_SIZE + The size of an SHA512 digest, i.e. 64. + + - Constant: SHA512_DATA_SIZE + The internal block size of SHA512. Useful for some special + constructions, in particular HMAC-SHA512. + + - Function: void sha512_init (struct sha512_ctx *CTX) + Initialize the SHA512 state. + + - Function: void sha512_update (struct sha512_ctx *CTX, unsigned + LENGTH, const uint8_t *DATA) + Hash some more data. + + - Function: void sha512_digest (struct sha512_ctx *CTX, unsigned + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `SHA512_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `sha512_init'. + +SHA384 +------ + +SHA384 is a variant of SHA512, with a different initial state, and with +the output truncated to 384 bits, or 48 octets. Nettle defines SHA384 in +`'. + + The functions are analogous to the MD5 ones. + + - Context struct: struct sha384_ctx + + - Constant: SHA384_DIGEST_SIZE + The size of an SHA384 digest, i.e. 48. + + - Constant: SHA384_DATA_SIZE + The internal block size of SHA384. Useful for some special + constructions, in particular HMAC-SHA384. + + - Function: void sha384_init (struct sha384_ctx *CTX) + Initialize the SHA384 state. + + - Function: void sha384_update (struct sha384_ctx *CTX, unsigned + LENGTH, const uint8_t *DATA) + Hash some more data. + + - Function: void sha384_digest (struct sha384_ctx *CTX, unsigned + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than `SHA384_DIGEST_SIZE', in + which case only the first LENGTH octets of the digest are written. + + This function also resets the context in the same way as + `sha384_init'. + +`struct nettle_hash' +-------------------- + +Nettle includes a struct including information about the supported hash +functions. It is defined in `', and is used by +Nettle's implementation of HMAC *note Keyed hash functions::. + + - Meta struct: `struct nettle_hash' name context_size digest_size + block_size init update digest + The last three attributes are function pointers, of types + `nettle_hash_init_func', `nettle_hash_update_func', and + `nettle_hash_digest_func'. The first argument to these functions is + `void *' pointer to a context struct, which is of size + `context_size'. + + - Constant Struct: struct nettle_hash nettle_md2 + - Constant Struct: struct nettle_hash nettle_md4 + - Constant Struct: struct nettle_hash nettle_md5 + - Constant Struct: struct nettle_hash nettle_sha1 + - Constant Struct: struct nettle_hash nettle_sha224 + - Constant Struct: struct nettle_hash nettle_sha256 + - Constant Struct: struct nettle_hash nettle_sha384 + - Constant Struct: struct nettle_hash nettle_sha512 + These are all the hash functions that Nettle implements. + + +File: nettle.info, Node: Cipher functions, Next: Cipher modes, Prev: Hash functions, Up: Reference + +Cipher functions +================ + +A "cipher" is a function that takes a message or "plaintext" and a +secret "key" and transforms it to a "ciphertext". Given only the +ciphertext, but not the key, it should be hard to find the plaintext. +Given matching pairs of plaintext and ciphertext, it should be hard to +find the key. + + There are two main classes of ciphers: Block ciphers and stream +ciphers. + + A block cipher can process data only in fixed size chunks, called +"blocks". Typical block sizes are 8 or 16 octets. To encrypt arbitrary +messages, you usually have to pad it to an integral number of blocks, +split it into blocks, and then process each block. The simplest way is +to process one block at a time, independent of each other. That mode of +operation is called "ECB", Electronic Code Book mode. However, using +ECB is usually a bad idea. For a start, plaintext blocks that are equal +are transformed to ciphertext blocks that are equal; that leaks +information about the plaintext. Usually you should apply the cipher is +some "feedback mode", "CBC" (Cipher Block Chaining) and "CTR" (Counter +mode) being two of of the most popular. See *Note Cipher modes::, for +information on how to apply CBC and CTR with Nettle. + + A stream cipher can be used for messages of arbitrary length. A +typical stream cipher is a keyed pseudo-random generator. To encrypt a +plaintext message of N octets, you key the generator, generate N octets +of pseudo-random data, and XOR it with the plaintext. To decrypt, +regenerate the same stream using the key, XOR it to the ciphertext, and +the plaintext is recovered. + + *Caution:* The first rule for this kind of cipher is the same as for +a One Time Pad: _never_ ever use the same key twice. + + A common misconception is that encryption, by itself, implies +authentication. Say that you and a friend share a secret key, and you +receive an encrypted message. You apply the key, and get a plaintext +message that makes sense to you. Can you then be sure that it really was +your friend that wrote the message you're reading? The answer is no. For +example, if you were using a block cipher in ECB mode, an attacker may +pick up the message on its way, and reorder, delete or repeat some of +the blocks. Even if the attacker can't decrypt the message, he can +change it so that you are not reading the same message as your friend +wrote. If you are using a block cipher in CBC mode rather than ECB, or +are using a stream cipher, the possibilities for this sort of attack +are different, but the attacker can still make predictable changes to +the message. + + It is recommended to _always_ use an authentication mechanism in +addition to encrypting the messages. Popular choices are Message +Authentication Codes like HMAC-SHA1 *note Keyed hash functions::, or +digital signatures like RSA. + + Some ciphers have so called "weak keys", keys that results in +undesirable structure after the key setup processing, and should be +avoided. In Nettle, most key setup functions have no return value, but +for ciphers with weak keys, the return value indicates whether or not +the given key is weak. For good keys, key setup returns 1, and for weak +keys, it returns 0. When possible, avoid algorithms that have weak +keys. There are several good ciphers that don't have any weak keys. + + To encrypt a message, you first initialize a cipher context for +encryption or decryption with a particular key. You then use the context +to process plaintext or ciphertext messages. The initialization is known +as "key setup". With Nettle, it is recommended to use each context +struct for only one direction, even if some of the ciphers use a single +key setup function that can be used for both encryption and decryption. + +AES +--- + +AES is a block cipher, specified by NIST as a replacement for the older +DES standard. The standard is the result of a competition between +cipher designers. The winning design, also known as RIJNDAEL, was +constructed by Joan Daemen and Vincent Rijnmen. + + Like all the AES candidates, the winning design uses a block size of +128 bits, or 16 octets, and variable key-size, 128, 192 and 256 bits +(16, 24 and 32 octets) being the allowed key sizes. It does not have +any weak keys. Nettle defines AES in `'. + + - Context struct: struct aes_ctx + + - Constant: AES_BLOCK_SIZE + The AES block-size, 16 + + - Constant: AES_MIN_KEY_SIZE + + - Constant: AES_MAX_KEY_SIZE + + - Constant: AES_KEY_SIZE + Default AES key size, 32 + + - Function: void aes_set_encrypt_key (struct aes_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + - Function: void aes_set_decrypt_key (struct aes_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + Initialize the cipher, for encryption or decryption, respectively. + + - Function: void aes_invert_key (struct aes_ctx *DST, const struct + aes_ctx *SRC) + Given a context SRC initialized for encryption, initializes the + context struct DST for decryption, using the same key. If the same + context struct is passed for both `src' and `dst', it is converted + in place. Calling `aes_set_encrypt_key' and `aes_invert_key' is + more efficient than calling `aes_set_encrypt_key' and + `aes_set_decrypt_key'. This function is mainly useful for + applications which needs to both encrypt and decrypt using the + _same_ key. + + - Function: void aes_encrypt (struct aes_ctx *CTX, unsigned LENGTH, + const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void aes_decrypt (struct aes_ctx *CTX, unsigned LENGTH, + const uint8_t *DST, uint8_t *SRC) + Analogous to `aes_encrypt' + +ARCFOUR +------- + +ARCFOUR is a stream cipher, also known under the trade marked name RC4, +and it is one of the fastest ciphers around. A problem is that the key +setup of ARCFOUR is quite weak, you should never use keys with +structure, keys that are ordinary passwords, or sequences of keys like +"secret:1", "secret:2", ..... If you have keys that don't look like +random bit strings, and you want to use ARCFOUR, always hash the key +before feeding it to ARCFOUR. Furthermore, the initial bytes of the +generated key stream leak information about the key; for this reason, it +is recommended to discard the first 512 bytes of the key stream. + + /* A more robust key setup function for ARCFOUR */ + void + arcfour_set_key_hashed(struct arcfour_ctx *ctx, + unsigned length, const uint8_t *key) + { + struct sha256_ctx hash; + uint8_t digest[SHA256_DIGEST_SIZE]; + uint8_t buffer[0x200]; + + sha256_init(&hash); + sha256_update(&hash, length, key); + sha256_digest(&hash, SHA256_DIGEST_SIZE, digest); + + arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest); + arcfour_crypt(ctx, sizeof(buffer), buffer, buffer); + } + + Nettle defines ARCFOUR in `'. + + - Context struct: struct arcfour_ctx + + - Constant: ARCFOUR_MIN_KEY_SIZE + Minimum key size, 1 + + - Constant: ARCFOUR_MAX_KEY_SIZE + Maximum key size, 256 + + - Constant: ARCFOUR_KEY_SIZE + Default ARCFOUR key size, 16 + + - Function: void arcfour_set_key (struct arcfour_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. + + - Function: void arcfour_crypt (struct arcfour_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Encrypt some data. The same function is used for both encryption + and decryption. Unlike the block ciphers, this function modifies + the context, so you can split the data into arbitrary chunks and + encrypt them one after another. The result is the same as if you + had called `arcfour_crypt' only once with all the data. + +ARCTWO +------ + +ARCTWO (also known as the trade marked name RC2) is a block cipher +specified in RFC 2268. Nettle also include a variation of the ARCTWO +set key operation that lack one step, to be compatible with the reverse +engineered RC2 cipher description, as described in a Usenet post to +`sci.crypt' by Peter Gutmann. + + ARCTWO uses a block size of 64 bits, and variable key-size ranging +from 1 to 128 octets. Besides the key, ARCTWO also has a second +parameter to key setup, the number of effective key bits, `ekb'. This +parameter can be used to artificially reduce the key size. In practice, +`ekb' is usually set equal to the input key size. Nettle defines +ARCTWO in `'. + + We do not recommend the use of ARCTWO; the Nettle implementation is +provided primarily for interoperability with existing applications and +standards. + + - Context struct: struct arctwo_ctx + + - Constant: ARCTWO_BLOCK_SIZE + The AES block-size, 8 + + - Constant: ARCTWO_MIN_KEY_SIZE + + - Constant: ARCTWO_MAX_KEY_SIZE + + - Constant: ARCTWO_KEY_SIZE + Default ARCTWO key size, 8 + + - Function: void arctwo_set_key_ekb (struct arctwo_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY, unsigned EKB) + - Function: void arctwo_set_key (struct arctwo_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + - Function: void arctwo_set_key_gutmann (struct arctwo_ctx *CTX, + unsigned LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. The first function is the most general + one, which lets you provide both the variable size key, and the + desired effective key size (in bits). The maximum value for EKB is + 1024, and for convenience, `ekb = 0' has the same effect as `ekb = + 1024'. + + `arctwo_set_key(ctx, length, key)' is equivalent to + `arctwo_set_key_ekb(ctx, length, key, 8*length)', and + `arctwo_set_key_gutmann(ctx, length, key)' is equivalent to + `arctwo_set_key_ekb(ctx, length, key, 1024)' + + - Function: void arctwo_encrypt (struct arctwo_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void arctwo_decrypt (struct arctwo_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Analogous to `arctwo_encrypt' + +BLOWFISH +-------- + +BLOWFISH is a block cipher designed by Bruce Schneier. It uses a block +size of 64 bits (8 octets), and a variable key size, up to 448 bits. It +has some weak keys. Nettle defines BLOWFISH in `'. + + - Context struct: struct blowfish_ctx + + - Constant: BLOWFISH_BLOCK_SIZE + The BLOWFISH block-size, 8 + + - Constant: BLOWFISH_MIN_KEY_SIZE + Minimum BLOWFISH key size, 8 + + - Constant: BLOWFISH_MAX_KEY_SIZE + Maximum BLOWFISH key size, 56 + + - Constant: BLOWFISH_KEY_SIZE + Default BLOWFISH key size, 16 + + - Function: int blowfish_set_key (struct blowfish_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. Checks for weak keys, returning 1 for + good keys and 0 for weak keys. Applications that don't care about + weak keys can ignore the return value. + + `blowfish_encrypt' or `blowfish_decrypt' with a weak key will + crash with an assert violation. + + - Function: void blowfish_encrypt (struct blowfish_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void blowfish_decrypt (struct blowfish_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Analogous to `blowfish_encrypt' + +Camellia +-------- + +Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph +and Telephone Corporation, described in `RFC3713', and recommended by +some Japanese and European authorities as an alternative to AES. The +algorithm is patented. The implementation in Nettle is derived from the +implementation released by NTT under the GNU LGPL (v2.1 or later), and +relies on the implicit patent license of the LGPL. There is also a +statement of royalty-free licensing for Camellia at +, but this +statement has some limitations which seem problematic for free software. + + Camellia uses a the same block size and key sizes as AES: The block +size is 128 bits (16 octets), and the supported key sizes are 128, 192, +and 256 bits. Nettle defines Camellia in `'. + + - Context struct: struct camellia_ctx + + - Constant: CAMELLIA_BLOCK_SIZE + The CAMELLIA block-size, 16 + + - Constant: CAMELLIA_MIN_KEY_SIZE + + - Constant: CAMELLIA_MAX_KEY_SIZE + + - Constant: CAMELLIA_KEY_SIZE + Default CAMELLIA key size, 32 + + - Function: void camellia_set_encrypt_key (struct camellia_ctx *CTX, + unsigned LENGTH, const uint8_t *KEY) + - Function: void camellia_set_decrypt_key (struct camellia_ctx *CTX, + unsigned LENGTH, const uint8_t *KEY) + Initialize the cipher, for encryption or decryption, respectively. + + - Function: void camellia_invert_key (struct camellia_ctx *DST, const + struct camellia_ctx *SRC) + Given a context SRC initialized for encryption, initializes the + context struct DST for decryption, using the same key. If the same + context struct is passed for both `src' and `dst', it is converted + in place. Calling `camellia_set_encrypt_key' and + `camellia_invert_key' is more efficient than calling + `camellia_set_encrypt_key' and `camellia_set_decrypt_key'. This + function is mainly useful for applications which needs to both + encrypt and decrypt using the _same_ key. + + - Function: void camellia_crypt (struct camellia_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + The same function is used for both encryption and decryption. + LENGTH must be an integral multiple of the block size. If it is + more than one block, the data is processed in ECB mode. `src' and + `dst' may be equal, but they must not overlap in any other way. + +CAST128 +------- + +CAST-128 is a block cipher, specified in `RFC 2144'. It uses a 64 bit +(8 octets) block size, and a variable key size of up to 128 bits. +Nettle defines cast128 in `'. + + - Context struct: struct cast128_ctx + + - Constant: CAST128_BLOCK_SIZE + The CAST128 block-size, 8 + + - Constant: CAST128_MIN_KEY_SIZE + Minimum CAST128 key size, 5 + + - Constant: CAST128_MAX_KEY_SIZE + Maximum CAST128 key size, 16 + + - Constant: CAST128_KEY_SIZE + Default CAST128 key size, 16 + + - Function: void cast128_set_key (struct cast128_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. + + - Function: void cast128_encrypt (struct cast128_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void cast128_decrypt (struct cast128_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Analogous to `cast128_encrypt' + +DES +--- + +DES is the old Data Encryption Standard, specified by NIST. It uses a +block size of 64 bits (8 octets), and a key size of 56 bits. However, +the key bits are distributed over 8 octets, where the least significant +bit of each octet may be used for parity. A common way to use DES is to +generate 8 random octets in some way, then set the least significant bit +of each octet to get odd parity, and initialize DES with the resulting +key. + + The key size of DES is so small that keys can be found by brute +force, using specialized hardware or lots of ordinary work stations in +parallel. One shouldn't be using plain DES at all today, if one uses +DES at all one should be using "triple DES", see DES3 below. + + DES also has some weak keys. Nettle defines DES in `'. + + - Context struct: struct des_ctx + + - Constant: DES_BLOCK_SIZE + The DES block-size, 8 + + - Constant: DES_KEY_SIZE + DES key size, 8 + + - Function: int des_set_key (struct des_ctx *CTX, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. Parity bits are ignored. Checks for + weak keys, returning 1 for good keys and 0 for weak keys. + Applications that don't care about weak keys can ignore the return + value. + + - Function: void des_encrypt (struct des_ctx *CTX, unsigned LENGTH, + const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void des_decrypt (struct des_ctx *CTX, unsigned LENGTH, + const uint8_t *DST, uint8_t *SRC) + Analogous to `des_encrypt' + + - Function: int des_check_parity (unsigned LENGTH, const uint8_t *KEY); + Checks that the given key has correct, odd, parity. Returns 1 for + correct parity, and 0 for bad parity. + + - Function: void des_fix_parity (unsigned LENGTH, uint8_t *DST, const + uint8_t *SRC) + Adjusts the parity bits to match DES's requirements. You need this + function if you have created a random-looking string by a key + agreement protocol, and want to use it as a DES key. DST and SRC + may be equal. + +DES3 +---- + +The inadequate key size of DES has already been mentioned. One way to +increase the key size is to pipe together several DES boxes with +independent keys. It turns out that using two DES ciphers is not as +secure as one might think, even if the key size of the combination is a +respectable 112 bits. + + The standard way to increase DES's key size is to use three DES +boxes. The mode of operation is a little peculiar: the middle DES box +is wired in the reverse direction. To encrypt a block with DES3, you +encrypt it using the first 56 bits of the key, then _decrypt_ it using +the middle 56 bits of the key, and finally encrypt it again using the +last 56 bits of the key. This is known as "ede" triple-DES, for +"encrypt-decrypt-encrypt". + + The "ede" construction provides some backward compatibility, as you +get plain single DES simply by feeding the same key to all three boxes. +That should help keeping down the gate count, and the price, of hardware +circuits implementing both plain DES and DES3. + + DES3 has a key size of 168 bits, but just like plain DES, useless +parity bits are inserted, so that keys are represented as 24 octets +(192 bits). As a 112 bit key is large enough to make brute force +attacks impractical, some applications uses a "two-key" variant of +triple-DES. In this mode, the same key bits are used for the first and +the last DES box in the pipe, while the middle box is keyed +independently. The two-key variant is believed to be secure, i.e. there +are no known attacks significantly better than brute force. + + Naturally, it's simple to implement triple-DES on top of Nettle's DES +functions. Nettle includes an implementation of three-key "ede" +triple-DES, it is defined in the same place as plain DES, +`'. + + - Context struct: struct des3_ctx + + - Constant: DES3_BLOCK_SIZE + The DES3 block-size is the same as DES_BLOCK_SIZE, 8 + + - Constant: DES3_KEY_SIZE + DES key size, 24 + + - Function: int des3_set_key (struct des3_ctx *CTX, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. Parity bits are ignored. Checks for + weak keys, returning 1 if all three keys are good keys, and 0 if + one or more key is weak. Applications that don't care about weak + keys can ignore the return value. + + For random-looking strings, you can use `des_fix_parity' to adjust +the parity bits before calling `des3_set_key'. + + - Function: void des3_encrypt (struct des3_ctx *CTX, unsigned LENGTH, + const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void des3_decrypt (struct des3_ctx *CTX, unsigned LENGTH, + const uint8_t *DST, uint8_t *SRC) + Analogous to `des_encrypt' + +SERPENT +------- + +SERPENT is one of the AES finalists, designed by Ross Anderson, Eli +Biham and Lars Knudsen. Thus, the interface and properties are similar +to AES'. One peculiarity is that it is quite pointless to use it with +anything but the maximum key size, smaller keys are just padded to +larger ones. Nettle defines SERPENT in `'. + + - Context struct: struct serpent_ctx + + - Constant: SERPENT_BLOCK_SIZE + The SERPENT block-size, 16 + + - Constant: SERPENT_MIN_KEY_SIZE + Minimum SERPENT key size, 16 + + - Constant: SERPENT_MAX_KEY_SIZE + Maximum SERPENT key size, 32 + + - Constant: SERPENT_KEY_SIZE + Default SERPENT key size, 32 + + - Function: void serpent_set_key (struct serpent_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. + + - Function: void serpent_encrypt (struct serpent_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void serpent_decrypt (struct serpent_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Analogous to `serpent_encrypt' + +TWOFISH +------- + +Another AES finalist, this one designed by Bruce Schneier and others. +Nettle defines it in `'. + + - Context struct: struct twofish_ctx + + - Constant: TWOFISH_BLOCK_SIZE + The TWOFISH block-size, 16 + + - Constant: TWOFISH_MIN_KEY_SIZE + Minimum TWOFISH key size, 16 + + - Constant: TWOFISH_MAX_KEY_SIZE + Maximum TWOFISH key size, 32 + + - Constant: TWOFISH_KEY_SIZE + Default TWOFISH key size, 32 + + - Function: void twofish_set_key (struct twofish_ctx *CTX, unsigned + LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. + + - Function: void twofish_encrypt (struct twofish_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Encryption function. LENGTH must be an integral multiple of the + block size. If it is more than one block, the data is processed in + ECB mode. `src' and `dst' may be equal, but they must not overlap + in any other way. + + - Function: void twofish_decrypt (struct twofish_ctx *CTX, unsigned + LENGTH, const uint8_t *DST, uint8_t *SRC) + Analogous to `twofish_encrypt' + +`struct nettle_cipher' +---------------------- + +Nettle includes a struct including information about some of the more +regular cipher functions. It should be considered a little experimental, +but can be useful for applications that need a simple way to handle +various algorithms. Nettle defines these structs in +`'. + + - Meta struct: `struct nettle_cipher' name context_size block_size + key_size set_encrypt_key set_decrypt_key encrypt decrypt + The last four attributes are function pointers, of types + `nettle_set_key_func' and `nettle_crypt_func'. The first argument + to these functions is a `void *' pointer to a context struct, + which is of size `context_size'. + + - Constant Struct: struct nettle_cipher nettle_aes128 + - Constant Struct: struct nettle_cipher nettle_aes192 + - Constant Struct: struct nettle_cipher nettle_aes256 + - Constant Struct: struct nettle_cipher nettle_arctwo40; + - Constant Struct: struct nettle_cipher nettle_arctwo64; + - Constant Struct: struct nettle_cipher nettle_arctwo128; + - Constant Struct: struct nettle_cipher nettle_arctwo_gutmann128; + - Constant Struct: struct nettle_cipher nettle_arcfour128 + - Constant Struct: struct nettle_cipher nettle_camellia128 + - Constant Struct: struct nettle_cipher nettle_camellia192 + - Constant Struct: struct nettle_cipher nettle_camellia256 + - Constant Struct: struct nettle_cipher nettle_cast128 + - Constant Struct: struct nettle_cipher nettle_serpent128 + - Constant Struct: struct nettle_cipher nettle_serpent192 + - Constant Struct: struct nettle_cipher nettle_serpent256 + - Constant Struct: struct nettle_cipher nettle_twofish128 + - Constant Struct: struct nettle_cipher nettle_twofish192 + - Constant Struct: struct nettle_cipher nettle_twofish256 + - Constant Struct: struct nettle_cipher nettle_arctwo40; + - Constant Struct: struct nettle_cipher nettle_arctwo64; + - Constant Struct: struct nettle_cipher nettle_arctwo128; + - Constant Struct: struct nettle_cipher nettle_arctwo_gutmann128; + Nettle includes such structs for all the _regular_ ciphers, i.e. + ones without weak keys or other oddities. + + +File: nettle.info, Node: Cipher modes, Next: Keyed hash functions, Prev: Cipher functions, Up: Reference + +Cipher modes +============ + +Cipher modes of operation specifies the procedure to use when +encrypting a message that is larger than the cipher's block size. As +explained in *Note Cipher functions::, splitting the message into blocks +and processing them independently with the block cipher (Electronic Code +Book mode, ECB) leaks information. Besides ECB, Nettle provides two +other modes of operation: Cipher Block Chaining (CBC) and Counter mode +(CTR). CBC is widely used, but there are a few subtle issues of +information leakage. CTR was standardized more recently, and is +believed to be more secure. + +Cipher Block Chaining +--------------------- + +When using CBC mode, plaintext blocks are not encrypted independently +of each other, like in Electronic Cook Book mode. Instead, when +encrypting a block in CBC mode, the previous ciphertext block is XORed +with the plaintext before it is fed to the block cipher. When +encrypting the first block, a random block called an "IV", or +Initialization Vector, is used as the "previous ciphertext block". The +IV should be chosen randomly, but it need not be kept secret, and can +even be transmitted in the clear together with the encrypted data. + + In symbols, if `E_k' is the encryption function of a block cipher, +and `IV' is the initialization vector, then `n' plaintext blocks +`M_1',... `M_n' are transformed into `n' ciphertext blocks `C_1',... +`C_n' as follows: + + C_1 = E_k(IV XOR M_1) + C_2 = E_k(C_1 XOR M_2) + + ... + + C_n = E_k(C_(n-1) XOR M_n) + + Nettle's includes two functions for applying a block cipher in Cipher +Block Chaining (CBC) mode, one for encryption and one for decryption. +These functions uses `void *' to pass cipher contexts around. + + - Function: void cbc_encrypt (void *CTX, nettle_crypt_func F, unsigned + BLOCK_SIZE, uint8_t *IV, unsigned LENGTH, uint8_t *DST, const + uint8_t *SRC) + - Function: void cbc_decrypt (void *CTX, void (*F)(), unsigned + BLOCK_SIZE, uint8_t *IV, unsigned LENGTH, uint8_t *DST, const + uint8_t *SRC) + Applies the encryption or decryption function F in CBC mode. The + final ciphertext block processed is copied into IV before + returning, so that large message be processed be a sequence of + calls to `cbc_encrypt'. The function F is of type + + `void f (void *CTX, unsigned LENGTH, uint8_t DST, const uint8_t + *SRC)', + + and the `cbc_encrypt' and `cbc_decrypt' functions pass their + argument CTX on to F. + + There are also some macros to help use these functions correctly. + + - Macro: CBC_CTX (CONTEXT_TYPE, BLOCK_SIZE) + Expands into + { + context_type ctx; + uint8_t iv[block_size]; + } + + It can be used to define a CBC context struct, either directly, + + struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx; + + or to give it a struct tag, + + struct aes_cbc_ctx CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE); + + - Macro: CBC_SET_IV (CTX, IV) + First argument is a pointer to a context struct as defined by + `CBC_CTX', and the second is a pointer to an Initialization Vector + (IV) that is copied into that context. + + - Macro: CBC_ENCRYPT (CTX, F, LENGTH, DST, SRC) + - Macro: CBC_DECRYPT (CTX, F, LENGTH, DST, SRC) + A simpler way to invoke `cbc_encrypt' and `cbc_decrypt'. The first + argument is a pointer to a context struct as defined by `CBC_CTX', + and the second argument is an encryption or decryption function + following Nettle's conventions. The last three arguments define + the source and destination area for the operation. + + These macros use some tricks to make the compiler display a warning +if the types of F and CTX don't match, e.g. if you try to use an +`struct aes_ctx' context with the `des_encrypt' function. + +Counter mode +------------ + +Counter mode (CTR) uses the block cipher as a keyed pseudo-random +generator. The output of the generator is XORed with the data to be +encrypted. It can be understood as a way to transform a block cipher to +a stream cipher. + + The message is divided into `n' blocks `M_1',... `M_n', where `M_n' +is of size `m' which may be smaller than the block size. Except for the +last block, all the message blocks must be of size equal to the +cipher's block size. + + If `E_k' is the encryption function of a block cipher, `IC' is the +initial counter, then the `n' plaintext blocks are transformed into `n' +ciphertext blocks `C_1',... `C_n' as follows: + + C_1 = E_k(IC) XOR M_1 + C_2 = E_k(IC + 1) XOR M_2 + + ... + + C_(n-1) = E_k(IC + n - 2) XOR M_(n-1) + C_n = E_k(IC + n - 1) [1..m] XOR M_n + + The IC is the initial value for the counter, it plays a similar role +as the IV for CBC. When adding, `IC + x', IC is interpreted as an +integer, in network byte order. For the last block, `E_k(IC + n - 1) +[1..m]' means that the cipher output is truncated to `m' bytes. + + - Function: void ctr_crypt (void *CTX, nettle_crypt_func F, unsigned + BLOCK_SIZE, uint8_t *CTR, unsigned LENGTH, uint8_t *DST, + const uint8_t *SRC) + Applies the encryption function F in CTR mode. Note that for CTR + mode, encryption and decryption is the same operation, and hence F + should always be the encryption function for the underlying block + cipher. + + When a message is encrypted using a sequence of calls to + `ctr_crypt', all but the last call _must_ use a length that is a + multiple of the block size. + + Like for CBC, there are also a couple of helper macros. + + - Macro: CTR_CTX (CONTEXT_TYPE, BLOCK_SIZE) + Expands into + { + context_type ctx; + uint8_t ctr[block_size]; + } + + - Macro: CTR_SET_COUNTER (CTX, IV) + First argument is a pointer to a context struct as defined by + `CTR_CTX', and the second is a pointer to an initial counter that + is copied into that context. + + - Macro: CTR_CRYPT (CTX, F, LENGTH, DST, SRC) + A simpler way to invoke `ctr_crypt'. The first argument is a + pointer to a context struct as defined by `CTR_CTX', and the second + argument is an encryption function following Nettle's conventions. + The last three arguments define the source and destination area + for the operation. + + +File: nettle.info, Node: Keyed hash functions, Next: Public-key algorithms, Prev: Cipher modes, Up: Reference + +Keyed Hash Functions +==================== + +A "keyed hash function", or "Message Authentication Code" (MAC) is a +function that takes a key and a message, and produces fixed size MAC. +It should be hard to compute a message and a matching MAC without +knowledge of the key. It should also be hard to compute the key given +only messages and corresponding MACs. + + Keyed hash functions are useful primarily for message authentication, +when Alice and Bob shares a secret: The sender, Alice, computes the MAC +and attaches it to the message. The receiver, Bob, also computes the +MAC of the message, using the same key, and compares that to Alice's +value. If they match, Bob can be assured that the message has not been +modified on its way from Alice. + + However, unlike digital signatures, this assurance is not +transferable. Bob can't show the message and the MAC to a third party +and prove that Alice sent that message. Not even if he gives away the +key to the third party. The reason is that the _same_ key is used on +both sides, and anyone knowing the key can create a correct MAC for any +message. If Bob believes that only he and Alice knows the key, and he +knows that he didn't attach a MAC to a particular message, he knows it +must be Alice who did it. However, the third party can't distinguish +between a MAC created by Alice and one created by Bob. + + Keyed hash functions are typically a lot faster than digital +signatures as well. + +HMAC +---- + +One can build keyed hash functions from ordinary hash functions. Older +constructions simply concatenate secret key and message and hashes +that, but such constructions have weaknesses. A better construction is +HMAC, described in `RFC 2104'. + + For an underlying hash function `H', with digest size `l' and +internal block size `b', HMAC-H is constructed as follows: From a given +key `k', two distinct subkeys `k_i' and `k_o' are constructed, both of +length `b'. The HMAC-H of a message `m' is then computed as `H(k_o | +H(k_i | m))', where `|' denotes string concatenation. + + HMAC keys can be of any length, but it is recommended to use keys of +length `l', the digest size of the underlying hash function `H'. Keys +that are longer than `b' are shortened to length `l' by hashing with +`H', so arbitrarily long keys aren't very useful. + + Nettle's HMAC functions are defined in `'. There are +abstract functions that use a pointer to a `struct nettle_hash' to +represent the underlying hash function and `void *' pointers that point +to three different context structs for that hash function. There are +also concrete functions for HMAC-MD5, HMAC-SHA1, HMAC-SHA256, and +HMAC-SHA512. First, the abstract functions: + + - Function: void hmac_set_key (void *OUTER, void *INNER, void *STATE, + const struct nettle_hash *H, unsigned LENGTH, const uint8_t + *KEY) + Initializes the three context structs from the key. The OUTER and + INNER contexts corresponds to the subkeys `k_o' and `k_i'. STATE + is used for hashing the message, and is initialized as a copy of + the INNER context. + + - Function: void hmac_update (void *STATE, const struct nettle_hash + *H, unsigned LENGTH, const uint8_t *DATA) + This function is called zero or more times to process the message. + Actually, `hmac_update(state, H, length, data)' is equivalent to + `H->update(state, length, data)', so if you wish you can use the + ordinary update function of the underlying hash function instead. + + - Function: void hmac_digest (const void *OUTER, const void *INNER, + void *STATE, const struct nettle_hash *H, unsigned LENGTH, + uint8_t *DIGEST) + Extracts the MAC of the message, writing it to DIGEST. OUTER and + INNER are not modified. LENGTH is usually equal to + `H->digest_size', but if you provide a smaller value, only the + first LENGTH octets of the MAC are written. + + This function also resets the STATE context so that you can start + over processing a new message (with the same key). + + Like for CBC, there are some macros to help use these functions +correctly. + + - Macro: HMAC_CTX (TYPE) + Expands into + { + type outer; + type inner; + type state; + } + + It can be used to define a HMAC context struct, either directly, + + struct HMAC_CTX(struct md5_ctx) ctx; + + or to give it a struct tag, + + struct hmac_md5_ctx HMAC_CTX (struct md5_ctx); + + - Macro: HMAC_SET_KEY (CTX, H, LENGTH, KEY) + CTX is a pointer to a context struct as defined by `HMAC_CTX', H + is a pointer to a `const struct nettle_hash' describing the + underlying hash function (so it must match the type of the + components of CTX). The last two arguments specify the secret key. + + - Macro: HMAC_DIGEST (CTX, H, LENGTH, DIGEST) + CTX is a pointer to a context struct as defined by `HMAC_CTX', H + is a pointer to a `const struct nettle_hash' describing the + underlying hash function. The last two arguments specify where the + digest is written. + + Note that there is no `HMAC_UPDATE' macro; simply call `hmac_update' +function directly, or the update function of the underlying hash +function. + +Concrete HMAC functions +----------------------- + +Now we come to the specialized HMAC functions, which are easier to use +than the general HMAC functions. + +HMAC-MD5 +........ + + - Context struct: struct hmac_md5_ctx + + - Function: void hmac_md5_set_key (struct hmac_md5_ctx *CTX, unsigned + KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + - Function: void hmac_md5_update (struct hmac_md5_ctx *CTX, unsigned + LENGTH, const uint8_t *DATA) + Process some more data. + + - Function: void hmac_md5_digest (struct hmac_md5_ctx *CTX, unsigned + LENGTH, uint8_t *DIGEST) + Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than + `MD5_DIGEST_SIZE', in which case only the first LENGTH octets of + the MAC are written. + + This function also resets the context for processing new messages, + with the same key. + +HMAC-SHA1 +......... + + - Context struct: struct hmac_sha1_ctx + + - Function: void hmac_sha1_set_key (struct hmac_sha1_ctx *CTX, + unsigned KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + - Function: void hmac_sha1_update (struct hmac_sha1_ctx *CTX, unsigned + LENGTH, const uint8_t *DATA) + Process some more data. + + - Function: void hmac_sha1_digest (struct hmac_sha1_ctx *CTX, unsigned + LENGTH, uint8_t *DIGEST) + Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than + `SHA1_DIGEST_SIZE', in which case only the first LENGTH octets of + the MAC are written. + + This function also resets the context for processing new messages, + with the same key. + +HMAC-SHA256 +........... + + - Context struct: struct hmac_sha256_ctx + + - Function: void hmac_sha256_set_key (struct hmac_sha256_ctx *CTX, + unsigned KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + - Function: void hmac_sha256_update (struct hmac_sha256_ctx *CTX, + unsigned LENGTH, const uint8_t *DATA) + Process some more data. + + - Function: void hmac_sha256_digest (struct hmac_sha256_ctx *CTX, + unsigned LENGTH, uint8_t *DIGEST) + Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than + `SHA256_DIGEST_SIZE', in which case only the first LENGTH octets + of the MAC are written. + + This function also resets the context for processing new messages, + with the same key. + +HMAC-SHA512 +........... + + - Context struct: struct hmac_sha512_ctx + + - Function: void hmac_sha512_set_key (struct hmac_sha512_ctx *CTX, + unsigned KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + - Function: void hmac_sha512_update (struct hmac_sha512_ctx *CTX, + unsigned LENGTH, const uint8_t *DATA) + Process some more data. + + - Function: void hmac_sha512_digest (struct hmac_sha512_ctx *CTX, + unsigned LENGTH, uint8_t *DIGEST) + Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than + `SHA512_DIGEST_SIZE', in which case only the first LENGTH octets + of the MAC are written. + + This function also resets the context for processing new messages, + with the same key. + + +File: nettle.info, Node: Public-key algorithms, Next: Randomness, Prev: Keyed hash functions, Up: Reference + +Public-key algorithms +===================== + +Nettle uses GMP, the GNU bignum library, for all calculations with +large numbers. In order to use the public-key features of Nettle, you +must install GMP, at least version 3.0, before compiling Nettle, and +you need to link your programs with `-lhogweed -lnettle -lgmp'. + + The concept of "Public-key" encryption and digital signatures was +discovered by Whitfield Diffie and Martin E. Hellman and described in a +paper 1976. In traditional, "symmetric", cryptography, sender and +receiver share the same keys, and these keys must be distributed in a +secure way. And if there are many users or entities that need to +communicate, each _pair_ needs a shared secret key known by nobody else. + + Public-key cryptography uses trapdoor one-way functions. A "one-way +function" is a function `F' such that it is easy to compute the value +`F(x)' for any `x', but given a value `y', it is hard to compute a +corresponding `x' such that `y = F(x)'. Two examples are cryptographic +hash functions, and exponentiation in certain groups. + + A "trapdoor one-way function" is a function `F' that is one-way, +unless one knows some secret information about `F'. If one knows the +secret, it is easy to compute both `F' and it's inverse. If this +sounds strange, look at the RSA example below. + + Two important uses for one-way functions with trapdoors are +public-key encryption, and digital signatures. The public-key +encryption functions in Nettle are not yet documented; the rest of this +chapter is about digital signatures. + + To use a digital signature algorithm, one must first create a +"key-pair": A public key and a corresponding private key. The private +key is used to sign messages, while the public key is used for verifying +that that signatures and messages match. Some care must be taken when +distributing the public key; it need not be kept secret, but if a bad +guy is able to replace it (in transit, or in some user's list of known +public keys), bad things may happen. + + There are two operations one can do with the keys. The signature +operation takes a message and a private key, and creates a signature for +the message. A signature is some string of bits, usually at most a few +thousand bits or a few hundred octets. Unlike paper-and-ink signatures, +the digital signature depends on the message, so one can't cut it out of +context and glue it to a different message. + + The verification operation takes a public key, a message, and a +string that is claimed to be a signature on the message, and returns +true or false. If it returns true, that means that the three input +values matched, and the verifier can be sure that someone went through +with the signature operation on that very message, and that the +"someone" also knows the private key corresponding to the public key. + + The desired properties of a digital signature algorithm are as +follows: Given the public key and pairs of messages and valid +signatures on them, it should be hard to compute the private key, and +it should also be hard to create a new message and signature that is +accepted by the verification operation. + + Besides signing meaningful messages, digital signatures can be used +for authorization. A server can be configured with a public key, such +that any client that connects to the service is given a random nonce +message. If the server gets a reply with a correct signature matching +the nonce message and the configured public key, the client is granted +access. So the configuration of the server can be understood as "grant +access to whoever knows the private key corresponding to this +particular public key, and to no others". + +* Menu: + +* RSA:: The RSA public key algorithm. +* DSA:: The DSA digital signature algorithm. + + +File: nettle.info, Node: RSA, Next: DSA, Prev: Public-key algorithms, Up: Public-key algorithms + +RSA +--- + +The RSA algorithm was the first practical digital signature algorithm +that was constructed. It was described 1978 in a paper by Ronald +Rivest, Adi Shamir and L.M. Adleman, and the technique was also +patented in the USA in 1983. The patent expired on September 20, 2000, +and since that day, RSA can be used freely, even in the USA. + + It's remarkably simple to describe the trapdoor function behind RSA. +The "one-way"-function used is + + F(x) = x^e mod n + + I.e. raise x to the `e':th power, while discarding all multiples of +`n'. The pair of numbers `n' and `e' is the public key. `e' can be +quite small, even `e = 3' has been used, although slightly larger +numbers are recommended. `n' should be about 1000 bits or larger. + + If `n' is large enough, and properly chosen, the inverse of F, the +computation of `e':th roots modulo `n', is very difficult. But, +where's the trapdoor? + + Let's first look at how RSA key-pairs are generated. First `n' is +chosen as the product of two large prime numbers `p' and `q' of roughly +the same size (so if `n' is 1000 bits, `p' and `q' are about 500 bits +each). One also computes the number `phi = (p-1)(q-1)', in mathematical +speak, `phi' is the order of the multiplicative group of integers +modulo n. + + Next, `e' is chosen. It must have no factors in common with `phi' (in +particular, it must be odd), but can otherwise be chosen more or less +randomly. `e = 65537' is a popular choice, because it makes raising to +the `e''th power particularly efficient, and being prime, it usually +has no factors common with `phi'. + + Finally, a number `d', `d < n' is computed such that `e d mod phi = +1'. It can be shown that such a number exists (this is why `e' and +`phi' must have no common factors), and that for all x, + + (x^e)^d mod n = x^(ed) mod n = (x^d)^e mod n = x + + Using Euclid's algorithm, `d' can be computed quite easily from +`phi' and `e'. But it is still hard to get `d' without knowing `phi', +which depends on the factorization of `n'. + + So `d' is the trapdoor, if we know `d' and `y = F(x)', we can +recover x as `y^d mod n'. `d' is also the private half of the RSA +key-pair. + + The most common signature operation for RSA is defined in `PKCS#1', +a specification by RSA Laboratories. The message to be signed is first +hashed using a cryptographic hash function, e.g. MD5 or SHA1. Next, +some padding, the ASN.1 "Algorithm Identifier" for the hash function, +and the message digest itself, are concatenated and converted to a +number `x'. The signature is computed from `x' and the private key as +`s = x^d mod n'(1) (*note RSA-Footnote-1::). The signature, `s' is a +number of about the same size of `n', and it usually encoded as a +sequence of octets, most significant octet first. + + The verification operation is straight-forward, `x' is computed from +the message in the same way as above. Then `s^e mod n' is computed, the +operation returns true if and only if the result equals `x'. + +Nettle's RSA support +-------------------- + +Nettle represents RSA keys using two structures that contain large +numbers (of type `mpz_t'). + + - Context struct: rsa_public_key size n e + `size' is the size, in octets, of the modulo, and is used + internally. `n' and `e' is the public key. + + - Context struct: rsa_private_key size d p q a b c + `size' is the size, in octets, of the modulo, and is used + internally. `d' is the secret exponent, but it is not actually + used when signing. Instead, the factors `p' and `q', and the + parameters `a', `b' and `c' are used. They are computed from `p', + `q' and `e' such that `a e mod (p - 1) = 1, b e mod (q - 1) = 1, c + q mod p = 1'. + + Before use, these structs must be initialized by calling one of + + - Function: void rsa_public_key_init (struct rsa_public_key *PUB) + - Function: void rsa_private_key_init (struct rsa_private_key *KEY) + Calls `mpz_init' on all numbers in the key struct. + + and when finished with them, the space for the numbers must be +deallocated by calling one of + + - Function: void rsa_public_key_clear (struct rsa_public_key *PUB) + - Function: void rsa_private_key_clear (struct rsa_private_key *KEY) + Calls `mpz_clear' on all numbers in the key struct. + + In general, Nettle's RSA functions deviates from Nettle's "no memory +allocation"-policy. Space for all the numbers, both in the key structs +above, and temporaries, are allocated dynamically. For information on +how to customize allocation, see *Note GMP Allocation: (gmp)Custom +Allocation. + + When you have assigned values to the attributes of a key, you must +call + + - Function: int rsa_public_key_prepare (struct rsa_public_key *PUB) + - Function: int rsa_private_key_prepare (struct rsa_private_key *KEY) + Computes the octet size of the key (stored in the `size' attribute, + and may also do other basic sanity checks. Returns one if + successful, or zero if the key can't be used, for instance if the + modulo is smaller than the minimum size needed for RSA operations + specified by PKCS#1. + + Before signing or verifying a message, you first hash it with the +appropriate hash function. You pass the hash function's context struct +to the RSA signature function, and it will extract the message digest +and do the rest of the work. There are also alternative functions that +take the hash digest as argument. + + There is currently no support for using SHA224 or SHA384 with RSA +signatures, since there's no gain in either computation time nor +message size compared to using SHA256 and SHA512, respectively. + + Creation and verification of signatures is done with the following +functions: + + - Function: int rsa_md5_sign (const struct rsa_private_key *KEY, + struct md5_ctx *HASH, mpz_t SIGNATURE) + - Function: int rsa_sha1_sign (const struct rsa_private_key *KEY, + struct sha1_ctx *HASH, mpz_t SIGNATURE) + - Function: int rsa_sha256_sign (const struct rsa_private_key *KEY, + struct sha256_ctx *HASH, mpz_t SIGNATURE) + - Function: int rsa_sha512_sign (const struct rsa_private_key *KEY, + struct sha512_ctx *HASH, mpz_t SIGNATURE) + The signature is stored in SIGNATURE (which must have been + `mpz_init''ed earlier). The hash context is reset so that it can be + used for new messages. Returns one on success, or zero on failure. + Signing fails if the key is too small for the given hash size, + e.g., it's not possible to create a signature using SHA512 and a + 512-bit RSA key. + + - Function: int rsa_md5_sign_digest (const struct rsa_private_key + *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE) + - Function: int rsa_sha1_sign_digest (const struct rsa_private_key + *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE); + - Function: int rsa_sha256_sign_digest (const struct rsa_private_key + *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE); + - Function: int rsa_sha512_sign_digest (const struct rsa_private_key + *KEY, const uint8_t *DIGEST, mpz_t SIGNATURE); + Creates a signature from the given hash digest. DIGEST should + point to a digest of size `MD5_DIGEST_SIZE', `SHA1_DIGEST_SIZE', + or `SHA256_DIGEST_SIZE', respectively. The signature is stored in + SIGNATURE (which must have been `mpz_init':ed earlier). Returns + one on success, or zero on failure. + + - Function: int rsa_md5_verify (const struct rsa_public_key *KEY, + struct md5_ctx *HASH, const mpz_t SIGNATURE) + - Function: int rsa_sha1_verify (const struct rsa_public_key *KEY, + struct sha1_ctx *HASH, const mpz_t SIGNATURE) + - Function: int rsa_sha256_verify (const struct rsa_public_key *KEY, + struct sha256_ctx *HASH, const mpz_t SIGNATURE) + - Function: int rsa_sha512_verify (const struct rsa_public_key *KEY, + struct sha512_ctx *HASH, const mpz_t SIGNATURE) + Returns 1 if the signature is valid, or 0 if it isn't. In either + case, the hash context is reset so that it can be used for new + messages. + + - Function: int rsa_md5_verify_digest (const struct rsa_public_key + *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE) + - Function: int rsa_sha1_verify_digest (const struct rsa_public_key + *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE) + - Function: int rsa_sha256_verify_digest (const struct rsa_public_key + *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE) + - Function: int rsa_sha512_verify_digest (const struct rsa_public_key + *KEY, const uint8_t *DIGEST, const mpz_t SIGNATURE) + Returns 1 if the signature is valid, or 0 if it isn't. DIGEST + should point to a digest of size `MD5_DIGEST_SIZE', + `SHA1_DIGEST_SIZE', or `SHA256_DIGEST_SIZE', respectively. + + If you need to use the RSA trapdoor, the private key, in a way that +isn't supported by the above functions Nettle also includes a function +that computes `x^d mod n' and nothing more, using the CRT optimization. + + - Function: void rsa_compute_root (struct rsa_private_key *KEY, mpz_t + X, const mpz_t M) + Computes `x = m^d', efficiently. + + At last, how do you create new keys? + + - Function: int rsa_generate_keypair (struct rsa_public_key *PUB, + struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func RANDOM, void *PROGRESS_CTX, + nettle_progress_func PROGRESS, unsigned N_SIZE, unsigned + E_SIZE); + There are lots of parameters. PUB and KEY is where the resulting + key pair is stored. The structs should be initialized, but you + don't need to call `rsa_public_key_prepare' or + `rsa_private_key_prepare' after key generation. + + RANDOM_CTX and RANDOM is a randomness generator. + `random(random_ctx, length, dst)' should generate `length' random + octets and store them at `dst'. For advice, see *Note Randomness::. + + PROGRESS and PROGRESS_CTX can be used to get callbacks during the + key generation process, in order to uphold an illusion of + progress. PROGRESS can be NULL, in that case there are no + callbacks. + + SIZE_N is the desired size of the modulo, in bits. If SIZE_E is + non-zero, it is the desired size of the public exponent and a + random exponent of that size is selected. But if E_SIZE is zero, + it is assumed that the caller has already chosen a value for `e', + and stored it in PUB. Returns one on success, and zero on + failure. The function can fail for example if if N_SIZE is too + small, or if E_SIZE is zero and `pub->e' is an even number. + + +File: nettle.info, Node: RSA-Footnotes, Up: RSA + + (1) Actually, the computation is not done like this, it is done more +efficiently using `p', `q' and the Chinese remainder theorem (CRT). But +the result is the same. + + +File: nettle.info, Node: DSA, Prev: RSA, Up: Public-key algorithms + +Nettle's DSA support +-------------------- + +The DSA digital signature algorithm is more complex than RSA. It was +specified during the early 1990s, and in 1994 NIST published FIPS 186 +which is the authoritative specification. Sometimes DSA is referred to +using the acronym DSS, for Digital Signature Standard. The most recent +revision of the specification, FIPS186-3, was issueed in 2009, and it +adds support for larger hash functions than sha1. + + For DSA, the underlying mathematical problem is the computation of +discreet logarithms. The public key consists of a large prime `p', a +small prime `q' which is a factor of `p-1', a number `g' which +generates a subgroup of order `q' modulo `p', and an element `y' in +that subgroup. + + In the original DSA, the size of `q' is fixed to 160 bits, to match +with the SHA1 hash algorithm. The size of `p' is in principle +unlimited, but the standard specifies only nine specific sizes: `512 + +l*64', where `l' is between 0 and 8. Thus, the maximum size of `p' is +1024 bits, and sizes less than 1024 bits are considered obsolete and not +secure. + + The subgroup requirement means that if you compute + + g^t mod p + + for all possible integers `t', you will get precisely `q' distinct +values. + + The private key is a secret exponent `x', such that + + g^x = y mod p + + In mathematical speak, `x' is the "discrete logarithm" of `y' mod +`p', with respect to the generator `g'. The size of `x' will also be +about the same size as `q'. The security of the DSA algorithm relies on +the difficulty of the discrete logarithm problem. Current algorithms to +compute discrete logarithms in this setting, and hence crack DSA, are +of two types. The first type works directly in the (multiplicative) +group of integers mod `p'. The best known algorithm of this type is the +Number Field Sieve, and it's complexity is similar to the complexity of +factoring numbers of the same size as `p'. The other type works in the +smaller `q'-sized subgroup generated by `g', which has a more difficult +group structure. One good algorithm is Pollard-rho, which has +complexity `sqrt(q)'. + + The important point is that security depends on the size of _both_ +`p' and `q', and they should be choosen so that the difficulty of both +discrete logarithm methods are comparable. Today, the security margin +of the original DSA may be uncomfortably small. Using a `p' of 1024 +bits implies that cracking using the number field sieve is expected to +take about the same time as factoring a 1024-bit RSA modulo, and using +a `q' of size 160 bits implies that cracking using Pollard-rho will +take roughly `2^80' group operations. With the size of `q' fixed, tied +to the SHA1 digest size, it may be tempting to increase the size of `p' +to, say, 4096 bits. This will provide excellent resistance against +attacks like the number field sieve which works in the large group. But +it will do very little to defend against Pollard-rho attacking the small +subgroup; the attacker is slowed down at most by a single factor of 10 +due to the more expensive group operation. And the attacker will surely +choose the latter attack. + + The signature generation algorithm is randomized; in order to create +a DSA signature, you need a good source for random numbers (*note +Randomness::). Let us describe the common case of a 160-bit `q'. + + To create a signature, one starts with the hash digest of the +message, `h', which is a 160 bit number, and a random number `k, +0' is a +fast generator with good statistical properties, but is *not* for +cryptographic use, and therefore not documented here. It is included +mostly because the Nettle test suite needs to generate some test data +from a small seed. + + The recommended generator to use is Yarrow, described below. + +Yarrow +------ + +Yarrow is a family of pseudo-randomness generators, designed for +cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson. +Yarrow-160 is described in a paper at +, and it uses SHA1 and +triple-DES, and has a 160-bit internal state. Nettle implements +Yarrow-256, which is similar, but uses SHA256 and AES to get an +internal state of 256 bits. + + Yarrow was an almost finished project, the paper mentioned above is +the closest thing to a specification for it, but some smaller details +are left out. There is no official reference implementation or test +cases. This section includes an overview of Yarrow, but for the +details of Yarrow-256, as implemented by Nettle, you have to consult +the source code. Maybe a complete specification can be written later. + + Yarrow can use many sources (at least two are needed for proper +reseeding), and two randomness "pools", referred to as the "slow pool" +and the "fast pool". Input from the sources is fed alternatingly into +the two pools. When one of the sources has contributed 100 bits of +entropy to the fast pool, a "fast reseed" happens and the fast pool is +mixed into the internal state. When at least two of the sources have +contributed at least 160 bits each to the slow pool, a "slow reseed" +takes place. The contents of both pools are mixed into the internal +state. These procedures should ensure that the generator will eventually +recover after a key compromise. + + The output is generated by using AES to encrypt a counter, using the +generator's current key. After each request for output, another 256 +bits are generated which replace the key. This ensures forward secrecy. + + Yarrow can also use a "seed file" to save state across restarts. +Yarrow is seeded by either feeding it the contents of the previous seed +file, or feeding it input from its sources until a slow reseed happens. + + Nettle defines Yarrow-256 in `'. + + - Context struct: struct yarrow256_ctx + + - Context struct: struct yarrow_source + Information about a single source. + + - Constant: YARROW256_SEED_FILE_SIZE + Recommanded size of the Yarrow-256 seed file. + + - Function: void yarrow256_init (struct yarrow256_ctx *CTX, unsigned + NSOURCES, struct yarrow_source *SOURCES) + Initializes the yarrow context, and its NSOURCES sources. It's + possible to call it with NSOURCES=0 and SOURCES=NULL, if you don't + need the update features. + + - Function: void yarrow256_seed (struct yarrow256_ctx *CTX, unsigned + LENGTH, uint8_t *SEED_FILE) + Seeds Yarrow-256 from a previous seed file. LENGTH should be at + least `YARROW256_SEED_FILE_SIZE', but it can be larger. + + The generator will trust you that the SEED_FILE data really is + unguessable. After calling this function, you _must_ overwrite the + old seed file with newly generated data from `yarrow256_random'. + If it's possible for several processes to read the seed file at + about the same time, access must be coordinated using some locking + mechanism. + + - Function: int yarrow256_update (struct yarrow256_ctx *CTX, unsigned + SOURCE, unsigned ENTROPY, unsigned LENGTH, const uint8_t + *DATA) + Updates the generator with data from source SOURCE (an index that + must be smaller than the number of sources). ENTROPY is your + estimated lower bound for the entropy in the data, measured in + bits. Calling update with zero ENTROPY is always safe, no matter + if the data is random or not. + + Returns 1 if a reseed happened, in which case an application using + a seed file may want to generate new seed data with + `yarrow256_random' and overwrite the seed file. Otherwise, the + function returns 0. + + - Function: void yarrow256_random (struct yarrow256_ctx *CTX, unsigned + LENGTH, uint8_t *DST) + Generates LENGTH octets of output. The generator must be seeded + before you call this function. + + If you don't need forward secrecy, e.g. if you need non-secret + randomness for initialization vectors or padding, you can gain some + efficiency by buffering, calling this function for reasonably large + blocks of data, say 100-1000 octets at a time. + + - Function: int yarrow256_is_seeded (struct yarrow256_ctx *CTX) + Returns 1 if the generator is seeded and ready to generate output, + otherwise 0. + + - Function: unsigned yarrow256_needed_sources (struct yarrow256_ctx + *CTX) + Returns the number of sources that must reach the threshold before + a slow reseed will happen. Useful primarily when the generator is + unseeded. + + - Function: void yarrow256_fast_reseed (struct yarrow256_ctx *CTX) + - Function: void yarrow256_slow_reseed (struct yarrow256_ctx *CTX) + Causes a fast or slow reseed to take place immediately, regardless + of the current entropy estimates of the two pools. Use with care. + + Nettle includes an entropy estimator for one kind of input source: +User keyboard input. + + - Context struct: struct yarrow_key_event_ctx + Information about recent key events. + + - Function: void yarrow_key_event_init (struct yarrow_key_event_ctx + *CTX) + Initializes the context. + + - Function: unsigned yarrow_key_event_estimate (struct + yarrow_key_event_ctx *CTX, unsigned KEY, unsigned TIME) + KEY is the id of the key (ASCII value, hardware key code, X + keysym, ..., it doesn't matter), and TIME is the timestamp of the + event. The time must be given in units matching the resolution by + which you read the clock. If you read the clock with microsecond + precision, TIME should be provided in units of microseconds. But + if you use `gettimeofday' on a typical Unix system where the clock + ticks 10 or so microseconds at a time, TIME should be given in + units of 10 microseconds. + + Returns an entropy estimate, in bits, suitable for calling + `yarrow256_update'. Usually, 0, 1 or 2 bits. + + +File: nettle.info, Node: Miscellaneous functions, Next: Compatibility functions, Prev: Randomness, Up: Reference + +Miscellaneous functions +======================= + + - Function: uint8_t * memxor (uint8_t *DST, const uint8_t *SRC, size_t + N) + XORs the source area on top of the destination area. The interface + doesn't follow the Nettle conventions, because it is intended to be + similar to the ANSI-C `memcpy' function. + + `memxor' is declared in `'. + + +File: nettle.info, Node: Compatibility functions, Prev: Miscellaneous functions, Up: Reference + +Compatibility functions +======================= + +For convenience, Nettle includes alternative interfaces to some +algorithms, for compatibility with some other popular crypto toolkits. +These are not fully documented here; refer to the source or to the +documentation for the original implementation. + + MD5 is defined in [RFC 1321], which includes a reference +implementation. Nettle defines a compatible interface to MD5 in +`'. This file defines the typedef `MD5_CTX', and +declares the functions `MD5Init', `MD5Update' and `MD5Final'. + + Eric Young's "libdes" (also part of OpenSSL) is a quite popular DES +implementation. Nettle includes a subset if its interface in +`'. This file defines the typedefs +`des_key_schedule' and `des_cblock', two constants `DES_ENCRYPT' and +`DES_DECRYPT', and declares one global variable `des_check_key', and +the functions `des_cbc_cksum' `des_cbc_encrypt', `des_ecb2_encrypt', +`des_ecb3_encrypt', `des_ecb_encrypt', `des_ede2_cbc_encrypt', +`des_ede3_cbc_encrypt', `des_is_weak_key', `des_key_sched', +`des_ncbc_encrypt' `des_set_key', and `des_set_odd_parity'. + + +File: nettle.info, Node: Nettle soup, Next: Installation, Prev: Reference, Up: Top + +Traditional Nettle Soup +*********************** + +For the serious nettle hacker, here is a recipe for nettle soup. 4 +servings. + + 1 liter fresh nettles (urtica dioica) + + 2 tablespoons butter + + 3 tablespoons flour + + 1 liter stock (meat or vegetable) + + 1/2 teaspoon salt + + a tad white pepper + + some cream or milk + + Gather 1 liter fresh nettles. Use gloves! Small, tender shoots are +preferable but the tops of larger nettles can also be used. + + Rinse the nettles very well. Boil them for 10 minutes in lightly +salted water. Strain the nettles and save the water. Hack the nettles. +Melt the butter and mix in the flour. Dilute with stock and the +nettle-water you saved earlier. Add the hacked nettles. If you wish you +can add some milk or cream at this stage. Bring to a boil and let boil +for a few minutes. Season with salt and pepper. + + Serve with boiled egg-halves. + + +File: nettle.info, Node: Installation, Next: Index, Prev: Nettle soup, Up: Top + +Installation +************ + +Nettle uses `autoconf'. To build it, unpack the source and run + + ./configure + make + make check + make install + +to install in the default location, `/usr/local'. The library files are +installed in `/use/local/lib/libnettle.a' `/use/local/lib/libhogweed.a' +and the include files are installed in `/use/local/include/nettle/'. + + To get a list of configure options, use `./configure --help'. + + By default, only static libraries are built and installed. To also +build and install shared libraries, use the ` --enable-shared' option +to `./configure'. + + Using GNU make is recommended. For other make programs, in particular +BSD make, you may have to use the `--disable-dependency-tracking' +option to `./configure'. + + +File: nettle.info, Node: Index, Prev: Installation, Up: Top + +Function and Concept Index +************************** + +* Menu: + +* aes_decrypt: Cipher functions. +* aes_encrypt: Cipher functions. +* aes_invert_key: Cipher functions. +* aes_set_decrypt_key: Cipher functions. +* aes_set_encrypt_key: Cipher functions. +* arcfour_crypt: Cipher functions. +* arcfour_set_key: Cipher functions. +* arctwo_decrypt: Cipher functions. +* arctwo_encrypt: Cipher functions. +* arctwo_set_key: Cipher functions. +* arctwo_set_key_ekb: Cipher functions. +* arctwo_set_key_gutmann: Cipher functions. +* Block Cipher: Cipher functions. +* blowfish_decrypt: Cipher functions. +* blowfish_encrypt: Cipher functions. +* blowfish_set_key: Cipher functions. +* camellia_crypt: Cipher functions. +* camellia_invert_key: Cipher functions. +* camellia_set_decrypt_key: Cipher functions. +* camellia_set_encrypt_key: Cipher functions. +* cast128_decrypt: Cipher functions. +* cast128_encrypt: Cipher functions. +* cast128_set_key: Cipher functions. +* CBC Mode: Cipher modes. +* CBC_CTX: Cipher modes. +* CBC_DECRYPT: Cipher modes. +* cbc_decrypt: Cipher modes. +* CBC_ENCRYPT: Cipher modes. +* cbc_encrypt: Cipher modes. +* CBC_SET_IV: Cipher modes. +* Cipher: Cipher functions. +* Cipher Block Chaining: Cipher modes. +* Collision-resistant: Hash functions. +* Conditional entropy: Randomness. +* Counter Mode: Cipher modes. +* CTR Mode: Cipher modes. +* CTR_CRYPT: Cipher modes. +* ctr_crypt: Cipher modes. +* CTR_CTX: Cipher modes. +* CTR_SET_COUNTER: Cipher modes. +* des3_decrypt: Cipher functions. +* des3_encrypt: Cipher functions. +* des3_set_key: Cipher functions. +* des_check_parity: Cipher functions. +* des_decrypt: Cipher functions. +* des_encrypt: Cipher functions. +* des_fix_parity: Cipher functions. +* des_set_key: Cipher functions. +* dsa_generate_keypair: DSA. +* dsa_private_key_clear: DSA. +* dsa_private_key_init: DSA. +* dsa_public_key_clear: DSA. +* dsa_public_key_init: DSA. +* dsa_sha1_sign: DSA. +* dsa_sha1_sign_digest: DSA. +* dsa_sha1_verify: DSA. +* dsa_sha1_verify_digest: DSA. +* dsa_sha256_sign: DSA. +* dsa_sha256_sign_digest: DSA. +* dsa_sha256_verify: DSA. +* dsa_sha256_verify_digest: DSA. +* dsa_signature_clear: DSA. +* dsa_signature_init: DSA. +* Entropy: Randomness. +* Hash function: Hash functions. +* HMAC_CTX: Keyed hash functions. +* HMAC_DIGEST: Keyed hash functions. +* hmac_digest: Keyed hash functions. +* hmac_md5_digest: Keyed hash functions. +* hmac_md5_set_key: Keyed hash functions. +* hmac_md5_update: Keyed hash functions. +* HMAC_SET_KEY: Keyed hash functions. +* hmac_set_key: Keyed hash functions. +* hmac_sha1_digest: Keyed hash functions. +* hmac_sha1_set_key: Keyed hash functions. +* hmac_sha1_update: Keyed hash functions. +* hmac_sha256_digest: Keyed hash functions. +* hmac_sha256_set_key: Keyed hash functions. +* hmac_sha256_update: Keyed hash functions. +* hmac_sha512_digest: Keyed hash functions. +* hmac_sha512_set_key: Keyed hash functions. +* hmac_sha512_update: Keyed hash functions. +* hmac_update: Keyed hash functions. +* Keyed Hash Function: Keyed hash functions. +* MAC: Keyed hash functions. +* md2_digest: Hash functions. +* md2_init: Hash functions. +* md2_update: Hash functions. +* md4_digest: Hash functions. +* md4_init: Hash functions. +* md4_update: Hash functions. +* md5_digest: Hash functions. +* md5_init: Hash functions. +* md5_update: Hash functions. +* memxor: Miscellaneous functions. +* Message Authentication Code: Keyed hash functions. +* One-way: Hash functions. +* One-way function: Public-key algorithms. +* Public Key Cryptography: Public-key algorithms. +* Randomness: Randomness. +* rsa_compute_root: RSA. +* rsa_generate_keypair: RSA. +* rsa_md5_sign: RSA. +* rsa_md5_sign_digest: RSA. +* rsa_md5_verify: RSA. +* rsa_md5_verify_digest: RSA. +* rsa_private_key_clear: RSA. +* rsa_private_key_init: RSA. +* rsa_private_key_prepare: RSA. +* rsa_public_key_clear: RSA. +* rsa_public_key_init: RSA. +* rsa_public_key_prepare: RSA. +* rsa_sha1_sign: RSA. +* rsa_sha1_sign_digest: RSA. +* rsa_sha1_verify: RSA. +* rsa_sha1_verify_digest: RSA. +* rsa_sha256_sign: RSA. +* rsa_sha256_sign_digest: RSA. +* rsa_sha256_verify: RSA. +* rsa_sha256_verify_digest: RSA. +* rsa_sha512_sign: RSA. +* rsa_sha512_sign_digest: RSA. +* rsa_sha512_verify: RSA. +* rsa_sha512_verify_digest: RSA. +* serpent_decrypt: Cipher functions. +* serpent_encrypt: Cipher functions. +* serpent_set_key: Cipher functions. +* sha1_digest: Hash functions. +* sha1_init: Hash functions. +* sha1_update: Hash functions. +* sha224_digest: Hash functions. +* sha224_init: Hash functions. +* sha224_update: Hash functions. +* sha256_digest: Hash functions. +* sha256_init: Hash functions. +* sha256_update: Hash functions. +* sha384_digest: Hash functions. +* sha384_init: Hash functions. +* sha384_update: Hash functions. +* sha512_digest: Hash functions. +* sha512_init: Hash functions. +* sha512_update: Hash functions. +* Stream Cipher: Cipher functions. +* twofish_decrypt: Cipher functions. +* twofish_encrypt: Cipher functions. +* twofish_set_key: Cipher functions. +* yarrow256_fast_reseed: Randomness. +* yarrow256_init: Randomness. +* yarrow256_is_seeded: Randomness. +* yarrow256_needed_sources: Randomness. +* yarrow256_random: Randomness. +* yarrow256_seed: Randomness. +* yarrow256_slow_reseed: Randomness. +* yarrow256_update: Randomness. +* yarrow_key_event_estimate: Randomness. +* yarrow_key_event_init: Randomness. + + + +Tag Table: +Node: Top544 +Node: Introduction1719 +Node: Copyright3281 +Node: Conventions6951 +Node: Example8909 +Node: Linking10201 +Node: Reference11030 +Node: Hash functions11394 +Node: Cipher functions22959 +Node: Cipher modes48587 +Node: Keyed hash functions54929 +Node: Public-key algorithms63350 +Node: RSA67262 +Node: RSA-Footnotes77826 +Ref: RSA-Footnote-177879 +Node: DSA78048 +Node: Randomness89349 +Node: Miscellaneous functions104428 +Node: Compatibility functions104923 +Node: Nettle soup106160 +Node: Installation107149 +Node: Index107992 + +End Tag Table diff --git a/nettle.manifest b/nettle.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/nettle.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/nettle.pdf b/nettle.pdf new file mode 100644 index 0000000..6c20a77 Binary files /dev/null and b/nettle.pdf differ diff --git a/nettle.texinfo b/nettle.texinfo new file mode 100644 index 0000000..f994942 --- /dev/null +++ b/nettle.texinfo @@ -0,0 +1,2744 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename nettle.info +@settitle Nettle: a low-level cryptographic library +@documentencoding ISO-8859-1 +@footnotestyle separate +@syncodeindex fn cp +@c %**end of header + +@set UPDATED-FOR 2.1 +@set AUTHOR Niels Möller + +@copying +This manual is for the Nettle library (version @value{UPDATED-FOR}), a +low-level cryptographic library. + +Originally written 2001 by @value{AUTHOR}, updated 2010. + +@quotation +This manual is placed in the public domain. You may freely copy it, in +whole or in part, with or without modification. Attribution is +appreciated, but not required. +@end quotation +@end copying + +@titlepage +@title Nettle Manual +@subtitle For the Nettle Library version @value{UPDATED-FOR} +@author @value{AUTHOR} +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@dircategory Encryption +@direntry +* Nettle: (nettle). A low-level cryptographic library. +@end direntry + +@contents + +@ifnottex +@node Top, Introduction, (dir), (dir) +@comment node-name, next, previous, up +@top Nettle + +This document describes the Nettle low-level cryptographic library. You +can use the library directly from your C programs, or write or use an +object-oriented wrapper for your favorite language or application. + +@insertcopying + +@menu +* Introduction:: What is Nettle? +* Copyright:: Your rights. +* Conventions:: General interface conventions. +* Example:: An example program. +* Linking:: Linking with the libnettle and libhogweed. +* Reference:: All Nettle functions and features. +* Nettle soup:: For the serious nettle hacker. +* Installation:: How to install Nettle. +* Index:: Function and concept index. +@end menu + +@end ifnottex + +@node Introduction, Copyright, Top, Top +@comment node-name, next, previous, up +@chapter Introduction + +Nettle is a cryptographic library that is designed to fit easily in more +or less any context: In crypto toolkits for object-oriented languages +(C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in +kernel space. In most contexts, you need more than the basic +cryptographic algorithms, you also need some way to keep track of available +algorithms, their properties and variants. You often have some algorithm +selection process, often dictated by a protocol you want to implement. + +And as the requirements of applications differ in subtle and not so +subtle ways, an API that fits one application well can be a pain to use +in a different context. And that is why there are so many different +cryptographic libraries around. + +Nettle tries to avoid this problem by doing one thing, the low-level +crypto stuff, and providing a @emph{simple} but general interface to it. +In particular, Nettle doesn't do algorithm selection. It doesn't do +memory allocation. It doesn't do any I/O. + +The idea is that one can build several application and context specific +interfaces on top of Nettle, and share the code, test cases, benchmarks, +documentation, etc. Examples are the Nettle module for the Pike +language, and LSH, which both use an object-oriented abstraction on top +of the library. + +This manual explains how to use the Nettle library. It also tries to +provide some background on the cryptography, and advice on how to best +put it to use. + +@node Copyright, Conventions, Introduction, Top +@comment node-name, next, previous, up +@chapter Copyright + +Nettle is distributed under the GNU General Public License (GPL) (see +the file COPYING for details). However, most of the individual files +are dual licensed under less restrictive licenses like the GNU Lesser +General Public License (LGPL), or are in the public domain. This means +that if you don't use the parts of nettle that are GPL-only, you have +the option to use the Nettle library just as if it were licensed under +the LGPL. To find the current status of particular files, you have to +read the copyright notices at the top of the files. + +This manual is in the public domain. You may freely copy it in whole or +in part, e.g., into documentation of programs that build on Nettle. +Attribution, as well as contribution of improvements to the text, is of +course appreciated, but it is not required. + +A list of the supported algorithms, their origins and licenses: + +@table @emph +@item AES +The implementation of the AES cipher (also known as rijndael) is written +by Rafael Sevilla. Assembler for x86 by Rafael Sevilla and +@value{AUTHOR}, Sparc assembler by @value{AUTHOR}. Released under the +LGPL. + +@item ARCFOUR +The implementation of the ARCFOUR (also known as RC4) cipher is written +by @value{AUTHOR}. Released under the LGPL. + +@item ARCTWO +The implementation of the ARCTWO (also known as RC2) cipher is written +by Nikos Mavroyanopoulos and modified by Werner Koch and Simon +Josefsson. Released under the LGPL. + +@item BLOWFISH +The implementation of the BLOWFISH cipher is written by Werner Koch, +copyright owned by the Free Software Foundation. Also hacked by Ray +Dassen and @value{AUTHOR}. Released under the GPL. + +@item CAMELLIA +The C implementation is by Nippon Telegraph and Telephone Corporation +(NTT), heavily modified by @value{AUTHOR}. Assembler for x86 by +@value{AUTHOR}. Released under the LGPL. + +@item CAST128 +The implementation of the CAST128 cipher is written by Steve Reid. +Released into the public domain. + +@item DES +The implementation of the DES cipher is written by Dana L. How, and +released under the LGPL. + +@item MD2 +The implementation of MD2 is written by Andrew Kuchling, and hacked +some by Andreas Sigfridsson and @value{AUTHOR}. Python Cryptography +Toolkit license (essentially public domain). + +@item MD4 +This is almost the same code as for MD5 below, with modifications by +Marcus Comstedt. Released into the public domain. + +@item MD5 +The implementation of the MD5 message digest is written by Colin Plumb. +It has been hacked some more by Andrew Kuchling and @value{AUTHOR}. +Released into the public domain. + +@item SERPENT +The implementation of the SERPENT cipher is written by Ross Anderson, +Eli Biham, and Lars Knudsen, adapted to LSH by Rafael Sevilla, and to +Nettle by @value{AUTHOR}. Released under the GPL. + +@item SHA1 +The C implementation of the SHA1 message digest is written by Peter +Gutmann, and hacked some more by Andrew Kuchling and @value{AUTHOR}. +Released into the public domain. Assembler for x86 by @value{AUTHOR}, +released under the LGPL. + +@item SHA224, SHA256, SHA384, and SHA512 +Written by @value{AUTHOR}, using Peter Gutmann's SHA1 code as a model. +Released under the LGPL. + +@item TWOFISH +The implementation of the TWOFISH cipher is written by Ruud de Rooij. +Released under the LGPL. + +@item RSA +Written by @value{AUTHOR}, released under the LGPL. Uses the GMP library +for bignum operations. + +@item DSA +Written by @value{AUTHOR}, released under the LGPL. Uses the GMP library +for bignum operations. +@end table + +@node Conventions, Example, Copyright, Top +@comment node-name, next, previous, up +@chapter Conventions + +For each supported algorithm, there is an include file that defines a +@emph{context struct}, a few constants, and declares functions for +operating on the context. The context struct encapsulates all information +needed by the algorithm, and it can be copied or moved in memory with no +unexpected effects. + +For consistency, functions for different algorithms are very similar, +but there are some differences, for instance reflecting if the key setup +or encryption function differ for encryption and decryption, and whether +or not key setup can fail. There are also differences between algorithms +that don't show in function prototypes, but which the application must +nevertheless be aware of. There is no big difference between the +functions for stream ciphers and for block ciphers, although they should +be used quite differently by the application. + +If your application uses more than one algorithm of the same type, you +should probably create an interface that is tailor-made for your needs, +and then write a few lines of glue code on top of Nettle. + +By convention, for an algorithm named @code{foo}, the struct tag for the +context struct is @code{foo_ctx}, constants and functions uses prefixes +like @code{FOO_BLOCK_SIZE} (a constant) and @code{foo_set_key} (a +function). + +In all functions, strings are represented with an explicit length, of +type @code{unsigned}, and a pointer of type @code{uint8_t *} or +@code{const uint8_t *}. For functions that transform one string to +another, the argument order is length, destination pointer and source +pointer. Source and destination areas are of the same length. Source and +destination may be the same, so that you can process strings in place, +but they @emph{must not} overlap in any other way. + +Many of the functions lack return value and can never fail. Those +functions which can fail, return one on success and zero on failure. + +@c FIXME: Say something about the name mangling. + +@node Example, Linking, Conventions, Top +@comment node-name, next, previous, up +@chapter Example + +A simple example program that reads a file from standard input and +writes its SHA1 checksum on standard output should give the flavor of +Nettle. + +@example +@verbatiminclude sha-example.c +@end example + +On a typical Unix system, this program can be compiled and linked with +the command line +@example +cc sha-example.c -o sha-example -lnettle +@end example + +@node Linking, Reference, Example, Top +@comment node-name, next, previous, up +@chapter Linking + +Nettle actually consists of two libraries, @file{libnettle} and +@file{libhogweed}. The @file{libhogweed} library contains those +functions of Nettle that uses bignum operations, and depends on the GMP +library. With this division, linking works the same for both static and +dynamic libraries. + +If an application uses only the symmetric crypto algorithms of Nettle +(i.e., block ciphers, hash functions, and the like), it's sufficient to +link with @code{-lnettle}. If an application also uses public-key +algorithms, the recommended linker flags are @code{-lhogweed -lnettle +-lgmp}. If the involved libraries are installed as dynamic libraries, it +may be sufficient to link with just @code{-lhogweed}, and the loader +will resolve the dependencies automatically. + +@node Reference, Nettle soup, Linking, Top +@comment node-name, next, previous, up +@chapter Reference + +This chapter describes all the Nettle functions, grouped by family. + +@menu +* Hash functions:: +* Cipher functions:: +* Cipher modes:: +* Keyed hash functions:: +* Public-key algorithms:: +* Randomness:: +* Miscellaneous functions:: +* Compatibility functions:: +@end menu + +@node Hash functions, Cipher functions, Reference, Reference +@comment node-name, next, previous, up +@section Hash functions +@cindex Hash function +A cryptographic @dfn{hash function} is a function that takes variable +size strings, and maps them to strings of fixed, short, length. There +are naturally lots of collisions, as there are more possible 1MB files +than 20 byte strings. But the function is constructed such that is hard +to find the collisions. More precisely, a cryptographic hash function +@code{H} should have the following properties: + +@table @emph + +@item One-way +@cindex One-way +Given a hash value @code{H(x)} it is hard to find a string @code{x} +that hashes to that value. + +@item Collision-resistant +@cindex Collision-resistant +It is hard to find two different strings, @code{x} and @code{y}, such +that @code{H(x)} = @code{H(y)}. + +@end table + +Hash functions are useful as building blocks for digital signatures, +message authentication codes, pseudo random generators, association of +unique ids to documents, and many other things. + +The most commonly used hash functions are MD5 and SHA1. Unfortunately, +both these fail the collision-resistance requirement; cryptologists have +found ways to construct colliding inputs. The recommended hash function +for new applications is SHA256, even though it uses a structure similar +to MD5 and SHA1. Constructing better hash functions is an urgent research +problem. + +@subsection @acronym{MD5} + +MD5 is a message digest function constructed by Ronald Rivest, and +described in @cite{RFC 1321}. It outputs message digests of 128 bits, or +16 octets. Nettle defines MD5 in @file{}. + +@deftp {Context struct} {struct md5_ctx} +@end deftp + +@defvr Constant MD5_DIGEST_SIZE +The size of an MD5 digest, i.e. 16. +@end defvr + +@defvr Constant MD5_DATA_SIZE +The internal block size of MD5. Useful for some special constructions, +in particular HMAC-MD5. +@end defvr + +@deftypefun void md5_init (struct md5_ctx *@var{ctx}) +Initialize the MD5 state. +@end deftypefun + +@deftypefun void md5_update (struct md5_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void md5_digest (struct md5_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{MD5_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{md5_init}. +@end deftypefun + +The normal way to use MD5 is to call the functions in order: First +@code{md5_init}, then @code{md5_update} zero or more times, and finally +@code{md5_digest}. After @code{md5_digest}, the context is reset to +its initial state, so you can start over calling @code{md5_update} to +hash new data. + +To start over, you can call @code{md5_init} at any time. + +@subsection @acronym{MD2} + +MD2 is another hash function of Ronald Rivest's, described in +@cite{RFC 1319}. It outputs message digests of 128 bits, or 16 octets. +Nettle defines MD2 in @file{}. + +@deftp {Context struct} {struct md2_ctx} +@end deftp + +@defvr Constant MD2_DIGEST_SIZE +The size of an MD2 digest, i.e. 16. +@end defvr + +@defvr Constant MD2_DATA_SIZE +The internal block size of MD2. +@end defvr + +@deftypefun void md2_init (struct md2_ctx *@var{ctx}) +Initialize the MD2 state. +@end deftypefun + +@deftypefun void md2_update (struct md2_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void md2_digest (struct md2_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{MD2_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{md2_init}. +@end deftypefun + +@subsection @acronym{MD4} + +MD4 is a predecessor of MD5, described in @cite{RFC 1320}. Like MD5, it +is constructed by Ronald Rivest. It outputs message digests of 128 bits, +or 16 octets. Nettle defines MD4 in @file{}. Use of MD4 is +not recommended, but it is sometimes needed for compatibility with +existing applications and protocols. + +@deftp {Context struct} {struct md4_ctx} +@end deftp + +@defvr Constant MD4_DIGEST_SIZE +The size of an MD4 digest, i.e. 16. +@end defvr + +@defvr Constant MD4_DATA_SIZE +The internal block size of MD4. +@end defvr + +@deftypefun void md4_init (struct md4_ctx *@var{ctx}) +Initialize the MD4 state. +@end deftypefun + +@deftypefun void md4_update (struct md4_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void md4_digest (struct md4_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{MD4_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{md4_init}. +@end deftypefun + +@subsection @acronym{SHA1} + +SHA1 is a hash function specified by @dfn{NIST} (The U.S. National Institute +for Standards and Technology). It outputs hash values of 160 bits, or 20 +octets. Nettle defines SHA1 in @file{}. + +The functions are analogous to the MD5 ones. + +@deftp {Context struct} {struct sha1_ctx} +@end deftp + +@defvr Constant SHA1_DIGEST_SIZE +The size of an SHA1 digest, i.e. 20. +@end defvr + +@defvr Constant SHA1_DATA_SIZE +The internal block size of SHA1. Useful for some special constructions, +in particular HMAC-SHA1. +@end defvr + +@deftypefun void sha1_init (struct sha1_ctx *@var{ctx}) +Initialize the SHA1 state. +@end deftypefun + +@deftypefun void sha1_update (struct sha1_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void sha1_digest (struct sha1_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{SHA1_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{sha1_init}. +@end deftypefun + +@subsection @acronym{SHA256} + +SHA256 is another hash function specified by @dfn{NIST}, intended as a +replacement for @acronym{SHA1}, generating larger digests. It outputs +hash values of 256 bits, or 32 octets. Nettle defines SHA256 in +@file{}. + +The functions are analogous to the MD5 ones. + +@deftp {Context struct} {struct sha256_ctx} +@end deftp + +@defvr Constant SHA256_DIGEST_SIZE +The size of an SHA256 digest, i.e. 32. +@end defvr + +@defvr Constant SHA256_DATA_SIZE +The internal block size of SHA256. Useful for some special constructions, +in particular HMAC-SHA256. +@end defvr + +@deftypefun void sha256_init (struct sha256_ctx *@var{ctx}) +Initialize the SHA256 state. +@end deftypefun + +@deftypefun void sha256_update (struct sha256_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void sha256_digest (struct sha256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{SHA256_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{sha256_init}. +@end deftypefun + +@subsection @acronym{SHA224} + +SHA224 is a variant of SHA256, with a different initial state, and with +the output truncated to 224 bits, or 28 octets. Nettle defines SHA224 in +@file{}. + +The functions are analogous to the MD5 ones. + +@deftp {Context struct} {struct sha224_ctx} +@end deftp + +@defvr Constant SHA224_DIGEST_SIZE +The size of an SHA224 digest, i.e. 28. +@end defvr + +@defvr Constant SHA224_DATA_SIZE +The internal block size of SHA224. Useful for some special constructions, +in particular HMAC-SHA224. +@end defvr + +@deftypefun void sha224_init (struct sha224_ctx *@var{ctx}) +Initialize the SHA224 state. +@end deftypefun + +@deftypefun void sha224_update (struct sha224_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void sha224_digest (struct sha224_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{SHA224_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{sha224_init}. +@end deftypefun + +@subsection @acronym{SHA512} + +SHA512 is a larger sibling to SHA256, with a very similar structure but +with both the output and the internal variables of twice the size. The +internal variables are 64 bits rather than 32, making it significantly +slower on 32-bit computers. It outputs hash values of 512 bits, or 64 +octets. Nettle defines SHA512 in @file{}. + +The functions are analogous to the MD5 ones. + +@deftp {Context struct} {struct sha512_ctx} +@end deftp + +@defvr Constant SHA512_DIGEST_SIZE +The size of an SHA512 digest, i.e. 64. +@end defvr + +@defvr Constant SHA512_DATA_SIZE +The internal block size of SHA512. Useful for some special constructions, +in particular HMAC-SHA512. +@end defvr + +@deftypefun void sha512_init (struct sha512_ctx *@var{ctx}) +Initialize the SHA512 state. +@end deftypefun + +@deftypefun void sha512_update (struct sha512_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void sha512_digest (struct sha512_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{SHA512_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{sha512_init}. +@end deftypefun + +@subsection @acronym{SHA384} + +SHA384 is a variant of SHA512, with a different initial state, and with +the output truncated to 384 bits, or 48 octets. Nettle defines SHA384 in +@file{}. + +The functions are analogous to the MD5 ones. + +@deftp {Context struct} {struct sha384_ctx} +@end deftp + +@defvr Constant SHA384_DIGEST_SIZE +The size of an SHA384 digest, i.e. 48. +@end defvr + +@defvr Constant SHA384_DATA_SIZE +The internal block size of SHA384. Useful for some special constructions, +in particular HMAC-SHA384. +@end defvr + +@deftypefun void sha384_init (struct sha384_ctx *@var{ctx}) +Initialize the SHA384 state. +@end deftypefun + +@deftypefun void sha384_update (struct sha384_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Hash some more data. +@end deftypefun + +@deftypefun void sha384_digest (struct sha384_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Performs final processing and extracts the message digest, writing it +to @var{digest}. @var{length} may be smaller than +@code{SHA384_DIGEST_SIZE}, in which case only the first @var{length} +octets of the digest are written. + +This function also resets the context in the same way as +@code{sha384_init}. +@end deftypefun + +@subsection @code{struct nettle_hash} + +Nettle includes a struct including information about the supported hash +functions. It is defined in @file{}, and is used +by Nettle's implementation of @acronym{HMAC} @pxref{Keyed hash +functions}. + +@deftp {Meta struct} @code{struct nettle_hash} name context_size digest_size block_size init update digest +The last three attributes are function pointers, of types +@code{nettle_hash_init_func}, @code{nettle_hash_update_func}, and +@code{nettle_hash_digest_func}. The first argument to these functions is +@code{void *} pointer to a context struct, which is of size +@code{context_size}. +@end deftp + +@deftypevr {Constant Struct} {struct nettle_hash} nettle_md2 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_md4 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_md5 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha1 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha224 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha256 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha384 +@deftypevrx {Constant Struct} {struct nettle_hash} nettle_sha512 + +These are all the hash functions that Nettle implements. +@end deftypevr + +@node Cipher functions, Cipher modes, Hash functions, Reference +@comment node-name, next, previous, up +@section Cipher functions +@cindex Cipher + +A @dfn{cipher} is a function that takes a message or @dfn{plaintext} +and a secret @dfn{key} and transforms it to a @dfn{ciphertext}. Given +only the ciphertext, but not the key, it should be hard to find the +plaintext. Given matching pairs of plaintext and ciphertext, it should +be hard to find the key. + +@cindex Block Cipher +@cindex Stream Cipher + +There are two main classes of ciphers: Block ciphers and stream ciphers. + +A block cipher can process data only in fixed size chunks, called +@dfn{blocks}. Typical block sizes are 8 or 16 octets. To encrypt +arbitrary messages, you usually have to pad it to an integral number of +blocks, split it into blocks, and then process each block. The simplest +way is to process one block at a time, independent of each other. That +mode of operation is called @dfn{ECB}, Electronic Code Book mode. +However, using @acronym{ECB} is usually a bad idea. For a start, plaintext blocks +that are equal are transformed to ciphertext blocks that are equal; that +leaks information about the plaintext. Usually you should apply the +cipher is some ``feedback mode'', @dfn{CBC} (Cipher Block Chaining) and +@dfn{CTR} (Counter mode) being two of +of the most popular. See @xref{Cipher modes}, for information on +how to apply @acronym{CBC} and @acronym{CTR} with Nettle. + +A stream cipher can be used for messages of arbitrary length. A typical +stream cipher is a keyed pseudo-random generator. To encrypt a plaintext +message of @var{n} octets, you key the generator, generate @var{n} +octets of pseudo-random data, and XOR it with the plaintext. To decrypt, +regenerate the same stream using the key, XOR it to the ciphertext, and +the plaintext is recovered. + +@strong{Caution:} The first rule for this kind of cipher is the +same as for a One Time Pad: @emph{never} ever use the same key twice. + +A common misconception is that encryption, by itself, implies +authentication. Say that you and a friend share a secret key, and you +receive an encrypted message. You apply the key, and get a plaintext +message that makes sense to you. Can you then be sure that it really was +your friend that wrote the message you're reading? The answer is no. For +example, if you were using a block cipher in ECB mode, an attacker may +pick up the message on its way, and reorder, delete or repeat some of +the blocks. Even if the attacker can't decrypt the message, he can +change it so that you are not reading the same message as your friend +wrote. If you are using a block cipher in @acronym{CBC} mode rather than +ECB, or are using a stream cipher, the possibilities for this sort of +attack are different, but the attacker can still make predictable +changes to the message. + +It is recommended to @emph{always} use an authentication mechanism in +addition to encrypting the messages. Popular choices are Message +Authentication Codes like @acronym{HMAC-SHA1} @pxref{Keyed hash +functions}, or digital signatures like @acronym{RSA}. + +Some ciphers have so called ``weak keys'', keys that results in +undesirable structure after the key setup processing, and should be +avoided. In Nettle, most key setup functions have no return value, but +for ciphers with weak keys, the return value indicates whether or not +the given key is weak. For good keys, key setup returns 1, and for weak +keys, it returns 0. When possible, avoid algorithms that +have weak keys. There are several good ciphers that don't have any weak +keys. + +To encrypt a message, you first initialize a cipher context for +encryption or decryption with a particular key. You then use the context +to process plaintext or ciphertext messages. The initialization is known +as @dfn{key setup}. With Nettle, it is recommended to use each +context struct for only one direction, even if some of the ciphers use a +single key setup function that can be used for both encryption and +decryption. + +@subsection AES +AES is a block cipher, specified by NIST as a replacement for +the older DES standard. The standard is the result of a competition +between cipher designers. The winning design, also known as RIJNDAEL, +was constructed by Joan Daemen and Vincent Rijnmen. + +Like all the AES candidates, the winning design uses a block size of 128 +bits, or 16 octets, and variable key-size, 128, 192 and 256 bits (16, 24 +and 32 octets) being the allowed key sizes. It does not have any weak +keys. Nettle defines AES in @file{}. + +@deftp {Context struct} {struct aes_ctx} +@end deftp + +@defvr Constant AES_BLOCK_SIZE +The AES block-size, 16 +@end defvr + +@defvr Constant AES_MIN_KEY_SIZE +@end defvr + +@defvr Constant AES_MAX_KEY_SIZE +@end defvr + +@defvr Constant AES_KEY_SIZE +Default AES key size, 32 +@end defvr + +@deftypefun void aes_set_encrypt_key (struct aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +@deftypefunx void aes_set_decrypt_key (struct aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher, for encryption or decryption, respectively. +@end deftypefun + +@deftypefun void aes_invert_key (struct aes_ctx *@var{dst}, const struct aes_ctx *@var{src}) +Given a context @var{src} initialized for encryption, initializes the +context struct @var{dst} for decryption, using the same key. If the same +context struct is passed for both @code{src} and @code{dst}, it is +converted in place. Calling @code{aes_set_encrypt_key} and +@code{aes_invert_key} is more efficient than calling +@code{aes_set_encrypt_key} and @code{aes_set_decrypt_key}. This function +is mainly useful for applications which needs to both encrypt and +decrypt using the @emph{same} key. +@end deftypefun + +@deftypefun void aes_encrypt (struct aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void aes_decrypt (struct aes_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{aes_encrypt} +@end deftypefun + +@subsection ARCFOUR +ARCFOUR is a stream cipher, also known under the trade marked name RC4, +and it is one of the fastest ciphers around. A problem is that the key +setup of ARCFOUR is quite weak, you should never use keys with +structure, keys that are ordinary passwords, or sequences of keys like +``secret:1'', ``secret:2'', @enddots{}. If you have keys that don't look +like random bit strings, and you want to use ARCFOUR, always hash the +key before feeding it to ARCFOUR. Furthermore, the initial bytes of the +generated key stream leak information about the key; for this reason, it +is recommended to discard the first 512 bytes of the key stream. + +@example +/* A more robust key setup function for ARCFOUR */ +void +arcfour_set_key_hashed(struct arcfour_ctx *ctx, + unsigned length, const uint8_t *key) +@{ + struct sha256_ctx hash; + uint8_t digest[SHA256_DIGEST_SIZE]; + uint8_t buffer[0x200]; + + sha256_init(&hash); + sha256_update(&hash, length, key); + sha256_digest(&hash, SHA256_DIGEST_SIZE, digest); + + arcfour_set_key(ctx, SHA256_DIGEST_SIZE, digest); + arcfour_crypt(ctx, sizeof(buffer), buffer, buffer); +@} +@end example + +Nettle defines ARCFOUR in @file{}. + +@deftp {Context struct} {struct arcfour_ctx} +@end deftp + +@defvr Constant ARCFOUR_MIN_KEY_SIZE +Minimum key size, 1 +@end defvr + +@defvr Constant ARCFOUR_MAX_KEY_SIZE +Maximum key size, 256 +@end defvr + +@defvr Constant ARCFOUR_KEY_SIZE +Default ARCFOUR key size, 16 +@end defvr + +@deftypefun void arcfour_set_key (struct arcfour_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. +@end deftypefun + +@deftypefun void arcfour_crypt (struct arcfour_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encrypt some data. The same function is used for both encryption and +decryption. Unlike the block ciphers, this function modifies the +context, so you can split the data into arbitrary chunks and encrypt +them one after another. The result is the same as if you had called +@code{arcfour_crypt} only once with all the data. +@end deftypefun + +@subsection ARCTWO +ARCTWO (also known as the trade marked name RC2) is a block cipher +specified in RFC 2268. Nettle also include a variation of the ARCTWO +set key operation that lack one step, to be compatible with the +reverse engineered RC2 cipher description, as described in a Usenet +post to @code{sci.crypt} by Peter Gutmann. + +ARCTWO uses a block size of 64 bits, and variable key-size ranging +from 1 to 128 octets. Besides the key, ARCTWO also has a second +parameter to key setup, the number of effective key bits, @code{ekb}. +This parameter can be used to artificially reduce the key size. In +practice, @code{ekb} is usually set equal to the input key size. +Nettle defines ARCTWO in @file{}. + +We do not recommend the use of ARCTWO; the Nettle implementation is +provided primarily for interoperability with existing applications and +standards. + +@deftp {Context struct} {struct arctwo_ctx} +@end deftp + +@defvr Constant ARCTWO_BLOCK_SIZE +The AES block-size, 8 +@end defvr + +@defvr Constant ARCTWO_MIN_KEY_SIZE +@end defvr + +@defvr Constant ARCTWO_MAX_KEY_SIZE +@end defvr + +@defvr Constant ARCTWO_KEY_SIZE +Default ARCTWO key size, 8 +@end defvr + +@deftypefun void arctwo_set_key_ekb (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}, unsigned @var{ekb}) +@deftypefunx void arctwo_set_key (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +@deftypefunx void arctwo_set_key_gutmann (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption +and decryption. The first function is the most general one, which lets +you provide both the variable size key, and the desired effective key +size (in bits). The maximum value for @var{ekb} is 1024, and for +convenience, @code{ekb = 0} has the same effect as @code{ekb = 1024}. + +@code{arctwo_set_key(ctx, length, key)} is equivalent to +@code{arctwo_set_key_ekb(ctx, length, key, 8*length)}, and +@code{arctwo_set_key_gutmann(ctx, length, key)} is equivalent to +@code{arctwo_set_key_ekb(ctx, length, key, 1024)} +@end deftypefun + +@deftypefun void arctwo_encrypt (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not +overlap in any other way. +@end deftypefun + +@deftypefun void arctwo_decrypt (struct arctwo_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{arctwo_encrypt} +@end deftypefun + +@subsection BLOWFISH + +BLOWFISH is a block cipher designed by Bruce Schneier. It uses a block +size of 64 bits (8 octets), and a variable key size, up to 448 bits. It +has some weak keys. Nettle defines BLOWFISH in @file{}. + +@deftp {Context struct} {struct blowfish_ctx} +@end deftp + +@defvr Constant BLOWFISH_BLOCK_SIZE +The BLOWFISH block-size, 8 +@end defvr + +@defvr Constant BLOWFISH_MIN_KEY_SIZE +Minimum BLOWFISH key size, 8 +@end defvr + +@defvr Constant BLOWFISH_MAX_KEY_SIZE +Maximum BLOWFISH key size, 56 +@end defvr + +@defvr Constant BLOWFISH_KEY_SIZE +Default BLOWFISH key size, 16 +@end defvr + +@deftypefun int blowfish_set_key (struct blowfish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. Checks for weak keys, returning 1 +for good keys and 0 for weak keys. Applications that don't care about +weak keys can ignore the return value. + +@code{blowfish_encrypt} or @code{blowfish_decrypt} with a weak key will +crash with an assert violation. +@end deftypefun + +@deftypefun void blowfish_encrypt (struct blowfish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void blowfish_decrypt (struct blowfish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{blowfish_encrypt} +@end deftypefun + +@subsection Camellia + +Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph +and Telephone Corporation, described in @cite{RFC3713}, and recommended +by some Japanese and European authorities as an alternative to AES. The +algorithm is patented. The implementation in Nettle is derived from the +implementation released by NTT under the GNU LGPL (v2.1 or later), and +relies on the implicit patent license of the LGPL. There is also a +statement of royalty-free licensing for Camellia at +@url{http://www.ntt.co.jp/news/news01e/0104/010417.html}, but this +statement has some limitations which seem problematic for free software. + +Camellia uses a the same block size and key sizes as AES: The block size +is 128 bits (16 octets), and the supported key sizes are 128, 192, and +256 bits. Nettle defines Camellia in @file{}. + +@deftp {Context struct} {struct camellia_ctx} +@end deftp + +@defvr Constant CAMELLIA_BLOCK_SIZE +The CAMELLIA block-size, 16 +@end defvr + +@defvr Constant CAMELLIA_MIN_KEY_SIZE +@end defvr + +@defvr Constant CAMELLIA_MAX_KEY_SIZE +@end defvr + +@defvr Constant CAMELLIA_KEY_SIZE +Default CAMELLIA key size, 32 +@end defvr + +@deftypefun void camellia_set_encrypt_key (struct camellia_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +@deftypefunx void camellia_set_decrypt_key (struct camellia_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher, for encryption or decryption, respectively. +@end deftypefun + +@deftypefun void camellia_invert_key (struct camellia_ctx *@var{dst}, const struct camellia_ctx *@var{src}) +Given a context @var{src} initialized for encryption, initializes the +context struct @var{dst} for decryption, using the same key. If the same +context struct is passed for both @code{src} and @code{dst}, it is +converted in place. Calling @code{camellia_set_encrypt_key} and +@code{camellia_invert_key} is more efficient than calling +@code{camellia_set_encrypt_key} and @code{camellia_set_decrypt_key}. This function +is mainly useful for applications which needs to both encrypt and +decrypt using the @emph{same} key. +@end deftypefun + +@deftypefun void camellia_crypt (struct camellia_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +The same function is used for both encryption and decryption. +@var{length} must be an integral multiple of the block size. If it is +more than one block, the data is processed in ECB mode. @code{src} and +@code{dst} may be equal, but they must not overlap in any other way. +@end deftypefun + +@subsection CAST128 + +CAST-128 is a block cipher, specified in @cite{RFC 2144}. It uses a 64 +bit (8 octets) block size, and a variable key size of up to 128 bits. +Nettle defines cast128 in @file{}. + +@deftp {Context struct} {struct cast128_ctx} +@end deftp + +@defvr Constant CAST128_BLOCK_SIZE +The CAST128 block-size, 8 +@end defvr + +@defvr Constant CAST128_MIN_KEY_SIZE +Minimum CAST128 key size, 5 +@end defvr + +@defvr Constant CAST128_MAX_KEY_SIZE +Maximum CAST128 key size, 16 +@end defvr + +@defvr Constant CAST128_KEY_SIZE +Default CAST128 key size, 16 +@end defvr + +@deftypefun void cast128_set_key (struct cast128_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. +@end deftypefun + +@deftypefun void cast128_encrypt (struct cast128_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void cast128_decrypt (struct cast128_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{cast128_encrypt} +@end deftypefun + +@subsection DES +DES is the old Data Encryption Standard, specified by NIST. It uses a +block size of 64 bits (8 octets), and a key size of 56 bits. However, +the key bits are distributed over 8 octets, where the least significant +bit of each octet may be used for parity. A common way to use DES is to +generate 8 random octets in some way, then set the least significant bit +of each octet to get odd parity, and initialize DES with the resulting +key. + +The key size of DES is so small that keys can be found by brute force, +using specialized hardware or lots of ordinary work stations in +parallel. One shouldn't be using plain DES at all today, if one uses +DES at all one should be using ``triple DES'', see DES3 below. + +DES also has some weak keys. Nettle defines DES in @file{}. + +@deftp {Context struct} {struct des_ctx} +@end deftp + +@defvr Constant DES_BLOCK_SIZE +The DES block-size, 8 +@end defvr + +@defvr Constant DES_KEY_SIZE +DES key size, 8 +@end defvr + +@deftypefun int des_set_key (struct des_ctx *@var{ctx}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. Parity bits are ignored. Checks for weak keys, returning 1 +for good keys and 0 for weak keys. Applications that don't care about +weak keys can ignore the return value. +@end deftypefun + +@deftypefun void des_encrypt (struct des_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void des_decrypt (struct des_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{des_encrypt} +@end deftypefun + +@deftypefun int des_check_parity (unsigned @var{length}, const uint8_t *@var{key}); +Checks that the given key has correct, odd, parity. Returns 1 for +correct parity, and 0 for bad parity. +@end deftypefun + +@deftypefun void des_fix_parity (unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +Adjusts the parity bits to match DES's requirements. You need this +function if you have created a random-looking string by a key agreement +protocol, and want to use it as a DES key. @var{dst} and @var{src} may +be equal. +@end deftypefun + +@subsection DES3 +The inadequate key size of DES has already been mentioned. One way to +increase the key size is to pipe together several DES boxes with +independent keys. It turns out that using two DES ciphers is not as +secure as one might think, even if the key size of the combination is a +respectable 112 bits. + +The standard way to increase DES's key size is to use three DES boxes. +The mode of operation is a little peculiar: the middle DES box is wired +in the reverse direction. To encrypt a block with DES3, you encrypt it +using the first 56 bits of the key, then @emph{decrypt} it using the +middle 56 bits of the key, and finally encrypt it again using the last +56 bits of the key. This is known as ``ede'' triple-DES, for +``encrypt-decrypt-encrypt''. + +The ``ede'' construction provides some backward compatibility, as you get +plain single DES simply by feeding the same key to all three boxes. That +should help keeping down the gate count, and the price, of hardware +circuits implementing both plain DES and DES3. + +DES3 has a key size of 168 bits, but just like plain DES, useless parity +bits are inserted, so that keys are represented as 24 octets (192 bits). +As a 112 bit key is large enough to make brute force attacks +impractical, some applications uses a ``two-key'' variant of triple-DES. +In this mode, the same key bits are used for the first and the last DES +box in the pipe, while the middle box is keyed independently. The +two-key variant is believed to be secure, i.e. there are no known +attacks significantly better than brute force. + +Naturally, it's simple to implement triple-DES on top of Nettle's DES +functions. Nettle includes an implementation of three-key ``ede'' +triple-DES, it is defined in the same place as plain DES, +@file{}. + +@deftp {Context struct} {struct des3_ctx} +@end deftp + +@defvr Constant DES3_BLOCK_SIZE +The DES3 block-size is the same as DES_BLOCK_SIZE, 8 +@end defvr + +@defvr Constant DES3_KEY_SIZE +DES key size, 24 +@end defvr + +@deftypefun int des3_set_key (struct des3_ctx *@var{ctx}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. Parity bits are ignored. Checks for weak keys, returning 1 +if all three keys are good keys, and 0 if one or more key is weak. +Applications that don't care about weak keys can ignore the return +value. +@end deftypefun + +For random-looking strings, you can use @code{des_fix_parity} to adjust +the parity bits before calling @code{des3_set_key}. + +@deftypefun void des3_encrypt (struct des3_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void des3_decrypt (struct des3_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{des_encrypt} +@end deftypefun + +@subsection SERPENT +SERPENT is one of the AES finalists, designed by Ross Anderson, Eli +Biham and Lars Knudsen. Thus, the interface and properties are similar +to AES'. One peculiarity is that it is quite pointless to use it with +anything but the maximum key size, smaller keys are just padded to +larger ones. Nettle defines SERPENT in @file{}. + +@deftp {Context struct} {struct serpent_ctx} +@end deftp + +@defvr Constant SERPENT_BLOCK_SIZE +The SERPENT block-size, 16 +@end defvr + +@defvr Constant SERPENT_MIN_KEY_SIZE +Minimum SERPENT key size, 16 +@end defvr + +@defvr Constant SERPENT_MAX_KEY_SIZE +Maximum SERPENT key size, 32 +@end defvr + +@defvr Constant SERPENT_KEY_SIZE +Default SERPENT key size, 32 +@end defvr + +@deftypefun void serpent_set_key (struct serpent_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. +@end deftypefun + +@deftypefun void serpent_encrypt (struct serpent_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void serpent_decrypt (struct serpent_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{serpent_encrypt} +@end deftypefun + + +@subsection TWOFISH +Another AES finalist, this one designed by Bruce Schneier and others. +Nettle defines it in @file{}. + +@deftp {Context struct} {struct twofish_ctx} +@end deftp + +@defvr Constant TWOFISH_BLOCK_SIZE +The TWOFISH block-size, 16 +@end defvr + +@defvr Constant TWOFISH_MIN_KEY_SIZE +Minimum TWOFISH key size, 16 +@end defvr + +@defvr Constant TWOFISH_MAX_KEY_SIZE +Maximum TWOFISH key size, 32 +@end defvr + +@defvr Constant TWOFISH_KEY_SIZE +Default TWOFISH key size, 32 +@end defvr + +@deftypefun void twofish_set_key (struct twofish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{key}) +Initialize the cipher. The same function is used for both encryption and +decryption. +@end deftypefun + +@deftypefun void twofish_encrypt (struct twofish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Encryption function. @var{length} must be an integral multiple of the +block size. If it is more than one block, the data is processed in ECB +mode. @code{src} and @code{dst} may be equal, but they must not overlap +in any other way. +@end deftypefun + +@deftypefun void twofish_decrypt (struct twofish_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{dst}, uint8_t *@var{src}) +Analogous to @code{twofish_encrypt} +@end deftypefun + +@c @node nettle_cipher, Cipher Block Chaining, Cipher functions, Reference +@c @comment node-name, next, previous, up +@subsection @code{struct nettle_cipher} + +Nettle includes a struct including information about some of the more +regular cipher functions. It should be considered a little experimental, +but can be useful for applications that need a simple way to handle +various algorithms. Nettle defines these structs in +@file{}. + +@deftp {Meta struct} @code{struct nettle_cipher} name context_size block_size key_size set_encrypt_key set_decrypt_key encrypt decrypt +The last four attributes are function pointers, of types +@code{nettle_set_key_func} and @code{nettle_crypt_func}. The first +argument to these functions is a @code{void *} pointer to a context +struct, which is of size @code{context_size}. +@end deftp + +@deftypevr {Constant Struct} {struct nettle_cipher} nettle_aes128 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_aes192 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_aes256 + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo40; +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo64; +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo128; +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo_gutmann128; + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arcfour128 + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_camellia128 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_camellia192 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_camellia256 + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_cast128 + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_serpent128 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_serpent192 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_serpent256 + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_twofish128 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_twofish192 +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_twofish256 + +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo40; +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo64; +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo128; +@deftypevrx {Constant Struct} {struct nettle_cipher} nettle_arctwo_gutmann128; + +Nettle includes such structs for all the @emph{regular} ciphers, i.e. +ones without weak keys or other oddities. +@end deftypevr + +@node Cipher modes, Keyed hash functions, Cipher functions, Reference +@comment node-name, next, previous, up +@section Cipher modes + +Cipher modes of operation specifies the procedure to use when +encrypting a message that is larger than the cipher's block size. As +explained in @xref{Cipher functions}, splitting the message into blocks +and processing them independently with the block cipher (Electronic Code +Book mode, @acronym{ECB}) leaks information. Besides @acronym{ECB}, +Nettle provides two other modes of operation: Cipher Block Chaining +(@acronym{CBC}) and Counter mode (@acronym{CTR}). @acronym{CBC} is +widely used, but there are a few subtle issues of information leakage. +@acronym{CTR} was standardized more recently, and is believed to be more +secure. + +@subsection Cipher Block Chaining + +@cindex Cipher Block Chaining +@cindex CBC Mode + +When using @acronym{CBC} mode, plaintext blocks are not encrypted +independently of each other, like in Electronic Cook Book mode. Instead, +when encrypting a block in @acronym{CBC} mode, the previous ciphertext +block is XORed with the plaintext before it is fed to the block cipher. +When encrypting the first block, a random block called an @dfn{IV}, or +Initialization Vector, is used as the ``previous ciphertext block''. The +IV should be chosen randomly, but it need not be kept secret, and can +even be transmitted in the clear together with the encrypted data. + +In symbols, if @code{E_k} is the encryption function of a block cipher, +and @code{IV} is the initialization vector, then @code{n} plaintext blocks +@code{M_1},@dots{} @code{M_n} are transformed into @code{n} ciphertext blocks +@code{C_1},@dots{} @code{C_n} as follows: + +@example +C_1 = E_k(IV XOR M_1) +C_2 = E_k(C_1 XOR M_2) + +@dots{} + +C_n = E_k(C_(n-1) XOR M_n) +@end example + +Nettle's includes two functions for applying a block cipher in Cipher +Block Chaining (@acronym{CBC}) mode, one for encryption and one for +decryption. These functions uses @code{void *} to pass cipher contexts +around. + +@deftypefun {void} cbc_encrypt (void *@var{ctx}, nettle_crypt_func @var{f}, unsigned @var{block_size}, uint8_t *@var{iv}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx {void} cbc_decrypt (void *@var{ctx}, void (*@var{f})(), unsigned @var{block_size}, uint8_t *@var{iv}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) + +Applies the encryption or decryption function @var{f} in @acronym{CBC} +mode. The final ciphertext block processed is copied into @var{iv} +before returning, so that large message be processed be a sequence of +calls to @code{cbc_encrypt}. The function @var{f} is of type + +@code{void f (void *@var{ctx}, unsigned @var{length}, uint8_t @var{dst}, +const uint8_t *@var{src})}, + +@noindent and the @code{cbc_encrypt} and @code{cbc_decrypt} functions pass their +argument @var{ctx} on to @var{f}. +@end deftypefun + +There are also some macros to help use these functions correctly. + +@deffn Macro CBC_CTX (@var{context_type}, @var{block_size}) +Expands into +@example +@{ + context_type ctx; + uint8_t iv[block_size]; +@} +@end example +@end deffn + +It can be used to define a @acronym{CBC} context struct, either directly, + +@example +struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx; +@end example + +or to give it a struct tag, + +@example +struct aes_cbc_ctx CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE); +@end example + +@deffn Macro CBC_SET_IV (@var{ctx}, @var{iv}) +First argument is a pointer to a context struct as defined by @code{CBC_CTX}, +and the second is a pointer to an Initialization Vector (IV) that is +copied into that context. +@end deffn + +@deffn Macro CBC_ENCRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src}) +@deffnx Macro CBC_DECRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src}) +A simpler way to invoke @code{cbc_encrypt} and @code{cbc_decrypt}. The +first argument is a pointer to a context struct as defined by +@code{CBC_CTX}, and the second argument is an encryption or decryption +function following Nettle's conventions. The last three arguments define +the source and destination area for the operation. +@end deffn + +These macros use some tricks to make the compiler display a warning if +the types of @var{f} and @var{ctx} don't match, e.g. if you try to use +an @code{struct aes_ctx} context with the @code{des_encrypt} function. + +@subsection Counter mode + +@cindex Counter Mode +@cindex CTR Mode + +Counter mode (@acronym{CTR}) uses the block cipher as a keyed +pseudo-random generator. The output of the generator is XORed with the +data to be encrypted. It can be understood as a way to transform a block +cipher to a stream cipher. + +The message is divided into @code{n} blocks @code{M_1},@dots{} +@code{M_n}, where @code{M_n} is of size @code{m} which may be smaller +than the block size. Except for the last block, all the message blocks +must be of size equal to the cipher's block size. + +If @code{E_k} is the encryption function of a block cipher, @code{IC} is +the initial counter, then the @code{n} plaintext blocks are +transformed into @code{n} ciphertext blocks @code{C_1},@dots{} +@code{C_n} as follows: + +@example +C_1 = E_k(IC) XOR M_1 +C_2 = E_k(IC + 1) XOR M_2 + +@dots{} + +C_(n-1) = E_k(IC + n - 2) XOR M_(n-1) +C_n = E_k(IC + n - 1) [1..m] XOR M_n +@end example + +The @acronym{IC} is the initial value for the counter, it plays a +similar role as the @acronym{IV} for @acronym{CBC}. When adding, +@code{IC + x}, @acronym{IC} is interpreted as an integer, in network +byte order. For the last block, @code{E_k(IC + n - 1) [1..m]} means that +the cipher output is truncated to @code{m} bytes. + +@deftypefun {void} ctr_crypt (void *@var{ctx}, nettle_crypt_func @var{f}, unsigned @var{block_size}, uint8_t *@var{ctr}, unsigned @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) + +Applies the encryption function @var{f} in @acronym{CTR} mode. Note that +for @acronym{CTR} mode, encryption and decryption is the same operation, +and hence @var{f} should always be the encryption function for the +underlying block cipher. + +When a message is encrypted using a sequence of calls to +@code{ctr_crypt}, all but the last call @emph{must} use a length that is +a multiple of the block size. +@end deftypefun + +Like for @acronym{CBC}, there are also a couple of helper macros. + +@deffn Macro CTR_CTX (@var{context_type}, @var{block_size}) +Expands into +@example +@{ + context_type ctx; + uint8_t ctr[block_size]; +@} +@end example +@end deffn + +@deffn Macro CTR_SET_COUNTER (@var{ctx}, @var{iv}) +First argument is a pointer to a context struct as defined by +@code{CTR_CTX}, and the second is a pointer to an initial counter that +is copied into that context. +@end deffn + +@deffn Macro CTR_CRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src}) +A simpler way to invoke @code{ctr_crypt}. The first argument is a +pointer to a context struct as defined by @code{CTR_CTX}, and the second +argument is an encryption function following Nettle's conventions. The +last three arguments define the source and destination area for the +operation. +@end deffn + + +@node Keyed hash functions, Public-key algorithms, Cipher modes, Reference +@comment node-name, next, previous, up +@section Keyed Hash Functions + +@cindex Keyed Hash Function +@cindex Message Authentication Code +@cindex MAC + +A @dfn{keyed hash function}, or @dfn{Message Authentication Code} +(@acronym{MAC}) is a function that takes a key and a message, and +produces fixed size @acronym{MAC}. It should be hard to compute a +message and a matching @acronym{MAC} without knowledge of the key. It +should also be hard to compute the key given only messages and +corresponding @acronym{MAC}s. + +Keyed hash functions are useful primarily for message authentication, +when Alice and Bob shares a secret: The sender, Alice, computes the +@acronym{MAC} and attaches it to the message. The receiver, Bob, also computes +the @acronym{MAC} of the message, using the same key, and compares that +to Alice's value. If they match, Bob can be assured that +the message has not been modified on its way from Alice. + +However, unlike digital signatures, this assurance is not transferable. +Bob can't show the message and the @acronym{MAC} to a third party and +prove that Alice sent that message. Not even if he gives away the key to +the third party. The reason is that the @emph{same} key is used on both +sides, and anyone knowing the key can create a correct @acronym{MAC} for +any message. If Bob believes that only he and Alice knows the key, and +he knows that he didn't attach a @acronym{MAC} to a particular message, +he knows it must be Alice who did it. However, the third party can't +distinguish between a @acronym{MAC} created by Alice and one created by +Bob. + +Keyed hash functions are typically a lot faster than digital signatures +as well. + +@subsection @acronym{HMAC} + +One can build keyed hash functions from ordinary hash functions. Older +constructions simply concatenate secret key and message and hashes that, but +such constructions have weaknesses. A better construction is +@acronym{HMAC}, described in @cite{RFC 2104}. + +For an underlying hash function @code{H}, with digest size @code{l} and +internal block size @code{b}, @acronym{HMAC-H} is constructed as +follows: From a given key @code{k}, two distinct subkeys @code{k_i} and +@code{k_o} are constructed, both of length @code{b}. The +@acronym{HMAC-H} of a message @code{m} is then computed as @code{H(k_o | +H(k_i | m))}, where @code{|} denotes string concatenation. + +@acronym{HMAC} keys can be of any length, but it is recommended to use +keys of length @code{l}, the digest size of the underlying hash function +@code{H}. Keys that are longer than @code{b} are shortened to length +@code{l} by hashing with @code{H}, so arbitrarily long keys aren't +very useful. + +Nettle's @acronym{HMAC} functions are defined in @file{}. +There are abstract functions that use a pointer to a @code{struct +nettle_hash} to represent the underlying hash function and @code{void +*} pointers that point to three different context structs for that hash +function. There are also concrete functions for @acronym{HMAC-MD5}, +@acronym{HMAC-SHA1}, @acronym{HMAC-SHA256}, and @acronym{HMAC-SHA512}. +First, the abstract functions: + +@deftypefun void hmac_set_key (void *@var{outer}, void *@var{inner}, void *@var{state}, const struct nettle_hash *@var{H}, unsigned @var{length}, const uint8_t *@var{key}) +Initializes the three context structs from the key. The @var{outer} and +@var{inner} contexts corresponds to the subkeys @code{k_o} and +@code{k_i}. @var{state} is used for hashing the message, and is +initialized as a copy of the @var{inner} context. +@end deftypefun + +@deftypefun void hmac_update (void *@var{state}, const struct nettle_hash *@var{H}, unsigned @var{length}, const uint8_t *@var{data}) +This function is called zero or more times to process the message. +Actually, @code{hmac_update(state, H, length, data)} is equivalent to +@code{H->update(state, length, data)}, so if you wish you can use the +ordinary update function of the underlying hash function instead. +@end deftypefun + +@deftypefun void hmac_digest (const void *@var{outer}, const void *@var{inner}, void *@var{state}, const struct nettle_hash *@var{H}, unsigned @var{length}, uint8_t *@var{digest}) +Extracts the @acronym{MAC} of the message, writing it to @var{digest}. +@var{outer} and @var{inner} are not modified. @var{length} is usually +equal to @code{H->digest_size}, but if you provide a smaller value, +only the first @var{length} octets of the @acronym{MAC} are written. + +This function also resets the @var{state} context so that you can start +over processing a new message (with the same key). +@end deftypefun + +Like for @acronym{CBC}, there are some macros to help use these +functions correctly. + +@deffn Macro HMAC_CTX (@var{type}) +Expands into +@example +@{ + type outer; + type inner; + type state; +@} +@end example +@end deffn + +It can be used to define a @acronym{HMAC} context struct, either +directly, + +@example +struct HMAC_CTX(struct md5_ctx) ctx; +@end example + +or to give it a struct tag, + +@example +struct hmac_md5_ctx HMAC_CTX (struct md5_ctx); +@end example + +@deffn Macro HMAC_SET_KEY (@var{ctx}, @var{H}, @var{length}, @var{key}) +@var{ctx} is a pointer to a context struct as defined by +@code{HMAC_CTX}, @var{H} is a pointer to a @code{const struct +nettle_hash} describing the underlying hash function (so it must match +the type of the components of @var{ctx}). The last two arguments specify +the secret key. +@end deffn + +@deffn Macro HMAC_DIGEST (@var{ctx}, @var{H}, @var{length}, @var{digest}) +@var{ctx} is a pointer to a context struct as defined by +@code{HMAC_CTX}, @var{H} is a pointer to a @code{const struct +nettle_hash} describing the underlying hash function. The last two +arguments specify where the digest is written. +@end deffn + +Note that there is no @code{HMAC_UPDATE} macro; simply call +@code{hmac_update} function directly, or the update function of the +underlying hash function. + +@subsection Concrete @acronym{HMAC} functions +Now we come to the specialized @acronym{HMAC} functions, which are +easier to use than the general @acronym{HMAC} functions. + +@subsubsection @acronym{HMAC-MD5} + +@deftp {Context struct} {struct hmac_md5_ctx} +@end deftp + +@deftypefun void hmac_md5_set_key (struct hmac_md5_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key}) +Initializes the context with the key. +@end deftypefun + +@deftypefun void hmac_md5_update (struct hmac_md5_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Process some more data. +@end deftypefun + +@deftypefun void hmac_md5_digest (struct hmac_md5_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than +@code{MD5_DIGEST_SIZE}, in which case only the first @var{length} +octets of the @acronym{MAC} are written. + +This function also resets the context for processing new messages, with +the same key. +@end deftypefun + +@subsubsection @acronym{HMAC-SHA1} + +@deftp {Context struct} {struct hmac_sha1_ctx} +@end deftp + +@deftypefun void hmac_sha1_set_key (struct hmac_sha1_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key}) +Initializes the context with the key. +@end deftypefun + +@deftypefun void hmac_sha1_update (struct hmac_sha1_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Process some more data. +@end deftypefun + +@deftypefun void hmac_sha1_digest (struct hmac_sha1_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than +@code{SHA1_DIGEST_SIZE}, in which case only the first @var{length} +octets of the @acronym{MAC} are written. + +This function also resets the context for processing new messages, with +the same key. +@end deftypefun + + +@subsubsection @acronym{HMAC-SHA256} + +@deftp {Context struct} {struct hmac_sha256_ctx} +@end deftp + +@deftypefun void hmac_sha256_set_key (struct hmac_sha256_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key}) +Initializes the context with the key. +@end deftypefun + +@deftypefun void hmac_sha256_update (struct hmac_sha256_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Process some more data. +@end deftypefun + +@deftypefun void hmac_sha256_digest (struct hmac_sha256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than +@code{SHA256_DIGEST_SIZE}, in which case only the first @var{length} +octets of the @acronym{MAC} are written. + +This function also resets the context for processing new messages, with +the same key. +@end deftypefun + + +@subsubsection @acronym{HMAC-SHA512} + +@deftp {Context struct} {struct hmac_sha512_ctx} +@end deftp + +@deftypefun void hmac_sha512_set_key (struct hmac_sha512_ctx *@var{ctx}, unsigned @var{key_length}, const uint8_t *@var{key}) +Initializes the context with the key. +@end deftypefun + +@deftypefun void hmac_sha512_update (struct hmac_sha512_ctx *@var{ctx}, unsigned @var{length}, const uint8_t *@var{data}) +Process some more data. +@end deftypefun + +@deftypefun void hmac_sha512_digest (struct hmac_sha512_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{digest}) +Extracts the @acronym{MAC}, writing it to @var{digest}. @var{length} may be smaller than +@code{SHA512_DIGEST_SIZE}, in which case only the first @var{length} +octets of the @acronym{MAC} are written. + +This function also resets the context for processing new messages, with +the same key. +@end deftypefun + +@node Public-key algorithms, Randomness, Keyed hash functions, Reference +@comment node-name, next, previous, up +@section Public-key algorithms + +Nettle uses @acronym{GMP}, the GNU bignum library, for all calculations +with large numbers. In order to use the public-key features of Nettle, +you must install @acronym{GMP}, at least version 3.0, before compiling +Nettle, and you need to link your programs with @code{-lhogweed -lnettle +-lgmp}. + +The concept of @dfn{Public-key} encryption and digital signatures was +discovered by Whitfield Diffie and Martin E. Hellman and described in a +paper 1976. In traditional, ``symmetric'', cryptography, sender and +receiver share the same keys, and these keys must be distributed in a +secure way. And if there are many users or entities that need to +communicate, each @emph{pair} needs a shared secret key known by nobody +else. + +@cindex Public Key Cryptography +@cindex One-way function + +Public-key cryptography uses trapdoor one-way functions. A +@dfn{one-way function} is a function @code{F} such that it is easy to +compute the value @code{F(x)} for any @code{x}, but given a value +@code{y}, it is hard to compute a corresponding @code{x} such that +@code{y = F(x)}. Two examples are cryptographic hash functions, and +exponentiation in certain groups. + +A @dfn{trapdoor one-way function} is a function @code{F} that is +one-way, unless one knows some secret information about @code{F}. If one +knows the secret, it is easy to compute both @code{F} and it's inverse. +If this sounds strange, look at the @acronym{RSA} example below. + +Two important uses for one-way functions with trapdoors are public-key +encryption, and digital signatures. The public-key encryption functions +in Nettle are not yet documented; the rest of this chapter is about +digital signatures. + +To use a digital signature algorithm, one must first create a +@dfn{key-pair}: A public key and a corresponding private key. The private +key is used to sign messages, while the public key is used for verifying +that that signatures and messages match. Some care must be taken when +distributing the public key; it need not be kept secret, but if a bad +guy is able to replace it (in transit, or in some user's list of known +public keys), bad things may happen. + +There are two operations one can do with the keys. The signature +operation takes a message and a private key, and creates a signature for +the message. A signature is some string of bits, usually at most a few +thousand bits or a few hundred octets. Unlike paper-and-ink signatures, +the digital signature depends on the message, so one can't cut it out of +context and glue it to a different message. + +The verification operation takes a public key, a message, and a string +that is claimed to be a signature on the message, and returns true or +false. If it returns true, that means that the three input values +matched, and the verifier can be sure that someone went through with the +signature operation on that very message, and that the ``someone'' also +knows the private key corresponding to the public key. + +The desired properties of a digital signature algorithm are as follows: +Given the public key and pairs of messages and valid signatures on them, +it should be hard to compute the private key, and it should also be hard +to create a new message and signature that is accepted by the +verification operation. + +Besides signing meaningful messages, digital signatures can be used for +authorization. A server can be configured with a public key, such that +any client that connects to the service is given a random nonce message. +If the server gets a reply with a correct signature matching the nonce +message and the configured public key, the client is granted access. So +the configuration of the server can be understood as ``grant access to +whoever knows the private key corresponding to this particular public +key, and to no others''. + + +@menu +* RSA:: The RSA public key algorithm. +* DSA:: The DSA digital signature algorithm. +@end menu + +@node RSA, DSA, Public-key algorithms, Public-key algorithms +@comment node-name, next, previous, up +@subsection @acronym{RSA} + +The @acronym{RSA} algorithm was the first practical digital signature +algorithm that was constructed. It was described 1978 in a paper by +Ronald Rivest, Adi Shamir and L.M. Adleman, and the technique was also +patented in the @acronym{USA} in 1983. The patent expired on September 20, 2000, and since +that day, @acronym{RSA} can be used freely, even in the @acronym{USA}. + +It's remarkably simple to describe the trapdoor function behind +@acronym{RSA}. The ``one-way''-function used is + +@example +F(x) = x^e mod n +@end example + +I.e. raise x to the @code{e}:th power, while discarding all multiples of +@code{n}. The pair of numbers @code{n} and @code{e} is the public key. +@code{e} can be quite small, even @code{e = 3} has been used, although +slightly larger numbers are recommended. @code{n} should be about 1000 +bits or larger. + +If @code{n} is large enough, and properly chosen, the inverse of F, +the computation of @code{e}:th roots modulo @code{n}, is very difficult. +But, where's the trapdoor? + +Let's first look at how @acronym{RSA} key-pairs are generated. First +@code{n} is chosen as the product of two large prime numbers @code{p} +and @code{q} of roughly the same size (so if @code{n} is 1000 bits, +@code{p} and @code{q} are about 500 bits each). One also computes the +number @code{phi = (p-1)(q-1)}, in mathematical speak, @code{phi} is the +order of the multiplicative group of integers modulo n. + +Next, @code{e} is chosen. It must have no factors in common with @code{phi} (in +particular, it must be odd), but can otherwise be chosen more or less +randomly. @code{e = 65537} is a popular choice, because it makes raising +to the @code{e}'th power particularly efficient, and being prime, it +usually has no factors common with @code{phi}. + +Finally, a number @code{d}, @code{d < n} is computed such that @code{e d +mod phi = 1}. It can be shown that such a number exists (this is why +@code{e} and @code{phi} must have no common factors), and that for all x, + +@example +(x^e)^d mod n = x^(ed) mod n = (x^d)^e mod n = x +@end example + +Using Euclid's algorithm, @code{d} can be computed quite easily from +@code{phi} and @code{e}. But it is still hard to get @code{d} without +knowing @code{phi}, which depends on the factorization of @code{n}. + +So @code{d} is the trapdoor, if we know @code{d} and @code{y = F(x)}, we can +recover x as @code{y^d mod n}. @code{d} is also the private half of +the @acronym{RSA} key-pair. + +The most common signature operation for @acronym{RSA} is defined in +@cite{PKCS#1}, a specification by RSA Laboratories. The message to be +signed is first hashed using a cryptographic hash function, e.g. +@acronym{MD5} or @acronym{SHA1}. Next, some padding, the @acronym{ASN.1} +``Algorithm Identifier'' for the hash function, and the message digest +itself, are concatenated and converted to a number @code{x}. The +signature is computed from @code{x} and the private key as @code{s = x^d +mod n}@footnote{Actually, the computation is not done like this, it is +done more efficiently using @code{p}, @code{q} and the Chinese remainder +theorem (@acronym{CRT}). But the result is the same.}. The signature, @code{s} is a +number of about the same size of @code{n}, and it usually encoded as a +sequence of octets, most significant octet first. + +The verification operation is straight-forward, @code{x} is computed +from the message in the same way as above. Then @code{s^e mod n} is +computed, the operation returns true if and only if the result equals +@code{x}. + +@subsection Nettle's @acronym{RSA} support + +Nettle represents @acronym{RSA} keys using two structures that contain +large numbers (of type @code{mpz_t}). + +@deftp {Context struct} {rsa_public_key} size n e +@code{size} is the size, in octets, of the modulo, and is used internally. +@code{n} and @code{e} is the public key. +@end deftp + +@deftp {Context struct} {rsa_private_key} size d p q a b c +@code{size} is the size, in octets, of the modulo, and is used internally. +@code{d} is the secret exponent, but it is not actually used when +signing. Instead, the factors @code{p} and @code{q}, and the parameters +@code{a}, @code{b} and @code{c} are used. They are computed from @code{p}, +@code{q} and @code{e} such that @code{a e mod (p - 1) = 1, b e mod (q - +1) = 1, c q mod p = 1}. +@end deftp + +Before use, these structs must be initialized by calling one of + +@deftypefun void rsa_public_key_init (struct rsa_public_key *@var{pub}) +@deftypefunx void rsa_private_key_init (struct rsa_private_key *@var{key}) +Calls @code{mpz_init} on all numbers in the key struct. +@end deftypefun + +and when finished with them, the space for the numbers must be +deallocated by calling one of + +@deftypefun void rsa_public_key_clear (struct rsa_public_key *@var{pub}) +@deftypefunx void rsa_private_key_clear (struct rsa_private_key *@var{key}) +Calls @code{mpz_clear} on all numbers in the key struct. +@end deftypefun + +In general, Nettle's @acronym{RSA} functions deviates from Nettle's ``no +memory allocation''-policy. Space for all the numbers, both in the key structs +above, and temporaries, are allocated dynamically. For information on how +to customize allocation, see +@xref{Custom Allocation,,GMP Allocation,gmp, GMP Manual}. + +When you have assigned values to the attributes of a key, you must call + +@deftypefun int rsa_public_key_prepare (struct rsa_public_key *@var{pub}) +@deftypefunx int rsa_private_key_prepare (struct rsa_private_key *@var{key}) +Computes the octet size of the key (stored in the @code{size} attribute, +and may also do other basic sanity checks. Returns one if successful, or +zero if the key can't be used, for instance if the modulo is smaller +than the minimum size needed for @acronym{RSA} operations specified by PKCS#1. +@end deftypefun + +Before signing or verifying a message, you first hash it with the +appropriate hash function. You pass the hash function's context struct +to the @acronym{RSA} signature function, and it will extract the message +digest and do the rest of the work. There are also alternative functions +that take the hash digest as argument. + +There is currently no support for using SHA224 or SHA384 with +@acronym{RSA} signatures, since there's no gain in either computation +time nor message size compared to using SHA256 and SHA512, respectively. + +Creation and verification of signatures is done with the following functions: + +@deftypefun int rsa_md5_sign (const struct rsa_private_key *@var{key}, struct md5_ctx *@var{hash}, mpz_t @var{signature}) +@deftypefunx int rsa_sha1_sign (const struct rsa_private_key *@var{key}, struct sha1_ctx *@var{hash}, mpz_t @var{signature}) +@deftypefunx int rsa_sha256_sign (const struct rsa_private_key *@var{key}, struct sha256_ctx *@var{hash}, mpz_t @var{signature}) +@deftypefunx int rsa_sha512_sign (const struct rsa_private_key *@var{key}, struct sha512_ctx *@var{hash}, mpz_t @var{signature}) +The signature is stored in @var{signature} (which must have been +@code{mpz_init}'ed earlier). The hash context is reset so that it can be +used for new messages. Returns one on success, or zero on failure. +Signing fails if the key is too small for the given hash size, e.g., +it's not possible to create a signature using SHA512 and a 512-bit +@acronym{RSA} key. +@end deftypefun + +@deftypefun int rsa_md5_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature}) +@deftypefunx int rsa_sha1_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature}); +@deftypefunx int rsa_sha256_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature}); +@deftypefunx int rsa_sha512_sign_digest (const struct rsa_private_key *@var{key}, const uint8_t *@var{digest}, mpz_t @var{signature}); +Creates a signature from the given hash digest. @var{digest} should +point to a digest of size @code{MD5_DIGEST_SIZE}, +@code{SHA1_DIGEST_SIZE}, or @code{SHA256_DIGEST_SIZE}, respectively. The +signature is stored in @var{signature} (which must have been +@code{mpz_init}:ed earlier). Returns one on success, or zero on failure. +@end deftypefun + +@deftypefun int rsa_md5_verify (const struct rsa_public_key *@var{key}, struct md5_ctx *@var{hash}, const mpz_t @var{signature}) +@deftypefunx int rsa_sha1_verify (const struct rsa_public_key *@var{key}, struct sha1_ctx *@var{hash}, const mpz_t @var{signature}) +@deftypefunx int rsa_sha256_verify (const struct rsa_public_key *@var{key}, struct sha256_ctx *@var{hash}, const mpz_t @var{signature}) +@deftypefunx int rsa_sha512_verify (const struct rsa_public_key *@var{key}, struct sha512_ctx *@var{hash}, const mpz_t @var{signature}) +Returns 1 if the signature is valid, or 0 if it isn't. In either case, +the hash context is reset so that it can be used for new messages. +@end deftypefun + +@deftypefun int rsa_md5_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature}) +@deftypefunx int rsa_sha1_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature}) +@deftypefunx int rsa_sha256_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature}) +@deftypefunx int rsa_sha512_verify_digest (const struct rsa_public_key *@var{key}, const uint8_t *@var{digest}, const mpz_t @var{signature}) +Returns 1 if the signature is valid, or 0 if it isn't. @var{digest} should +point to a digest of size @code{MD5_DIGEST_SIZE}, +@code{SHA1_DIGEST_SIZE}, or @code{SHA256_DIGEST_SIZE}, respectively. +@end deftypefun + +If you need to use the @acronym{RSA} trapdoor, the private key, in a way +that isn't supported by the above functions Nettle also includes a +function that computes @code{x^d mod n} and nothing more, using the +@acronym{CRT} optimization. + +@deftypefun void rsa_compute_root (struct rsa_private_key *@var{key}, mpz_t @var{x}, const mpz_t @var{m}) +Computes @code{x = m^d}, efficiently. +@end deftypefun + +At last, how do you create new keys? + +@deftypefun int rsa_generate_keypair (struct rsa_public_key *@var{pub}, struct rsa_private_key *@var{key}, void *@var{random_ctx}, nettle_random_func @var{random}, void *@var{progress_ctx}, nettle_progress_func @var{progress}, unsigned @var{n_size}, unsigned @var{e_size}); +There are lots of parameters. @var{pub} and @var{key} is where the +resulting key pair is stored. The structs should be initialized, but you +don't need to call @code{rsa_public_key_prepare} or +@code{rsa_private_key_prepare} after key generation. + +@var{random_ctx} and @var{random} is a randomness generator. +@code{random(random_ctx, length, dst)} should generate @code{length} +random octets and store them at @code{dst}. For advice, see +@xref{Randomness}. + +@var{progress} and @var{progress_ctx} can be used to get callbacks +during the key generation process, in order to uphold an illusion of +progress. @var{progress} can be NULL, in that case there are no +callbacks. + +@var{size_n} is the desired size of the modulo, in bits. If @var{size_e} +is non-zero, it is the desired size of the public exponent and a random +exponent of that size is selected. But if @var{e_size} is zero, it is +assumed that the caller has already chosen a value for @code{e}, and +stored it in @var{pub}. +Returns one on success, and zero on failure. The function can fail for +example if if @var{n_size} is too small, or if @var{e_size} is zero and +@code{pub->e} is an even number. +@end deftypefun + +@node DSA, , RSA, Public-key algorithms +@comment node-name, next, previous, up +@subsection Nettle's @acronym{DSA} support + +The @acronym{DSA} digital signature algorithm is more complex than +@acronym{RSA}. It was specified during the early 1990s, and in 1994 NIST +published @acronym{FIPS} 186 which is the authoritative specification. +Sometimes @acronym{DSA} is referred to using the acronym @acronym{DSS}, +for Digital Signature Standard. The most recent revision of the +specification, FIPS186-3, was issueed in 2009, and it adds support for +larger hash functions than @acronym{sha1}. + +For @acronym{DSA}, the underlying mathematical problem is the +computation of discreet logarithms. The public key consists of a large +prime @code{p}, a small prime @code{q} which is a factor of @code{p-1}, +a number @code{g} which generates a subgroup of order @code{q} modulo +@code{p}, and an element @code{y} in that subgroup. + +In the original @acronym{DSA}, the size of @code{q} is fixed to 160 +bits, to match with the @acronym{SHA1} hash algorithm. The size of +@code{p} is in principle unlimited, but the +standard specifies only nine specific sizes: @code{512 + l*64}, where +@code{l} is between 0 and 8. Thus, the maximum size of @code{p} is 1024 +bits, and sizes less than 1024 bits are considered obsolete and not +secure. + +The subgroup requirement means that if you compute + +@example +g^t mod p +@end example + +for all possible integers @code{t}, you will get precisely @code{q} +distinct values. + +The private key is a secret exponent @code{x}, such that + +@example +g^x = y mod p +@end example + +In mathematical speak, @code{x} is the @dfn{discrete logarithm} of +@code{y} mod @code{p}, with respect to the generator @code{g}. The size +of @code{x} will also be about the same size as @code{q}. The security of the +@acronym{DSA} algorithm relies on the difficulty of the discrete +logarithm problem. Current algorithms to compute discrete logarithms in +this setting, and hence crack @acronym{DSA}, are of two types. The first +type works directly in the (multiplicative) group of integers mod +@code{p}. The best known algorithm of this type is the Number Field +Sieve, and it's complexity is similar to the complexity of factoring +numbers of the same size as @code{p}. The other type works in the +smaller @code{q}-sized subgroup generated by @code{g}, which has a more +difficult group structure. One good algorithm is Pollard-rho, which has +complexity @code{sqrt(q)}. + +The important point is that security depends on the size of @emph{both} +@code{p} and @code{q}, and they should be choosen so that the difficulty +of both discrete logarithm methods are comparable. Today, the security +margin of the original @acronym{DSA} may be uncomfortably small. Using a +@code{p} of 1024 bits implies that cracking using the number field sieve +is expected to take about the same time as factoring a 1024-bit +@acronym{RSA} modulo, and using a @code{q} of size 160 bits implies +that cracking using Pollard-rho will take roughly @code{2^80} group +operations. With the size of @code{q} fixed, tied to the @acronym{SHA1} +digest size, it may be tempting to increase the size of @code{p} to, +say, 4096 bits. This will provide excellent resistance against attacks +like the number field sieve which works in the large group. But it will +do very little to defend against Pollard-rho attacking the small +subgroup; the attacker is slowed down at most by a single factor of 10 +due to the more expensive group operation. And the attacker will surely +choose the latter attack. + +The signature generation algorithm is randomized; in order to create a +@acronym{DSA} signature, you need a good source for random numbers +(@pxref{Randomness}). Let us describe the common case of a 160-bit +@code{q}. + +To create a signature, one starts with the hash digest of the message, +@code{h}, which is a 160 bit number, and a random number @code{k, +0} is a +fast generator with good statistical properties, but is @strong{not} for +cryptographic use, and therefore not documented here. It is included +mostly because the Nettle test suite needs to generate some test data +from a small seed. + +The recommended generator to use is Yarrow, described below. + +@subsection Yarrow + +Yarrow is a family of pseudo-randomness generators, designed for +cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson. +Yarrow-160 is described in a paper at +@url{http://www.counterpane.com/yarrow.html}, and it uses @acronym{SHA1} +and triple-DES, and has a 160-bit internal state. Nettle implements +Yarrow-256, which is similar, but uses @acronym{SHA256} and +@acronym{AES} to get an internal state of 256 bits. + +Yarrow was an almost finished project, the paper mentioned above is the +closest thing to a specification for it, but some smaller details are +left out. There is no official reference implementation or test cases. +This section includes an overview of Yarrow, but for the details of +Yarrow-256, as implemented by Nettle, you have to consult the source +code. Maybe a complete specification can be written later. + +Yarrow can use many sources (at least two are needed for proper +reseeding), and two randomness ``pools'', referred to as the ``slow pool'' and +the ``fast pool''. Input from the sources is fed alternatingly into the +two pools. When one of the sources has contributed 100 bits of entropy +to the fast pool, a ``fast reseed'' happens and the fast pool is mixed +into the internal state. When at least two of the sources have +contributed at least 160 bits each to the slow pool, a ``slow reseed'' +takes place. The contents of both pools are mixed into the internal +state. These procedures should ensure that the generator will eventually +recover after a key compromise. + +The output is generated by using @acronym{AES} to encrypt a counter, +using the generator's current key. After each request for output, +another 256 bits are generated which replace the key. This ensures +forward secrecy. + +Yarrow can also use a @dfn{seed file} to save state across restarts. +Yarrow is seeded by either feeding it the contents of the previous seed +file, or feeding it input from its sources until a slow reseed happens. + +Nettle defines Yarrow-256 in @file{}. + +@deftp {Context struct} {struct yarrow256_ctx} +@end deftp + +@deftp {Context struct} {struct yarrow_source} +Information about a single source. +@end deftp + +@defvr Constant YARROW256_SEED_FILE_SIZE +Recommanded size of the Yarrow-256 seed file. +@end defvr + +@deftypefun void yarrow256_init (struct yarrow256_ctx *@var{ctx}, unsigned @var{nsources}, struct yarrow_source *@var{sources}) +Initializes the yarrow context, and its @var{nsources} sources. It's +possible to call it with @var{nsources}=0 and @var{sources}=NULL, if +you don't need the update features. +@end deftypefun + +@deftypefun void yarrow256_seed (struct yarrow256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{seed_file}) +Seeds Yarrow-256 from a previous seed file. @var{length} should be at least +@code{YARROW256_SEED_FILE_SIZE}, but it can be larger. + +The generator will trust you that the @var{seed_file} data really is +unguessable. After calling this function, you @emph{must} overwrite the old +seed file with newly generated data from @code{yarrow256_random}. If it's +possible for several processes to read the seed file at about the same +time, access must be coordinated using some locking mechanism. +@end deftypefun + +@deftypefun int yarrow256_update (struct yarrow256_ctx *@var{ctx}, unsigned @var{source}, unsigned @var{entropy}, unsigned @var{length}, const uint8_t *@var{data}) +Updates the generator with data from source @var{SOURCE} (an index that +must be smaller than the number of sources). @var{entropy} is your +estimated lower bound for the entropy in the data, measured in bits. +Calling update with zero @var{entropy} is always safe, no matter if the +data is random or not. + +Returns 1 if a reseed happened, in which case an application using a +seed file may want to generate new seed data with +@code{yarrow256_random} and overwrite the seed file. Otherwise, the +function returns 0. +@end deftypefun + +@deftypefun void yarrow256_random (struct yarrow256_ctx *@var{ctx}, unsigned @var{length}, uint8_t *@var{dst}) +Generates @var{length} octets of output. The generator must be seeded +before you call this function. + +If you don't need forward secrecy, e.g. if you need non-secret +randomness for initialization vectors or padding, you can gain some +efficiency by buffering, calling this function for reasonably large +blocks of data, say 100-1000 octets at a time. +@end deftypefun + +@deftypefun int yarrow256_is_seeded (struct yarrow256_ctx *@var{ctx}) +Returns 1 if the generator is seeded and ready to generate output, +otherwise 0. +@end deftypefun + +@deftypefun unsigned yarrow256_needed_sources (struct yarrow256_ctx *@var{ctx}) +Returns the number of sources that must reach the threshold before a +slow reseed will happen. Useful primarily when the generator is unseeded. +@end deftypefun + +@deftypefun void yarrow256_fast_reseed (struct yarrow256_ctx *@var{ctx}) +@deftypefunx void yarrow256_slow_reseed (struct yarrow256_ctx *@var{ctx}) +Causes a fast or slow reseed to take place immediately, regardless of the +current entropy estimates of the two pools. Use with care. +@end deftypefun + +Nettle includes an entropy estimator for one kind of input source: User +keyboard input. + +@deftp {Context struct} {struct yarrow_key_event_ctx} +Information about recent key events. +@end deftp + +@deftypefun void yarrow_key_event_init (struct yarrow_key_event_ctx *@var{ctx}) +Initializes the context. +@end deftypefun + +@deftypefun unsigned yarrow_key_event_estimate (struct yarrow_key_event_ctx *@var{ctx}, unsigned @var{key}, unsigned @var{time}) +@var{key} is the id of the key (ASCII value, hardware key code, X +keysym, @dots{}, it doesn't matter), and @var{time} is the timestamp of +the event. The time must be given in units matching the resolution by +which you read the clock. If you read the clock with microsecond +precision, @var{time} should be provided in units of microseconds. But +if you use @code{gettimeofday} on a typical Unix system where the clock +ticks 10 or so microseconds at a time, @var{time} should be given in +units of 10 microseconds. + +Returns an entropy estimate, in bits, suitable for calling +@code{yarrow256_update}. Usually, 0, 1 or 2 bits. +@end deftypefun + +@node Miscellaneous functions, Compatibility functions, Randomness, Reference +@comment node-name, next, previous, up +@section Miscellaneous functions + +@deftypefun {uint8_t *} memxor (uint8_t *@var{dst}, const uint8_t *@var{src}, size_t @var{n}) +XORs the source area on top of the destination area. The interface +doesn't follow the Nettle conventions, because it is intended to be +similar to the ANSI-C @code{memcpy} function. +@end deftypefun + +@code{memxor} is declared in @file{}. + +@node Compatibility functions, , Miscellaneous functions, Reference +@comment node-name, next, previous, up +@section Compatibility functions + +For convenience, Nettle includes alternative interfaces to some +algorithms, for compatibility with some other popular crypto toolkits. +These are not fully documented here; refer to the source or to the +documentation for the original implementation. + +MD5 is defined in [RFC 1321], which includes a reference implementation. +Nettle defines a compatible interface to MD5 in +@file{}. This file defines the typedef +@code{MD5_CTX}, and declares the functions @code{MD5Init}, @code{MD5Update} and +@code{MD5Final}. + +Eric Young's ``libdes'' (also part of OpenSSL) is a quite popular DES +implementation. Nettle includes a subset if its interface in +@file{}. This file defines the typedefs +@code{des_key_schedule} and @code{des_cblock}, two constants +@code{DES_ENCRYPT} and @code{DES_DECRYPT}, and declares one global +variable @code{des_check_key}, and the functions @code{des_cbc_cksum} +@code{des_cbc_encrypt}, @code{des_ecb2_encrypt}, +@code{des_ecb3_encrypt}, @code{des_ecb_encrypt}, +@code{des_ede2_cbc_encrypt}, @code{des_ede3_cbc_encrypt}, +@code{des_is_weak_key}, @code{des_key_sched}, @code{des_ncbc_encrypt} +@code{des_set_key}, and @code{des_set_odd_parity}. + +@node Nettle soup, Installation, Reference, Top +@comment node-name, next, previous, up +@chapter Traditional Nettle Soup +For the serious nettle hacker, here is a recipe for nettle soup. 4 servings. + +@itemize @w{} +@item +1 liter fresh nettles (urtica dioica) +@item +2 tablespoons butter +@item +3 tablespoons flour +@item +1 liter stock (meat or vegetable) +@item +1/2 teaspoon salt +@item +a tad white pepper +@item +some cream or milk +@end itemize + +Gather 1 liter fresh nettles. Use gloves! Small, tender shoots are +preferable but the tops of larger nettles can also be used. + +Rinse the nettles very well. Boil them for 10 minutes in lightly salted +water. Strain the nettles and save the water. Hack the nettles. Melt the +butter and mix in the flour. Dilute with stock and the nettle-water you +saved earlier. Add the hacked nettles. If you wish you can add some milk +or cream at this stage. Bring to a boil and let boil for a few minutes. +Season with salt and pepper. + +Serve with boiled egg-halves. + +@c And the original Swedish version. +@ignore + +Recept på nässelsoppa +4 portioner + +1 l färska nässlor +2 msk smör +3 msk vetemjöl +1 l kött- eller grönsaksbuljong +1/2 tsk salt +1-2 krm peppar +(lite grädde eller mjölk) + +Plocka 1 liter färska nässlor. Använd handskar! Helst små och späda +skott, men topparna av större nässlor går också bra. + +Skölj nässlorna väl. Förväll dem ca 10 minuter i lätt saltat vatten. +Häll av och spara spadet. Hacka nässlorna. Smält smöret, rör i mjöl och +späd med buljong och nässelspad. Lägg i de hackade nässlorna. Om så +önskas, häll i en skvätt mjölk eller grädde. Koka några minuter, och +smaksätt med salt och peppar. + +Servera med kokta ägghalvor. +@end ignore + +@node Installation, Index, Nettle soup, Top +@comment node-name, next, previous, up +@chapter Installation + +Nettle uses @command{autoconf}. To build it, unpack the source and run + +@example +./configure +make +make check +make install +@end example + +@noindent +to install in the default location, @file{/usr/local}. The library files +are installed in @file{/use/local/lib/libnettle.a} +@file{/use/local/lib/libhogweed.a} and the include files are installed +in @file{/use/local/include/nettle/}. + +To get a list of configure options, use @code{./configure --help}. + +By default, only static libraries are built and installed. To also build +and install shared libraries, use the @option{ --enable-shared} option +to @command{./configure}. + +Using GNU make is recommended. For other make programs, in particular +BSD make, you may have to use the @option{--disable-dependency-tracking} +option to @command{./configure}. + +@node Index, , Installation, Top +@comment node-name, next, previous, up +@unnumbered Function and Concept Index + +@printindex cp + +@bye + +Local Variables: +ispell-local-dictionary: "american" +ispell-skip-region-alist: ( + (ispell-words-keyword forward-line) + ("^@example" . "^@end.*example") + ("^@ignore" . "^@end.*ignore") + ("^@\\(end\\|syncodeindex\\|vskip\\|\\(un\\)?macro\\|node\\|deftp\\) .*$") + ("^@\\(printindex\\|set\\) .*$") + ("^@def.*$") + ;; Allows one level of nested braces in the argument + ("@\\(uref\\|value\\|badspell\\|code\\|file\\|var\\|url\\){[^{}]*\\({[^{}]*}[^{}]*\\)*}") + ("@[a-z]+[{ ]") + ("@[a-z]+$") + ("\input texinfo.*$") + ("ispell-ignore" . "ispell-end-ignore") + ("^Local Variables:$" . "^End:$")) +End: + +@c LocalWords: cryptographics crypto LSH GNUPG API GPL LGPL aes rijndael ller +@c LocalWords: Sevilla arcfour RC Niels Dassen Colin Kuchling Biham sha Ruud +@c LocalWords: Gutmann twofish de Rooij struct MB Rivest RFC Nettle's ECB CBC +@c LocalWords: RSA Daemen Rijnmen Schneier DES's ede structs oddnesses HMAC +@c LocalWords: NIST Alice's GMP bignum Diffie Adi Shamir Adleman Euclid's ASN +@c LocalWords: PKCS callbacks Young's urtica dioica autoconf SSH tad +@c LocalWords: unguessability reseeding reseed alternatingly keysym subkeys +@c LocalWords: DSA gmp FIPS DSS libdes OpenSSL ARCTWO Josefsson Nikos Andreas +@c LocalWords: Mavroyanopoulos Sigfridsson Comstedt interoperability Sparc IC +@c LocalWords: DES FIXME Rivest's plaintext ciphertext CTR XORed timestamp +@c LocalWords: XORs cryptologists diff --git a/packaging/nettle.spec b/packaging/nettle.spec new file mode 100644 index 0000000..e0ccd25 --- /dev/null +++ b/packaging/nettle.spec @@ -0,0 +1,75 @@ +%define nettlemajor 4 +%define hogweedmajor 2 +%define develname nettle-devel + +Name: nettle +Summary: Nettle cryptographic library +Version: 2.1_2.2 +Release: 1 +License: LGPLv2+ +Group: System/Libraries +URL: http://www.lysator.liu.se/~nisse/nettle/ +Source0: %{name}-%{version}.tar.gz +BuildRequires: autoconf +BuildRequires: openssl-devel +BuildRequires: gmp-devel + +%description +Nettle is a cryptographic library that is designed to fit easily in more or less any context: +In crypto toolkits for object-oriented languages (C++, Python, Pike, ...), +in applications like LSH or GNUPG, or even in kernel space. + +%package -n %develname +Group: Development/C++ +Summary: Header files for compiling against Nettle library +Provides: %name-devel = %{version}-%{release} + +%description -n %develname +This is the development package of nettle. + +%prep +%setup -q + +%build +%configure --disable-openssl --enable-shared +make + +%install +make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" +make install-shared DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" +rm -f $RPM_BUILD_ROOT%{_libdir}/*.a +mkdir -p %{buildroot}/usr/share/license +cp COPYING %{buildroot}/usr/share/license/%{name} + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +/usr/share/license/%{name} +%manifest nettle.manifest +%{_bindir}/* +%{_infodir}/* +%{_libdir}/libnettle.so.%{nettlemajor}* +%{_libdir}/libhogweed.so.%{hogweedmajor}* + +%files -n %develname +%{_libdir}/libnettle.so +%{_libdir}/libhogweed.so +%{_includedir}/nettle + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%changelog +* Fri Oct 12 2012 Kwangtae Ko +- [Release] Update changelog for nettle-2.1_2.2 + +* Fri Oct 12 2012 Kwangtae Ko +- [Title] Add License Information + +* Fri Sep 21 2012 Kwangtae Ko +- [Release] Update changelog for nettle-2.1_2.1 + +* Thu Aug 16 2012 Keunsoon Lee +- release nettle-2.1-2 diff --git a/pgp-encode.c b/pgp-encode.c new file mode 100644 index 0000000..0ac46d2 --- /dev/null +++ b/pgp-encode.c @@ -0,0 +1,413 @@ +/* pgp.c + * + * PGP related functions. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "pgp.h" + +#include "base64.h" +#include "buffer.h" +#include "macros.h" +#include "rsa.h" + +int +pgp_put_uint32(struct nettle_buffer *buffer, uint32_t i) +{ + uint8_t *p = nettle_buffer_space(buffer, 4); + if (!p) + return 0; + + WRITE_UINT32(p, i); + return 1; +} + +int +pgp_put_uint16(struct nettle_buffer *buffer, unsigned i) +{ + uint8_t *p = nettle_buffer_space(buffer, 2); + if (!p) + return 0; + + WRITE_UINT16(p, i); + return 1; +} + +int +pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x) +{ + unsigned bits = mpz_sizeinbase(x, 2); + unsigned octets = (bits + 7) / 8; + + uint8_t *p; + + /* FIXME: What's the correct representation of zero? */ + if (!pgp_put_uint16(buffer, bits)) + return 0; + + p = nettle_buffer_space(buffer, octets); + + if (!p) + return 0; + + nettle_mpz_get_str_256(octets, p, x); + + return 1; +} + +int +pgp_put_string(struct nettle_buffer *buffer, + unsigned length, + const uint8_t *s) +{ + return nettle_buffer_write(buffer, length, s); +} + +#if 0 +static unsigned +length_field(unsigned length) +{ + if (length < PGP_LENGTH_TWO_OCTET) + return 1; + else if (length < PGP_LENGTH_FOUR_OCTETS) + return 2; + else return 4; +} +#endif + +/* bodyLen = ((1st_octet - 192) << 8) + (2nd_octet) + 192 + * ==> bodyLen - 192 + 192 << 8 = (1st_octet << 8) + (2nd_octet) + */ + +#define LENGTH_TWO_OFFSET (192 * 255) + +int +pgp_put_length(struct nettle_buffer *buffer, + unsigned length) +{ + if (length < PGP_LENGTH_TWO_OCTETS) + return NETTLE_BUFFER_PUTC(buffer, length); + + else if (length < PGP_LENGTH_FOUR_OCTETS) + return pgp_put_uint16(buffer, length + LENGTH_TWO_OFFSET); + else + return NETTLE_BUFFER_PUTC(buffer, 0xff) && pgp_put_uint32(buffer, length); +} + +/* Uses the "new" packet format */ +int +pgp_put_header(struct nettle_buffer *buffer, + unsigned tag, unsigned length) +{ + assert(tag < 0x40); + + return (NETTLE_BUFFER_PUTC(buffer, 0xC0 | tag) + && pgp_put_length(buffer, length)); +} + +/* FIXME: Should we abort or return error if the length and the field + * size don't match? */ +void +pgp_put_header_length(struct nettle_buffer *buffer, + /* start of the header */ + unsigned start, + unsigned field_size) +{ + unsigned length; + switch (field_size) + { + case 1: + length = buffer->size - (start + 2); + assert(length < PGP_LENGTH_TWO_OCTETS); + buffer->contents[start + 1] = length; + break; + case 2: + length = buffer->size - (start + 3); + assert(length < PGP_LENGTH_FOUR_OCTETS + && length >= PGP_LENGTH_TWO_OCTETS); + WRITE_UINT16(buffer->contents + start + 1, length + LENGTH_TWO_OFFSET); + break; + case 4: + length = buffer->size - (start + 5); + WRITE_UINT32(buffer->contents + start + 2, length); + break; + default: + abort(); + } +} + +int +pgp_put_userid(struct nettle_buffer *buffer, + unsigned length, + const uint8_t *name) +{ + return (pgp_put_header(buffer, PGP_TAG_USERID, length) + && pgp_put_string(buffer, length, name)); +} + +unsigned +pgp_sub_packet_start(struct nettle_buffer *buffer) +{ + return nettle_buffer_space(buffer, 2) ? buffer->size : 0; +} + +int +pgp_put_sub_packet(struct nettle_buffer *buffer, + unsigned type, + unsigned length, + const uint8_t *data) +{ + return (pgp_put_length(buffer, length + 1) + && NETTLE_BUFFER_PUTC(buffer, type) + && pgp_put_string(buffer, length, data)); +} + +void +pgp_sub_packet_end(struct nettle_buffer *buffer, unsigned start) +{ + unsigned length; + + assert(start >= 2); + assert(start <= buffer->size); + + length = buffer->size - start; + WRITE_UINT32(buffer->contents + start - 2, length); +} + +int +pgp_put_public_rsa_key(struct nettle_buffer *buffer, + const struct rsa_public_key *pub, + time_t timestamp) +{ + /* Public key packet, version 4 */ + unsigned start; + unsigned length; + + /* Size of packet is 16 + the size of e and n */ + length = (4 * 4 + + nettle_mpz_sizeinbase_256_u(pub->n) + + nettle_mpz_sizeinbase_256_u(pub->e)); + + if (!pgp_put_header(buffer, PGP_TAG_PUBLIC_KEY, length)) + return 0; + + start = buffer->size; + + if (! (pgp_put_header(buffer, PGP_TAG_PUBLIC_KEY, + /* Assume that we need two octets */ + PGP_LENGTH_TWO_OCTETS) + && pgp_put_uint32(buffer, 4) /* Version */ + && pgp_put_uint32(buffer, timestamp)/* Time stamp */ + && pgp_put_uint32(buffer, PGP_RSA) /* Algorithm */ + && pgp_put_mpi(buffer, pub->n) + && pgp_put_mpi(buffer, pub->e)) ) + return 0; + + assert(buffer->size == start + length); + + return 1; +} + +int +pgp_put_rsa_sha1_signature(struct nettle_buffer *buffer, + const struct rsa_private_key *key, + const uint8_t *keyid, + unsigned type, + struct sha1_ctx *hash) +{ + unsigned signature_start = buffer->size; + unsigned hash_end; + unsigned sub_packet_start; + uint8_t trailer[6]; + uint8_t digest16[2]; + mpz_t s; + + /* Signature packet. The packet could reasonably be both smaller and + * larger than 192, so for simplicity we use the 4 octet header + * form. */ + + if (! (pgp_put_header(buffer, PGP_TAG_SIGNATURE, PGP_LENGTH_FOUR_OCTETS) + && NETTLE_BUFFER_PUTC(buffer, 4) /* Version */ + && NETTLE_BUFFER_PUTC(buffer, type) + /* Could also be PGP_RSA_SIGN */ + && NETTLE_BUFFER_PUTC(buffer, PGP_RSA) + && NETTLE_BUFFER_PUTC(buffer, PGP_SHA1) + && pgp_put_uint16(buffer, 0))) /* Hashed subpacket length */ + return 0; + + hash_end = buffer->size; + + sha1_update(hash, + hash_end - signature_start, + buffer->contents + signature_start); + + trailer[0] = 4; trailer[1] = 0xff; + WRITE_UINT32(trailer + 2, buffer->size - signature_start); + + sha1_update(hash, sizeof(trailer), trailer); + + { + struct sha1_ctx hcopy = *hash; + uint8_t *p = nettle_buffer_space(buffer, 2); + if (!p) + return 0; + + sha1_digest(&hcopy, 2, p); + } + + /* One "sub-packet" field with the issuer keyid */ + sub_packet_start = pgp_sub_packet_start(buffer); + if (!sub_packet_start) + return 0; + + if (pgp_put_sub_packet(buffer, PGP_SUBPACKET_ISSUER_KEY_ID, 8, keyid)) + { + pgp_sub_packet_end(buffer, sub_packet_start); + return 0; + } + + mpz_init(s); + if (!(rsa_sha1_sign(key, hash, s) + && pgp_put_mpi(buffer, s))) + { + mpz_clear(s); + return 0; + } + + mpz_clear(s); + pgp_put_header_length(buffer, signature_start, 4); + + return 1; +} + +#define CRC24_INIT 0x0b704ceL +#define CRC24_POLY 0x1864cfbL + +uint32_t +pgp_crc24(unsigned length, const uint8_t *data) +{ + uint32_t crc = CRC24_INIT; + + unsigned i; + for (i = 0; i= BINARY_PER_LINE; + length -= BINARY_PER_LINE, data += BINARY_PER_LINE) + { + unsigned done; + uint8_t *p + = nettle_buffer_space(buffer, TEXT_PER_LINE); + + if (!p) + return 0; + + done = base64_encode_update(&ctx, p, BINARY_PER_LINE, data); + assert(done <= TEXT_PER_LINE); + + /* FIXME: Create some official way to do this */ + buffer->size -= (TEXT_PER_LINE - done); + + if (!NETTLE_BUFFER_PUTC(buffer, '\n')) + return 0; + } + + if (length) + { + unsigned text_size = BASE64_ENCODE_LENGTH(length) + + BASE64_ENCODE_FINAL_LENGTH; + unsigned done; + + uint8_t *p + = nettle_buffer_space(buffer, text_size); + if (!p) + return 0; + + done = base64_encode_update(&ctx, p, length, data); + done += base64_encode_final(&ctx, p + done); + + /* FIXME: Create some official way to do this */ + buffer->size -= (text_size - done); + + if (!NETTLE_BUFFER_PUTC(buffer, '\n')) + return 0; + } + /* Checksum */ + if (!NETTLE_BUFFER_PUTC(buffer, '=')) + return 0; + + { + uint8_t *p = nettle_buffer_space(buffer, 4); + if (!p) + return 0; + base64_encode_group(p, crc); + } + + return (WRITE(buffer, "\nBEGIN PGP ") + && WRITE(buffer, tag) + && NETTLE_BUFFER_PUTC(buffer, '\n')); +} diff --git a/pgp.h b/pgp.h new file mode 100644 index 0000000..c2e20fe --- /dev/null +++ b/pgp.h @@ -0,0 +1,240 @@ +/* pgp.h + * + * PGP related functions. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_PGP_H_INCLUDED +#define NETTLE_PGP_H_INCLUDED + +#include + +#include "nettle-types.h" +#include "bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define pgp_put_uint32 nettle_pgp_put_uint32 +#define pgp_put_uint16 nettle_pgp_put_uint16 +#define pgp_put_mpi nettle_pgp_put_mpi +#define pgp_put_string nettle_pgp_put_string +#define pgp_put_length nettle_pgp_put_length +#define pgp_put_header nettle_pgp_put_header +#define pgp_put_header_length nettle_pgp_put_header_length +#define pgp_sub_packet_start nettle_pgp_sub_packet_start +#define pgp_put_sub_packet nettle_pgp_put_sub_packet +#define pgp_sub_packet_end nettle_pgp_sub_packet_end +#define pgp_put_public_rsa_key nettle_pgp_put_public_rsa_key +#define pgp_put_rsa_sha1_signature nettle_pgp_put_rsa_sha1_signature +#define pgp_put_userid nettle_pgp_put_userid +#define pgp_crc24 nettle_pgp_crc24 +#define pgp_armor nettle_pgp_armor + +struct nettle_buffer; +struct rsa_public_key; +struct rsa_private_key; +struct sha1_ctx; + +int +pgp_put_uint32(struct nettle_buffer *buffer, uint32_t i); + +int +pgp_put_uint16(struct nettle_buffer *buffer, unsigned i); + +int +pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x); + +int +pgp_put_string(struct nettle_buffer *buffer, + unsigned length, + const uint8_t *s); + +int +pgp_put_length(struct nettle_buffer *buffer, + unsigned length); + +int +pgp_put_header(struct nettle_buffer *buffer, + unsigned tag, unsigned length); + +void +pgp_put_header_length(struct nettle_buffer *buffer, + /* start of the header */ + unsigned start, + unsigned field_size); + +unsigned +pgp_sub_packet_start(struct nettle_buffer *buffer); + +int +pgp_put_sub_packet(struct nettle_buffer *buffer, + unsigned type, + unsigned length, + const uint8_t *data); + +void +pgp_sub_packet_end(struct nettle_buffer *buffer, unsigned start); + +int +pgp_put_public_rsa_key(struct nettle_buffer *, + const struct rsa_public_key *key, + time_t timestamp); + +int +pgp_put_rsa_sha1_signature(struct nettle_buffer *buffer, + const struct rsa_private_key *key, + const uint8_t *keyid, + unsigned type, + struct sha1_ctx *hash); + +int +pgp_put_userid(struct nettle_buffer *buffer, + unsigned length, + const uint8_t *name); + +uint32_t +pgp_crc24(unsigned length, const uint8_t *data); + +int +pgp_armor(struct nettle_buffer *buffer, + const char *tag, + unsigned length, + const uint8_t *data); + +/* Values that can be passed to pgp_put_header when the size of the + * length field, but not the length itself, is known. Also the minimum length + * for the given field size. */ +enum pgp_lengths + { + PGP_LENGTH_ONE_OCTET = 0, + PGP_LENGTH_TWO_OCTETS = 192, + PGP_LENGTH_FOUR_OCTETS = 8384, + }; + +enum pgp_public_key_algorithm + { + PGP_RSA = 1, + PGP_RSA_ENCRYPT = 2, + PGP_RSA_SIGN = 3, + PGP_EL_GAMAL_ENCRYPT = 16, + PGP_DSA = 17, + PGP_EL_GAMAL = 20, + }; + +enum pgp_symmetric_algorithm + { + PGP_PLAINTEXT = 0, + PGP_IDEA = 1, + PGP_3DES = 2, + PGP_CAST5 = 3, + PGP_BLOWFISH = 4, + PGP_SAFER_SK = 5, + PGP_AES128 = 7, + PGP_AES192 = 8, + PGP_AES256 = 9, + }; + +enum pgp_compression_algorithm + { + PGP_UNCOMPRESSED = 0, + PGP_ZIP = 1, + PGP_ZLIB = 2, + }; + +enum pgp_hash_algorithm + { + PGP_MD5 = 1, + PGP_SHA1 = 2, + PGP_RIPEMD = 3, + PGP_MD2 = 5, + PGP_TIGER192 = 6, + PGP_HAVAL = 7, + }; + +enum pgp_tag + { + PGP_TAG_PUBLIC_SESSION_KEY = 1, + PGP_TAG_SIGNATURE = 2, + PGP_TAG_SYMMETRIC_SESSION_KEY = 3, + PGP_TAG_ONE_PASS_SIGNATURE = 4, + PGP_TAG_SECRET_KEY = 5, + PGP_TAG_PUBLIC_KEY = 6, + PGP_TAG_SECRET_SUBKEY = 7, + PGP_TAG_COMPRESSED = 8, + PGP_TAG_ENCRYPTED = 9, + PGP_TAG_MARKER = 10, + PGP_TAG_LITERAL = 11, + PGP_TAG_TRUST = 12, + PGP_TAG_USERID = 13, + PGP_TAG_PUBLIC_SUBKEY = 14, + }; + +enum pgp_signature_type + { + PGP_SIGN_BINARY = 0, + PGP_SIGN_TEXT = 1, + PGP_SIGN_STANDALONE = 2, + PGP_SIGN_CERTIFICATION = 0x10, + PGP_SIGN_CERTIFICATION_PERSONA = 0x11, + PGP_SIGN_CERTIFICATION_CASUAL = 0x12, + PGP_SIGN_CERTIFICATION_POSITIVE = 0x13, + PGP_SIGN_SUBKEY = 0x18, + PGP_SIGN_KEY = 0x1f, + PGP_SIGN_REVOCATION = 0x20, + PGP_SIGN_REVOCATION_SUBKEY = 0x28, + PGP_SIGN_REVOCATION_CERTIFICATE = 0x30, + PGP_SIGN_TIMESTAMP = 0x40, + }; + +enum pgp_subpacket_tag + { + PGP_SUBPACKET_CREATION_TIME = 2, + PGP_SUBPACKET_SIGNATURE_EXPIRATION_TIME = 3, + PGP_SUBPACKET_EXPORTABLE_CERTIFICATION = 4, + PGP_SUBPACKET_TRUST_SIGNATURE = 5, + PGP_SUBPACKET_REGULAR_EXPRESSION = 6, + PGP_SUBPACKET_REVOCABLE = 7, + PGP_SUBPACKET_KEY_EXPIRATION_TIME = 9, + PGP_SUBPACKET_PLACEHOLDER = 10 , + PGP_SUBPACKET_PREFERRED_SYMMETRIC_ALGORITHMS = 11, + PGP_SUBPACKET_REVOCATION_KEY = 12, + PGP_SUBPACKET_ISSUER_KEY_ID = 16, + PGP_SUBPACKET_NOTATION_DATA = 20, + PGP_SUBPACKET_PREFERRED_HASH_ALGORITHMS = 21, + PGP_SUBPACKET_PREFERRED_COMPRESSION_ALGORITHMS = 22, + PGP_SUBPACKET_KEY_SERVER_PREFERENCES = 23, + PGP_SUBPACKET_PREFERRED_KEY_SERVER = 24, + PGP_SUBPACKET_PRIMARY_USER_ID = 25, + PGP_SUBPACKET_POLICY_URL = 26, + PGP_SUBPACKET_KEY_FLAGS = 27, + PGP_SUBPACKET_SIGNERS_USER_ID = 28, + PGP_SUBPACKET_REASON_FOR_REVOCATION = 29, + }; + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_PGP_H_INCLUDED */ diff --git a/pkcs1-rsa-md5.c b/pkcs1-rsa-md5.c new file mode 100644 index 0000000..eff25fa --- /dev/null +++ b/pkcs1-rsa-md5.c @@ -0,0 +1,100 @@ +/* pkcs1-rsa-md5.c + * + * PKCS stuff for rsa-md5. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +#include "nettle-internal.h" + +/* From pkcs-1v2 + * + * md5 OBJECT IDENTIFIER ::= + * {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5} + * + * The parameters part of the algorithm identifier is NULL: + * + * md5Identifier ::= AlgorithmIdentifier {md5, NULL} + */ + +static const uint8_t +md5_prefix[] = +{ + /* 18 octets prefix, 16 octets hash, 34 total. */ + 0x30, 32, /* SEQUENCE */ + 0x30, 12, /* SEQUENCE */ + 0x06, 8, /* OBJECT IDENTIFIER */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, + 0x05, 0, /* NULL */ + 0x04, 16 /* OCTET STRING */ + /* Here comes the raw hash value */ +}; + +int +pkcs1_rsa_md5_encode(mpz_t m, unsigned size, struct md5_ctx *hash) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(md5_prefix), + md5_prefix, + MD5_DIGEST_SIZE)) + { + md5_digest(hash, MD5_DIGEST_SIZE, em + size - MD5_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} + +int +pkcs1_rsa_md5_encode_digest(mpz_t m, unsigned size, const uint8_t *digest) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(md5_prefix), + md5_prefix, + MD5_DIGEST_SIZE)) + { + memcpy(em + size - MD5_DIGEST_SIZE, digest, MD5_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} diff --git a/pkcs1-rsa-sha1.c b/pkcs1-rsa-sha1.c new file mode 100644 index 0000000..85395bd --- /dev/null +++ b/pkcs1-rsa-sha1.c @@ -0,0 +1,100 @@ +/* pkcs1-rsa-sha1.c + * + * PKCS stuff for rsa-sha1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +#include "nettle-internal.h" + +/* From pkcs-1v2 + * + * id-sha1 OBJECT IDENTIFIER ::= + * {iso(1) identified-organization(3) oiw(14) secsig(3) + * algorithms(2) 26} + * + * The default hash function is SHA-1: + * sha1Identifier ::= AlgorithmIdentifier {id-sha1, NULL} + */ + +static const uint8_t +sha1_prefix[] = +{ + /* 15 octets prefix, 20 octets hash, total 35 */ + 0x30, 33, /* SEQUENCE */ + 0x30, 9, /* SEQUENCE */ + 0x06, 5, /* OBJECT IDENTIFIER */ + 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0, /* NULL */ + 0x04, 20 /* OCTET STRING */ + /* Here comes the raw hash value */ +}; + +int +pkcs1_rsa_sha1_encode(mpz_t m, unsigned size, struct sha1_ctx *hash) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(sha1_prefix), + sha1_prefix, + SHA1_DIGEST_SIZE)) + { + sha1_digest(hash, SHA1_DIGEST_SIZE, em + size - SHA1_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} + +int +pkcs1_rsa_sha1_encode_digest(mpz_t m, unsigned size, const uint8_t *digest) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(sha1_prefix), + sha1_prefix, + SHA1_DIGEST_SIZE)) + { + memcpy(em + size - SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} diff --git a/pkcs1-rsa-sha256.c b/pkcs1-rsa-sha256.c new file mode 100644 index 0000000..363f784 --- /dev/null +++ b/pkcs1-rsa-sha256.c @@ -0,0 +1,98 @@ +/* pkcs1-rsa-sha256.c + * + * PKCS stuff for rsa-sha256. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003, 2006 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +#include "nettle-internal.h" + +/* From RFC 3447, Public-Key Cryptography Standards (PKCS) #1: RSA + * Cryptography Specifications Version 2.1. + * + * id-sha256 OBJECT IDENTIFIER ::= + * {joint-iso-itu-t(2) country(16) us(840) organization(1) + * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1} + */ + +static const uint8_t +sha256_prefix[] = +{ + /* 19 octets prefix, 32 octets hash, total 51 */ + 0x30, 49, /* SEQUENCE */ + 0x30, 13, /* SEQUENCE */ + 0x06, 9, /* OBJECT IDENTIFIER */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, + 0x05, 0, /* NULL */ + 0x04, 32 /* OCTET STRING */ + /* Here comes the raw hash value */ +}; + +int +pkcs1_rsa_sha256_encode(mpz_t m, unsigned size, struct sha256_ctx *hash) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(sha256_prefix), + sha256_prefix, + SHA256_DIGEST_SIZE)) + { + sha256_digest(hash, SHA256_DIGEST_SIZE, em + size - SHA256_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} + +int +pkcs1_rsa_sha256_encode_digest(mpz_t m, unsigned size, const uint8_t *digest) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(sha256_prefix), + sha256_prefix, + SHA256_DIGEST_SIZE)) + { + memcpy(em + size - SHA256_DIGEST_SIZE, digest, SHA256_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} diff --git a/pkcs1-rsa-sha512.c b/pkcs1-rsa-sha512.c new file mode 100644 index 0000000..8eb4377 --- /dev/null +++ b/pkcs1-rsa-sha512.c @@ -0,0 +1,99 @@ +/* pkcs1-rsa-sha512.c + * + * PKCS stuff for rsa-sha512. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003, 2006, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +#include "nettle-internal.h" + +/* From RFC 3447, Public-Key Cryptography Standards (PKCS) #1: RSA + * Cryptography Specifications Version 2.1. + * + * id-sha512 OBJECT IDENTIFIER ::= + * {joint-iso-itu-t(2) country(16) us(840) organization(1) + * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3} + */ + +static const uint8_t +sha512_prefix[] = +{ + /* 19 octets prefix, 64 octets hash, total 83 */ + 0x30, 81, /* SEQUENCE */ + 0x30, 13, /* SEQUENCE */ + 0x06, 9, /* OBJECT IDENTIFIER */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, + 0x05, 0, /* NULL */ + 0x04, 64 /* OCTET STRING */ + /* Here comes the raw hash value, 64 octets */ +}; + +int +pkcs1_rsa_sha512_encode(mpz_t m, unsigned size, struct sha512_ctx *hash) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(sha512_prefix), + sha512_prefix, + SHA512_DIGEST_SIZE)) + { + sha512_digest(hash, SHA512_DIGEST_SIZE, + em + size - SHA512_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} + +int +pkcs1_rsa_sha512_encode_digest(mpz_t m, unsigned size, const uint8_t *digest) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + TMP_ALLOC(em, size); + + if (pkcs1_signature_prefix(size, em, + sizeof(sha512_prefix), + sha512_prefix, + SHA512_DIGEST_SIZE)) + { + memcpy(em + size - SHA512_DIGEST_SIZE, digest, SHA512_DIGEST_SIZE); + nettle_mpz_set_str_256_u(m, size, em); + return 1; + } + else + return 0; +} diff --git a/pkcs1.c b/pkcs1.c new file mode 100644 index 0000000..786ee63 --- /dev/null +++ b/pkcs1.c @@ -0,0 +1,64 @@ +/* pkcs1.c + * + * PKCS1 embedding. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "pkcs1.h" + +/* Formats the PKCS#1 padding, of the form + * + * 0x01 0xff ... 0xff 0x00 id ...digest... + * + * where the 0xff ... 0xff part consists of at least 8 octets. The + * total size should be one less than the octet size of n. + */ +int +pkcs1_signature_prefix(unsigned size, + uint8_t *buffer, + unsigned id_size, + const uint8_t *id, + unsigned digest_size) +{ + unsigned j; + + if (size < 10 + id_size + digest_size) + return 0; + + j = size - digest_size - id_size; + + memcpy (buffer + j, id, id_size); + buffer[0] = 1; + buffer[--j] = 0; + + assert(j >= 9); + memset(buffer + 1, 0xff, j - 1); + + return 1; +} diff --git a/pkcs1.h b/pkcs1.h new file mode 100644 index 0000000..a2d00ee --- /dev/null +++ b/pkcs1.h @@ -0,0 +1,87 @@ +/* pkcs1.h + * + * PKCS1 embedding. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_PKCS1_H_INCLUDED +#define NETTLE_PKCS1_H_INCLUDED + +#include +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define pkcs1_signature_prefix nettle_pkcs1_signature_prefix +#define pkcs1_rsa_md5_encode nettle_pkcs1_rsa_md5_encode +#define pkcs1_rsa_md5_encode_digest nettle_pkcs1_rsa_md5_encode_digest +#define pkcs1_rsa_sha1_encode nettle_pkcs1_rsa_sha1_encode +#define pkcs1_rsa_sha1_encode_digest nettle_pkcs1_rsa_sha1_encode_digest +#define pkcs1_rsa_sha256_encode nettle_pkcs1_rsa_sha256_encode +#define pkcs1_rsa_sha256_encode_digest nettle_pkcs1_rsa_sha256_encode_digest +#define pkcs1_rsa_sha512_encode nettle_pkcs1_rsa_sha512_encode +#define pkcs1_rsa_sha512_encode_digest nettle_pkcs1_rsa_sha512_encode_digest + +struct md5_ctx; +struct sha1_ctx; +struct sha256_ctx; +struct sha512_ctx; + +int +pkcs1_signature_prefix(unsigned size, + uint8_t *buffer, + unsigned id_size, + const uint8_t *id, + unsigned digest_size); + +int +pkcs1_rsa_md5_encode(mpz_t m, unsigned length, struct md5_ctx *hash); + +int +pkcs1_rsa_md5_encode_digest(mpz_t m, unsigned length, const uint8_t *digest); + +int +pkcs1_rsa_sha1_encode(mpz_t m, unsigned length, struct sha1_ctx *hash); + +int +pkcs1_rsa_sha1_encode_digest(mpz_t m, unsigned length, const uint8_t *digest); + +int +pkcs1_rsa_sha256_encode(mpz_t m, unsigned length, struct sha256_ctx *hash); + +int +pkcs1_rsa_sha256_encode_digest(mpz_t m, unsigned length, const uint8_t *digest); + +int +pkcs1_rsa_sha512_encode(mpz_t m, unsigned length, struct sha512_ctx *hash); + +int +pkcs1_rsa_sha512_encode_digest(mpz_t m, unsigned length, const uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_PKCS1_H_INCLUDED */ diff --git a/prime-list.h b/prime-list.h new file mode 100644 index 0000000..3645926 --- /dev/null +++ b/prime-list.h @@ -0,0 +1,656 @@ + +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, 5003, 5009, +5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, +5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, +5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, +5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, +5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, +5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, +5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, +5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, +5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, +5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, +5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, +5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, +6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, +6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, +6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, +6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, +6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, +6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, +6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, +6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, +6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, +6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, +6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, +7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, +7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, +7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, +7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, +7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, +7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, +7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, +7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, +7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, +7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, +7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, +8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, +8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, +8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, +8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, +8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, +8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, +8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, +8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, +8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, +8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, +8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, +9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, +9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, +9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, +9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, +9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, +9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, +9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, +9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, +9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, +9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, +9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, +10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, +10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, +10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, 10273, +10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, 10357, +10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 10463, +10477, 10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567, 10589, +10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, 10657, 10663, +10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, 10753, +10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, +10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, +10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, +11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, +11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, +11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, 11351, +11353, 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443, 11447, +11467, 11471, 11483, 11489, 11491, 11497, 11503, 11519, 11527, 11549, +11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 11677, +11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777, 11779, +11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, 11839, +11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, +11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, +12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, +12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, +12239, 12241, 12251, 12253, 12263, 12269, 12277, 12281, 12289, 12301, +12323, 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 12409, +12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487, 12491, +12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553, 12569, +12577, 12583, 12589, 12601, 12611, 12613, 12619, 12637, 12641, 12647, +12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 12743, +12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, 12841, +12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, +12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, +13033, 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, +13127, 13147, 13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, +13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313, +13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411, 13417, +13421, 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, 13513, +13523, 13537, 13553, 13567, 13577, 13591, 13597, 13613, 13619, 13627, +13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697, 13709, +13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781, 13789, +13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, 13883, +13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, +13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, +14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, +14221, 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, +14341, 14347, 14369, 14387, 14389, 14401, 14407, 14411, 14419, 14423, +14431, 14437, 14447, 14449, 14461, 14479, 14489, 14503, 14519, 14533, +14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593, 14621, +14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 14713, +14717, 14723, 14731, 14737, 14741, 14747, 14753, 14759, 14767, 14771, +14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, 14851, 14867, +14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, 14951, +14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, +15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, +15173, 15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, +15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, +15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, +15427, 15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497, 15511, +15527, 15541, 15551, 15559, 15569, 15581, 15583, 15601, 15607, 15619, +15629, 15641, 15643, 15647, 15649, 15661, 15667, 15671, 15679, 15683, +15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 15787, +15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881, 15887, +15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, 15973, +15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, +16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, +16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, +16301, 16319, 16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, +16417, 16421, 16427, 16433, 16447, 16451, 16453, 16477, 16481, 16487, +16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 16607, +16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691, 16693, +16699, 16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811, 16823, +16829, 16831, 16843, 16871, 16879, 16883, 16889, 16901, 16903, 16921, +16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 17011, +17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, 17099, +17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, +17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, +17327, 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, +17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, +17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, +17581, 17597, 17599, 17609, 17623, 17627, 17657, 17659, 17669, 17681, +17683, 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 17789, +17791, 17807, 17827, 17837, 17839, 17851, 17863, 17881, 17891, 17903, +17909, 17911, 17921, 17923, 17929, 17939, 17957, 17959, 17971, 17977, +17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, 18059, 18061, +18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, 18149, +18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, 18251, +18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, 18329, +18341, 18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, 18433, +18439, 18443, 18451, 18457, 18461, 18481, 18493, 18503, 18517, 18521, +18523, 18539, 18541, 18553, 18583, 18587, 18593, 18617, 18637, 18661, +18671, 18679, 18691, 18701, 18713, 18719, 18731, 18743, 18749, 18757, +18773, 18787, 18793, 18797, 18803, 18839, 18859, 18869, 18899, 18911, +18913, 18917, 18919, 18947, 18959, 18973, 18979, 19001, 19009, 19013, +19031, 19037, 19051, 19069, 19073, 19079, 19081, 19087, 19121, 19139, +19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, 19219, 19231, +19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319, 19333, +19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423, 19427, +19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483, +19489, 19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, +19583, 19597, 19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, +19717, 19727, 19739, 19751, 19753, 19759, 19763, 19777, 19793, 19801, +19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891, 19913, +19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979, 19991, 19993, +19997, 20011, 20021, 20023, 20029, 20047, 20051, 20063, 20071, 20089, +20101, 20107, 20113, 20117, 20123, 20129, 20143, 20147, 20149, 20161, +20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, 20261, 20269, +20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, 20359, +20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, 20477, +20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551, 20563, +20593, 20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, 20707, +20717, 20719, 20731, 20743, 20747, 20749, 20753, 20759, 20771, 20773, +20789, 20807, 20809, 20849, 20857, 20873, 20879, 20887, 20897, 20899, +20903, 20921, 20929, 20939, 20947, 20959, 20963, 20981, 20983, 21001, +21011, 21013, 21017, 21019, 21023, 21031, 21059, 21061, 21067, 21089, +21101, 21107, 21121, 21139, 21143, 21149, 21157, 21163, 21169, 21179, +21187, 21191, 21193, 21211, 21221, 21227, 21247, 21269, 21277, 21283, +21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, 21383, 21391, +21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491, 21493, +21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, 21569, +21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, 21649, +21661, 21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, 21757, +21767, 21773, 21787, 21799, 21803, 21817, 21821, 21839, 21841, 21851, +21859, 21863, 21871, 21881, 21893, 21911, 21929, 21937, 21943, 21961, +21977, 21991, 21997, 22003, 22013, 22027, 22031, 22037, 22039, 22051, +22063, 22067, 22073, 22079, 22091, 22093, 22109, 22111, 22123, 22129, +22133, 22147, 22153, 22157, 22159, 22171, 22189, 22193, 22229, 22247, +22259, 22271, 22273, 22277, 22279, 22283, 22291, 22303, 22307, 22343, +22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, 22441, 22447, +22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, 22549, +22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643, 22651, +22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727, 22739, +22741, 22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817, 22853, +22859, 22861, 22871, 22877, 22901, 22907, 22921, 22937, 22943, 22961, +22963, 22973, 22993, 23003, 23011, 23017, 23021, 23027, 23029, 23039, +23041, 23053, 23057, 23059, 23063, 23071, 23081, 23087, 23099, 23117, +23131, 23143, 23159, 23167, 23173, 23189, 23197, 23201, 23203, 23209, +23227, 23251, 23269, 23279, 23291, 23293, 23297, 23311, 23321, 23327, +23333, 23339, 23357, 23369, 23371, 23399, 23417, 23431, 23447, 23459, +23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, 23561, 23563, +23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629, 23633, +23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, 23747, +23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, 23831, +23833, 23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909, 23911, +23917, 23929, 23957, 23971, 23977, 23981, 23993, 24001, 24007, 24019, +24023, 24029, 24043, 24049, 24061, 24071, 24077, 24083, 24091, 24097, +24103, 24107, 24109, 24113, 24121, 24133, 24137, 24151, 24169, 24179, +24181, 24197, 24203, 24223, 24229, 24239, 24247, 24251, 24281, 24317, +24329, 24337, 24359, 24371, 24373, 24379, 24391, 24407, 24413, 24419, +24421, 24439, 24443, 24469, 24473, 24481, 24499, 24509, 24517, 24527, +24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, 24659, 24671, +24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, 24781, +24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877, 24889, +24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977, 24979, +24989, 25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, 25111, +25117, 25121, 25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189, +25219, 25229, 25237, 25243, 25247, 25253, 25261, 25301, 25303, 25307, +25309, 25321, 25339, 25343, 25349, 25357, 25367, 25373, 25391, 25409, +25411, 25423, 25439, 25447, 25453, 25457, 25463, 25469, 25471, 25523, +25537, 25541, 25561, 25577, 25579, 25583, 25589, 25601, 25603, 25609, +25621, 25633, 25639, 25643, 25657, 25667, 25673, 25679, 25693, 25703, +25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, 25799, 25801, +25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913, 25919, +25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, +26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113, +26119, 26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203, 26209, +26227, 26237, 26249, 26251, 26261, 26263, 26267, 26293, 26297, 26309, +26317, 26321, 26339, 26347, 26357, 26371, 26387, 26393, 26399, 26407, +26417, 26423, 26431, 26437, 26449, 26459, 26479, 26489, 26497, 26501, +26513, 26539, 26557, 26561, 26573, 26591, 26597, 26627, 26633, 26641, +26647, 26669, 26681, 26683, 26687, 26693, 26699, 26701, 26711, 26713, +26717, 26723, 26729, 26731, 26737, 26759, 26777, 26783, 26801, 26813, +26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, 26891, 26893, +26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, 26993, +27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077, 27091, +27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211, 27239, +27241, 27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, 27337, +27361, 27367, 27397, 27407, 27409, 27427, 27431, 27437, 27449, 27457, +27479, 27481, 27487, 27509, 27527, 27529, 27539, 27541, 27551, 27581, +27583, 27611, 27617, 27631, 27647, 27653, 27673, 27689, 27691, 27697, +27701, 27733, 27737, 27739, 27743, 27749, 27751, 27763, 27767, 27773, +27779, 27791, 27793, 27799, 27803, 27809, 27817, 27823, 27827, 27847, +27851, 27883, 27893, 27901, 27917, 27919, 27941, 27943, 27947, 27953, +27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, 28051, 28057, +28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151, 28163, +28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, 28289, +28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, 28409, +28411, 28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499, 28513, +28517, 28537, 28541, 28547, 28549, 28559, 28571, 28573, 28579, 28591, +28597, 28603, 28607, 28619, 28621, 28627, 28631, 28643, 28649, 28657, +28661, 28663, 28669, 28687, 28697, 28703, 28711, 28723, 28729, 28751, +28753, 28759, 28771, 28789, 28793, 28807, 28813, 28817, 28837, 28843, +28859, 28867, 28871, 28879, 28901, 28909, 28921, 28927, 28933, 28949, +28961, 28979, 29009, 29017, 29021, 29023, 29027, 29033, 29059, 29063, +29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, 29167, 29173, +29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251, 29269, +29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363, 29383, +29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443, 29453, +29473, 29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, 29581, +29587, 29599, 29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, +29717, 29723, 29741, 29753, 29759, 29761, 29789, 29803, 29819, 29833, +29837, 29851, 29863, 29867, 29873, 29879, 29881, 29917, 29921, 29927, +29947, 29959, 29983, 29989, 30011, 30013, 30029, 30047, 30059, 30071, +30089, 30091, 30097, 30103, 30109, 30113, 30119, 30133, 30137, 30139, +30161, 30169, 30181, 30187, 30197, 30203, 30211, 30223, 30241, 30253, +30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, 30341, 30347, +30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, 30491, +30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, 30577, +30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, +30703, 30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, 30809, +30817, 30829, 30839, 30841, 30851, 30853, 30859, 30869, 30871, 30881, +30893, 30911, 30931, 30937, 30941, 30949, 30971, 30977, 30983, 31013, +31019, 31033, 31039, 31051, 31063, 31069, 31079, 31081, 31091, 31121, +31123, 31139, 31147, 31151, 31153, 31159, 31177, 31181, 31183, 31189, +31193, 31219, 31223, 31231, 31237, 31247, 31249, 31253, 31259, 31267, +31271, 31277, 31307, 31319, 31321, 31327, 31333, 31337, 31357, 31379, +31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, 31511, 31513, +31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601, 31607, +31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, 31723, +31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, 31847, +31849, 31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, 31981, +31991, 32003, 32009, 32027, 32029, 32051, 32057, 32059, 32063, 32069, +32077, 32083, 32089, 32099, 32117, 32119, 32141, 32143, 32159, 32173, +32183, 32189, 32191, 32203, 32213, 32233, 32237, 32251, 32257, 32261, +32297, 32299, 32303, 32309, 32321, 32323, 32327, 32341, 32353, 32359, +32363, 32369, 32371, 32377, 32381, 32401, 32411, 32413, 32423, 32429, +32441, 32443, 32467, 32479, 32491, 32497, 32503, 32507, 32531, 32533, +32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, 32609, 32611, +32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, 32719, +32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, 32833, +32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939, 32941, +32957, 32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023, 33029, +33037, 33049, 33053, 33071, 33073, 33083, 33091, 33107, 33113, 33119, +33149, 33151, 33161, 33179, 33181, 33191, 33199, 33203, 33211, 33223, +33247, 33287, 33289, 33301, 33311, 33317, 33329, 33331, 33343, 33347, +33349, 33353, 33359, 33377, 33391, 33403, 33409, 33413, 33427, 33457, +33461, 33469, 33479, 33487, 33493, 33503, 33521, 33529, 33533, 33547, +33563, 33569, 33577, 33581, 33587, 33589, 33599, 33601, 33613, 33617, +33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, 33713, 33721, +33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797, 33809, +33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893, 33911, +33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, 34033, +34039, 34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, 34159, +34171, 34183, 34211, 34213, 34217, 34231, 34253, 34259, 34261, 34267, +34273, 34283, 34297, 34301, 34303, 34313, 34319, 34327, 34337, 34351, +34361, 34367, 34369, 34381, 34403, 34421, 34429, 34439, 34457, 34469, +34471, 34483, 34487, 34499, 34501, 34511, 34513, 34519, 34537, 34543, +34549, 34583, 34589, 34591, 34603, 34607, 34613, 34631, 34649, 34651, +34667, 34673, 34679, 34687, 34693, 34703, 34721, 34729, 34739, 34747, +34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, 34847, 34849, +34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, 34963, +34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, 35089, +35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159, 35171, +35201, 35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291, 35311, +35317, 35323, 35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407, +35419, 35423, 35437, 35447, 35449, 35461, 35491, 35507, 35509, 35521, +35527, 35531, 35533, 35537, 35543, 35569, 35573, 35591, 35593, 35597, +35603, 35617, 35671, 35677, 35729, 35731, 35747, 35753, 35759, 35771, +35797, 35801, 35803, 35809, 35831, 35837, 35839, 35851, 35863, 35869, +35879, 35897, 35899, 35911, 35923, 35933, 35951, 35963, 35969, 35977, +35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, 36061, 36067, +36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161, 36187, +36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277, 36293, +36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389, +36433, 36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, 36523, +36527, 36529, 36541, 36551, 36559, 36563, 36571, 36583, 36587, 36599, +36607, 36629, 36637, 36643, 36653, 36671, 36677, 36683, 36691, 36697, +36709, 36713, 36721, 36739, 36749, 36761, 36767, 36779, 36781, 36787, +36791, 36793, 36809, 36821, 36833, 36847, 36857, 36871, 36877, 36887, +36899, 36901, 36913, 36919, 36923, 36929, 36931, 36943, 36947, 36973, +36979, 36997, 37003, 37013, 37019, 37021, 37039, 37049, 37057, 37061, +37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, 37189, 37199, +37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, 37313, +37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397, 37409, +37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507, 37511, +37517, 37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573, 37579, +37589, 37591, 37607, 37619, 37633, 37643, 37649, 37657, 37663, 37691, +37693, 37699, 37717, 37747, 37781, 37783, 37799, 37811, 37813, 37831, +37847, 37853, 37861, 37871, 37879, 37889, 37897, 37907, 37951, 37957, +37963, 37967, 37987, 37991, 37993, 37997, 38011, 38039, 38047, 38053, +38069, 38083, 38113, 38119, 38149, 38153, 38167, 38177, 38183, 38189, +38197, 38201, 38219, 38231, 38237, 38239, 38261, 38273, 38281, 38287, +38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, 38371, 38377, +38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543, 38557, +38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, 38651, +38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, 38723, +38729, 38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821, 38833, +38839, 38851, 38861, 38867, 38873, 38891, 38903, 38917, 38921, 38923, +38933, 38953, 38959, 38971, 38977, 38993, 39019, 39023, 39041, 39043, +39047, 39079, 39089, 39097, 39103, 39107, 39113, 39119, 39133, 39139, +39157, 39161, 39163, 39181, 39191, 39199, 39209, 39217, 39227, 39229, +39233, 39239, 39241, 39251, 39293, 39301, 39313, 39317, 39323, 39341, +39343, 39359, 39367, 39371, 39373, 39383, 39397, 39409, 39419, 39439, +39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, 39541, 39551, +39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, 39671, +39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769, 39779, +39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857, 39863, +39869, 39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, 39979, +39983, 39989, 40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, +40099, 40111, 40123, 40127, 40129, 40151, 40153, 40163, 40169, 40177, +40189, 40193, 40213, 40231, 40237, 40241, 40253, 40277, 40283, 40289, +40343, 40351, 40357, 40361, 40387, 40423, 40427, 40429, 40433, 40459, +40471, 40483, 40487, 40493, 40499, 40507, 40519, 40529, 40531, 40543, +40559, 40577, 40583, 40591, 40597, 40609, 40627, 40637, 40639, 40693, +40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, 40787, 40801, +40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867, 40879, +40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, 40993, +41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, +41117, 41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, 41189, +41201, 41203, 41213, 41221, 41227, 41231, 41233, 41243, 41257, 41263, +41269, 41281, 41299, 41333, 41341, 41351, 41357, 41381, 41387, 41389, +41399, 41411, 41413, 41443, 41453, 41467, 41479, 41491, 41507, 41513, +41519, 41521, 41539, 41543, 41549, 41579, 41593, 41597, 41603, 41609, +41611, 41617, 41621, 41627, 41641, 41647, 41651, 41659, 41669, 41681, +41687, 41719, 41729, 41737, 41759, 41761, 41771, 41777, 41801, 41809, +41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, 41897, 41903, +41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, 41983, +41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, 42083, +42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187, 42193, +42197, 42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, 42293, +42299, 42307, 42323, 42331, 42337, 42349, 42359, 42373, 42379, 42391, +42397, 42403, 42407, 42409, 42433, 42437, 42443, 42451, 42457, 42461, +42463, 42467, 42473, 42487, 42491, 42499, 42509, 42533, 42557, 42569, +42571, 42577, 42589, 42611, 42641, 42643, 42649, 42667, 42677, 42683, +42689, 42697, 42701, 42703, 42709, 42719, 42727, 42737, 42743, 42751, +42767, 42773, 42787, 42793, 42797, 42821, 42829, 42839, 42841, 42853, +42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, 42953, 42961, +42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051, 43063, +43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, 43201, +43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, 43321, +43331, 43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451, 43457, +43481, 43487, 43499, 43517, 43541, 43543, 43573, 43577, 43579, 43591, +43597, 43607, 43609, 43613, 43627, 43633, 43649, 43651, 43661, 43669, +43691, 43711, 43717, 43721, 43753, 43759, 43777, 43781, 43783, 43787, +43789, 43793, 43801, 43853, 43867, 43889, 43891, 43913, 43933, 43943, +43951, 43961, 43963, 43969, 43973, 43987, 43991, 43997, 44017, 44021, +44027, 44029, 44041, 44053, 44059, 44071, 44087, 44089, 44101, 44111, +44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, 44201, 44203, +44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279, 44281, +44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449, 44453, +44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537, 44543, +44549, 44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, 44647, +44651, 44657, 44683, 44687, 44699, 44701, 44711, 44729, 44741, 44753, +44771, 44773, 44777, 44789, 44797, 44809, 44819, 44839, 44843, 44851, +44867, 44879, 44887, 44893, 44909, 44917, 44927, 44939, 44953, 44959, +44963, 44971, 44983, 44987, 45007, 45013, 45053, 45061, 45077, 45083, +45119, 45121, 45127, 45131, 45137, 45139, 45161, 45179, 45181, 45191, +45197, 45233, 45247, 45259, 45263, 45281, 45289, 45293, 45307, 45317, +45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, 45403, 45413, +45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, 45541, +45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, 45659, +45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757, 45763, +45767, 45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853, 45863, +45869, 45887, 45893, 45943, 45949, 45953, 45959, 45971, 45979, 45989, +46021, 46027, 46049, 46051, 46061, 46073, 46091, 46093, 46099, 46103, +46133, 46141, 46147, 46153, 46171, 46181, 46183, 46187, 46199, 46219, +46229, 46237, 46261, 46271, 46273, 46279, 46301, 46307, 46309, 46327, +46337, 46349, 46351, 46381, 46399, 46411, 46439, 46441, 46447, 46451, +46457, 46471, 46477, 46489, 46499, 46507, 46511, 46523, 46549, 46559, +46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, 46643, 46649, +46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747, 46751, +46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831, 46853, +46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, 46997, +47017, 47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, 47123, +47129, 47137, 47143, 47147, 47149, 47161, 47189, 47207, 47221, 47237, +47251, 47269, 47279, 47287, 47293, 47297, 47303, 47309, 47317, 47339, +47351, 47353, 47363, 47381, 47387, 47389, 47407, 47417, 47419, 47431, +47441, 47459, 47491, 47497, 47501, 47507, 47513, 47521, 47527, 47533, +47543, 47563, 47569, 47581, 47591, 47599, 47609, 47623, 47629, 47639, +47653, 47657, 47659, 47681, 47699, 47701, 47711, 47713, 47717, 47737, +47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, 47819, 47837, +47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, 47947, +47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, 48073, +48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179, 48187, +48193, 48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299, 48311, +48313, 48337, 48341, 48353, 48371, 48383, 48397, 48407, 48409, 48413, +48437, 48449, 48463, 48473, 48479, 48481, 48487, 48491, 48497, 48523, +48527, 48533, 48539, 48541, 48563, 48571, 48589, 48593, 48611, 48619, +48623, 48647, 48649, 48661, 48673, 48677, 48679, 48731, 48733, 48751, +48757, 48761, 48767, 48779, 48781, 48787, 48799, 48809, 48817, 48821, +48823, 48847, 48857, 48859, 48869, 48871, 48883, 48889, 48907, 48947, +48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, 49033, 49037, +49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123, 49139, +49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211, 49223, +49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, 49363, +49367, 49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, 49451, +49459, 49463, 49477, 49481, 49499, 49523, 49529, 49531, 49537, 49547, +49549, 49559, 49597, 49603, 49613, 49627, 49633, 49639, 49663, 49667, +49669, 49681, 49697, 49711, 49727, 49739, 49741, 49747, 49757, 49783, +49787, 49789, 49801, 49807, 49811, 49823, 49831, 49843, 49853, 49871, +49877, 49891, 49919, 49921, 49927, 49937, 49939, 49943, 49957, 49991, +49993, 49999, 50021, 50023, 50033, 50047, 50051, 50053, 50069, 50077, +50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, 50147, 50153, +50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, 50287, +50291, 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, 50383, +50387, 50411, 50417, 50423, 50441, 50459, 50461, 50497, 50503, 50513, +50527, 50539, 50543, 50549, 50551, 50581, 50587, 50591, 50593, 50599, +50627, 50647, 50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, +50773, 50777, 50789, 50821, 50833, 50839, 50849, 50857, 50867, 50873, +50891, 50893, 50909, 50923, 50929, 50951, 50957, 50969, 50971, 50989, +50993, 51001, 51031, 51043, 51047, 51059, 51061, 51071, 51109, 51131, +51133, 51137, 51151, 51157, 51169, 51193, 51197, 51199, 51203, 51217, +51229, 51239, 51241, 51257, 51263, 51283, 51287, 51307, 51329, 51341, +51343, 51347, 51349, 51361, 51383, 51407, 51413, 51419, 51421, 51427, +51431, 51437, 51439, 51449, 51461, 51473, 51479, 51481, 51487, 51503, +51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, 51593, 51599, +51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, +51713, 51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817, +51827, 51829, 51839, 51853, 51859, 51869, 51871, 51893, 51899, 51907, +51913, 51929, 51941, 51949, 51971, 51973, 51977, 51991, 52009, 52021, +52027, 52051, 52057, 52067, 52069, 52081, 52103, 52121, 52127, 52147, +52153, 52163, 52177, 52181, 52183, 52189, 52201, 52223, 52237, 52249, +52253, 52259, 52267, 52289, 52291, 52301, 52313, 52321, 52361, 52363, +52369, 52379, 52387, 52391, 52433, 52453, 52457, 52489, 52501, 52511, +52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, 52579, 52583, +52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, 52711, +52721, 52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817, +52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919, 52937, +52951, 52957, 52963, 52967, 52973, 52981, 52999, 53003, 53017, 53047, +53051, 53069, 53077, 53087, 53089, 53093, 53101, 53113, 53117, 53129, +53147, 53149, 53161, 53171, 53173, 53189, 53197, 53201, 53231, 53233, +53239, 53267, 53269, 53279, 53281, 53299, 53309, 53323, 53327, 53353, +53359, 53377, 53381, 53401, 53407, 53411, 53419, 53437, 53441, 53453, +53479, 53503, 53507, 53527, 53549, 53551, 53569, 53591, 53593, 53597, +53609, 53611, 53617, 53623, 53629, 53633, 53639, 53653, 53657, 53681, +53693, 53699, 53717, 53719, 53731, 53759, 53773, 53777, 53783, 53791, +53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891, 53897, +53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, 54001, +54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, 54133, +54139, 54151, 54163, 54167, 54181, 54193, 54217, 54251, 54269, 54277, +54287, 54293, 54311, 54319, 54323, 54331, 54347, 54361, 54367, 54371, +54377, 54401, 54403, 54409, 54413, 54419, 54421, 54437, 54443, 54449, +54469, 54493, 54497, 54499, 54503, 54517, 54521, 54539, 54541, 54547, +54559, 54563, 54577, 54581, 54583, 54601, 54617, 54623, 54629, 54631, +54647, 54667, 54673, 54679, 54709, 54713, 54721, 54727, 54751, 54767, +54773, 54779, 54787, 54799, 54829, 54833, 54851, 54869, 54877, 54881, +54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, 54983, 55001, +55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, 55109, +55117, 55127, 55147, 55163, 55171, 55201, 55207, 55213, 55217, 55219, +55229, 55243, 55249, 55259, 55291, 55313, 55331, 55333, 55337, 55339, +55343, 55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, 55469, +55487, 55501, 55511, 55529, 55541, 55547, 55579, 55589, 55603, 55609, +55619, 55621, 55631, 55633, 55639, 55661, 55663, 55667, 55673, 55681, +55691, 55697, 55711, 55717, 55721, 55733, 55763, 55787, 55793, 55799, +55807, 55813, 55817, 55819, 55823, 55829, 55837, 55843, 55849, 55871, +55889, 55897, 55901, 55903, 55921, 55927, 55931, 55933, 55949, 55967, +55987, 55997, 56003, 56009, 56039, 56041, 56053, 56081, 56087, 56093, +56099, 56101, 56113, 56123, 56131, 56149, 56167, 56171, 56179, 56197, +56207, 56209, 56237, 56239, 56249, 56263, 56267, 56269, 56299, 56311, +56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, 56437, +56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, 56509, +56519, 56527, 56531, 56533, 56543, 56569, 56591, 56597, 56599, 56611, +56629, 56633, 56659, 56663, 56671, 56681, 56687, 56701, 56711, 56713, +56731, 56737, 56747, 56767, 56773, 56779, 56783, 56807, 56809, 56813, +56821, 56827, 56843, 56857, 56873, 56891, 56893, 56897, 56909, 56911, +56921, 56923, 56929, 56941, 56951, 56957, 56963, 56983, 56989, 56993, +56999, 57037, 57041, 57047, 57059, 57073, 57077, 57089, 57097, 57107, +57119, 57131, 57139, 57143, 57149, 57163, 57173, 57179, 57191, 57193, +57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, 57283, 57287, +57301, 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, 57397, +57413, 57427, 57457, 57467, 57487, 57493, 57503, 57527, 57529, 57557, +57559, 57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, 57667, +57679, 57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, 57751, +57773, 57781, 57787, 57791, 57793, 57803, 57809, 57829, 57839, 57847, +57853, 57859, 57881, 57899, 57901, 57917, 57923, 57943, 57947, 57973, +57977, 57991, 58013, 58027, 58031, 58043, 58049, 58057, 58061, 58067, +58073, 58099, 58109, 58111, 58129, 58147, 58151, 58153, 58169, 58171, +58189, 58193, 58199, 58207, 58211, 58217, 58229, 58231, 58237, 58243, +58271, 58309, 58313, 58321, 58337, 58363, 58367, 58369, 58379, 58391, +58393, 58403, 58411, 58417, 58427, 58439, 58441, 58451, 58453, 58477, +58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, 58603, +58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, 58727, +58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, 58897, +58901, 58907, 58909, 58913, 58921, 58937, 58943, 58963, 58967, 58979, +58991, 58997, 59009, 59011, 59021, 59023, 59029, 59051, 59053, 59063, +59069, 59077, 59083, 59093, 59107, 59113, 59119, 59123, 59141, 59149, +59159, 59167, 59183, 59197, 59207, 59209, 59219, 59221, 59233, 59239, +59243, 59263, 59273, 59281, 59333, 59341, 59351, 59357, 59359, 59369, +59377, 59387, 59393, 59399, 59407, 59417, 59419, 59441, 59443, 59447, +59453, 59467, 59471, 59473, 59497, 59509, 59513, 59539, 59557, 59561, +59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, 59659, 59663, +59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743, 59747, 59753, +59771, 59779, 59791, 59797, 59809, 59833, 59863, 59879, 59887, 59921, +59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, 60029, 60037, +60041, 60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, 60133, +60139, 60149, 60161, 60167, 60169, 60209, 60217, 60223, 60251, 60257, +60259, 60271, 60289, 60293, 60317, 60331, 60337, 60343, 60353, 60373, +60383, 60397, 60413, 60427, 60443, 60449, 60457, 60493, 60497, 60509, +60521, 60527, 60539, 60589, 60601, 60607, 60611, 60617, 60623, 60631, +60637, 60647, 60649, 60659, 60661, 60679, 60689, 60703, 60719, 60727, +60733, 60737, 60757, 60761, 60763, 60773, 60779, 60793, 60811, 60821, +60859, 60869, 60887, 60889, 60899, 60901, 60913, 60917, 60919, 60923, +60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, 61051, +61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, 61211, +61223, 61231, 61253, 61261, 61283, 61291, 61297, 61331, 61333, 61339, +61343, 61357, 61363, 61379, 61381, 61403, 61409, 61417, 61441, 61463, +61469, 61471, 61483, 61487, 61493, 61507, 61511, 61519, 61543, 61547, +61553, 61559, 61561, 61583, 61603, 61609, 61613, 61627, 61631, 61637, +61643, 61651, 61657, 61667, 61673, 61681, 61687, 61703, 61717, 61723, +61729, 61751, 61757, 61781, 61813, 61819, 61837, 61843, 61861, 61871, +61879, 61909, 61927, 61933, 61949, 61961, 61967, 61979, 61981, 61987, +61991, 62003, 62011, 62017, 62039, 62047, 62053, 62057, 62071, 62081, +62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, 62189, 62191, +62201, 62207, 62213, 62219, 62233, 62273, 62297, 62299, 62303, 62311, +62323, 62327, 62347, 62351, 62383, 62401, 62417, 62423, 62459, 62467, +62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, 62563, +62581, 62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659, +62683, 62687, 62701, 62723, 62731, 62743, 62753, 62761, 62773, 62791, +62801, 62819, 62827, 62851, 62861, 62869, 62873, 62897, 62903, 62921, +62927, 62929, 62939, 62969, 62971, 62981, 62983, 62987, 62989, 63029, +63031, 63059, 63067, 63073, 63079, 63097, 63103, 63113, 63127, 63131, +63149, 63179, 63197, 63199, 63211, 63241, 63247, 63277, 63281, 63299, +63311, 63313, 63317, 63331, 63337, 63347, 63353, 63361, 63367, 63377, +63389, 63391, 63397, 63409, 63419, 63421, 63439, 63443, 63463, 63467, +63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, 63577, +63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649, +63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719, 63727, +63737, 63743, 63761, 63773, 63781, 63793, 63799, 63803, 63809, 63823, +63839, 63841, 63853, 63857, 63863, 63901, 63907, 63913, 63929, 63949, +63977, 63997, 64007, 64013, 64019, 64033, 64037, 64063, 64067, 64081, +64091, 64109, 64123, 64151, 64153, 64157, 64171, 64187, 64189, 64217, +64223, 64231, 64237, 64271, 64279, 64283, 64301, 64303, 64319, 64327, +64333, 64373, 64381, 64399, 64403, 64433, 64439, 64451, 64453, 64483, +64489, 64499, 64513, 64553, 64567, 64577, 64579, 64591, 64601, 64609, +64613, 64621, 64627, 64633, 64661, 64663, 64667, 64679, 64693, 64709, +64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849, 64853, +64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927, 64937, 64951, +64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, 65071, +65089, 65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, 65167, +65171, 65173, 65179, 65183, 65203, 65213, 65239, 65257, 65267, 65269, +65287, 65293, 65309, 65323, 65327, 65353, 65357, 65371, 65381, 65393, +65407, 65413, 65419, 65423, 65437, 65447, 65449, 65479, 65497, 65519, +65521, diff --git a/realloc.c b/realloc.c new file mode 100644 index 0000000..57e6d42 --- /dev/null +++ b/realloc.c @@ -0,0 +1,50 @@ +/* realloc.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "realloc.h" + +void * +nettle_realloc(void *ctx UNUSED, void *p, unsigned length) +{ + return realloc(p, length); +} + +void * +nettle_xrealloc(void *ctx UNUSED, void *p, unsigned length) +{ + void *n = realloc(p, length); + if (length && !n) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + return n; +} diff --git a/realloc.h b/realloc.h new file mode 100644 index 0000000..c8c6aa4 --- /dev/null +++ b/realloc.h @@ -0,0 +1,43 @@ +/* realloc.h + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_REALLOC_H_INCLUDED +#define NETTLE_REALLOC_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *nettle_realloc_func(void *ctx, void *p, unsigned length); + +nettle_realloc_func nettle_realloc; +nettle_realloc_func nettle_xrealloc; + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_REALLOC_H_INCLUDED */ diff --git a/rotors.h b/rotors.h new file mode 100644 index 0000000..290f5d9 --- /dev/null +++ b/rotors.h @@ -0,0 +1,82 @@ +/* automagically made - do not fuss with this */ + + 34, 13, 5, 46, 47, 18, 32, 41, 11, 53, 33, 20, + 14, 36, 30, 24, 49, 2, 15, 37, 42, 50, 0, 21, + 38, 48, 6, 26, 39, 4, 52, 25, 12, 27, 31, 40, + 1, 17, 28, 29, 23, 51, 35, 7, 3, 22, 9, 43, + + 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27, + 21, 43, 37, 0, 1, 9, 22, 44, 49, 2, 7, 28, + 45, 55, 13, 33, 46, 11, 6, 32, 19, 34, 38, 47, + 8, 24, 35, 36, 30, 3, 42, 14, 10, 29, 16, 50, + + 55, 34, 26, 38, 11, 39, 53, 5, 32, 45, 54, 41, + 35, 2, 51, 14, 15, 23, 36, 3, 8, 16, 21, 42, + 6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52, 4, + 22, 7, 49, 50, 44, 17, 1, 28, 24, 43, 30, 9, + + 12, 48, 40, 52, 25, 53, 38, 19, 46, 6, 11, 55, + 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35, 1, + 20, 26, 41, 4, 45, 39, 34, 31, 47, 5, 13, 18, + 36, 21, 8, 9, 3, 0, 15, 42, 7, 2, 44, 23, + + 26, 5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12, + 8, 30, 24, 42, 43, 51, 9, 0, 36, 44, 49, 15, + 34, 40, 55, 18, 6, 53, 48, 45, 4, 19, 27, 32, + 50, 35, 22, 23, 17, 14, 29, 1, 21, 16, 3, 37, + + 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26, + 22, 44, 7, 1, 2, 10, 23, 14, 50, 3, 8, 29, + 48, 54, 12, 32, 20, 38, 5, 6, 18, 33, 41, 46, + 9, 49, 36, 37, 0, 28, 43, 15, 35, 30, 17, 51, + + 54, 33, 25, 41, 38, 13, 27, 4, 6, 48, 53, 40, + 36, 3, 21, 15, 16, 24, 37, 28, 9, 17, 22, 43, + 5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31, + 23, 8, 50, 51, 14, 42, 2, 29, 49, 44, 0, 10, + + 11, 47, 39, 55, 52, 27, 41, 18, 20, 5, 38, 54, + 50, 17, 35, 29, 30, 7, 51, 42, 23, 0, 36, 2, + 19, 25, 40, 31, 48, 13, 33, 34, 46, 4, 12, 45, + 37, 22, 9, 10, 28, 1, 16, 43, 8, 3, 14, 24, + + 18, 54, 46, 5, 6, 34, 48, 25, 27, 12, 45, 4, + 2, 24, 42, 36, 37, 14, 3, 49, 30, 7, 43, 9, + 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52, + 44, 29, 16, 17, 35, 8, 23, 50, 15, 10, 21, 0, + + 32, 11, 31, 19, 20, 48, 5, 39, 41, 26, 6, 18, + 16, 7, 1, 50, 51, 28, 17, 8, 44, 21, 2, 23, + 40, 46, 4, 52, 12, 34, 54, 55, 38, 25, 33, 13, + 3, 43, 30, 0, 49, 22, 37, 9, 29, 24, 35, 14, + + 46, 25, 45, 33, 34, 5, 19, 53, 55, 40, 20, 32, + 30, 21, 15, 9, 10, 42, 0, 22, 3, 35, 16, 37, + 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27, + 17, 2, 44, 14, 8, 36, 51, 23, 43, 7, 49, 28, + + 31, 39, 6, 47, 48, 19, 33, 38, 12, 54, 34, 46, + 44, 35, 29, 23, 24, 1, 14, 36, 17, 49, 30, 51, + 11, 45, 32, 27, 40, 5, 25, 26, 13, 53, 4, 41, + 0, 16, 3, 28, 22, 50, 10, 37, 2, 21, 8, 42, + + 45, 53, 20, 4, 5, 33, 47, 52, 26, 11, 48, 31, + 3, 49, 43, 37, 7, 15, 28, 50, 0, 8, 44, 10, + 25, 6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55, + 14, 30, 17, 42, 36, 9, 24, 51, 16, 35, 22, 1, + + 6, 38, 34, 18, 19, 47, 4, 13, 40, 25, 5, 45, + 17, 8, 2, 51, 21, 29, 42, 9, 14, 22, 3, 24, + 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12, + 28, 44, 0, 1, 50, 23, 7, 10, 30, 49, 36, 15, + + 20, 52, 48, 32, 33, 4, 18, 27, 54, 39, 19, 6, + 0, 22, 16, 10, 35, 43, 1, 23, 28, 36, 17, 7, + 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26, + 42, 3, 14, 15, 9, 37, 21, 24, 44, 8, 50, 29, + + 27, 6, 55, 39, 40, 11, 25, 34, 4, 46, 26, 13, + 7, 29, 23, 17, 42, 50, 8, 30, 35, 43, 24, 14, + 31, 41, 52, 19, 32, 54, 45, 18, 5, 20, 53, 33, + 49, 10, 21, 22, 16, 44, 28, 0, 51, 15, 2, 36, + diff --git a/rsa-compat.c b/rsa-compat.c new file mode 100644 index 0000000..8eef185 --- /dev/null +++ b/rsa-compat.c @@ -0,0 +1,157 @@ +/* rsa-compat.c + * + * The RSA publickey algorithm, RSAREF compatible interface. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa-compat.h" + +#include "bignum.h" +#include "md5.h" + +int +R_SignInit(R_SIGNATURE_CTX *ctx, + int digestAlgorithm) +{ + if (digestAlgorithm != DA_MD5) + return RE_DIGEST_ALGORITHM; + + md5_init(&ctx->hash); + + return 0; +} + +int +R_SignUpdate(R_SIGNATURE_CTX *ctx, + const uint8_t *data, + /* Length is an unsigned char according to rsaref.txt, + * but that must be a typo. */ + unsigned length) +{ + md5_update(&ctx->hash, length, data); + + return RE_SUCCESS; +} + +int +R_SignFinal(R_SIGNATURE_CTX *ctx, + uint8_t *signature, + unsigned *length, + R_RSA_PRIVATE_KEY *key) +{ + struct rsa_private_key k; + int res; + + nettle_mpz_init_set_str_256_u(k.p, + MAX_RSA_MODULUS_LEN, key->prime[0]); + nettle_mpz_init_set_str_256_u(k.q, + MAX_RSA_MODULUS_LEN, key->prime[1]); + nettle_mpz_init_set_str_256_u(k.a, + MAX_RSA_MODULUS_LEN, key->primeExponent[0]); + nettle_mpz_init_set_str_256_u(k.b, + MAX_RSA_MODULUS_LEN, key->primeExponent[1]); + nettle_mpz_init_set_str_256_u(k.c, + MAX_RSA_MODULUS_LEN, key->coefficient); + + if (rsa_private_key_prepare(&k) && (k.size <= MAX_RSA_MODULUS_LEN)) + { + mpz_t s; + mpz_init(s); + + if (rsa_md5_sign(&k, &ctx->hash, s)) + { + nettle_mpz_get_str_256(k.size, signature, s); + *length = k.size; + + res = RE_SUCCESS; + } + else + res = RE_PRIVATE_KEY; + + mpz_clear(s); + } + else + res = RE_PRIVATE_KEY; + + mpz_clear(k.p); + mpz_clear(k.q); + mpz_clear(k.a); + mpz_clear(k.b); + mpz_clear(k.c); + + return res; +} + +int +R_VerifyInit(R_SIGNATURE_CTX *ctx, + int digestAlgorithm) +{ + return R_SignInit(ctx, digestAlgorithm); +} + +int +R_VerifyUpdate(R_SIGNATURE_CTX *ctx, + const uint8_t *data, + /* Length is an unsigned char according to rsaref.txt, + * but that must be a typo. */ + unsigned length) +{ + return R_SignUpdate(ctx, data, length); +} + +int +R_VerifyFinal(R_SIGNATURE_CTX *ctx, + uint8_t *signature, + unsigned length, + R_RSA_PUBLIC_KEY *key) +{ + struct rsa_public_key k; + int res; + + nettle_mpz_init_set_str_256_u(k.n, + MAX_RSA_MODULUS_LEN, key->modulus); + nettle_mpz_init_set_str_256_u(k.e, + MAX_RSA_MODULUS_LEN, key->exponent); + + if (rsa_public_key_prepare(&k) && (k.size == length)) + { + mpz_t s; + + nettle_mpz_init_set_str_256_u(s, + k.size, signature); + res = rsa_md5_verify(&k, &ctx->hash, s) + ? RE_SUCCESS : RE_SIGNATURE; + + mpz_clear(s); + } + else + res = RE_PUBLIC_KEY; + + mpz_clear(k.n); + mpz_clear(k.e); + + return res; +} diff --git a/rsa-compat.h b/rsa-compat.h new file mode 100644 index 0000000..9622503 --- /dev/null +++ b/rsa-compat.h @@ -0,0 +1,131 @@ +/* rsa-compat.h + * + * The RSA publickey algorithm, RSAREF compatible interface. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_RSA_COMPAT_H_INCLUDED +#define NETTLE_RSA_COMPAT_H_INCLUDED + +#include "rsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define R_SignInit nettle_R_SignInit +#define R_SignUpdate nettle_R_SignUpdate +#define R_SignFinal nettle_R_SignFinal +#define R_VerifyInit nettle_R_VerifyInit +#define R_VerifyUpdate nettle_R_VerifyUpdate +#define R_VerifyFinal nettle_R_VerifyFinal + +/* 256 octets or 2048 bits */ +#define MAX_RSA_MODULUS_LEN 256 + +typedef struct +{ + unsigned bits; + uint8_t modulus[MAX_RSA_MODULUS_LEN]; + uint8_t exponent[MAX_RSA_MODULUS_LEN]; +} R_RSA_PUBLIC_KEY; + +typedef struct +{ + unsigned bits; + uint8_t modulus[MAX_RSA_MODULUS_LEN]; + uint8_t publicExponent[MAX_RSA_MODULUS_LEN]; + uint8_t exponent[MAX_RSA_MODULUS_LEN]; + uint8_t prime[2][MAX_RSA_MODULUS_LEN]; + uint8_t primeExponent[2][MAX_RSA_MODULUS_LEN]; + uint8_t coefficient[MAX_RSA_MODULUS_LEN]; +} R_RSA_PRIVATE_KEY; + +/* Only MD5 is supported for now */ +typedef struct +{ + struct md5_ctx hash; +} R_SIGNATURE_CTX; + +/* Digest algorithms */ +/* DA_MD2 not implemented */ +enum { DA_MD5 = 1 }; + +/* Return values */ +enum { + RE_SUCCESS = 0, + RE_CONTENT_ENCODING, /* encryptedContent has RFC 1421 encoding error */ + RE_DATA, /* other party's private value out of range */ + RE_DIGEST_ALGORITHM, /* message-digest algorithm is invalid */ + RE_ENCODING, /* encoded block has RFC 1421 encoding error */ + RE_ENCRYPTION_ALGORITHM, /* encryption algorithm is invalid */ + RE_KEY, /* recovered data encryption key cannot decrypt */ + RE_KEY_ENCODING, /* encrypted key has RFC 1421 encoding error */ + RE_LEN, /* signatureLen out of range */ + RE_MODULUS_LEN, /* modulus length invalid */ + RE_NEED_RANDOM, /* random structure is not seeded */ + RE_PRIVATE_KEY, /* private key cannot encrypt message digest, */ + RE_PUBLIC_KEY, /* publicKey cannot decrypt signature */ + RE_SIGNATURE, /* signature is incorrect */ + RE_SIGNATURE_ENCODING, /* encodedSignature has RFC 1421 encoding error */ +}; + +int +R_SignInit(R_SIGNATURE_CTX *ctx, + int digestAlgorithm); + +int +R_SignUpdate(R_SIGNATURE_CTX *ctx, + const uint8_t *data, + /* Length is an unsigned char according to rsaref.txt, + * but that must be a typo. */ + unsigned length); + +int +R_SignFinal(R_SIGNATURE_CTX *ctx, + uint8_t *signature, + unsigned *length, + R_RSA_PRIVATE_KEY *key); + +int +R_VerifyInit(R_SIGNATURE_CTX *ctx, + int digestAlgorithm); + +int +R_VerifyUpdate(R_SIGNATURE_CTX *ctx, + const uint8_t *data, + /* Length is an unsigned char according to rsaref.txt, + * but that must be a typo. */ + unsigned length); + +int +R_VerifyFinal(R_SIGNATURE_CTX *ctx, + uint8_t *signature, + unsigned length, + R_RSA_PUBLIC_KEY *key); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_RSA_COMPAT_H_INCLUDED */ diff --git a/rsa-decrypt.c b/rsa-decrypt.c new file mode 100644 index 0000000..973fa65 --- /dev/null +++ b/rsa-decrypt.c @@ -0,0 +1,80 @@ +/* rsa_decrypt.c + * + * The RSA publickey algorithm. PKCS#1 encryption. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "rsa.h" + +#include "bignum.h" +#include "nettle-internal.h" + +int +rsa_decrypt(const struct rsa_private_key *key, + unsigned *length, uint8_t *message, + const mpz_t gibberish) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + uint8_t *terminator; + unsigned padding; + unsigned message_length; + + mpz_t m; + + mpz_init(m); + rsa_compute_root(key, m, gibberish); + + TMP_ALLOC(em, key->size); + nettle_mpz_get_str_256(key->size, em, m); + mpz_clear(m); + + /* Check format */ + if (em[0] || em[1] != 2) + return 0; + + terminator = memchr(em + 2, 0, key->size - 2); + + if (!terminator) + return 0; + + padding = terminator - (em + 2); + if (padding < 8) + return 0; + + message_length = key->size - 3 - padding; + + if (*length < message_length) + return 0; + + memcpy(message, terminator + 1, message_length); + *length = message_length; + + return 1; +} diff --git a/rsa-encrypt.c b/rsa-encrypt.c new file mode 100644 index 0000000..a901e71 --- /dev/null +++ b/rsa-encrypt.c @@ -0,0 +1,83 @@ +/* rsa_encrypt.c + * + * The RSA publickey algorithm. PKCS#1 encryption. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "rsa.h" + +#include "bignum.h" +#include "nettle-internal.h" + +int +rsa_encrypt(const struct rsa_public_key *key, + /* For padding */ + void *random_ctx, nettle_random_func random, + unsigned length, const uint8_t *message, + mpz_t gibbberish) +{ + TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_BITS / 8); + unsigned padding; + unsigned i; + + /* The message is encoded as a string of the same length as the + * modulo n, of the form + * + * 00 02 pad 00 message + * + * where padding should be at least 8 pseudorandomly generated + * *non-zero* octets. */ + + if (length + 11 > key->size) + /* Message too long for this key. */ + return 0; + + /* At least 8 octets of random padding */ + padding = key->size - length - 3; + assert(padding >= 8); + + TMP_ALLOC(em, key->size - 1); + em[0] = 2; + + random(random_ctx, padding, em + 1); + + /* Replace 0-octets with 1 */ + for (i = 0; isize - 1, em); + mpz_powm(gibbberish, gibbberish, key->e, key->n); + + return 1; +} diff --git a/rsa-keygen.c b/rsa-keygen.c new file mode 100644 index 0000000..8c56bb4 --- /dev/null +++ b/rsa-keygen.c @@ -0,0 +1,204 @@ +/* rsa-keygen.c + * + * Generation of RSA keypairs + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "rsa.h" +#include "bignum.h" + +#ifndef DEBUG +# define DEBUG 0 +#endif + +#if DEBUG +# include +#endif + + +int +rsa_generate_keypair(struct rsa_public_key *pub, + struct rsa_private_key *key, + void *random_ctx, nettle_random_func random, + void *progress_ctx, nettle_progress_func progress, + unsigned n_size, + unsigned e_size) +{ + mpz_t p1; + mpz_t q1; + mpz_t phi; + mpz_t tmp; + + if (e_size) + { + /* We should choose e randomly. Is the size reasonable? */ + if ((e_size < 16) || (e_size >= n_size) ) + return 0; + } + else + { + /* We have a fixed e. Check that it makes sense */ + + /* It must be odd */ + if (!mpz_tstbit(pub->e, 0)) + return 0; + + /* And 3 or larger */ + if (mpz_cmp_ui(pub->e, 3) < 0) + return 0; + + /* And size less than n */ + if (mpz_sizeinbase(pub->e, 2) >= n_size) + return 0; + } + + if (n_size < RSA_MINIMUM_N_BITS) + return 0; + + mpz_init(p1); mpz_init(q1); mpz_init(phi); mpz_init(tmp); + + /* Generate primes */ + for (;;) + { + /* Generate p, such that gcd(p-1, e) = 1 */ + for (;;) + { + nettle_random_prime(key->p, (n_size+1)/2, 1, + random_ctx, random, + progress_ctx, progress); + + mpz_sub_ui(p1, key->p, 1); + + /* If e was given, we must chose p such that p-1 has no factors in + * common with e. */ + if (e_size) + break; + + mpz_gcd(tmp, pub->e, p1); + + if (mpz_cmp_ui(tmp, 1) == 0) + break; + else if (progress) progress(progress_ctx, 'c'); + } + + if (progress) + progress(progress_ctx, '\n'); + + /* Generate q, such that gcd(q-1, e) = 1 */ + for (;;) + { + nettle_random_prime(key->q, n_size/2, 1, + random_ctx, random, + progress_ctx, progress); + + /* Very unlikely. */ + if (mpz_cmp (key->q, key->p) == 0) + continue; + + mpz_sub_ui(q1, key->q, 1); + + /* If e was given, we must chose q such that q-1 has no factors in + * common with e. */ + if (e_size) + break; + + mpz_gcd(tmp, pub->e, q1); + + if (mpz_cmp_ui(tmp, 1) == 0) + break; + else if (progress) progress(progress_ctx, 'c'); + } + + /* Now we have the primes. Is the product of the right size? */ + mpz_mul(pub->n, key->p, key->q); + + assert (mpz_sizeinbase(pub->n, 2) == n_size); + + if (progress) + progress(progress_ctx, '\n'); + + /* c = q^{-1} (mod p) */ + if (mpz_invert(key->c, key->q, key->p)) + /* This should succeed everytime. But if it doesn't, + * we try again. */ + break; + else if (progress) progress(progress_ctx, '?'); + } + + mpz_mul(phi, p1, q1); + + /* If we didn't have a given e, generate one now. */ + if (e_size) + { + int retried = 0; + for (;;) + { + nettle_mpz_random_size(pub->e, + random_ctx, random, + e_size); + + /* Make sure it's odd and that the most significant bit is + * set */ + mpz_setbit(pub->e, 0); + mpz_setbit(pub->e, e_size - 1); + + /* Needs gmp-3, or inverse might be negative. */ + if (mpz_invert(key->d, pub->e, phi)) + break; + + if (progress) progress(progress_ctx, 'e'); + retried = 1; + } + if (retried && progress) + progress(progress_ctx, '\n'); + } + else + { + /* Must always succeed, as we already that e + * doesn't have any common factor with p-1 or q-1. */ + int res = mpz_invert(key->d, pub->e, phi); + assert(res); + } + + /* Done! Almost, we must compute the auxillary private values. */ + /* a = d % (p-1) */ + mpz_fdiv_r(key->a, key->d, p1); + + /* b = d % (q-1) */ + mpz_fdiv_r(key->b, key->d, q1); + + /* c was computed earlier */ + + pub->size = key->size = (n_size + 7) / 8; + assert(pub->size >= RSA_MINIMUM_N_OCTETS); + + mpz_clear(p1); mpz_clear(q1); mpz_clear(phi); mpz_clear(tmp); + + return 1; +} diff --git a/rsa-md5-sign.c b/rsa-md5-sign.c new file mode 100644 index 0000000..166cba7 --- /dev/null +++ b/rsa-md5-sign.c @@ -0,0 +1,73 @@ +/* rsa-md5-sign.c + * + * Signatures using RSA and MD5. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_md5_sign(const struct rsa_private_key *key, + struct md5_ctx *hash, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_md5_encode(s, key->size - 1, hash)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} + +int +rsa_md5_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_md5_encode_digest(s, key->size - 1, digest)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} diff --git a/rsa-md5-verify.c b/rsa-md5-verify.c new file mode 100644 index 0000000..f8931c7 --- /dev/null +++ b/rsa-md5-verify.c @@ -0,0 +1,73 @@ +/* rsa-md5-verify.c + * + * Verifying signatures created with RSA and MD5. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_md5_verify(const struct rsa_public_key *key, + struct md5_ctx *hash, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_md5_encode(m, key->size - 1, hash) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} + +int +rsa_md5_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_md5_encode_digest(m, key->size - 1, digest) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} diff --git a/rsa-sha1-sign.c b/rsa-sha1-sign.c new file mode 100644 index 0000000..f120c7b --- /dev/null +++ b/rsa-sha1-sign.c @@ -0,0 +1,73 @@ +/* rsa-sha1-sign.c + * + * Signatures using RSA and SHA1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_sha1_sign(const struct rsa_private_key *key, + struct sha1_ctx *hash, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_sha1_encode(s, key->size - 1, hash)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} + +int +rsa_sha1_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_sha1_encode_digest(s, key->size - 1, digest)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} diff --git a/rsa-sha1-verify.c b/rsa-sha1-verify.c new file mode 100644 index 0000000..71ed848 --- /dev/null +++ b/rsa-sha1-verify.c @@ -0,0 +1,73 @@ +/* rsa-sha1-verify.c + * + * Verifying signatures created with RSA and SHA1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_sha1_verify(const struct rsa_public_key *key, + struct sha1_ctx *hash, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_sha1_encode(m, key->size - 1, hash) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} + +int +rsa_sha1_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_sha1_encode_digest(m, key->size - 1, digest) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} diff --git a/rsa-sha256-sign.c b/rsa-sha256-sign.c new file mode 100644 index 0000000..5f3cf7c --- /dev/null +++ b/rsa-sha256-sign.c @@ -0,0 +1,73 @@ +/* rsa-sha256-sign.c + * + * Signatures using RSA and SHA256. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003, 2006 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_sha256_sign(const struct rsa_private_key *key, + struct sha256_ctx *hash, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_sha256_encode(s, key->size - 1, hash)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} + +int +rsa_sha256_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_sha256_encode_digest(s, key->size - 1, digest)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} diff --git a/rsa-sha256-verify.c b/rsa-sha256-verify.c new file mode 100644 index 0000000..ef3f1e3 --- /dev/null +++ b/rsa-sha256-verify.c @@ -0,0 +1,73 @@ +/* rsa-sha256-verify.c + * + * Verifying signatures created with RSA and SHA256. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003, 2006 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_sha256_verify(const struct rsa_public_key *key, + struct sha256_ctx *hash, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_sha256_encode(m, key->size - 1, hash) + &&_rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} + +int +rsa_sha256_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_sha256_encode_digest(m, key->size - 1, digest) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} diff --git a/rsa-sha512-sign.c b/rsa-sha512-sign.c new file mode 100644 index 0000000..fa14487 --- /dev/null +++ b/rsa-sha512-sign.c @@ -0,0 +1,73 @@ +/* rsa-sha512-sign.c + * + * Signatures using RSA and SHA512. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003, 2006, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_sha512_sign(const struct rsa_private_key *key, + struct sha512_ctx *hash, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_sha512_encode(s, key->size - 1, hash)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} + +int +rsa_sha512_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s) +{ + assert(key->size > 0); + + if (pkcs1_rsa_sha512_encode_digest(s, key->size - 1, digest)) + { + rsa_compute_root(key, s, s); + return 1; + } + else + { + mpz_set_ui(s, 0); + return 0; + } +} diff --git a/rsa-sha512-verify.c b/rsa-sha512-verify.c new file mode 100644 index 0000000..869a8f5 --- /dev/null +++ b/rsa-sha512-verify.c @@ -0,0 +1,73 @@ +/* rsa-sha512-verify.c + * + * Verifying signatures created with RSA and SHA512. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003, 2006, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "pkcs1.h" + +int +rsa_sha512_verify(const struct rsa_public_key *key, + struct sha512_ctx *hash, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_sha512_encode(m, key->size - 1, hash) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} + +int +rsa_sha512_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t s) +{ + int res; + mpz_t m; + + assert(key->size > 0); + mpz_init(m); + + res = (pkcs1_rsa_sha512_encode_digest(m, key->size - 1, digest) + && _rsa_verify(key, m, s)); + + mpz_clear(m); + + return res; +} diff --git a/rsa-sign.c b/rsa-sign.c new file mode 100644 index 0000000..aa407ca --- /dev/null +++ b/rsa-sign.c @@ -0,0 +1,136 @@ +/* rsa-sign.c + * + * Creating RSA signatures. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa.h" + +#include "bignum.h" + +void +rsa_private_key_init(struct rsa_private_key *key) +{ + mpz_init(key->d); + mpz_init(key->p); + mpz_init(key->q); + mpz_init(key->a); + mpz_init(key->b); + mpz_init(key->c); + + /* Not really necessary, but it seems cleaner to initialize all the + * storage. */ + key->size = 0; +} + +void +rsa_private_key_clear(struct rsa_private_key *key) +{ + mpz_clear(key->d); + mpz_clear(key->p); + mpz_clear(key->q); + mpz_clear(key->a); + mpz_clear(key->b); + mpz_clear(key->c); +} + +int +rsa_private_key_prepare(struct rsa_private_key *key) +{ + mpz_t n; + + /* The size of the product is the sum of the sizes of the factors, + * or sometimes one less. It's possible but tricky to compute the + * size without computing the full product. */ + + mpz_init(n); + mpz_mul(n, key->p, key->q); + + key->size = _rsa_check_size(n); + + mpz_clear(n); + + return (key->size > 0); +} + +/* Computing an rsa root. */ +void +rsa_compute_root(const struct rsa_private_key *key, + mpz_t x, const mpz_t m) +{ + mpz_t xp; /* modulo p */ + mpz_t xq; /* modulo q */ + + mpz_init(xp); mpz_init(xq); + + /* Compute xq = m^d % q = (m%q)^b % q */ + mpz_fdiv_r(xq, m, key->q); + mpz_powm(xq, xq, key->b, key->q); + + /* Compute xp = m^d % p = (m%p)^a % p */ + mpz_fdiv_r(xp, m, key->p); + mpz_powm(xp, xp, key->a, key->p); + + /* Set xp' = (xp - xq) c % p. */ + mpz_sub(xp, xp, xq); + mpz_mul(xp, xp, key->c); + mpz_fdiv_r(xp, xp, key->p); + + /* Finally, compute x = xq + q xp' + * + * To prove that this works, note that + * + * xp = x + i p, + * xq = x + j q, + * c q = 1 + k p + * + * for some integers i, j and k. Now, for some integer l, + * + * xp' = (xp - xq) c + l p + * = (x + i p - (x + j q)) c + l p + * = (i p - j q) c + l p + * = (i c + l) p - j (c q) + * = (i c + l) p - j (1 + kp) + * = (i c + l - j k) p - j + * + * which shows that xp' = -j (mod p). We get + * + * xq + q xp' = x + j q + (i c + l - j k) p q - j q + * = x + (i c + l - j k) p q + * + * so that + * + * xq + q xp' = x (mod pq) + * + * We also get 0 <= xq + q xp' < p q, because + * + * 0 <= xq < q and 0 <= xp' < p. + */ + mpz_mul(x, key->q, xp); + mpz_add(x, x, xq); + + mpz_clear(xp); mpz_clear(xq); +} diff --git a/rsa-verify.c b/rsa-verify.c new file mode 100644 index 0000000..2e3b52f --- /dev/null +++ b/rsa-verify.c @@ -0,0 +1,56 @@ +/* rsa-verify.c + * + * Verifying RSA signatures. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa.h" + +#include "bignum.h" + +int +_rsa_verify(const struct rsa_public_key *key, + const mpz_t m, + const mpz_t s) +{ + int res; + + mpz_t m1; + + if ( (mpz_sgn(s) <= 0) + || (mpz_cmp(s, key->n) >= 0) ) + return 0; + + mpz_init(m1); + + mpz_powm(m1, s, key->e, key->n); + + res = !mpz_cmp(m, m1); + + mpz_clear(m1); + + return res; +} diff --git a/rsa.c b/rsa.c new file mode 100644 index 0000000..ae20421 --- /dev/null +++ b/rsa.c @@ -0,0 +1,73 @@ +/* rsa.c + * + * The RSA publickey algorithm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa.h" + +#include "bignum.h" + +void +rsa_public_key_init(struct rsa_public_key *key) +{ + mpz_init(key->n); + mpz_init(key->e); + + /* Not really necessary, but it seems cleaner to initialize all the + * storage. */ + key->size = 0; +} + +void +rsa_public_key_clear(struct rsa_public_key *key) +{ + mpz_clear(key->n); + mpz_clear(key->e); +} + +/* Computes the size, in octets, of a the modulo. Returns 0 if the + * modulo is too small to be useful. */ + +unsigned +_rsa_check_size(mpz_t n) +{ + /* Round upwards */ + unsigned size = (mpz_sizeinbase(n, 2) + 7) / 8; + + if (size < RSA_MINIMUM_N_OCTETS) + return 0; + + return size; +} + +int +rsa_public_key_prepare(struct rsa_public_key *key) +{ + key->size = _rsa_check_size(key->n); + + return (key->size > 0); +} diff --git a/rsa.h b/rsa.h new file mode 100644 index 0000000..9631e50 --- /dev/null +++ b/rsa.h @@ -0,0 +1,384 @@ +/* rsa.h + * + * The RSA publickey algorithm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_RSA_H_INCLUDED +#define NETTLE_RSA_H_INCLUDED + +#include +#include "nettle-types.h" + +#include "md5.h" +#include "sha.h" + +/* For nettle_random_func */ +#include "nettle-meta.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define rsa_public_key_init nettle_rsa_public_key_init +#define rsa_public_key_clear nettle_rsa_public_key_clear +#define rsa_public_key_prepare nettle_rsa_public_key_prepare +#define rsa_private_key_init nettle_rsa_private_key_init +#define rsa_private_key_clear nettle_rsa_private_key_clear +#define rsa_private_key_prepare nettle_rsa_private_key_prepare +#define rsa_md5_sign nettle_rsa_md5_sign +#define rsa_md5_verify nettle_rsa_md5_verify +#define rsa_sha1_sign nettle_rsa_sha1_sign +#define rsa_sha1_verify nettle_rsa_sha1_verify +#define rsa_sha256_sign nettle_rsa_sha256_sign +#define rsa_sha256_verify nettle_rsa_sha256_verify +#define rsa_sha512_sign nettle_rsa_sha512_sign +#define rsa_sha512_verify nettle_rsa_sha512_verify +#define rsa_md5_sign_digest nettle_rsa_md5_sign_digest +#define rsa_md5_verify_digest nettle_rsa_md5_verify_digest +#define rsa_sha1_sign_digest nettle_rsa_sha1_sign_digest +#define rsa_sha1_verify_digest nettle_rsa_sha1_verify_digest +#define rsa_sha256_sign_digest nettle_rsa_sha256_sign_digest +#define rsa_sha256_verify_digest nettle_rsa_sha256_verify_digest +#define rsa_sha512_sign_digest nettle_rsa_sha512_sign_digest +#define rsa_sha512_verify_digest nettle_rsa_sha512_verify_digest +#define rsa_encrypt nettle_rsa_encrypt +#define rsa_decrypt nettle_rsa_decrypt +#define rsa_compute_root nettle_rsa_compute_root +#define rsa_generate_keypair nettle_rsa_generate_keypair +#define rsa_keypair_to_sexp nettle_rsa_keypair_to_sexp +#define rsa_keypair_from_sexp_alist nettle_rsa_keypair_from_sexp_alist +#define rsa_keypair_from_sexp nettle_rsa_keypair_from_sexp +#define rsa_public_key_from_der_iterator nettle_rsa_public_key_from_der_iterator +#define rsa_private_key_from_der_iterator nettle_rsa_private_key_from_der_iterator +#define rsa_keypair_from_der nettle_rsa_keypair_from_der +#define rsa_keypair_to_openpgp nettle_rsa_keypair_to_openpgp +#define _rsa_verify _nettle_rsa_verify +#define _rsa_check_size _nettle_rsa_check_size + +/* This limit is somewhat arbitrary. Technically, the smallest modulo + which makes sense at all is 15 = 3*5, phi(15) = 8, size 4 bits. But + for ridiculously small keys, not all odd e are possible (e.g., for + 5 bits, the only possible modulo is 3*7 = 21, phi(21) = 12, and e = + 3 don't work). The smallest size that makes sense with pkcs#1, and + which allows RSA encryption of one byte messages, is 12 octets, 89 + bits. */ + +#define RSA_MINIMUM_N_OCTETS 12 +#define RSA_MINIMUM_N_BITS (8*RSA_MINIMUM_N_OCTETS - 7) + +struct rsa_public_key +{ + /* Size of the modulo, in octets. This is also the size of all + * signatures that are created or verified with this key. */ + unsigned size; + + /* Modulo */ + mpz_t n; + + /* Public exponent */ + mpz_t e; +}; + +struct rsa_private_key +{ + unsigned size; + + /* d is filled in by the key generation function; otherwise it's + * completely unused. */ + mpz_t d; + + /* The two factors */ + mpz_t p; mpz_t q; + + /* d % (p-1), i.e. a e = 1 (mod (p-1)) */ + mpz_t a; + + /* d % (q-1), i.e. b e = 1 (mod (q-1)) */ + mpz_t b; + + /* modular inverse of q , i.e. c q = 1 (mod p) */ + mpz_t c; +}; + +/* Signing a message works as follows: + * + * Store the private key in a rsa_private_key struct. + * + * Call rsa_private_key_prepare. This initializes the size attribute + * to the length of a signature. + * + * Initialize a hashing context, by callling + * md5_init + * + * Hash the message by calling + * md5_update + * + * Create the signature by calling + * rsa_md5_sign + * + * The signature is represented as a mpz_t bignum. This call also + * resets the hashing context. + * + * When done with the key and signature, don't forget to call + * mpz_clear. + */ + +/* Calls mpz_init to initialize bignum storage. */ +void +rsa_public_key_init(struct rsa_public_key *key); + +/* Calls mpz_clear to deallocate bignum storage. */ +void +rsa_public_key_clear(struct rsa_public_key *key); + +int +rsa_public_key_prepare(struct rsa_public_key *key); + +/* Calls mpz_init to initialize bignum storage. */ +void +rsa_private_key_init(struct rsa_private_key *key); + +/* Calls mpz_clear to deallocate bignum storage. */ +void +rsa_private_key_clear(struct rsa_private_key *key); + +int +rsa_private_key_prepare(struct rsa_private_key *key); + + +/* PKCS#1 style signatures */ +int +rsa_md5_sign(const struct rsa_private_key *key, + struct md5_ctx *hash, + mpz_t signature); + + +int +rsa_md5_verify(const struct rsa_public_key *key, + struct md5_ctx *hash, + const mpz_t signature); + +int +rsa_sha1_sign(const struct rsa_private_key *key, + struct sha1_ctx *hash, + mpz_t signature); + +int +rsa_sha1_verify(const struct rsa_public_key *key, + struct sha1_ctx *hash, + const mpz_t signature); + +int +rsa_sha256_sign(const struct rsa_private_key *key, + struct sha256_ctx *hash, + mpz_t signature); + +int +rsa_sha256_verify(const struct rsa_public_key *key, + struct sha256_ctx *hash, + const mpz_t signature); + +int +rsa_sha512_sign(const struct rsa_private_key *key, + struct sha512_ctx *hash, + mpz_t signature); + +int +rsa_sha512_verify(const struct rsa_public_key *key, + struct sha512_ctx *hash, + const mpz_t signature); + +/* Variants taking the digest as argument. */ +int +rsa_md5_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s); + +int +rsa_md5_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t signature); + +int +rsa_sha1_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s); + +int +rsa_sha1_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t signature); + +int +rsa_sha256_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s); + +int +rsa_sha256_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t signature); + +int +rsa_sha512_sign_digest(const struct rsa_private_key *key, + const uint8_t *digest, + mpz_t s); + +int +rsa_sha512_verify_digest(const struct rsa_public_key *key, + const uint8_t *digest, + const mpz_t signature); + + +/* RSA encryption, using PKCS#1 */ +/* These functions uses the v1.5 padding. What should the v2 (OAEP) + * functions be called? */ + +/* Returns 1 on success, 0 on failure, which happens if the + * message is too long for the key. */ +int +rsa_encrypt(const struct rsa_public_key *key, + /* For padding */ + void *random_ctx, nettle_random_func random, + unsigned length, const uint8_t *cleartext, + mpz_t cipher); + +/* Message must point to a buffer of size *LENGTH. KEY->size is enough + * for all valid messages. On success, *LENGTH is updated to reflect + * the actual length of the message. Returns 1 on success, 0 on + * failure, which happens if decryption failed or if the message + * didn't fit. */ +int +rsa_decrypt(const struct rsa_private_key *key, + unsigned *length, uint8_t *cleartext, + const mpz_t ciphertext); + +/* Compute x, the e:th root of m. Calling it with x == m is allowed. */ +void +rsa_compute_root(const struct rsa_private_key *key, + mpz_t x, const mpz_t m); + + +/* Key generation */ + +/* Note that the key structs must be initialized first. */ +int +rsa_generate_keypair(struct rsa_public_key *pub, + struct rsa_private_key *key, + + void *random_ctx, nettle_random_func random, + void *progress_ctx, nettle_progress_func progress, + + /* Desired size of modulo, in bits */ + unsigned n_size, + + /* Desired size of public exponent, in bits. If + * zero, the passed in value pub->e is used. */ + unsigned e_size); + + +#define RSA_SIGN(key, algorithm, ctx, length, data, signature) ( \ + algorithm##_update(ctx, length, data), \ + rsa_##algorithm##_sign(key, ctx, signature) \ +) + +#define RSA_VERIFY(key, algorithm, ctx, length, data, signature) ( \ + algorithm##_update(ctx, length, data), \ + rsa_##algorithm##_verify(key, ctx, signature) \ +) + + +/* Keys in sexp form. */ + +struct nettle_buffer; + +/* Generates a public-key expression if PRIV is NULL .*/ +int +rsa_keypair_to_sexp(struct nettle_buffer *buffer, + const char *algorithm_name, /* NULL means "rsa" */ + const struct rsa_public_key *pub, + const struct rsa_private_key *priv); + +struct sexp_iterator; + +int +rsa_keypair_from_sexp_alist(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + struct sexp_iterator *i); + +/* If PRIV is NULL, expect a public-key expression. If PUB is NULL, + * expect a private key expression and ignore the parts not needed for + * the public key. */ +/* Keys must be initialized before calling this function, as usual. */ +int +rsa_keypair_from_sexp(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + unsigned length, const uint8_t *expr); + + +/* Keys in PKCS#1 format. */ +struct asn1_der_iterator; + +int +rsa_public_key_from_der_iterator(struct rsa_public_key *pub, + unsigned limit, + struct asn1_der_iterator *i); + +int +rsa_private_key_from_der_iterator(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + struct asn1_der_iterator *i); + +/* For public keys, use PRIV == NULL */ +int +rsa_keypair_from_der(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + unsigned length, const uint8_t *data); + +/* OpenPGP format. Experimental interface, subject to change. */ +int +rsa_keypair_to_openpgp(struct nettle_buffer *buffer, + const struct rsa_public_key *pub, + const struct rsa_private_key *priv, + /* A single user id. NUL-terminated utf8. */ + const char *userid); + +/* Internal functions. */ +int +_rsa_verify(const struct rsa_public_key *key, + const mpz_t m, + const mpz_t s); + +unsigned +_rsa_check_size(mpz_t n); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_RSA_H_INCLUDED */ diff --git a/rsa2openpgp.c b/rsa2openpgp.c new file mode 100644 index 0000000..f129ff7 --- /dev/null +++ b/rsa2openpgp.c @@ -0,0 +1,102 @@ +/* rsa2openpgp.c + * + * Converting rsa keys to OpenPGP format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "rsa.h" + +#include "buffer.h" +#include "pgp.h" + + +/* According to RFC 2440, a public key consists of the following packets: + * + * Public key packet + * + * Zero or more revocation signatures + * + * One or more User ID packets + * + * After each User ID packet, zero or more signature packets + * + * Zero or more Subkey packets + * + * After each Subkey packet, one signature packet, optionally a + * revocation. + * + * Currently, we generate a public key packet, a single user id, and a + * signature. */ + +int +rsa_keypair_to_openpgp(struct nettle_buffer *buffer, + const struct rsa_public_key *pub, + const struct rsa_private_key *priv, + /* A single user id. NUL-terminated utf8. */ + const char *userid) +{ + time_t now = time(NULL); + + unsigned key_start; + unsigned key_length; + unsigned userid_start; + + struct sha1_ctx key_hash; + struct sha1_ctx signature_hash; + uint8_t fingerprint[SHA1_DIGEST_SIZE]; + + key_start = buffer->size; + + if (!pgp_put_public_rsa_key(buffer, pub, now)) + return 0; + + /* userid packet */ + userid_start = buffer->size; + if (!pgp_put_userid(buffer, strlen(userid), userid)) + return 0; + + /* FIXME: We hash the key first, and then the user id. Is this right? */ + sha1_init(&key_hash); + sha1_update(&key_hash, + userid_start - key_start, + buffer->contents + key_start); + + signature_hash = key_hash; + sha1_digest(&key_hash, sizeof(fingerprint), fingerprint); + + sha1_update(&signature_hash, + buffer->size - userid_start, + buffer->contents + userid_start); + + return pgp_put_rsa_sha1_signature(buffer, + priv, + fingerprint + SHA1_DIGEST_SIZE - 8, + PGP_SIGN_CERTIFICATION, + &signature_hash); +} diff --git a/rsa2sexp.c b/rsa2sexp.c new file mode 100644 index 0000000..8578ec3 --- /dev/null +++ b/rsa2sexp.c @@ -0,0 +1,52 @@ +/* rsa2sexp.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rsa.h" + +#include "sexp.h" + +int +rsa_keypair_to_sexp(struct nettle_buffer *buffer, + const char *algorithm_name, + const struct rsa_public_key *pub, + const struct rsa_private_key *priv) +{ + if (!algorithm_name) + algorithm_name = "rsa-pkcs1"; + + if (priv) + return sexp_format(buffer, + "(private-key(%0s(n%b)(e%b)" + "(d%b)(p%b)(q%b)(a%b)(b%b)(c%b)))", + algorithm_name, pub->n, pub->e, + priv->d, priv->p, priv->q, + priv->a, priv->b, priv->c); + else + return sexp_format(buffer, "(public-key(%0s(n%b)(e%b)))", + algorithm_name, pub->n, pub->e); +} diff --git a/serpent-meta.c b/serpent-meta.c new file mode 100644 index 0000000..204d2a1 --- /dev/null +++ b/serpent-meta.c @@ -0,0 +1,38 @@ +/* serpent-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "serpent.h" + +const struct nettle_cipher nettle_serpent128 += _NETTLE_CIPHER(serpent, SERPENT, 128); + +const struct nettle_cipher nettle_serpent192 += _NETTLE_CIPHER(serpent, SERPENT, 192); + +const struct nettle_cipher nettle_serpent256 += _NETTLE_CIPHER(serpent, SERPENT, 256); diff --git a/serpent.c b/serpent.c new file mode 100644 index 0000000..65344b0 --- /dev/null +++ b/serpent.c @@ -0,0 +1,374 @@ +/* serpent.h + * + * The serpent block cipher. + * + * For more details on this algorithm, see the Serpent website at + * http://www.cl.cam.ac.uk/~rja14/serpent.html + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 1998, 2000, 2001, Ross Anderson, Eli Biham, Lars + * Knudsen, Rafael R. Sevilla, Niels Möller + * + * 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 + */ + +/* I've modified this code a bit so that it interoperates with lsh + * properly. 2000-9-5, Rafael R. Sevilla + */ + +/* NOTE: The copyright notice for the original version of this code + * said "All rights reserved. This code is freely distributed for AES + * selection process. No other use is allowed." However, the authors + * later decided to GPL the code. /nisse */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "serpent.h" +#include "serpent_sboxes.h" + +#include "macros.h" + +void +serpent_set_key(struct serpent_ctx *ctx, + unsigned key_size, const uint8_t *key) +{ + unsigned i, j; + uint32_t w[132], k[132]; + + assert(key_size >= SERPENT_MIN_KEY_SIZE); + assert(key_size <= SERPENT_MAX_KEY_SIZE); + + for (i = key_size, j = 0; + (i >= 4); + i-=4, j++) + { + assert(j<8); + /* Read the key in the reverse direction. Why? */ + w[j] = READ_UINT32(key + i - 4); + } + + if (j < 8) + { + /* Pad key, "aabbccddeeff" -> 0xccddeeff, 0x01aabb" */ + uint32_t partial = 0x01; + while (i) + partial = (partial << 8 ) | *key++; + w[j++] = partial; + + while (j < 8) + w[j++] = 0; + } + + for(i=8; i<16; i++) + w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11); + for(i=0; i<8; i++) + w[i]=w[i+8]; + for(i=8; i<132; i++) + w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11); + + RND03(w[ 0], w[ 1], w[ 2], w[ 3], k[ 0], k[ 1], k[ 2], k[ 3]); + RND02(w[ 4], w[ 5], w[ 6], w[ 7], k[ 4], k[ 5], k[ 6], k[ 7]); + RND01(w[ 8], w[ 9], w[ 10], w[ 11], k[ 8], k[ 9], k[ 10], k[ 11]); + RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]); + RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]); + RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]); + RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]); + RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]); + RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]); + RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]); + RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]); + RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]); + RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]); + RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]); + RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]); + RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]); + RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]); + RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]); + RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]); + RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]); + RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]); + RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]); + RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]); + RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]); + RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]); + RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]); + RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]); + RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]); + RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]); + RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]); + RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]); + RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]); + RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]); + + for(i=0; i<=32; i++) + for(j=0; j<4; j++) + ctx->keys[i][j] = k[4*i+j]; +} + +void +serpent_encrypt(const struct serpent_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *plain) +{ + register uint32_t x0, x1, x2, x3; + register uint32_t y0, y1, y2, y3; + + FOR_BLOCKS(length, dst, plain, SERPENT_BLOCK_SIZE) + { + /* Why the reverse order? */ + x0=READ_UINT32(plain + 12); + x1=READ_UINT32(plain + 8); + x2=READ_UINT32(plain + 4); + x3=READ_UINT32(plain); + + /* Start to encrypt the plaintext x */ + keying(x0, x1, x2, x3, ctx->keys[ 0]); + RND00(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 1]); + RND01(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 2]); + RND02(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 3]); + RND03(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 4]); + RND04(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 5]); + RND05(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 6]); + RND06(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 7]); + RND07(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 8]); + RND08(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[ 9]); + RND09(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[10]); + RND10(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[11]); + RND11(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[12]); + RND12(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[13]); + RND13(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[14]); + RND14(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[15]); + RND15(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[16]); + RND16(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[17]); + RND17(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[18]); + RND18(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[19]); + RND19(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[20]); + RND20(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[21]); + RND21(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[22]); + RND22(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[23]); + RND23(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[24]); + RND24(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[25]); + RND25(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[26]); + RND26(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[27]); + RND27(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[28]); + RND28(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[29]); + RND29(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[30]); + RND30(x0, x1, x2, x3, y0, y1, y2, y3); + transform(y0, y1, y2, y3, x0, x1, x2, x3); + keying(x0, x1, x2, x3, ctx->keys[31]); + RND31(x0, x1, x2, x3, y0, y1, y2, y3); + x0 = y0; x1 = y1; x2 = y2; x3 = y3; + keying(x0, x1, x2, x3, ctx->keys[32]); + + /* The ciphertext is now in x */ + + /* Why the reverse order? */ + WRITE_UINT32(dst, x3); + WRITE_UINT32(dst+4, x2); + WRITE_UINT32(dst+8, x1); + WRITE_UINT32(dst+12, x0); + } +} + +void +serpent_decrypt(const struct serpent_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *cipher) +{ + register uint32_t x0, x1, x2, x3; + register uint32_t y0, y1, y2, y3; + + FOR_BLOCKS(length, dst, cipher, SERPENT_BLOCK_SIZE) + { + /* Why the reverse order? */ + x0 = READ_UINT32(cipher + 12); + x1 = READ_UINT32(cipher + 8); + x2 = READ_UINT32(cipher + 4); + x3 = READ_UINT32(cipher); + + /* Start to decrypt the ciphertext x */ + keying(x0, x1, x2, x3, ctx->keys[32]); + InvRND31(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[31]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND30(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[30]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND29(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[29]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND28(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[28]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND27(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[27]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND26(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[26]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND25(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[25]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND24(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[24]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND23(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[23]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND22(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[22]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND21(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[21]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND20(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[20]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND19(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[19]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND18(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[18]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND17(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[17]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND16(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[16]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND15(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[15]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND14(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[14]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND13(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[13]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND12(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[12]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND11(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[11]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND10(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[10]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND09(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 9]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND08(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 8]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND07(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 7]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND06(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 6]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND05(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 5]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND04(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 4]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND03(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 3]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND02(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 2]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND01(x0, x1, x2, x3, y0, y1, y2, y3); + keying(y0, y1, y2, y3, ctx->keys[ 1]); + inv_transform(y0, y1, y2, y3, x0, x1, x2, x3); + InvRND00(x0, x1, x2, x3, y0, y1, y2, y3); + x0 = y0; x1 = y1; x2 = y2; x3 = y3; + keying(x0, x1, x2, x3, ctx->keys[ 0]); + + /* The plaintext is now in x */ + + /* Why the reverse order? */ + WRITE_UINT32(dst, x3); + WRITE_UINT32(dst+4, x2); + WRITE_UINT32(dst+8, x1); + WRITE_UINT32(dst+12, x0); + } +} diff --git a/serpent.h b/serpent.h new file mode 100644 index 0000000..2ae1da7 --- /dev/null +++ b/serpent.h @@ -0,0 +1,81 @@ +/* serpent.h + * + * The serpent block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Serpent is a 128-bit block cipher that accepts a key size of 256 + * bits, designed by Ross Anderson, Eli Biham, and Lars Knudsen. See + * http://www.cl.cam.ac.uk/~rja14/serpent.html for details. + */ + +#ifndef NETTLE_SERPENT_H_INCLUDED +#define NETTLE_SERPENT_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define serpent_set_key nettle_serpent_set_key +#define serpent_encrypt nettle_serpent_encrypt +#define serpent_decrypt nettle_serpent_decrypt + +#define SERPENT_BLOCK_SIZE 16 + +/* Other key lengths are possible, but the design of Serpent makes + * smaller key lengths quite pointless; they cheated with the AES + * requirements, using a 256-bit key length exclusively and just + * padding it out if the desired key length was less, so there really + * is no advantage to using key lengths less than 256 bits. */ +#define SERPENT_KEY_SIZE 32 + +/* Allow keys of size 128 <= bits <= 256 */ + +#define SERPENT_MIN_KEY_SIZE 16 +#define SERPENT_MAX_KEY_SIZE 32 + +struct serpent_ctx +{ + uint32_t keys[33][4]; /* key schedule */ +}; + +void +serpent_set_key(struct serpent_ctx *ctx, + unsigned length, const uint8_t *key); + +void +serpent_encrypt(const struct serpent_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +serpent_decrypt(const struct serpent_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_SERPENT_H_INCLUDED */ diff --git a/serpent_sboxes.h b/serpent_sboxes.h new file mode 100644 index 0000000..5f94025 --- /dev/null +++ b/serpent_sboxes.h @@ -0,0 +1,511 @@ +/* serpentsboxes.h + * + * $Id: serpent_sboxes.h,v 1.1 2007/04/05 14:20:35 nisse Exp $ + * + * For more details on this algorithm, see the Serpent website at + * http://www.cl.cam.ac.uk/~rja14/serpent.html + */ + +/* Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen + * + * 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 + */ + +/* I've modified this code a bit so that it interoperates with lsh + * properly. 2000-9-5, Rafael R. Sevilla + */ + +/* NOTE: The copyright notice for the original version of this code + * said "All rights reserved. This code is freely distributed for AES + * selection process. No other use is allowed." However, the authors + * later decided to GPL the code. /nisse */ + +#ifndef SERPENT_SBOXES_H_INCLUDED +#define SERPENT_SBOXES_H_INCLUDED + +#include "serpent.h" + +/* S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12 */ + +/* depth = 5,7,4,2, Total gates=18 */ +#define RND00(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t05, t06, t07, t08, t09, 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; } + +/* InvS0: 13 3 11 0 10 6 5 12 1 14 4 7 15 9 8 2 */ + +/* depth = 8,4,3,6, Total gates=19 */ +#define InvRND00(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, 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; } + +/* S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4 */ + +/* depth = 10,7,3,5, Total gates=18 */ +#define RND01(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, 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; } + +/* InvS1: 5 8 2 14 15 6 12 3 11 4 7 9 1 13 10 0 */ + +/* depth = 7,4,5,3, Total gates=18 */ +#define InvRND01(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, 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; } + +/* S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2 */ + +/* depth = 3,8,11,7, Total gates=16 */ +#define RND02(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t05, t06, t07, t08, 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; } + +/* InvS2: 12 9 15 4 11 14 1 2 0 3 6 13 5 8 10 7 */ + +/* depth = 3,6,8,3, Total gates=18 */ +#define InvRND02(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t06, t07, t08, t09, 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; } + +/* S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14 */ + +/* depth = 8,3,5,5, Total gates=18 */ +#define RND03(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, 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; } + +/* InvS3: 0 9 10 7 11 14 6 13 3 5 12 2 4 8 15 1 */ + +/* depth = 3,6,4,4, Total gates=17 */ +#define InvRND03(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t09, 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; } + +/* S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13 */ + +/* depth = 6,7,5,3, Total gates=19 */ +#define RND04(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t08, t09, 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; } + +/* InvS4: 5 0 8 3 10 9 7 14 2 12 11 6 4 15 13 1 */ + +/* depth = 6,4,7,3, Total gates=17 */ +#define InvRND04(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t09, 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; } + +/* S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1 */ + +/* depth = 4,6,8,6, Total gates=17 */ +#define RND05(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t07, t08, t09, 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; } + +/* InvS5: 8 15 2 9 4 1 13 14 11 6 5 3 7 12 10 0 */ + +/* depth = 4,6,9,7, Total gates=17 */ +#define InvRND05(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t07, t08, t09, 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; } + +/* S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0 */ + +/* depth = 8,3,6,3, Total gates=19 */ +#define RND06(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t07, t08, t09, t10, 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; } + +/* InvS6: 15 10 1 13 5 3 6 0 4 9 14 7 2 12 8 11 */ + +/* depth = 5,3,8,6, Total gates=19 */ +#define InvRND06(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t07, t08, t09, 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; } + +/* S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6 */ + +/* depth = 10,7,10,4, Total gates=19 */ +#define RND07(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, 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; } + +/* InvS7: 3 0 6 13 9 14 15 8 5 12 11 7 10 1 4 2 */ + +/* depth = 9,7,3,3, Total gates=18 */ +#define InvRND07(a,b,c,d,w,x,y,z) \ + { register uint32_t t02, t03, t04, t06, t07, t08, t09, 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; } + +#define RND08(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h) +#define RND09(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h) +#define RND10(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h) +#define RND11(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h) +#define RND12(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h) +#define RND13(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h) +#define RND14(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h) +#define RND15(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h) +#define RND16(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h) +#define RND17(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h) +#define RND18(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h) +#define RND19(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h) +#define RND20(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h) +#define RND21(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h) +#define RND22(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h) +#define RND23(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h) +#define RND24(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h) +#define RND25(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h) +#define RND26(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h) +#define RND27(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h) +#define RND28(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h) +#define RND29(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h) +#define RND30(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h) +#define RND31(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h) + +#define InvRND08(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h) +#define InvRND09(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h) +#define InvRND10(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h) +#define InvRND11(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h) +#define InvRND12(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h) +#define InvRND13(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h) +#define InvRND14(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h) +#define InvRND15(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h) +#define InvRND16(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h) +#define InvRND17(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h) +#define InvRND18(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h) +#define InvRND19(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h) +#define InvRND20(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h) +#define InvRND21(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h) +#define InvRND22(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h) +#define InvRND23(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h) +#define InvRND24(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h) +#define InvRND25(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h) +#define InvRND26(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h) +#define InvRND27(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h) +#define InvRND28(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h) +#define InvRND29(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h) +#define InvRND30(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h) +#define InvRND31(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h) + +/* Linear transformations and key mixing: */ + +#define ROL(x,n) ((((uint32_t)(x))<<(n))| \ + (((uint32_t)(x))>>(32-(n)))) +#define ROR(x,n) ((((uint32_t)(x))<<(32-(n)))| \ + (((uint32_t)(x))>>(n))) + +#define transform(x0, x1, x2, x3, y0, y1, y2, y3) \ + y0 = ROL(x0, 13); \ + y2 = ROL(x2, 3); \ + y1 = x1 ^ y0 ^ y2; \ + y3 = x3 ^ y2 ^ ((uint32_t)y0)<<3; \ + y1 = ROL(y1, 1); \ + y3 = ROL(y3, 7); \ + y0 = y0 ^ y1 ^ y3; \ + y2 = y2 ^ y3 ^ ((uint32_t)y1<<7); \ + y0 = ROL(y0, 5); \ + y2 = ROL(y2, 22) + +#define inv_transform(x0, x1, x2, x3, y0, y1, y2, y3) \ + y2 = ROR(x2, 22);\ + y0 = ROR(x0, 5); \ + y2 = y2 ^ x3 ^ ((uint32_t)x1<<7); \ + y0 = y0 ^ x1 ^ x3; \ + y3 = ROR(x3, 7); \ + y1 = ROR(x1, 1); \ + y3 = y3 ^ y2 ^ ((uint32_t)y0)<<3; \ + y1 = y1 ^ y0 ^ y2; \ + y2 = ROR(y2, 3); \ + y0 = ROR(y0, 13) + +#define keying(x0, x1, x2, x3, subkey) \ + x0^=subkey[0];x1^=subkey[1]; \ + x2^=subkey[2];x3^=subkey[3] + +/* PHI: Constant used in the key schedule */ +#define PHI 0x9e3779b9L + +#endif /* SERPENT_SBOXES_H_INCLUDED */ diff --git a/sexp-format.c b/sexp-format.c new file mode 100644 index 0000000..a3e6d92 --- /dev/null +++ b/sexp-format.c @@ -0,0 +1,333 @@ +/* sexp-format.c + * + * Writing s-expressions. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "sexp.h" +#include "buffer.h" + +#include "bignum.h" + +static unsigned +format_prefix(struct nettle_buffer *buffer, + unsigned length) +{ + unsigned digit = 1; + unsigned prefix_length = 1; + + for (;;) + { + unsigned next = digit * 10; + if (next > length) + break; + + prefix_length++; + digit = next; + } + + if (buffer) + { + for (; digit; length %= digit, digit /= 10) + if (!NETTLE_BUFFER_PUTC(buffer, '0' + length / digit)) + return 0; + + if (!NETTLE_BUFFER_PUTC(buffer, ':')) + return 0; + } + + return prefix_length + 1; +} + +static unsigned +format_string(struct nettle_buffer *buffer, + unsigned length, const uint8_t *s) +{ + unsigned prefix_length = format_prefix(buffer, length); + if (!prefix_length) + return 0; + + if (buffer && !nettle_buffer_write(buffer, length, s)) + return 0; + + return prefix_length + length; +} + +unsigned +sexp_vformat(struct nettle_buffer *buffer, const char *format, va_list args) +{ + unsigned nesting = 0; + unsigned done = 0; + + for (;;) + switch (*format++) + { + default: + { + const char *start = format - 1; + unsigned length = 1 + strcspn(format, "()% \t"); + unsigned output_length = format_string(buffer, length, start); + if (!output_length) + return 0; + + done += output_length; + format = start + length; + + break; + } + case ' ': case '\t': + break; + + case '\0': + assert(!nesting); + + return done; + + case '(': + if (buffer && !NETTLE_BUFFER_PUTC(buffer, '(')) + return 0; + + done++; + nesting++; + break; + + case ')': + assert (nesting); + if (buffer && !NETTLE_BUFFER_PUTC(buffer, ')')) + return 0; + + done++; + nesting--; + break; + + case '%': + { + int nul_flag = 0; + + if (*format == '0') + { + format++; + nul_flag = 1; + } + switch (*format++) + { + default: + abort(); + + case '(': + case ')': + /* Allow unbalanced parenthesis */ + if (buffer && !NETTLE_BUFFER_PUTC(buffer, format[-1])) + return 0; + done++; + break; + + case 's': + { + const char *s; + unsigned length; + unsigned output_length; + + if (nul_flag) + { + s = va_arg(args, const char *); + length = strlen(s); + } + else + { + length = va_arg(args, unsigned); + s = va_arg(args, const char *); + } + + output_length = format_string(buffer, length, s); + if (!output_length) + return 0; + + done += output_length; + break; + } + case 't': + { + const char *s; + unsigned length; + unsigned output_length; + + if (nul_flag) + { + s = va_arg(args, const char *); + if (!s) + break; + + length = strlen(s); + } + else + { + length = va_arg(args, unsigned); + s = va_arg(args, const char *); + if (!s) + break; + } + + if (buffer && !NETTLE_BUFFER_PUTC(buffer, '[')) + return 0; + done++; + + output_length = format_string(buffer, length, s); + + if (!output_length) + return 0; + + done += output_length; + + if (buffer && !NETTLE_BUFFER_PUTC(buffer, ']')) + return 0; + done++; + + break; + } + + case 'l': + { + const char *s; + unsigned length; + + if (nul_flag) + { + s = va_arg(args, const char *); + length = strlen(s); + } + else + { + length = va_arg(args, unsigned); + s = va_arg(args, const char *); + } + + if (buffer && !nettle_buffer_write(buffer, length, s)) + return 0; + + done += length; + break; + } + case 'i': + { + uint32_t x = va_arg(args, uint32_t); + unsigned length; + + if (x < 0x80) + length = 1; + else if (x < 0x8000L) + length = 2; + else if (x < 0x800000L) + length = 3; + else if (x < 0x80000000L) + length = 4; + else + length = 5; + + if (buffer && !(NETTLE_BUFFER_PUTC(buffer, '0' + length) + && NETTLE_BUFFER_PUTC(buffer, ':'))) + return 0; + + done += (2 + length); + + if (buffer) + switch(length) + { + case 5: + /* Leading byte needed for the sign. */ + if (!NETTLE_BUFFER_PUTC(buffer, 0)) + return 0; + /* Fall through */ + case 4: + if (!NETTLE_BUFFER_PUTC(buffer, x >> 24)) + return 0; + /* Fall through */ + case 3: + if (!NETTLE_BUFFER_PUTC(buffer, (x >> 16) & 0xff)) + return 0; + /* Fall through */ + case 2: + if (!NETTLE_BUFFER_PUTC(buffer, (x >> 8) & 0xff)) + return 0; + /* Fall through */ + case 1: + if (!NETTLE_BUFFER_PUTC(buffer, x & 0xff)) + return 0; + break; + default: + abort(); + } + break; + } + case 'b': + { + const MP_INT *n = va_arg(args, const MP_INT *); + unsigned length; + unsigned prefix_length; + + length = nettle_mpz_sizeinbase_256_s(n); + prefix_length = format_prefix(buffer, length); + if (!prefix_length) + return 0; + + done += prefix_length; + + if (buffer) + { + uint8_t *space = nettle_buffer_space(buffer, length); + if (!space) + return 0; + + nettle_mpz_get_str_256(length, space, n); + } + + done += length; + + break; + } + } + } + } +} + +unsigned +sexp_format(struct nettle_buffer *buffer, const char *format, ...) +{ + va_list args; + unsigned done; + + va_start(args, format); + done = sexp_vformat(buffer, format, args); + va_end(args); + + return done; +} diff --git a/sexp-transport-format.c b/sexp-transport-format.c new file mode 100644 index 0000000..db4b193 --- /dev/null +++ b/sexp-transport-format.c @@ -0,0 +1,85 @@ +/* sexp-transport-format.c + * + * Writing s-expressions in transport format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "sexp.h" + +#include "base64.h" +#include "buffer.h" + +unsigned +sexp_transport_vformat(struct nettle_buffer *buffer, + const char *format, va_list args) +{ + unsigned start = 0; + unsigned length; + unsigned base64_length; + + if (buffer) + { + if (!NETTLE_BUFFER_PUTC(buffer, '{')) + return 0; + + start = buffer->size; + } + + length = sexp_vformat(buffer, format, args); + + if (!length) + return 0; + + base64_length = BASE64_ENCODE_RAW_LENGTH(length); + + if (buffer) + { + if (!nettle_buffer_space(buffer, base64_length - length)) + return 0; + + base64_encode_raw(buffer->contents + start, + length, buffer->contents + start); + + if (!NETTLE_BUFFER_PUTC(buffer, '}')) + return 0; + } + + return base64_length + 2; +} + +unsigned +sexp_transport_format(struct nettle_buffer *buffer, + const char *format, ...) +{ + unsigned done; + va_list args; + + va_start(args, format); + done = sexp_transport_vformat(buffer, format, args); + va_end(args); + + return done; +} diff --git a/sexp-transport.c b/sexp-transport.c new file mode 100644 index 0000000..37865e7 --- /dev/null +++ b/sexp-transport.c @@ -0,0 +1,128 @@ +/* sexp-transport.c + * + * Parsing s-expressions in transport format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "sexp.h" + +#include "base64.h" + +/* NOTE: Decodes the input string in place */ +int +sexp_transport_iterator_first(struct sexp_iterator *iterator, + unsigned length, uint8_t *input) +{ + /* We first base64 decode any transport encoded sexp at the start of + * the input. */ + + unsigned in = 0; + unsigned out = 0; + + while (in < length) + switch(input[in]) + { + case ' ': /* SPC, TAB, LF, CR */ + case '\t': + case '\n': + case '\r': + in++; + break; + + case ';': /* Comments */ + while (++in < length && input[in] != '\n') + ; + break; + + case '{': + { + /* Found transport encoding */ + struct base64_decode_ctx ctx; + unsigned coded_length; + unsigned end; + + for (end = ++in; end < length && input[end] != '}'; end++) + ; + + if (end == length) + return 0; + + base64_decode_init(&ctx); + coded_length = end - in; + + if (base64_decode_update(&ctx, &coded_length, input + out, + coded_length, input + in) + && base64_decode_final(&ctx)) + { + out += coded_length; + in = end + 1; + } + else + return 0; + + break; + } + default: + /* Expression isn't in transport encoding. Rest of the input + * should be in canonical encoding. */ + goto transport_done; + } + + transport_done: + + /* Here, we have two, possibly empty, input parts in canonical + * encoding: + * + * 0...out-1, in...length -1 + * + * If the input was already in canonical encoding, out = 0 and in = + * amount of leading space. + * + * If all input was in transport encoding, in == length. + */ + if (!out) + { + input += in; + length -= in; + } + else if (in == length) + length = out; + else if (out == in) + /* Unusual case, nothing happens */ + ; + else + { + /* Both parts non-empty */ + assert(out < in); + memmove(input + out, input + in, length - in); + length -= (in - out); + } + + return sexp_iterator_first(iterator, length, input); +} diff --git a/sexp.c b/sexp.c new file mode 100644 index 0000000..0933e68 --- /dev/null +++ b/sexp.c @@ -0,0 +1,391 @@ +/* sexp.c + * + * Parsing s-expressions. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "sexp.h" + +#include "macros.h" +#include "nettle-internal.h" + +/* Initializes the iterator, but one has to call next to get to the + * first element. */ +static void +sexp_iterator_init(struct sexp_iterator *iterator, + unsigned length, const uint8_t *input) +{ + iterator->length = length; + iterator->buffer = input; + iterator->pos = 0; + iterator->level = 0; + iterator->type = SEXP_END; /* Value doesn't matter */ + iterator->display_length = 0; + iterator->display = NULL; + iterator->atom_length = 0; + iterator->atom = NULL; +} + +#define EMPTY(i) ((i)->pos == (i)->length) +#define NEXT(i) ((i)->buffer[(i)->pos++]) + +static int +sexp_iterator_simple(struct sexp_iterator *iterator, + unsigned *size, + const uint8_t **string) +{ + unsigned length = 0; + uint8_t c; + + if (EMPTY(iterator)) return 0; + c = NEXT(iterator); + if (EMPTY(iterator)) return 0; + + if (c >= '1' && c <= '9') + do + { + length = length * 10 + (c - '0'); + if (length > (iterator->length - iterator->pos)) + return 0; + + if (EMPTY(iterator)) return 0; + c = NEXT(iterator); + } + while (c >= '0' && c <= '9'); + + else if (c == '0') + /* There can be only one */ + c = NEXT(iterator); + else + return 0; + + if (c != ':') + return 0; + + *size = length; + *string = iterator->buffer + iterator->pos; + iterator->pos += length; + + return 1; +} + +/* All these functions return 1 on success, 0 on failure */ + +/* Look at the current position in the data. Sets iterator->type, and + * ignores the old value. */ + +static int +sexp_iterator_parse(struct sexp_iterator *iterator) +{ + iterator->start = iterator->pos; + + if (EMPTY(iterator)) + { + if (iterator->level) + return 0; + + iterator->type = SEXP_END; + return 1; + } + switch (iterator->buffer[iterator->pos]) + { + case '(': /* A list */ + iterator->type = SEXP_LIST; + return 1; + + case ')': + if (!iterator->level) + return 0; + + iterator->pos++; + iterator->type = SEXP_END; + return 1; + + case '[': /* Atom with display type */ + iterator->pos++; + if (!sexp_iterator_simple(iterator, + &iterator->display_length, + &iterator->display)) + return 0; + if (EMPTY(iterator) || NEXT(iterator) != ']') + return 0; + + break; + + default: + /* Must be either a decimal digit or a syntax error. + * Errors are detected by sexp_iterator_simple. */ + iterator->display_length = 0; + iterator->display = NULL; + + break; + } + + iterator->type = SEXP_ATOM; + + return sexp_iterator_simple(iterator, + &iterator->atom_length, + &iterator->atom); +} + +int +sexp_iterator_first(struct sexp_iterator *iterator, + unsigned length, const uint8_t *input) +{ + sexp_iterator_init(iterator, length, input); + return sexp_iterator_parse(iterator); +} + +int +sexp_iterator_next(struct sexp_iterator *iterator) +{ + switch (iterator->type) + { + case SEXP_END: + return 1; + case SEXP_LIST: + /* Skip this list */ + return sexp_iterator_enter_list(iterator) + && sexp_iterator_exit_list(iterator); + case SEXP_ATOM: + /* iterator->pos should already point at the start of the next + * element. */ + return sexp_iterator_parse(iterator); + } + /* If we get here, we have a bug. */ + abort(); +} + +/* Current element must be a list. */ +int +sexp_iterator_enter_list(struct sexp_iterator *iterator) +{ + if (iterator->type != SEXP_LIST) + return 0; + + if (EMPTY(iterator) || NEXT(iterator) != '(') + /* Internal error */ + abort(); + + iterator->level++; + + return sexp_iterator_parse(iterator); +} + +/* Skips the rest of the current list */ +int +sexp_iterator_exit_list(struct sexp_iterator *iterator) +{ + if (!iterator->level) + return 0; + + while(iterator->type != SEXP_END) + if (!sexp_iterator_next(iterator)) + return 0; + + iterator->level--; + + return sexp_iterator_parse(iterator); +} + +#if 0 +/* What's a reasonable interface for this? */ +int +sexp_iterator_exit_lists(struct sexp_iterator *iterator, + unsigned level) +{ + assert(iterator->level >= level); + + while (iterator->level > level) + if (!sexp_iterator_exit_list(iterator)) + return 0; + + return 1; +} +#endif + +const uint8_t * +sexp_iterator_subexpr(struct sexp_iterator *iterator, + unsigned *length) +{ + unsigned start = iterator->start; + if (!sexp_iterator_next(iterator)) + return 0; + + *length = iterator->start - start; + return iterator->buffer + start; +} + +int +sexp_iterator_get_uint32(struct sexp_iterator *iterator, + uint32_t *x) +{ + if (iterator->type == SEXP_ATOM + && !iterator->display + && iterator->atom_length + && iterator->atom[0] < 0x80) + { + unsigned length = iterator->atom_length; + const uint8_t *p = iterator->atom; + + /* Skip leading zeros. */ + while(length && !*p) + { + length--; p++; + } + + switch(length) + { + case 0: + *x = 0; + break; + case 1: + *x = p[0]; + break; + case 2: + *x = READ_UINT16(p); + break; + case 3: + *x = READ_UINT24(p); + break; + case 4: + *x = READ_UINT32(p); + break; + default: + return 0; + } + return sexp_iterator_next(iterator); + } + return 0; +} + +int +sexp_iterator_check_type(struct sexp_iterator *iterator, + const uint8_t *type) +{ + return (sexp_iterator_enter_list(iterator) + && iterator->type == SEXP_ATOM + && !iterator->display + && strlen(type) == iterator->atom_length + && !memcmp(type, iterator->atom, iterator->atom_length) + && sexp_iterator_next(iterator)); +} + +const uint8_t * +sexp_iterator_check_types(struct sexp_iterator *iterator, + unsigned ntypes, + const uint8_t * const *types) +{ + if (sexp_iterator_enter_list(iterator) + && iterator->type == SEXP_ATOM + && !iterator->display) + { + unsigned i; + for (i = 0; iatom_length + && !memcmp(types[i], iterator->atom, + iterator->atom_length)) + return sexp_iterator_next(iterator) ? types[i] : NULL; + } + return NULL; +} + +int +sexp_iterator_assoc(struct sexp_iterator *iterator, + unsigned nkeys, + const uint8_t * const *keys, + struct sexp_iterator *values) +{ + TMP_DECL(found, int, NETTLE_MAX_SEXP_ASSOC); + unsigned nfound; + unsigned i; + + TMP_ALLOC(found, nkeys); + for (i = 0; itype) + { + case SEXP_LIST: + + if (!sexp_iterator_enter_list(iterator)) + return 0; + + if (iterator->type == SEXP_ATOM + && !iterator->display) + { + /* Compare to the given keys */ + for (i = 0; iatom_length + && !memcmp(keys[i], iterator->atom, + iterator->atom_length)) + { + if (found[i]) + /* We don't allow duplicates */ + return 0; + + /* Advance to point to value */ + if (!sexp_iterator_next(iterator)) + return 0; + + found[i] = 1; + nfound++; + + /* Record this position. */ + values[i] = *iterator; + + break; + } + } + } + if (!sexp_iterator_exit_list(iterator)) + return 0; + break; + case SEXP_ATOM: + /* Just ignore */ + if (!sexp_iterator_next(iterator)) + return 0; + break; + + case SEXP_END: + return sexp_iterator_exit_list(iterator) + && (nfound == nkeys); + + default: + abort(); + } + } +} diff --git a/sexp.h b/sexp.h new file mode 100644 index 0000000..53a90a1 --- /dev/null +++ b/sexp.h @@ -0,0 +1,212 @@ +/* sexp.h + * + * Parsing s-expressions. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_SEXP_H_INCLUDED +#define NETTLE_SEXP_H_INCLUDED + +#include +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define sexp_iterator_first nettle_sexp_iterator_first +#define sexp_transport_iterator_first nettle_sexp_transport_iterator_first +#define sexp_iterator_next nettle_sexp_iterator_next +#define sexp_iterator_enter_list nettle_sexp_iterator_enter_list +#define sexp_iterator_exit_list nettle_sexp_iterator_exit_list +#define sexp_iterator_subexpr nettle_sexp_iterator_subexpr +#define sexp_iterator_get_uint32 nettle_sexp_iterator_get_uint32 +#define sexp_iterator_check_type nettle_sexp_iterator_check_type +#define sexp_iterator_check_types nettle_sexp_iterator_check_types +#define sexp_iterator_assoc nettle_sexp_iterator_assoc +#define sexp_format nettle_sexp_format +#define sexp_vformat nettle_sexp_vformat +#define sexp_transport_format nettle_sexp_transport_format +#define sexp_transport_vformat nettle_sexp_transport_vformat +#define sexp_token_chars nettle_sexp_token_chars + +enum sexp_type + { SEXP_ATOM, SEXP_LIST, SEXP_END }; + +struct sexp_iterator +{ + unsigned length; + const uint8_t *buffer; + + /* Points at the start of the current sub expression. */ + unsigned start; + /* If type is SEXP_LIST, pos points at the start of the current + * element. Otherwise, it points at the end. */ + unsigned pos; + unsigned level; + + enum sexp_type type; + + unsigned display_length; + const uint8_t *display; + + unsigned atom_length; + const uint8_t *atom; +}; + + +/* All these functions return 1 on success, 0 on failure */ + +/* Initializes the iterator. */ +int +sexp_iterator_first(struct sexp_iterator *iterator, + unsigned length, const uint8_t *input); + +/* NOTE: Decodes the input string in place */ +int +sexp_transport_iterator_first(struct sexp_iterator *iterator, + unsigned length, uint8_t *input); + +int +sexp_iterator_next(struct sexp_iterator *iterator); + +/* Current element must be a list. */ +int +sexp_iterator_enter_list(struct sexp_iterator *iterator); + +/* Skips the rest of the current list */ +int +sexp_iterator_exit_list(struct sexp_iterator *iterator); + +#if 0 +/* Skips out of as many lists as necessary to get back to the given + * level. */ +int +sexp_iterator_exit_lists(struct sexp_iterator *iterator, + unsigned level); +#endif + +/* Gets start and length of the current subexpression. Implies + * sexp_iterator_next. */ +const uint8_t * +sexp_iterator_subexpr(struct sexp_iterator *iterator, + unsigned *length); + +int +sexp_iterator_get_uint32(struct sexp_iterator *iterator, + uint32_t *x); + + +/* Checks the type of the current expression, which should be a list + * + * ( ...) + */ +int +sexp_iterator_check_type(struct sexp_iterator *iterator, + const uint8_t *type); + +const uint8_t * +sexp_iterator_check_types(struct sexp_iterator *iterator, + unsigned ntypes, + const uint8_t * const *types); + +/* Current element must be a list. Looks up element of type + * + * (key rest...) + * + * For a matching key, the corresponding iterator is initialized + * pointing at the start of REST. + * + * On success, exits the current list. + */ +int +sexp_iterator_assoc(struct sexp_iterator *iterator, + unsigned nkeys, + const uint8_t * const *keys, + struct sexp_iterator *values); + + +/* Output functions. What is a reasonable API for this? It seems + * ugly to have to reimplement string streams. */ + +/* Declared for real in buffer.h */ +struct nettle_buffer; + +/* Returns the number of output characters, or 0 on out of memory. If + * buffer == NULL, just compute length. + * + * Format strings can contained matched parentheses, tokens ("foo" in + * the format string is formatted as "3:foo"), whitespace (which + * separates tokens but is otherwise ignored) and the following + * formatting specifiers: + * + * %s String represented as unsigned length, const uint8_t *data. + * + * %t Optional display type, represented as + * unsigned display_length, const uint8_t *display, + * display == NULL means no display type. + * + * %i Non-negative small integer, uint32_t. + * + * %b Non-negative bignum, mpz_t. + * + * %l Literal string (no length added), typically a balanced + * subexpression. Represented as unsigned length, const uint8_t + * *data. + * + * %(, %) Allows insertion of unbalanced parenthesis. + * + * Modifiers: + * + * %0 For %s, %t and %l, says that there's no length argument, + * instead the string is NUL-terminated, and there's only one + * const uint8_t * argument. + */ + +unsigned +sexp_format(struct nettle_buffer *buffer, + const char *format, ...); + +unsigned +sexp_vformat(struct nettle_buffer *buffer, + const char *format, va_list args); + +unsigned +sexp_transport_format(struct nettle_buffer *buffer, + const char *format, ...); + +unsigned +sexp_transport_vformat(struct nettle_buffer *buffer, + const char *format, va_list args); + +/* Classification for advanced syntax. */ +extern const char +sexp_token_chars[0x80]; + +#define TOKEN_CHAR(c) ((c) < 0x80 && sexp_token_chars[(c)]) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_SEXP_H_INCLUDED */ diff --git a/sexp2bignum.c b/sexp2bignum.c new file mode 100644 index 0000000..eca790e --- /dev/null +++ b/sexp2bignum.c @@ -0,0 +1,53 @@ +/* sexp2bignum.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "sexp.h" +#include "bignum.h" + +int +nettle_mpz_set_sexp(mpz_t x, unsigned limit, struct sexp_iterator *i) +{ + if (i->type == SEXP_ATOM + && i->atom_length + && !i->display) + { + /* Allow some extra here, for leading sign octets. */ + if (limit && (8 * i->atom_length > (16 + limit))) + return 0; + + nettle_mpz_set_str_256_s(x, i->atom_length, i->atom); + + /* FIXME: How to interpret a limit for negative numbers? */ + if (limit && mpz_sizeinbase(x, 2) > limit) + return 0; + + return sexp_iterator_next(i); + } + else + return 0; +} diff --git a/sexp2dsa.c b/sexp2dsa.c new file mode 100644 index 0000000..a3bc5e3 --- /dev/null +++ b/sexp2dsa.c @@ -0,0 +1,120 @@ +/* sexp2dsa.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "dsa.h" + +#include "bignum.h" +#include "sexp.h" + +#define GET(x, l, v) \ +do { \ + if (!nettle_mpz_set_sexp((x), (l), (v)) \ + || mpz_sgn(x) <= 0) \ + return 0; \ +} while(0) + +/* Iterator should point past the algorithm tag, e.g. + * + * (public-key (dsa (p |xxxx|) ...) + * ^ here + */ + +int +dsa_keypair_from_sexp_alist(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned q_bits, + struct sexp_iterator *i) +{ + static const uint8_t * const names[5] + = { "p", "q", "g", "y", "x" }; + struct sexp_iterator values[5]; + unsigned nvalues = priv ? 5 : 4; + + if (!sexp_iterator_assoc(i, nvalues, names, values)) + return 0; + + if (priv) + GET(priv->x, q_bits, &values[4]); + + GET(pub->p, p_max_bits, &values[0]); + GET(pub->q, q_bits, &values[1]); + if (mpz_sizeinbase(pub->q, 2) != q_bits) + return 0; + GET(pub->g, p_max_bits, &values[2]); + GET(pub->y, p_max_bits, &values[3]); + + return 1; +} + +int +dsa_sha1_keypair_from_sexp(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned length, const uint8_t *expr) +{ + struct sexp_iterator i; + + return sexp_iterator_first(&i, length, expr) + && sexp_iterator_check_type(&i, priv ? "private-key" : "public-key") + && sexp_iterator_check_type(&i, "dsa") + && dsa_keypair_from_sexp_alist(pub, priv, p_max_bits, DSA_SHA1_Q_BITS, &i); +} + +int +dsa_sha256_keypair_from_sexp(struct dsa_public_key *pub, + struct dsa_private_key *priv, + unsigned p_max_bits, + unsigned length, const uint8_t *expr) +{ + struct sexp_iterator i; + + return sexp_iterator_first(&i, length, expr) + && sexp_iterator_check_type(&i, priv ? "private-key" : "public-key") + && sexp_iterator_check_type(&i, "dsa-sha256") + && dsa_keypair_from_sexp_alist(pub, priv, p_max_bits, DSA_SHA256_Q_BITS, &i); +} + +int +dsa_signature_from_sexp(struct dsa_signature *rs, + struct sexp_iterator *i, + unsigned q_bits) +{ + static const uint8_t * const names[2] = { "r", "s" }; + struct sexp_iterator values[2]; + + if (!sexp_iterator_assoc(i, 2, names, values)) + return 0; + + GET(rs->r, q_bits, &values[0]); + GET(rs->s, q_bits, &values[1]); + + return 1; +} diff --git a/sexp2rsa.c b/sexp2rsa.c new file mode 100644 index 0000000..e3faf68 --- /dev/null +++ b/sexp2rsa.c @@ -0,0 +1,108 @@ +/* sexp2rsa.c + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "rsa.h" + +#include "bignum.h" +#include "sexp.h" + +#define GET(x, l, v) \ +do { \ + if (!nettle_mpz_set_sexp((x), (l), (v)) \ + || mpz_sgn(x) <= 0) \ + return 0; \ +} while(0) + +/* Iterator should point past the algorithm tag, e.g. + * + * (public-key (rsa (n |xxxx|) (e |xxxx|)) + * ^ here + */ + +int +rsa_keypair_from_sexp_alist(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + struct sexp_iterator *i) +{ + static const uint8_t * const names[8] + = { "n", "e", "d", "p", "q", "a", "b", "c" }; + struct sexp_iterator values[8]; + unsigned nvalues = priv ? 8 : 2; + + if (!sexp_iterator_assoc(i, nvalues, names, values)) + return 0; + + if (priv) + { + GET(priv->d, limit, &values[2]); + GET(priv->p, limit, &values[3]); + GET(priv->q, limit, &values[4]); + GET(priv->a, limit, &values[5]); + GET(priv->b, limit, &values[6]); + GET(priv->c, limit, &values[7]); + + if (!rsa_private_key_prepare(priv)) + return 0; + } + + if (pub) + { + GET(pub->n, limit, &values[0]); + GET(pub->e, limit, &values[1]); + + if (!rsa_public_key_prepare(pub)) + return 0; + } + + return 1; +} + +int +rsa_keypair_from_sexp(struct rsa_public_key *pub, + struct rsa_private_key *priv, + unsigned limit, + unsigned length, const uint8_t *expr) +{ + struct sexp_iterator i; + static const uint8_t * const names[3] + = { "rsa", "rsa-pkcs1", "rsa-pkcs1-sha1" }; + + if (!sexp_iterator_first(&i, length, expr)) + return 0; + + if (!sexp_iterator_check_type(&i, priv ? "private-key" : "public-key")) + return 0; + + if (!sexp_iterator_check_types(&i, 3, names)) + return 0; + + return rsa_keypair_from_sexp_alist(pub, priv, limit, &i); +} diff --git a/sha-example.c b/sha-example.c new file mode 100644 index 0000000..8b3d505 --- /dev/null +++ b/sha-example.c @@ -0,0 +1,41 @@ +#include +#include + +#include + +#define BUF_SIZE 1000 + +static void +display_hex(unsigned length, uint8_t *data) +{ + unsigned i; + + for (i = 0; i: + * + * The following is my SHA (FIPS 180) code updated to allow use of the "fixed" + * SHA, thanks to Jim Gillogly and an anonymous contributor for the information on + * what's changed in the new version. The fix is a simple change which involves + * adding a single rotate in the initial expansion function. It is unknown + * whether this is an optimal solution to the problem which was discovered in the + * SHA or whether it's simply a bandaid which fixes the problem with a minimum of + * effort (for example the reengineering of a great many Capstone chips). + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef SHA1_DEBUG +# define SHA1_DEBUG 0 +#endif + +#if SHA1_DEBUG +# include +# define DEBUG(i) \ + fprintf(stderr, "%2d: %8x %8x %8x %8x %8x\n", i, A, B, C, D ,E) +#else +# define DEBUG(i) +#endif + +#include +#include +#include + +#include "sha.h" + +#include "macros.h" + +/* A block, treated as a sequence of 32-bit words. */ +#define SHA1_DATA_LENGTH 16 + +/* The SHA f()-functions. The f1 and f3 functions can be optimized to + save one boolean operation each - thanks to Rich Schroeppel, + rcs@cs.arizona.edu for discovering this */ + +/* FIXME: Can save a temporary in f3 by using ( (x & y) + (z & (x ^ + y)) ), and then, in the round, compute one of the terms and add it + into the destination word before computing the second term. Credits + to George Spelvin for pointing this out. Unfortunately, gcc + doesn't seem to be smart enough to take advantage of this. */ + +/* #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) Rounds 0-19 */ +#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */ +#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ +/* #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) Rounds 40-59 */ +#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */ +#define f4 f2 + +/* The SHA Mysterious Constants */ + +#define K1 0x5A827999L /* Rounds 0-19 */ +#define K2 0x6ED9EBA1L /* Rounds 20-39 */ +#define K3 0x8F1BBCDCL /* Rounds 40-59 */ +#define K4 0xCA62C1D6L /* Rounds 60-79 */ + +/* 32-bit rotate left - kludged with shifts */ + +#define ROTL(n,X) ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) ) + +/* The initial expanding function. The hash function is defined over an + 80-word expanded input array W, where the first 16 are copies of the input + data, and the remaining 64 are defined by + + W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] + + This implementation generates these values on the fly in a circular + buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this + optimization. + + The updated SHA changes the expanding function by adding a rotate of 1 + bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor + for this information */ + +#define expand(W,i) ( W[ i & 15 ] = \ + ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \ + W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) ) + + +/* The prototype SHA sub-round. The fundamental sub-round is: + + a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; + b' = a; + c' = ROTL( 30, b ); + d' = c; + e' = d; + + but this is implemented by unrolling the loop 5 times and renaming the + variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. + This code is then replicated 20 times for each of the 4 functions, using + the next 20 values from the W[] array each time */ + +#define subRound(a, b, c, d, e, f, k, data) \ + ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) ) + +/* Perform the SHA transformation. Note that this code, like MD5, seems to + break some optimizing compilers due to the complexity of the expressions + and the size of the basic block. It may be necessary to split it into + sections, e.g. based on the four subrounds. */ + +void +_nettle_sha1_compress(uint32_t *state, const uint8_t *input) +{ + uint32_t data[SHA1_DATA_LENGTH]; + uint32_t A, B, C, D, E; /* Local vars */ + int i; + + for (i = 0; i < SHA1_DATA_LENGTH; i++, input+= 4) + { + data[i] = READ_UINT32(input); + } + + /* Set up first buffer and local data buffer */ + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + DEBUG(-1); + /* Heavy mangling, in 4 sub-rounds of 20 interations each. */ + subRound( A, B, C, D, E, f1, K1, data[ 0] ); DEBUG(0); + subRound( E, A, B, C, D, f1, K1, data[ 1] ); DEBUG(1); + subRound( D, E, A, B, C, f1, K1, data[ 2] ); + subRound( C, D, E, A, B, f1, K1, data[ 3] ); + subRound( B, C, D, E, A, f1, K1, data[ 4] ); + subRound( A, B, C, D, E, f1, K1, data[ 5] ); + subRound( E, A, B, C, D, f1, K1, data[ 6] ); + subRound( D, E, A, B, C, f1, K1, data[ 7] ); + subRound( C, D, E, A, B, f1, K1, data[ 8] ); + subRound( B, C, D, E, A, f1, K1, data[ 9] ); + subRound( A, B, C, D, E, f1, K1, data[10] ); + subRound( E, A, B, C, D, f1, K1, data[11] ); + subRound( D, E, A, B, C, f1, K1, data[12] ); + subRound( C, D, E, A, B, f1, K1, data[13] ); + subRound( B, C, D, E, A, f1, K1, data[14] ); + subRound( A, B, C, D, E, f1, K1, data[15] ); DEBUG(15); + subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) ); DEBUG(16); + subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) ); DEBUG(17); + subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) ); DEBUG(18); + subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) ); DEBUG(19); + + subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) ); DEBUG(20); + subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) ); DEBUG(21); + subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) ); + subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) ); + subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) ); + subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) ); + subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) ); + subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) ); + subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) ); + subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) ); + subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) ); + subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) ); + subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) ); + subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) ); + subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) ); + subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) ); + subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) ); + subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) ); + subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) ); DEBUG(38); + subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) ); DEBUG(39); + + subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) ); DEBUG(40); + subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) ); DEBUG(41); + subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) ); + subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) ); + subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) ); + subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) ); + subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) ); + subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) ); + subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) ); + subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) ); + subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) ); + subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) ); + subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) ); + subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) ); + subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) ); + subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) ); + subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) ); + subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) ); + subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) ); DEBUG(58); + subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) ); DEBUG(59); + + subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) ); DEBUG(60); + subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) ); DEBUG(61); + subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) ); + subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) ); + subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) ); + subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) ); + subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) ); + subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) ); + subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) ); + subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) ); + subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) ); + subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) ); + subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) ); + subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) ); + subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) ); + subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) ); + subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) ); + subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) ); + subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) ); DEBUG(78); + subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) ); DEBUG(79); + + /* Build message digest */ + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; + +#if SHA1_DEBUG + fprintf(stderr, "99: %8x %8x %8x %8x %8x\n", + state[0], state[1], state[2], state[3], state[4]); +#endif +} diff --git a/sha1-meta.c b/sha1-meta.c new file mode 100644 index 0000000..d201da8 --- /dev/null +++ b/sha1-meta.c @@ -0,0 +1,32 @@ +/* sha1-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "sha.h" + +const struct nettle_hash nettle_sha1 += _NETTLE_HASH(sha1, SHA1); diff --git a/sha1.c b/sha1.c new file mode 100644 index 0000000..c04ab77 --- /dev/null +++ b/sha1.c @@ -0,0 +1,173 @@ +/* sha1.c + * + * The sha1 hash function. + * Defined by http://www.itl.nist.gov/fipspubs/fip180-1.htm. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Peter Gutmann, Andrew Kuchling, Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Here's the first paragraph of Peter Gutmann's posting, + * <30ajo5$oe8@ccu2.auckland.ac.nz>: + * + * The following is my SHA (FIPS 180) code updated to allow use of the "fixed" + * SHA, thanks to Jim Gillogly and an anonymous contributor for the information on + * what's changed in the new version. The fix is a simple change which involves + * adding a single rotate in the initial expansion function. It is unknown + * whether this is an optimal solution to the problem which was discovered in the + * SHA or whether it's simply a bandaid which fixes the problem with a minimum of + * effort (for example the reengineering of a great many Capstone chips). + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "sha.h" + +#include "macros.h" +#include "nettle-write.h" + +/* A block, treated as a sequence of 32-bit words. */ +#define SHA1_DATA_LENGTH 16 + +/* SHA initial values */ + +#define h0init 0x67452301L +#define h1init 0xEFCDAB89L +#define h2init 0x98BADCFEL +#define h3init 0x10325476L +#define h4init 0xC3D2E1F0L + +/* Initialize the SHA values */ + +void +sha1_init(struct sha1_ctx *ctx) +{ + /* Set the h-vars to their initial values */ + ctx->digest[ 0 ] = h0init; + ctx->digest[ 1 ] = h1init; + ctx->digest[ 2 ] = h2init; + ctx->digest[ 3 ] = h3init; + ctx->digest[ 4 ] = h4init; + + /* Initialize bit count */ + ctx->count_low = ctx->count_high = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +#define SHA1_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +void +sha1_update(struct sha1_ctx *ctx, + unsigned length, const uint8_t *buffer) +{ + if (ctx->index) + { /* Try to fill partial block */ + unsigned left = SHA1_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, buffer, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, buffer, left); + + _nettle_sha1_compress(ctx->digest, ctx->block); + SHA1_INCR(ctx); + + buffer += left; + length -= left; + } + } + while (length >= SHA1_DATA_SIZE) + { + _nettle_sha1_compress(ctx->digest, buffer); + SHA1_INCR(ctx); + + buffer += SHA1_DATA_SIZE; + length -= SHA1_DATA_SIZE; + } + if ((ctx->index = length)) /* This assignment is intended */ + /* Buffer leftovers */ + memcpy(ctx->block, buffer, length); +} + +/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +static void +sha1_final(struct sha1_ctx *ctx) +{ + uint32_t bitcount_high; + uint32_t bitcount_low; + unsigned i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + + assert(i < SHA1_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (SHA1_DATA_SIZE - 8)) + { /* No room for length in this block. Process it and + pad with another one */ + memset(ctx->block + i, 0, SHA1_DATA_SIZE - i); + + _nettle_sha1_compress(ctx->digest, ctx->block); + i = 0; + } + if (i < (SHA1_DATA_SIZE - 8)) + memset(ctx->block + i, 0, (SHA1_DATA_SIZE - 8) - i); + + /* There are 512 = 2^9 bits in one block */ + bitcount_high = (ctx->count_high << 9) | (ctx->count_low >> 23); + bitcount_low = (ctx->count_low << 9) | (ctx->index << 3); + + /* This is slightly inefficient, as the numbers are converted to + big-endian format, and will be converted back by the compression + function. It's probably not worth the effort to fix this. */ + WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 8), bitcount_high); + WRITE_UINT32(ctx->block + (SHA1_DATA_SIZE - 4), bitcount_low); + + _nettle_sha1_compress(ctx->digest, ctx->block); +} + +void +sha1_digest(struct sha1_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA1_DIGEST_SIZE); + + sha1_final(ctx); + _nettle_write_be32(length, digest, ctx->digest); + sha1_init(ctx); +} diff --git a/sha224-meta.c b/sha224-meta.c new file mode 100644 index 0000000..a8bbafc --- /dev/null +++ b/sha224-meta.c @@ -0,0 +1,32 @@ +/* sha224-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "sha.h" + +const struct nettle_hash nettle_sha224 += _NETTLE_HASH(sha224, SHA224); diff --git a/sha256-compress.c b/sha256-compress.c new file mode 100644 index 0000000..ad03039 --- /dev/null +++ b/sha256-compress.c @@ -0,0 +1,168 @@ +/* sha256-compress.c + * + * The compression function of the sha256 hash function. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "sha.h" + +#include "macros.h" + +/* A block, treated as a sequence of 32-bit words. */ +#define SHA256_DATA_LENGTH 16 + +#define ROTR(n,x) ((x)>>(n) | ((x)<<(32-(n)))) +#define SHR(n,x) ((x)>>(n)) + +/* The SHA256 functions. The Choice function is the same as the SHA1 + function f1, and the majority function is the same as the SHA1 f3 + function. They can be optimized to save one boolean operation each + - thanks to Rich Schroeppel, rcs@cs.arizona.edu for discovering + this */ + +/* #define Choice(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */ +#define Choice(x,y,z) ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) +/* #define Majority(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */ +#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) ) + +#define S0(x) (ROTR(2,(x)) ^ ROTR(13,(x)) ^ ROTR(22,(x))) +#define S1(x) (ROTR(6,(x)) ^ ROTR(11,(x)) ^ ROTR(25,(x))) + +#define s0(x) (ROTR(7,(x)) ^ ROTR(18,(x)) ^ SHR(3,(x))) +#define s1(x) (ROTR(17,(x)) ^ ROTR(19,(x)) ^ SHR(10,(x))) + +/* The initial expanding function. The hash function is defined over an + 64-word expanded input array W, where the first 16 are copies of the input + data, and the remaining 64 are defined by + + W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16] + + This implementation generates these values on the fly in a circular + buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this + optimization. +*/ + +#define EXPAND(W,i) \ +( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) ) + +/* The prototype SHA sub-round. The fundamental sub-round is: + + T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t] + T2 = S0(a) + Majority(a,b,c) + a' = T1+T2 + b' = a + c' = b + d' = c + e' = d + T1 + f' = e + g' = f + h' = g + + but this is implemented by unrolling the loop 8 times and renaming + the variables + ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each + iteration. */ + +/* It's crucial that DATA is only used once, as that argument will + * have side effects. */ +#define ROUND(a,b,c,d,e,f,g,h,k,data) do { \ + uint32_t T = h + S1(e) + Choice(e,f,g) + k + data; \ + d += T; \ + h = T + S0(a) + Majority(a,b,c); \ +} while (0) + +void +_nettle_sha256_compress(uint32_t *state, const uint8_t *input, const uint32_t *k) +{ + uint32_t data[SHA256_DATA_LENGTH]; + uint32_t A, B, C, D, E, F, G, H; /* Local vars */ + unsigned i; + uint32_t *d; + + for (i = 0; i < SHA256_DATA_LENGTH; i++, input+= 4) + { + data[i] = READ_UINT32(input); + } + + /* Set up first buffer and local data buffer */ + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + F = state[5]; + G = state[6]; + H = state[7]; + + /* Heavy mangling */ + /* First 16 subrounds that act on the original data */ + + for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8) + { + ROUND(A, B, C, D, E, F, G, H, k[0], d[0]); + ROUND(H, A, B, C, D, E, F, G, k[1], d[1]); + ROUND(G, H, A, B, C, D, E, F, k[2], d[2]); + ROUND(F, G, H, A, B, C, D, E, k[3], d[3]); + ROUND(E, F, G, H, A, B, C, D, k[4], d[4]); + ROUND(D, E, F, G, H, A, B, C, k[5], d[5]); + ROUND(C, D, E, F, G, H, A, B, k[6], d[6]); + ROUND(B, C, D, E, F, G, H, A, k[7], d[7]); + } + + for (; i<64; i += 16, k+= 16) + { + ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data, 0)); + ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data, 1)); + ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data, 2)); + ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data, 3)); + ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data, 4)); + ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data, 5)); + ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data, 6)); + ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data, 7)); + ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data, 8)); + ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data, 9)); + ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10)); + ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11)); + ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12)); + ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13)); + ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14)); + ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15)); + } + + /* Update state */ + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; + state[5] += F; + state[6] += G; + state[7] += H; +} diff --git a/sha256-meta.c b/sha256-meta.c new file mode 100644 index 0000000..c21c792 --- /dev/null +++ b/sha256-meta.c @@ -0,0 +1,32 @@ +/* sha256-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "sha.h" + +const struct nettle_hash nettle_sha256 += _NETTLE_HASH(sha256, SHA256); diff --git a/sha256.c b/sha256.c new file mode 100644 index 0000000..fa4f735 --- /dev/null +++ b/sha256.c @@ -0,0 +1,214 @@ +/* sha256.c + * + * The sha256 hash function. + * + * See http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Modelled after the sha1.c code by Peter Gutmann. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "sha.h" + +#include "macros.h" +#include "nettle-write.h" + +/* Generated by the shadata program. */ +static const uint32_t +K[64] = +{ + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0xfc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x6ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, +}; + +/* Initialize the SHA values */ + +void +sha256_init(struct sha256_ctx *ctx) +{ + /* Initial values, also generated by the shadata program. */ + static const uint32_t H0[_SHA256_DIGEST_LENGTH] = + { + 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, + 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL, + }; + + memcpy(ctx->state, H0, sizeof(H0)); + + /* Initialize bit count */ + ctx->count_low = ctx->count_high = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +#define SHA256_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +void +sha256_update(struct sha256_ctx *ctx, + unsigned length, const uint8_t *buffer) +{ + if (ctx->index) + { /* Try to fill partial block */ + unsigned left = SHA256_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, buffer, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, buffer, left); + + _nettle_sha256_compress(ctx->state, ctx->block, K); + SHA256_INCR(ctx); + + buffer += left; + length -= left; + } + } + while (length >= SHA256_DATA_SIZE) + { + _nettle_sha256_compress(ctx->state, buffer, K); + SHA256_INCR(ctx); + + buffer += SHA256_DATA_SIZE; + length -= SHA256_DATA_SIZE; + } + /* Buffer leftovers */ + /* NOTE: The corresponding sha1 code checks for the special case length == 0. + * That seems supoptimal, as I suspect it increases the number of branches. */ + + memcpy(ctx->block, buffer, length); + ctx->index = length; +} + +/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +static void +sha256_final(struct sha256_ctx *ctx) +{ + uint32_t bitcount_high; + uint32_t bitcount_low; + int i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + + assert(i < SHA256_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (SHA1_DATA_SIZE - 8)) + { /* No room for length in this block. Process it and + * pad with another one */ + memset(ctx->block + i, 0, SHA256_DATA_SIZE - i); + _nettle_sha256_compress(ctx->state, ctx->block, K); + + i = 0; + } + + if (i < (SHA256_DATA_SIZE - 8)) + memset(ctx->block + i, 0, (SHA256_DATA_SIZE - 8) - i); + + /* There are 512 = 2^9 bits in one block */ + bitcount_high = (ctx->count_high << 9) | (ctx->count_low >> 23); + bitcount_low = (ctx->count_low << 9) | (ctx->index << 3); + + /* This is slightly inefficient, as the numbers are converted to + big-endian format, and will be converted back by the compression + function. It's probably not worth the effort to fix this. */ + WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 8), bitcount_high); + WRITE_UINT32(ctx->block + (SHA256_DATA_SIZE - 4), bitcount_low); + + _nettle_sha256_compress(ctx->state, ctx->block, K); +} + +void +sha256_digest(struct sha256_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA256_DIGEST_SIZE); + + sha256_final(ctx); + _nettle_write_be32(length, digest, ctx->state); + sha256_init(ctx); +} + +/* sha224 variant. FIXME: Move to seperate file? */ + +void +sha224_init(struct sha256_ctx *ctx) +{ + /* Initial values. I's unclear how they are chosen. */ + static const uint32_t H0[_SHA256_DIGEST_LENGTH] = + { + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, + }; + + memcpy(ctx->state, H0, sizeof(H0)); + + /* Initialize bit count */ + ctx->count_low = ctx->count_high = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +void +sha224_digest(struct sha256_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA224_DIGEST_SIZE); + + sha256_final(ctx); + _nettle_write_be32(length, digest, ctx->state); + sha224_init(ctx); +} diff --git a/sha384-meta.c b/sha384-meta.c new file mode 100644 index 0000000..0c02239 --- /dev/null +++ b/sha384-meta.c @@ -0,0 +1,32 @@ +/* sha384-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "sha.h" + +const struct nettle_hash nettle_sha384 += _NETTLE_HASH(sha384, SHA384); diff --git a/sha512-compress.c b/sha512-compress.c new file mode 100644 index 0000000..f11226e --- /dev/null +++ b/sha512-compress.c @@ -0,0 +1,164 @@ +/* sha512-compress.c + * + * The compression function of the sha512 hash function. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "sha.h" + +#include "macros.h" + +/* A block, treated as a sequence of 64-bit words. */ +#define SHA512_DATA_LENGTH 16 + +#define ROTR(n,x) ((x)>>(n) | ((x)<<(64-(n)))) +#define SHR(n,x) ((x)>>(n)) + +/* The SHA512 functions. The Choice function is the same as the SHA1 + function f1, and the majority function is the same as the SHA1 f3 + function, and the same as for SHA256. */ + +#define Choice(x,y,z) ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) +#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) ) + +#define S0(x) (ROTR(28,(x)) ^ ROTR(34,(x)) ^ ROTR(39,(x))) +#define S1(x) (ROTR(14,(x)) ^ ROTR(18,(x)) ^ ROTR(41,(x))) + +#define s0(x) (ROTR(1,(x)) ^ ROTR(8,(x)) ^ SHR(7,(x))) +#define s1(x) (ROTR(19,(x)) ^ ROTR(61,(x)) ^ SHR(6,(x))) + +/* The initial expanding function. The hash function is defined over + an 64-word expanded input array W, where the first 16 are copies of + the input data, and the remaining 64 are defined by + + W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16] + + This implementation generates these values on the fly in a circular + buffer. +*/ + +#define EXPAND(W,i) \ +( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) ) + +/* The prototype SHA sub-round. The fundamental sub-round is: + + T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t] + T2 = S0(a) + Majority(a,b,c) + a' = T1+T2 + b' = a + c' = b + d' = c + e' = d + T1 + f' = e + g' = f + h' = g + + but this is implemented by unrolling the loop 8 times and renaming + the variables + ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each + iteration. This code is then replicated 8, using the next 8 values + from the W[] array each time */ + +/* It's crucial that DATA is only used once, as that argument will + * have side effects. */ +#define ROUND(a,b,c,d,e,f,g,h,k,data) do { \ + uint64_t T = h + S1(e) + Choice(e,f,g) + k + data; \ + d += T; \ + h = T + S0(a) + Majority(a,b,c); \ +} while (0) + +void +_nettle_sha512_compress(uint64_t *state, const uint8_t *input, const uint64_t *k) +{ + uint64_t data[SHA512_DATA_LENGTH]; + uint64_t A, B, C, D, E, F, G, H; /* Local vars */ + unsigned i; + uint64_t *d; + + for (i = 0; i < SHA512_DATA_LENGTH; i++, input += 8) + { + data[i] = READ_UINT64(input); + } + + /* Set up first buffer and local data buffer */ + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + F = state[5]; + G = state[6]; + H = state[7]; + + /* Heavy mangling */ + /* First 16 subrounds that act on the original data */ + + for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8) + { + ROUND(A, B, C, D, E, F, G, H, k[0], d[0]); + ROUND(H, A, B, C, D, E, F, G, k[1], d[1]); + ROUND(G, H, A, B, C, D, E, F, k[2], d[2]); + ROUND(F, G, H, A, B, C, D, E, k[3], d[3]); + ROUND(E, F, G, H, A, B, C, D, k[4], d[4]); + ROUND(D, E, F, G, H, A, B, C, k[5], d[5]); + ROUND(C, D, E, F, G, H, A, B, k[6], d[6]); + ROUND(B, C, D, E, F, G, H, A, k[7], d[7]); + } + + for (; i<80; i += 16, k+= 16) + { + ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data, 0)); + ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data, 1)); + ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data, 2)); + ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data, 3)); + ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data, 4)); + ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data, 5)); + ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data, 6)); + ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data, 7)); + ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data, 8)); + ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data, 9)); + ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10)); + ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11)); + ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12)); + ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13)); + ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14)); + ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15)); + } + + /* Update state */ + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; + state[5] += F; + state[6] += G; + state[7] += H; +} diff --git a/sha512-meta.c b/sha512-meta.c new file mode 100644 index 0000000..d9ba03e --- /dev/null +++ b/sha512-meta.c @@ -0,0 +1,32 @@ +/* sha512-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "sha.h" + +const struct nettle_hash nettle_sha512 += _NETTLE_HASH(sha512, SHA512); diff --git a/sha512.c b/sha512.c new file mode 100644 index 0000000..244ac80 --- /dev/null +++ b/sha512.c @@ -0,0 +1,298 @@ +/* sha512.c + * + * The sha512 hash function FIXME: Add the SHA384 variant. + * + * See http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2010 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* Modelled after the sha1.c code by Peter Gutmann. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "sha.h" + +#include "macros.h" + +/* Generated by the gp script + + { + print("obase=16"); + for (i = 1,80, + root = prime(i)^(1/3); + fraction = root - floor(root); + print(floor(2^64 * fraction)); + ); + quit(); + } + + piped through + + |grep -v '^[' | bc \ + |awk '{printf("0x%sULL,%s", $1, NR%3 == 0 ? "\n" : "");}' + + to convert it to hex. +*/ + +static const uint64_t +K[80] = +{ + 0x428A2F98D728AE22ULL,0x7137449123EF65CDULL, + 0xB5C0FBCFEC4D3B2FULL,0xE9B5DBA58189DBBCULL, + 0x3956C25BF348B538ULL,0x59F111F1B605D019ULL, + 0x923F82A4AF194F9BULL,0xAB1C5ED5DA6D8118ULL, + 0xD807AA98A3030242ULL,0x12835B0145706FBEULL, + 0x243185BE4EE4B28CULL,0x550C7DC3D5FFB4E2ULL, + 0x72BE5D74F27B896FULL,0x80DEB1FE3B1696B1ULL, + 0x9BDC06A725C71235ULL,0xC19BF174CF692694ULL, + 0xE49B69C19EF14AD2ULL,0xEFBE4786384F25E3ULL, + 0xFC19DC68B8CD5B5ULL,0x240CA1CC77AC9C65ULL, + 0x2DE92C6F592B0275ULL,0x4A7484AA6EA6E483ULL, + 0x5CB0A9DCBD41FBD4ULL,0x76F988DA831153B5ULL, + 0x983E5152EE66DFABULL,0xA831C66D2DB43210ULL, + 0xB00327C898FB213FULL,0xBF597FC7BEEF0EE4ULL, + 0xC6E00BF33DA88FC2ULL,0xD5A79147930AA725ULL, + 0x6CA6351E003826FULL,0x142929670A0E6E70ULL, + 0x27B70A8546D22FFCULL,0x2E1B21385C26C926ULL, + 0x4D2C6DFC5AC42AEDULL,0x53380D139D95B3DFULL, + 0x650A73548BAF63DEULL,0x766A0ABB3C77B2A8ULL, + 0x81C2C92E47EDAEE6ULL,0x92722C851482353BULL, + 0xA2BFE8A14CF10364ULL,0xA81A664BBC423001ULL, + 0xC24B8B70D0F89791ULL,0xC76C51A30654BE30ULL, + 0xD192E819D6EF5218ULL,0xD69906245565A910ULL, + 0xF40E35855771202AULL,0x106AA07032BBD1B8ULL, + 0x19A4C116B8D2D0C8ULL,0x1E376C085141AB53ULL, + 0x2748774CDF8EEB99ULL,0x34B0BCB5E19B48A8ULL, + 0x391C0CB3C5C95A63ULL,0x4ED8AA4AE3418ACBULL, + 0x5B9CCA4F7763E373ULL,0x682E6FF3D6B2B8A3ULL, + 0x748F82EE5DEFB2FCULL,0x78A5636F43172F60ULL, + 0x84C87814A1F0AB72ULL,0x8CC702081A6439ECULL, + 0x90BEFFFA23631E28ULL,0xA4506CEBDE82BDE9ULL, + 0xBEF9A3F7B2C67915ULL,0xC67178F2E372532BULL, + 0xCA273ECEEA26619CULL,0xD186B8C721C0C207ULL, + 0xEADA7DD6CDE0EB1EULL,0xF57D4F7FEE6ED178ULL, + 0x6F067AA72176FBAULL,0xA637DC5A2C898A6ULL, + 0x113F9804BEF90DAEULL,0x1B710B35131C471BULL, + 0x28DB77F523047D84ULL,0x32CAAB7B40C72493ULL, + 0x3C9EBE0A15C9BEBCULL,0x431D67C49C100D4CULL, + 0x4CC5D4BECB3E42B6ULL,0x597F299CFC657E2AULL, + 0x5FCB6FAB3AD6FAECULL,0x6C44198C4A475817ULL, +}; + +void +sha512_init(struct sha512_ctx *ctx) +{ + /* Initial values, generated by the gp script + { + for (i = 1,8, + root = prime(i)^(1/2); + fraction = root - floor(root); + print(floor(2^64 * fraction)); + ); + } +. */ + static const uint64_t H0[_SHA512_DIGEST_LENGTH] = + { + 0x6A09E667F3BCC908ULL,0xBB67AE8584CAA73BULL, + 0x3C6EF372FE94F82BULL,0xA54FF53A5F1D36F1ULL, + 0x510E527FADE682D1ULL,0x9B05688C2B3E6C1FULL, + 0x1F83D9ABFB41BD6BULL,0x5BE0CD19137E2179ULL, + }; + + memcpy(ctx->state, H0, sizeof(H0)); + + /* Initialize bit count */ + ctx->count_low = ctx->count_high = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +#define SHA512_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +void +sha512_update(struct sha512_ctx *ctx, + unsigned length, const uint8_t *buffer) +{ + if (ctx->index) + { /* Try to fill partial block */ + unsigned left = SHA512_DATA_SIZE - ctx->index; + if (length < left) + { + memcpy(ctx->block + ctx->index, buffer, length); + ctx->index += length; + return; /* Finished */ + } + else + { + memcpy(ctx->block + ctx->index, buffer, left); + + _nettle_sha512_compress(ctx->state, ctx->block, K); + SHA512_INCR(ctx); + + buffer += left; + length -= left; + } + } + while (length >= SHA512_DATA_SIZE) + { + _nettle_sha512_compress(ctx->state, buffer, K); + SHA512_INCR(ctx); + + buffer += SHA512_DATA_SIZE; + length -= SHA512_DATA_SIZE; + } + + /* Buffer leftovers */ + memcpy(ctx->block, buffer, length); + ctx->index = length; +} + +/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ + +static void +sha512_final(struct sha512_ctx *ctx) +{ + uint64_t bitcount_high; + uint64_t bitcount_low; + int i; + + i = ctx->index; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + + assert(i < SHA512_DATA_SIZE); + ctx->block[i++] = 0x80; + + if (i > (SHA512_DATA_SIZE-16)) + { /* No room for length in this block. Process it and + * pad with another one */ + memset(ctx->block + i, 0, SHA512_DATA_SIZE - i); + _nettle_sha512_compress(ctx->state, ctx->block, K); + + i = 0; + } + + if (i < (SHA512_DATA_SIZE - 16)) + memset(ctx->block + i, 0, (SHA512_DATA_SIZE - 16) - i); + + /* There are 1024 = 2^10 bits in one block */ + bitcount_high = (ctx->count_high << 10) | (ctx->count_low >> 54); + bitcount_low = (ctx->count_low << 10) | (ctx->index << 3); + + /* This is slightly inefficient, as the numbers are converted to + big-endian format, and will be converted back by the compression + function. It's probably not worth the effort to fix this. */ + WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 16), bitcount_high); + WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 8), bitcount_low); + + _nettle_sha512_compress(ctx->state, ctx->block, K); +} + +static void +sha512_write_digest(struct sha512_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + unsigned i; + unsigned words; + unsigned leftover; + + sha512_final(ctx); + + words = length / 8; + leftover = length % 8; + + for (i = 0; i < words; i++, digest += 8) + WRITE_UINT64(digest, ctx->state[i]); + + if (leftover) + { + /* Truncate to the right size */ + uint64_t word = ctx->state[i] >> (8*(8 - leftover)); + + do { + digest[--leftover] = word & 0xff; + word >>= 8; + } while (leftover); + } +} + +void +sha512_digest(struct sha512_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA512_DIGEST_SIZE); + + sha512_write_digest(ctx, length, digest); + sha512_init(ctx); +} + +/* sha384 variant. FIXME: Move to separate file? */ +void +sha384_init(struct sha512_ctx *ctx) +{ + /* Initial values, generated by the gp script + { + for (i = 9,16, + root = prime(i)^(1/2); + fraction = root - floor(root); + print(floor(2^64 * fraction)); + ); + } +. */ + static const uint64_t H0[_SHA512_DIGEST_LENGTH] = + { + 0xCBBB9D5DC1059ED8ULL, 0x629A292A367CD507ULL, + 0x9159015A3070DD17ULL, 0x152FECD8F70E5939ULL, + 0x67332667FFC00B31ULL, 0x8EB44A8768581511ULL, + 0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL, + }; + + memcpy(ctx->state, H0, sizeof(H0)); + + /* Initialize bit count */ + ctx->count_low = ctx->count_high = 0; + + /* Initialize buffer */ + ctx->index = 0; +} + +void +sha384_digest(struct sha512_ctx *ctx, + unsigned length, + uint8_t *digest) +{ + assert(length <= SHA384_DIGEST_SIZE); + + sha512_write_digest(ctx, length, digest); + sha384_init(ctx); +} diff --git a/shadata.c b/shadata.c new file mode 100644 index 0000000..3275f0c --- /dev/null +++ b/shadata.c @@ -0,0 +1,50 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +static const unsigned primes[64] = +{ + 2, 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 +}; + +int main(int argc UNUSED, char **argv UNUSED) +{ + int i; + static const double third = 1.0/3; + + printf("SHA-256 constants: \n"); + for (i = 0; i < 64; ) + { + double root = pow(primes[i++], third); + double fraction = root - floor(root); + double value = floor(ldexp(fraction, 32)); + + printf("0x%lxUL, ", (unsigned long) value); + if (!(i % 4)) + printf("\n"); + } + + printf("\nSHA-256 initial values: \n"); + + for (i = 0; i < 8; ) + { + double root = pow(primes[i++], 0.5); + double fraction = root - (floor(root)); + double value = floor(ldexp(fraction, 32)); + + printf("0x%lxUL, ", (unsigned long) value); + if (!(i % 4)) + printf("\n"); + } + + return 0; +} diff --git a/sparc32/aes-decrypt-internal.asm b/sparc32/aes-decrypt-internal.asm new file mode 100644 index 0000000..0d432e0 --- /dev/null +++ b/sparc32/aes-decrypt-internal.asm @@ -0,0 +1,132 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2002, 2005 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +include_src() + +C Arguments +define(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%o5>) + +C %g1, %g2, %g3 are TMP1, TMP2 and TMP3 + +C The sparc32 stack frame looks like +C +C %fp - 4: OS-dependent link field +C %fp - 8: OS-dependent link field +C %fp - 104: OS register save area. +define(, 104) + + .file "aes-decrypt-internal.asm" + + C _aes_decrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + + .section ".text" + .align 16 + .proc 020 + +PROLOGUE(_nettle_aes_decrypt) + + save %sp, -FRAME_SIZE, %sp + cmp LENGTH, 0 + be .Lend + + C Loop invariants + add T, AES_TABLE0, T0 + add T, AES_TABLE1, T1 + add T, AES_TABLE2, T2 + add T, AES_TABLE3, T3 + +.Lblock_loop: + C Read src, and add initial subkey + add CTX, AES_KEYS, KEY + AES_LOAD(0, SRC, KEY, W0) + AES_LOAD(1, SRC, KEY, W1) + AES_LOAD(2, SRC, KEY, W2) + AES_LOAD(3, SRC, KEY, W3) + + C Must be even, and includes the final round + ld [AES_NROUNDS + CTX], ROUND + add SRC, 16, SRC + add KEY, 16, KEY + + srl ROUND, 1, ROUND + C Last two rounds handled specially + sub ROUND, 1, ROUND +.Lround_loop: + C The AES_ROUND macro uses T0,... T3 + C Transform W -> X + AES_ROUND(0, W0, W3, W2, W1, KEY, X0) + AES_ROUND(1, W1, W0, W3, W2, KEY, X1) + AES_ROUND(2, W2, W1, W0, W3, KEY, X2) + AES_ROUND(3, W3, W2, W1, W0, KEY, X3) + + C Transform X -> W + AES_ROUND(4, X0, X3, X2, X1, KEY, W0) + AES_ROUND(5, X1, X0, X3, X2, KEY, W1) + AES_ROUND(6, X2, X1, X0, X3, KEY, W2) + AES_ROUND(7, X3, X2, X1, X0, KEY, W3) + + subcc ROUND, 1, ROUND + bne .Lround_loop + add KEY, 32, KEY + + C Penultimate round + AES_ROUND(0, W0, W3, W2, W1, KEY, X0) + AES_ROUND(1, W1, W0, W3, W2, KEY, X1) + AES_ROUND(2, W2, W1, W0, W3, KEY, X2) + AES_ROUND(3, W3, W2, W1, W0, KEY, X3) + + add KEY, 16, KEY + C Final round + AES_FINAL_ROUND(0, T, X0, X3, X2, X1, KEY, DST) + AES_FINAL_ROUND(1, T, X1, X0, X3, X2, KEY, DST) + AES_FINAL_ROUND(2, T, X2, X1, X0, X3, KEY, DST) + AES_FINAL_ROUND(3, T, X3, X2, X1, X0, KEY, DST) + + subcc LENGTH, 16, LENGTH + bne .Lblock_loop + add DST, 16, DST + +.Lend: + ret + restore +EPILOGUE(_nettle_aes_decrypt) diff --git a/sparc32/aes-encrypt-internal.asm b/sparc32/aes-encrypt-internal.asm new file mode 100644 index 0000000..e013822 --- /dev/null +++ b/sparc32/aes-encrypt-internal.asm @@ -0,0 +1,156 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2002, 2005 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +include_src() + +C Arguments +define(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%o5>) + +C %g1, %g2, %g3 are TMP1, TMP2 and TMP3 + +C I'm still slightly confused by the frame layout, specified in +C "SYSTEM V APPLICATION BINARY INTERFACE SPARC Processor Supplement". +C However, Sun's cc generates a 104 byte stack frame for a function +C with no local variables, so that should be good enough for us too. + +C The sparc32 stack frame looks like +C +C %fp - 4: OS-dependent link field +C %fp - 8: OS-dependent link field +C %fp - 104: OS register save area +define(, 104) + + .file "aes-encrypt-internal.asm" + + C _aes_encrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + + .section ".text" + .align 16 + .proc 020 + +PROLOGUE(_nettle_aes_encrypt) + + save %sp, -FRAME_SIZE, %sp + cmp LENGTH, 0 + be .Lend + + C Loop invariants + add T, AES_TABLE0, T0 + add T, AES_TABLE1, T1 + add T, AES_TABLE2, T2 + add T, AES_TABLE3, T3 + +.Lblock_loop: + C Read src, and add initial subkey + add CTX, AES_KEYS, KEY + AES_LOAD(0, SRC, KEY, W0) + AES_LOAD(1, SRC, KEY, W1) + AES_LOAD(2, SRC, KEY, W2) + AES_LOAD(3, SRC, KEY, W3) + + C Must be even, and includes the final round + ld [AES_NROUNDS + CTX], ROUND + add SRC, 16, SRC + add KEY, 16, KEY + + srl ROUND, 1, ROUND + C Last two rounds handled specially + sub ROUND, 1, ROUND +.Lround_loop: + C The AES_ROUND macro uses T0,... T3 + C Transform W -> X + AES_ROUND(0, W0, W1, W2, W3, KEY, X0) + AES_ROUND(1, W1, W2, W3, W0, KEY, X1) + AES_ROUND(2, W2, W3, W0, W1, KEY, X2) + AES_ROUND(3, W3, W0, W1, W2, KEY, X3) + + C Transform X -> W + AES_ROUND(4, X0, X1, X2, X3, KEY, W0) + AES_ROUND(5, X1, X2, X3, X0, KEY, W1) + AES_ROUND(6, X2, X3, X0, X1, KEY, W2) + AES_ROUND(7, X3, X0, X1, X2, KEY, W3) + + subcc ROUND, 1, ROUND + bne .Lround_loop + add KEY, 32, KEY + + C Penultimate round + AES_ROUND(0, W0, W1, W2, W3, KEY, X0) + AES_ROUND(1, W1, W2, W3, W0, KEY, X1) + AES_ROUND(2, W2, W3, W0, W1, KEY, X2) + AES_ROUND(3, W3, W0, W1, W2, KEY, X3) + + add KEY, 16, KEY + C Final round + AES_FINAL_ROUND(0, T, X0, X1, X2, X3, KEY, DST) + AES_FINAL_ROUND(1, T, X1, X2, X3, X0, KEY, DST) + AES_FINAL_ROUND(2, T, X2, X3, X0, X1, KEY, DST) + AES_FINAL_ROUND(3, T, X3, X0, X1, X2, KEY, DST) + + subcc LENGTH, 16, LENGTH + bne .Lblock_loop + add DST, 16, DST + +.Lend: + ret + restore +EPILOGUE(_nettle_aes_encrypt) + +C Some stats from adriana.lysator.liu.se (SS1000$, 85 MHz), for AES 128 + +C 1: nettle-1.13 C-code +C 2: nettle-1.13 assembler +C 3: New C-code +C 4: New assembler, first correct version +C 5: New assembler, with basic scheduling of AES_ROUND. +C 6: New assembpler, with loop invariants T0-T3. +C 7: New assembler, with basic scheduling also of AES_FINAL_ROUND. + +C MB/s cycles/block Code size (bytes) +C 1 1.2 1107 592 +C 2 2.3 572 1032 +C 3 2.1 627 +C 4 1.8 722 +C 5 2.6 496 +C 6 3.0 437 +C 7 3.1 415 1448 diff --git a/sparc32/aes.m4 b/sparc32/aes.m4 new file mode 100644 index 0000000..05f465e --- /dev/null +++ b/sparc32/aes.m4 @@ -0,0 +1,83 @@ +C Used as temporaries by the AES macros +define(, <%g1>) +define(, <%g2>) +define(, <%g3>) + +C Loop invariants used by AES_ROUND +define(, <%o0>) +define(, <%o1>) +define(, <%o2>) +define(, <%o3>) + +C AES_LOAD(i, src, key, res) +define(, < + ldub [$2 + 4*$1], $4 + ldub [$2 + 4*$1 + 1], TMP1 + ldub [$2 + 4*$1 + 2], TMP2 + sll TMP1, 8, TMP1 + + or $4, TMP1, $4 + ldub [$2 + 4*$1+3], TMP1 + sll TMP2, 16, TMP2 + or $4, TMP2, $4 + + sll TMP1, 24, TMP1 + C Get subkey + ld [$3 + 4*$1], TMP2 + or $4, TMP1, $4 + xor $4, TMP2, $4>)dnl + +C AES_ROUND(i, a, b, c, d, key, res) +C Computes one word of the AES round +C FIXME: Could use registers pointing directly to the four tables +C FIXME: Needs better instruction scheduling, and perhaps more temporaries +C Alternatively, we can use a single table and some rotations +define(, < + and $2, 0xff, TMP1 C 0 + srl $3, 6, TMP2 C 1 + sll TMP1, 2, TMP1 C 0 + and TMP2, 0x3fc, TMP2 C 1 + ld [T0 + TMP1], $7 C 0 E0 + srl $4, 14, TMP1 C 2 + ld [T1 + TMP2], TMP2 C 1 + and TMP1, 0x3fc, TMP1 C 2 + xor $7, TMP2, $7 C 1 E1 + srl $5, 22, TMP2 C 3 + ld [T2 + TMP1], TMP1 C 2 + and TMP2, 0x3fc, TMP2 C 3 + xor $7, TMP1, $7 C 2 E2 + ld [$6 + 4*$1], TMP1 C 4 + ld [T3 + TMP2], TMP2 C 3 + xor $7, TMP1, $7 C 4 E4 + xor $7, TMP2, $7 C 3 E3 +>)dnl + +C AES_FINAL_ROUND(i, T, a, b, c, d, key, dst) +C Compute one word in the final round function. Output is converted to +C octets and stored at dst. Relies on AES_SBOX being zero. +define(, < + C Load subkey + ld [$7 + 4*$1], TMP3 + + and $3, 0xff, TMP1 C 0 + srl $4, 8, TMP2 C 1 + ldub [T + TMP1], TMP1 C 0 + and TMP2, 0xff, TMP2 C 1 + xor TMP3, TMP1, TMP1 C 0 + ldub [T + TMP2], TMP2 C 1 + stb TMP1, [$8 + 4*$1] C 0 E0 + srl $5, 16, TMP1 C 2 + srl TMP3, 8, TMP3 C 1 + and TMP1, 0xff, TMP1 C 2 + xor TMP3, TMP2, TMP2 C 1 + ldub [T + TMP1], TMP1 C 2 + stb TMP2, [$8 + 4*$1 + 1] C 1 E1 + srl $6, 24, TMP2 C 3 + srl TMP3, 8, TMP3 C 2 + ldub [T + TMP2], TMP2 C 3 + xor TMP3, TMP1, TMP1 C 2 + srl TMP3, 8, TMP3 C 3 + stb TMP1, [$8 + 4*$1 + 2] C 2 E2 + xor TMP3, TMP2, TMP2 C 3 + stb TMP2, [$8 + 4*$1 + 3] C 3 E3 +>) diff --git a/sparc32/arcfour-crypt.asm b/sparc32/arcfour-crypt.asm new file mode 100644 index 0000000..4d8dac9 --- /dev/null +++ b/sparc32/arcfour-crypt.asm @@ -0,0 +1,230 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2002, 2005 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C Define to YES, to enable the complex code to special case SRC +C and DST with compatible alignment. + +define(, ) + +C Registers + +define(, <%i0>) +define(,<%i1>) +define(, <%i2>) +define(, <%i3>) + +define(, <%i4>) +define(, <%i5>) +define(, <%g1>) +define(, <%g2>) +define(, <%g3>) +define(, <%o0>) +define(, <%o1>) +define(, <%o2>) +define(, <%o3>) + +C Computes the next byte of the key stream. As input, i must +C already point to the index for the current access, the index +C for the next access is stored in ni. The resulting key byte is +C stored in res. +C ARCFOUR_BYTE(i, ni, res) +define(, < + ldub [CTX + $1], SI + add $1, 1, $2 + add J, SI, J + and J, 0xff, J + ldub [CTX + J], SJ + and $2, 0xff, $2 + stb SI, [CTX + J] + add SI, SJ, SI + and SI, 0xff, SI + stb SJ, [CTX + $1] + ldub [CTX + SI], $3 +>)dnl + +C FIXME: Consider using the callers window +define(, 104) + + .file "arcfour-crypt.asm" + + C arcfour_crypt(struct arcfour_ctx *ctx, + C unsigned length, uint8_t *dst, + C const uint8_t *src) + + .section ".text" + .align 16 + .proc 020 + +PROLOGUE(nettle_arcfour_crypt) + + save %sp, -FRAME_SIZE, %sp + cmp LENGTH, 0 + be .Lend + nop + + C Load both I and J + lduh [CTX + ARCFOUR_I], I1 + and I1, 0xff, J + srl I1, 8, I1 + + C We want an even address for DST + andcc DST, 1, %g0 + add I1, 1 ,I1 + beq .Laligned2 + and I1, 0xff, I1 + + mov I1, I2 + ldub [SRC], DATA + ARCFOUR_BYTE(I2, I1, TMP) + subcc LENGTH, 1, LENGTH + add SRC, 1, SRC + xor DATA, TMP, DATA + stb DATA, [DST] + beq .Ldone + add DST, 1, DST + +.Laligned2: + + cmp LENGTH, 2 + blu .Lfinal1 + C Harmless delay slot instruction + andcc DST, 2, %g0 + beq .Laligned4 + nop + + ldub [SRC], DATA + ARCFOUR_BYTE(I1, I2, TMP) + ldub [SRC + 1], TMP2 + add SRC, 2, SRC + xor DATA, TMP, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + subcc LENGTH, 2, LENGTH + or DATA, TMP, DATA + + sth DATA, [DST] + beq .Ldone + add DST, 2, DST + +.Laligned4: + cmp LENGTH, 4 + blu .Lfinal2 + C Harmless delay slot instruction + srl LENGTH, 2, N + +.Loop: + C Main loop, with aligned writes + + C FIXME: Could check if SRC is aligned, and + C use 32-bit reads in that case. + + ldub [SRC], DATA + ARCFOUR_BYTE(I1, I2, TMP) + ldub [SRC + 1], TMP2 + xor TMP, DATA, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + ldub [SRC + 2], TMP2 + or TMP, DATA, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I1, I2, TMP) + xor TMP2, TMP, TMP + ldub [SRC + 3], TMP2 + or TMP, DATA, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + or TMP, DATA, DATA + subcc N, 1, N + add SRC, 4, SRC + st DATA, [DST] + bne .Loop + add DST, 4, DST + + andcc LENGTH, 3, LENGTH + beq .Ldone + nop + +.Lfinal2: + C DST address must be 2-aligned + cmp LENGTH, 2 + blu .Lfinal1 + nop + + ldub [SRC], DATA + ARCFOUR_BYTE(I1, I2, TMP) + ldub [SRC + 1], TMP2 + add SRC, 2, SRC + xor DATA, TMP, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + or DATA, TMP, DATA + + sth DATA, [DST] + beq .Ldone + add DST, 2, DST + +.Lfinal1: + mov I1, I2 + ldub [SRC], DATA + ARCFOUR_BYTE(I2, I1, TMP) + xor DATA, TMP, DATA + stb DATA, [DST] + +.Ldone: + C Save back I and J + sll I2, 8, I2 + or I2, J, I2 + stuh I2, [CTX + ARCFOUR_I] + +.Lend: + ret + restore + +EPILOGUE(nettle_arcfour_crypt) + +C Some stats from adriana.lysator.liu.se (SS1000E, 85 MHz), for AES 128 + +C 1: nettle-1.13 C-code +C 2: First working version of the assembler code +C 3: Moved load of source byte +C 4: Better instruction scheduling +C 5: Special case SRC and DST with compatible alignment +C 6: After bugfix (reorder of ld [CTX+SI+SJ] and st [CTX + SI]) +C 7: Unrolled only twice, with byte-accesses +C 8: Unrolled, using 8-bit reads and aligned 32-bit writes. + +C MB/s cycles/byte Code size (bytes) +C 1: 6.6 12.4 132 +C 2: 5.6 14.5 116 +C 3: 6.0 13.5 116 +C 4: 6.5 12.4 116 +C 5: 7.9 10.4 496 +C 6: 8.3 9.7 496 +C 7: 6.7 12.1 268 +C 8: 8.3 9.8 768 diff --git a/sparc32/machine.m4 b/sparc32/machine.m4 new file mode 100644 index 0000000..e69de29 diff --git a/sparc64/aes-decrypt-internal.asm b/sparc64/aes-decrypt-internal.asm new file mode 100644 index 0000000..408dd72 --- /dev/null +++ b/sparc64/aes-decrypt-internal.asm @@ -0,0 +1,138 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2002, 2005 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C The only difference between this code and the sparc32 code is the +C frame offsets, and the magic BIAS when accessing the stack (which +C doesn't matter, since we don't access any data on the stack). + + +C Use the same AES macros as on sparc32. +include_src(sparc32/aes.m4) + +C Arguments +define(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%o5>) + +C %g1, %g2, %g3 are TMP1, TMP2 and TMP3 + +C The sparc64 stack frame looks like +C +C %fp - 8: OS-dependent link field +C %fp - 16: OS-dependent link field +C %fp - 192: OS register save area (22*8 == 176 bytes) +define(, 192) + + .file "aes-decrypt-internal.asm" + + C _aes_decrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + + .section ".text" + .align 16 + .proc 020 + +PROLOGUE(_nettle_aes_decrypt) + + save %sp, -FRAME_SIZE, %sp + cmp LENGTH, 0 + be .Lend + + C Loop invariants + add T, AES_TABLE0, T0 + add T, AES_TABLE1, T1 + add T, AES_TABLE2, T2 + add T, AES_TABLE3, T3 + +.Lblock_loop: + C Read src, and add initial subkey + add CTX, AES_KEYS, KEY + AES_LOAD(0, SRC, KEY, W0) + AES_LOAD(1, SRC, KEY, W1) + AES_LOAD(2, SRC, KEY, W2) + AES_LOAD(3, SRC, KEY, W3) + + C Must be even, and includes the final round + ld [AES_NROUNDS + CTX], ROUND + add SRC, 16, SRC + add KEY, 16, KEY + + srl ROUND, 1, ROUND + C Last two rounds handled specially + sub ROUND, 1, ROUND +.Lround_loop: + C The AES_ROUND macro uses T0,... T3 + C Transform W -> X + AES_ROUND(0, W0, W3, W2, W1, KEY, X0) + AES_ROUND(1, W1, W0, W3, W2, KEY, X1) + AES_ROUND(2, W2, W1, W0, W3, KEY, X2) + AES_ROUND(3, W3, W2, W1, W0, KEY, X3) + + C Transform X -> W + AES_ROUND(4, X0, X3, X2, X1, KEY, W0) + AES_ROUND(5, X1, X0, X3, X2, KEY, W1) + AES_ROUND(6, X2, X1, X0, X3, KEY, W2) + AES_ROUND(7, X3, X2, X1, X0, KEY, W3) + + subcc ROUND, 1, ROUND + bne .Lround_loop + add KEY, 32, KEY + + C Penultimate round + AES_ROUND(0, W0, W3, W2, W1, KEY, X0) + AES_ROUND(1, W1, W0, W3, W2, KEY, X1) + AES_ROUND(2, W2, W1, W0, W3, KEY, X2) + AES_ROUND(3, W3, W2, W1, W0, KEY, X3) + + add KEY, 16, KEY + C Final round + AES_FINAL_ROUND(0, T, X0, X3, X2, X1, KEY, DST) + AES_FINAL_ROUND(1, T, X1, X0, X3, X2, KEY, DST) + AES_FINAL_ROUND(2, T, X2, X1, X0, X3, KEY, DST) + AES_FINAL_ROUND(3, T, X3, X2, X1, X0, KEY, DST) + + subcc LENGTH, 16, LENGTH + bne .Lblock_loop + add DST, 16, DST + +.Lend: + ret + restore +EPILOGUE(_nettle_aes_decrypt) diff --git a/sparc64/aes-encrypt-internal.asm b/sparc64/aes-encrypt-internal.asm new file mode 100644 index 0000000..5462056 --- /dev/null +++ b/sparc64/aes-encrypt-internal.asm @@ -0,0 +1,149 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2002, 2005 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C The only difference between this code and the sparc32 code is the +C frame offsets, and the magic BIAS when accessing the stack (which +C doesn't matter, since we don't access any data on the stack). + + +C Use the same AES macros as on sparc32. +include_src(sparc32/aes.m4) + +C Arguments +define(, <%i0>) +define(, <%i1>) +define(,<%i2>) +define(, <%i3>) +define(, <%i4>) + +C AES state, two copies for unrolling + +define(, <%l0>) +define(, <%l1>) +define(, <%l2>) +define(, <%l3>) + +define(, <%l4>) +define(, <%l5>) +define(, <%l6>) +define(, <%l7>) + +C %o0-%03 are used for loop invariants T0-T3 +define(, <%o4>) +define(, <%o5>) + +C %g1, %g2, %g3 are TMP1, TMP2 and TMP3 + +C The sparc64 stack frame looks like +C +C %fp - 8: OS-dependent link field +C %fp - 16: OS-dependent link field +C %fp - 192: OS register save area (22*8 == 176 bytes) +define(, 192) + + .file "aes-encrypt-internal.asm" + + C _aes_encrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + + .section ".text" + .align 16 + .proc 020 + +PROLOGUE(_nettle_aes_encrypt) + + save %sp, -FRAME_SIZE, %sp + cmp LENGTH, 0 + be .Lend + + C Loop invariants + add T, AES_TABLE0, T0 + add T, AES_TABLE1, T1 + add T, AES_TABLE2, T2 + add T, AES_TABLE3, T3 + +.Lblock_loop: + C Read src, and add initial subkey + add CTX, AES_KEYS, KEY + AES_LOAD(0, SRC, KEY, W0) + AES_LOAD(1, SRC, KEY, W1) + AES_LOAD(2, SRC, KEY, W2) + AES_LOAD(3, SRC, KEY, W3) + + C Must be even, and includes the final round + ld [AES_NROUNDS + CTX], ROUND + add SRC, 16, SRC + add KEY, 16, KEY + + srl ROUND, 1, ROUND + C Last two rounds handled specially + sub ROUND, 1, ROUND +.Lround_loop: + C The AES_ROUND macro uses T0,... T3 + C Transform W -> X + AES_ROUND(0, W0, W1, W2, W3, KEY, X0) + AES_ROUND(1, W1, W2, W3, W0, KEY, X1) + AES_ROUND(2, W2, W3, W0, W1, KEY, X2) + AES_ROUND(3, W3, W0, W1, W2, KEY, X3) + + C Transform X -> W + AES_ROUND(4, X0, X1, X2, X3, KEY, W0) + AES_ROUND(5, X1, X2, X3, X0, KEY, W1) + AES_ROUND(6, X2, X3, X0, X1, KEY, W2) + AES_ROUND(7, X3, X0, X1, X2, KEY, W3) + + subcc ROUND, 1, ROUND + bne .Lround_loop + add KEY, 32, KEY + + C Penultimate round + AES_ROUND(0, W0, W1, W2, W3, KEY, X0) + AES_ROUND(1, W1, W2, W3, W0, KEY, X1) + AES_ROUND(2, W2, W3, W0, W1, KEY, X2) + AES_ROUND(3, W3, W0, W1, W2, KEY, X3) + + add KEY, 16, KEY + C Final round + AES_FINAL_ROUND(0, T, X0, X1, X2, X3, KEY, DST) + AES_FINAL_ROUND(1, T, X1, X2, X3, X0, KEY, DST) + AES_FINAL_ROUND(2, T, X2, X3, X0, X1, KEY, DST) + AES_FINAL_ROUND(3, T, X3, X0, X1, X2, KEY, DST) + + subcc LENGTH, 16, LENGTH + bne .Lblock_loop + add DST, 16, DST + +.Lend: + ret + restore +EPILOGUE(_nettle_aes_encrypt) + +C Stats for AES 128 on sellafield.lysator.liu.se (UE450, 296 MHz) + +C 1. nettle-1.13 C-code (nettle-1.13 assembler was broken for sparc64) +C 2. New C-code +C 3. New assembler code (basically the same as for sparc32) + +C MB/s cycles/block +C 1 0.8 5781 +C 2 1.8 2460 +C 3 8.2 548 diff --git a/sparc64/arcfour-crypt.asm b/sparc64/arcfour-crypt.asm new file mode 100644 index 0000000..0e407d1 --- /dev/null +++ b/sparc64/arcfour-crypt.asm @@ -0,0 +1,217 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2002, 2005 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C Define to YES, to enable the complex code to special case SRC +C and DST with compatible alignment. + +define(, ) + +C Registers + +define(, <%i0>) +define(,<%i1>) +define(, <%i2>) +define(, <%i3>) + +define(, <%i4>) +define(, <%i5>) +define(, <%g1>) +define(, <%g2>) +define(, <%g3>) +define(, <%o0>) +define(, <%o1>) +define(, <%o2>) +define(, <%o3>) + +C Computes the next byte of the key stream. As input, i must +C already point to the index for the current access, the index +C for the next access is stored in ni. The resulting key byte is +C stored in res. +C ARCFOUR_BYTE(i, ni, res) +define(, < + ldub [CTX + $1], SI + add $1, 1, $2 + add J, SI, J + and J, 0xff, J + ldub [CTX + J], SJ + and $2, 0xff, $2 + stb SI, [CTX + J] + add SI, SJ, SI + and SI, 0xff, SI + stb SJ, [CTX + $1] + ldub [CTX + SI], $3 +>)dnl + +define(, 192) + + .file "arcfour-crypt.asm" + + C arcfour_crypt(struct arcfour_ctx *ctx, + C unsigned length, uint8_t *dst, + C const uint8_t *src) + + .section ".text" + .align 16 + .proc 020 + +PROLOGUE(nettle_arcfour_crypt) + + save %sp, -FRAME_SIZE, %sp + cmp LENGTH, 0 + be .Lend + nop + + C Load both I and J + lduh [CTX + ARCFOUR_I], I1 + and I1, 0xff, J + srl I1, 8, I1 + + C We want an even address for DST + andcc DST, 1, %g0 + add I1, 1 ,I1 + beq .Laligned2 + and I1, 0xff, I1 + + mov I1, I2 + ldub [SRC], DATA + ARCFOUR_BYTE(I2, I1, TMP) + subcc LENGTH, 1, LENGTH + add SRC, 1, SRC + xor DATA, TMP, DATA + stb DATA, [DST] + beq .Ldone + add DST, 1, DST + +.Laligned2: + + cmp LENGTH, 2 + blu .Lfinal1 + C Harmless delay slot instruction + andcc DST, 2, %g0 + beq .Laligned4 + nop + + ldub [SRC], DATA + ARCFOUR_BYTE(I1, I2, TMP) + ldub [SRC + 1], TMP2 + add SRC, 2, SRC + xor DATA, TMP, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + subcc LENGTH, 2, LENGTH + or DATA, TMP, DATA + + sth DATA, [DST] + beq .Ldone + add DST, 2, DST + +.Laligned4: + cmp LENGTH, 4 + blu .Lfinal2 + C Harmless delay slot instruction + srl LENGTH, 2, N + +.Loop: + C Main loop, with aligned writes + + C FIXME: Could check if SRC is aligned, and + C use 32-bit reads in that case. + + ldub [SRC], DATA + ARCFOUR_BYTE(I1, I2, TMP) + ldub [SRC + 1], TMP2 + xor TMP, DATA, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + ldub [SRC + 2], TMP2 + or TMP, DATA, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I1, I2, TMP) + xor TMP2, TMP, TMP + ldub [SRC + 3], TMP2 + or TMP, DATA, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + or TMP, DATA, DATA + subcc N, 1, N + add SRC, 4, SRC + st DATA, [DST] + bne .Loop + add DST, 4, DST + + andcc LENGTH, 3, LENGTH + beq .Ldone + nop + +.Lfinal2: + C DST address must be 2-aligned + cmp LENGTH, 2 + blu .Lfinal1 + nop + + ldub [SRC], DATA + ARCFOUR_BYTE(I1, I2, TMP) + ldub [SRC + 1], TMP2 + add SRC, 2, SRC + xor DATA, TMP, DATA + sll DATA, 8, DATA + + ARCFOUR_BYTE(I2, I1, TMP) + xor TMP2, TMP, TMP + or DATA, TMP, DATA + + sth DATA, [DST] + beq .Ldone + add DST, 2, DST + +.Lfinal1: + mov I1, I2 + ldub [SRC], DATA + ARCFOUR_BYTE(I2, I1, TMP) + xor DATA, TMP, DATA + stb DATA, [DST] + +.Ldone: + C Save back I and J + sll I2, 8, I2 + or I2, J, I2 + stuh I2, [CTX + ARCFOUR_I] + +.Lend: + ret + restore + +EPILOGUE(nettle_arcfour_crypt) + +C Stats for AES 128 on sellafield.lysator.liu.se (UE450, 296 MHz) + +C 1: nettle-1.13 C-code +C 2: New assembler code (basically the same as for sparc32) + +C MB/s cycles/byte +C 1: 3.6 77.7 +C 2: 21.8 13.0 diff --git a/sparc64/machine.m4 b/sparc64/machine.m4 new file mode 100644 index 0000000..4c1c0e5 --- /dev/null +++ b/sparc64/machine.m4 @@ -0,0 +1,4 @@ +define(, 2047) C Magic stack bias for the Sparc64 ABI + +.register %g2,#scratch +.register %g3,#scratch diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make new file mode 100644 index 0000000..fe6489d --- /dev/null +++ b/testsuite/.test-rules.make @@ -0,0 +1,126 @@ +aes-test$(EXEEXT): aes-test.$(OBJEXT) + $(LINK) aes-test.$(OBJEXT) $(TEST_OBJS) -o aes-test$(EXEEXT) + +arcfour-test$(EXEEXT): arcfour-test.$(OBJEXT) + $(LINK) arcfour-test.$(OBJEXT) $(TEST_OBJS) -o arcfour-test$(EXEEXT) + +arctwo-test$(EXEEXT): arctwo-test.$(OBJEXT) + $(LINK) arctwo-test.$(OBJEXT) $(TEST_OBJS) -o arctwo-test$(EXEEXT) + +blowfish-test$(EXEEXT): blowfish-test.$(OBJEXT) + $(LINK) blowfish-test.$(OBJEXT) $(TEST_OBJS) -o blowfish-test$(EXEEXT) + +cast128-test$(EXEEXT): cast128-test.$(OBJEXT) + $(LINK) cast128-test.$(OBJEXT) $(TEST_OBJS) -o cast128-test$(EXEEXT) + +base16-test$(EXEEXT): base16-test.$(OBJEXT) + $(LINK) base16-test.$(OBJEXT) $(TEST_OBJS) -o base16-test$(EXEEXT) + +base64-test$(EXEEXT): base64-test.$(OBJEXT) + $(LINK) base64-test.$(OBJEXT) $(TEST_OBJS) -o base64-test$(EXEEXT) + +camellia-test$(EXEEXT): camellia-test.$(OBJEXT) + $(LINK) camellia-test.$(OBJEXT) $(TEST_OBJS) -o camellia-test$(EXEEXT) + +des-test$(EXEEXT): des-test.$(OBJEXT) + $(LINK) des-test.$(OBJEXT) $(TEST_OBJS) -o des-test$(EXEEXT) + +des3-test$(EXEEXT): des3-test.$(OBJEXT) + $(LINK) des3-test.$(OBJEXT) $(TEST_OBJS) -o des3-test$(EXEEXT) + +des-compat-test$(EXEEXT): des-compat-test.$(OBJEXT) + $(LINK) des-compat-test.$(OBJEXT) $(TEST_OBJS) -o des-compat-test$(EXEEXT) + +md2-test$(EXEEXT): md2-test.$(OBJEXT) + $(LINK) md2-test.$(OBJEXT) $(TEST_OBJS) -o md2-test$(EXEEXT) + +md4-test$(EXEEXT): md4-test.$(OBJEXT) + $(LINK) md4-test.$(OBJEXT) $(TEST_OBJS) -o md4-test$(EXEEXT) + +md5-test$(EXEEXT): md5-test.$(OBJEXT) + $(LINK) md5-test.$(OBJEXT) $(TEST_OBJS) -o md5-test$(EXEEXT) + +md5-compat-test$(EXEEXT): md5-compat-test.$(OBJEXT) + $(LINK) md5-compat-test.$(OBJEXT) $(TEST_OBJS) -o md5-compat-test$(EXEEXT) + +sha1-test$(EXEEXT): sha1-test.$(OBJEXT) + $(LINK) sha1-test.$(OBJEXT) $(TEST_OBJS) -o sha1-test$(EXEEXT) + +sha224-test$(EXEEXT): sha224-test.$(OBJEXT) + $(LINK) sha224-test.$(OBJEXT) $(TEST_OBJS) -o sha224-test$(EXEEXT) + +sha256-test$(EXEEXT): sha256-test.$(OBJEXT) + $(LINK) sha256-test.$(OBJEXT) $(TEST_OBJS) -o sha256-test$(EXEEXT) + +sha384-test$(EXEEXT): sha384-test.$(OBJEXT) + $(LINK) sha384-test.$(OBJEXT) $(TEST_OBJS) -o sha384-test$(EXEEXT) + +sha512-test$(EXEEXT): sha512-test.$(OBJEXT) + $(LINK) sha512-test.$(OBJEXT) $(TEST_OBJS) -o sha512-test$(EXEEXT) + +serpent-test$(EXEEXT): serpent-test.$(OBJEXT) + $(LINK) serpent-test.$(OBJEXT) $(TEST_OBJS) -o serpent-test$(EXEEXT) + +twofish-test$(EXEEXT): twofish-test.$(OBJEXT) + $(LINK) twofish-test.$(OBJEXT) $(TEST_OBJS) -o twofish-test$(EXEEXT) + +knuth-lfib-test$(EXEEXT): knuth-lfib-test.$(OBJEXT) + $(LINK) knuth-lfib-test.$(OBJEXT) $(TEST_OBJS) -o knuth-lfib-test$(EXEEXT) + +cbc-test$(EXEEXT): cbc-test.$(OBJEXT) + $(LINK) cbc-test.$(OBJEXT) $(TEST_OBJS) -o cbc-test$(EXEEXT) + +ctr-test$(EXEEXT): ctr-test.$(OBJEXT) + $(LINK) ctr-test.$(OBJEXT) $(TEST_OBJS) -o ctr-test$(EXEEXT) + +hmac-test$(EXEEXT): hmac-test.$(OBJEXT) + $(LINK) hmac-test.$(OBJEXT) $(TEST_OBJS) -o hmac-test$(EXEEXT) + +buffer-test$(EXEEXT): buffer-test.$(OBJEXT) + $(LINK) buffer-test.$(OBJEXT) $(TEST_OBJS) -o buffer-test$(EXEEXT) + +yarrow-test$(EXEEXT): yarrow-test.$(OBJEXT) + $(LINK) yarrow-test.$(OBJEXT) $(TEST_OBJS) -o yarrow-test$(EXEEXT) + +sexp-test$(EXEEXT): sexp-test.$(OBJEXT) + $(LINK) sexp-test.$(OBJEXT) $(TEST_OBJS) -o sexp-test$(EXEEXT) + +sexp-format-test$(EXEEXT): sexp-format-test.$(OBJEXT) + $(LINK) sexp-format-test.$(OBJEXT) $(TEST_OBJS) -o sexp-format-test$(EXEEXT) + +rsa2sexp-test$(EXEEXT): rsa2sexp-test.$(OBJEXT) + $(LINK) rsa2sexp-test.$(OBJEXT) $(TEST_OBJS) -o rsa2sexp-test$(EXEEXT) + +sexp2rsa-test$(EXEEXT): sexp2rsa-test.$(OBJEXT) + $(LINK) sexp2rsa-test.$(OBJEXT) $(TEST_OBJS) -o sexp2rsa-test$(EXEEXT) + +bignum-test$(EXEEXT): bignum-test.$(OBJEXT) + $(LINK) bignum-test.$(OBJEXT) $(TEST_OBJS) -o bignum-test$(EXEEXT) + +random-prime-test$(EXEEXT): random-prime-test.$(OBJEXT) + $(LINK) random-prime-test.$(OBJEXT) $(TEST_OBJS) -o random-prime-test$(EXEEXT) + +pkcs1-test$(EXEEXT): pkcs1-test.$(OBJEXT) + $(LINK) pkcs1-test.$(OBJEXT) $(TEST_OBJS) -o pkcs1-test$(EXEEXT) + +rsa-test$(EXEEXT): rsa-test.$(OBJEXT) + $(LINK) rsa-test.$(OBJEXT) $(TEST_OBJS) -o rsa-test$(EXEEXT) + +rsa-encrypt-test$(EXEEXT): rsa-encrypt-test.$(OBJEXT) + $(LINK) rsa-encrypt-test.$(OBJEXT) $(TEST_OBJS) -o rsa-encrypt-test$(EXEEXT) + +rsa-keygen-test$(EXEEXT): rsa-keygen-test.$(OBJEXT) + $(LINK) rsa-keygen-test.$(OBJEXT) $(TEST_OBJS) -o rsa-keygen-test$(EXEEXT) + +dsa-test$(EXEEXT): dsa-test.$(OBJEXT) + $(LINK) dsa-test.$(OBJEXT) $(TEST_OBJS) -o dsa-test$(EXEEXT) + +dsa-keygen-test$(EXEEXT): dsa-keygen-test.$(OBJEXT) + $(LINK) dsa-keygen-test.$(OBJEXT) $(TEST_OBJS) -o dsa-keygen-test$(EXEEXT) + +sha1-huge-test$(EXEEXT): sha1-huge-test.$(OBJEXT) + $(LINK) sha1-huge-test.$(OBJEXT) $(TEST_OBJS) -o sha1-huge-test$(EXEEXT) + +cxx-test$(EXEEXT): cxx-test.$(OBJEXT) + $(LINK_CXX) cxx-test.$(OBJEXT) $(TEST_OBJS) -o cxx-test$(EXEEXT) + diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in new file mode 100644 index 0000000..1549362 --- /dev/null +++ b/testsuite/Makefile.in @@ -0,0 +1,109 @@ +@SET_MAKE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +top_srcdir = @top_srcdir@ + +include ../config.make + +PRE_CPPFLAGS = -I.. -I$(top_srcdir) +PRE_LDFLAGS = -L.. + +TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \ + blowfish-test.c cast128-test.c \ + base16-test.c base64-test.c \ + camellia-test.c \ + des-test.c des3-test.c des-compat-test.c \ + md2-test.c md4-test.c md5-test.c md5-compat-test.c \ + sha1-test.c sha224-test.c sha256-test.c \ + sha384-test.c sha512-test.c \ + serpent-test.c twofish-test.c \ + knuth-lfib-test.c \ + cbc-test.c ctr-test.c hmac-test.c \ + buffer-test.c yarrow-test.c + +TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ + rsa2sexp-test.c sexp2rsa-test.c \ + bignum-test.c random-prime-test.c \ + pkcs1-test.c \ + rsa-test.c rsa-encrypt-test.c rsa-keygen-test.c \ + dsa-test.c dsa-keygen-test.c + +TS_SOURCES = $(TS_NETTLE_SOURCES) @IF_HOGWEED@ $(TS_HOGWEED_SOURCES) + +TS_NETTLE = $(TS_NETTLE_SOURCES:.c=$(EXEEXT)) +TS_HOGWEED = $(TS_HOGWEED_SOURCES:.c=$(EXEEXT)) +TS_C = $(TS_NETTLE) @IF_HOGWEED@ $(TS_HOGWEED) +TS_CXX = @CXX_TESTS@ +TARGETS = $(TS_C) $(TS_CXX) +TS_SH = sexp-conv-test pkcs1-conv-test symbols-test +TS_ALL = $(TARGETS) $(TS_SH) +EXTRA_SOURCES = sha1-huge-test.c +EXTRA_TARGETS = $(EXTRA_SOURCES:.c=$(EXEEXT)) + +SOURCES = $(TS_SOURCES) testutils.c + +DISTFILES = $(SOURCES) $(EXTRA_SOURCES) cxx-test.cxx Makefile.in .test-rules.make \ + $(TS_SH) run-tests teardown-env \ + gold-bug.txt testutils.h + +all: $(TARGETS) $(EXTRA_TARGETS) + +.c.$(OBJEXT): + $(COMPILE) -c $< && $(DEP_PROCESS) + +.SUFFIXES: .cxx +.cxx.$(OBJEXT): + $(COMPILE_CXX) -c $< && $(DEP_PROCESS) + +# BSD (and Solaris) make doesn't allow extra dependencies together one +# single-suffix rules, which makes it impossible or almost impossible +# to use suffix rules to build the test executables. So we use an +# explicit rule for each and every executable. + +LIB_HOGWEED = @IF_HOGWEED@ -lhogweed +TEST_OBJS = testutils.$(OBJEXT) $(LIB_HOGWEED) -lnettle $(LIBS) + +.PHONY: test-rules +test-rules: + (for f in $(TS_NETTLE) $(TS_HOGWEED) $(EXTRA_TARGETS) ; do \ + echo $$f'$$(EXEEXT): '$$f'.$$(OBJEXT)' ; \ + echo ' $$(LINK) '$$f'.$$(OBJEXT) $$(TEST_OBJS) -o '$$f'$$(EXEEXT)' ; \ + echo ; \ + done ; \ + for f in $(TS_CXX) ; do \ + echo $$f'$$(EXEEXT): '$$f'.$$(OBJEXT)' ; \ + echo ' $$(LINK_CXX) '$$f'.$$(OBJEXT) $$(TEST_OBJS) -o '$$f'$$(EXEEXT)' ; \ + echo ; \ + done) > $(srcdir)/.test-rules.make + +include $(srcdir)/.test-rules.make + +$(TARGETS) $(EXTRA_TARGETS): testutils.$(OBJEXT) \ + ../libnettle.a @IF_HOGWEED@ ../libhogweed.a + +check: $(TS_ALL) $(srcdir)/run-tests + LD_LIBRARY_PATH=../.lib srcdir="$(srcdir)" \ + $(srcdir)/run-tests $(TS_ALL) + + +Makefile: $(srcdir)/Makefile.in ../config.status + cd .. && $(SHELL) ./config.status testsuite/$@ + +install uninstall: + true + +distdir: $(DISTFILES) + cp $? $(distdir) + +clean: + -rm -f $(TARGETS) $(EXTRA_TARGETS) *.o test.in test1.out test2.out + +distclean: clean + -rm -f Makefile *.d + +tags: + etags -o $(srcdir)/TAGS --include $(top_srcdir) $(srcdir)/*.c $(srcdir)/*.h + +@DEP_INCLUDE@ $(SOURCES:.c=.$(OBJEXT).d) diff --git a/testsuite/aes-test.c b/testsuite/aes-test.c new file mode 100644 index 0000000..87be806 --- /dev/null +++ b/testsuite/aes-test.c @@ -0,0 +1,171 @@ +#include "testutils.h" +#include "aes.h" + +static void +test_invert(unsigned key_length, const uint8_t *key, + unsigned length, const uint8_t *cleartext, + const uint8_t *ciphertext) +{ + struct aes_ctx encrypt; + struct aes_ctx decrypt; + uint8_t *data = xalloc(length); + + aes_set_encrypt_key (&encrypt, key_length, key); + aes_encrypt (&encrypt, length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + { + fprintf(stderr, "test_invert: Encrypt failed:\nInput:"); + print_hex(length, cleartext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, ciphertext); + fprintf(stderr, "\n"); + FAIL(); + } + + aes_invert_key (&decrypt, &encrypt); + aes_decrypt (&decrypt, length, data, data); + + if (!MEMEQ(length, data, cleartext)) + { + fprintf(stderr, "test_invert: Decrypt failed:\nInput:"); + print_hex(length, ciphertext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, cleartext); + fprintf(stderr, "\n"); + FAIL(); + } + free (data); +} + +int +test_main(void) +{ + /* 128 bit keys */ + test_cipher(&nettle_aes128, + HL("0001020305060708 0A0B0C0D0F101112"), + HL("506812A45F08C889 B97F5980038B8359"), + H("D8F532538289EF7D 06B506A4FD5BE9C9")); + + test_cipher(&nettle_aes128, + HL("14151617191A1B1C 1E1F202123242526"), + HL("5C6D71CA30DE8B8B 00549984D2EC7D4B"), + H("59AB30F4D4EE6E4F F9907EF65B1FB68C")); + + test_cipher(&nettle_aes128, + HL("28292A2B2D2E2F30 323334353738393A"), + HL("53F3F4C64F8616E4 E7C56199F48F21F6"), + H("BF1ED2FCB2AF3FD4 1443B56D85025CB1")); + + test_cipher(&nettle_aes128, + HL("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2"), + HL("F5F4F7F684878689 A6A7A0A1D2CDCCCF"), + H("CE52AF650D088CA5 59425223F4D32694")); + + /* 192 bit keys */ + + test_cipher(&nettle_aes192, + HL("0001020305060708 0A0B0C0D0F101112" + "14151617191A1B1C"), + HL("2D33EEF2C0430A8A 9EBF45E809C40BB6"), + H("DFF4945E0336DF4C 1C56BC700EFF837F")); + + /* 256 bit keys */ + + test_cipher(&nettle_aes256, + HL("0001020305060708 0A0B0C0D0F101112" + "14151617191A1B1C 1E1F202123242526"), + HL("834EADFCCAC7E1B30664B1ABA44815AB"), + H("1946DABF6A03A2A2 C3D0B05080AED6FC")); + + + /* This test case has been problematic with the CBC test case */ + test_cipher(&nettle_aes256, + HL("8d ae 93 ff fc 78 c9 44" + "2a bd 0c 1e 68 bc a6 c7" + "05 c7 84 e3 5a a9 11 8b" + "d3 16 aa 54 9b 44 08 9e"), + HL("a5 ce 55 d4 21 15 a1 c6 4a a4 0c b2 ca a6 d1 37"), + /* In the cbc test, I once got the bad value + * "b2 a0 6c d2 2f df 7d 2c 26 d2 42 88 8f 20 74 a2" */ + H("1f 94 fc 85 f2 36 21 06" + "4a ea e3 c9 cc 38 01 0e")); + + /* From draft NIST spec on AES modes. + * + * F.1 ECB Example Vectors + * F.1.1 ECB-AES128-Encrypt + */ + + test_cipher(&nettle_aes128, + HL("2b7e151628aed2a6abf7158809cf4f3c"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("3ad77bb40d7a3660a89ecaf32466ef97" + "f5d3d58503b9699de785895a96fdbaaf" + "43b1cd7f598ece23881b00e3ed030688" + "7b0c785e27e8ad3f8223207104725dd4")); + + /* F.1.3 ECB-AES192-Encrypt */ + + test_cipher(&nettle_aes192, + HL("8e73b0f7da0e6452c810f32b809079e5 62f8ead2522c6b7b"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("bd334f1d6e45f25ff712a214571fa5cc" + "974104846d0ad3ad7734ecb3ecee4eef" + "ef7afd2270e2e60adce0ba2face6444e" + "9a4b41ba738d6c72fb16691603c18e0e")); + + /* F.1.5 ECB-AES256-Encrypt */ + test_cipher(&nettle_aes256, + HL("603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("f3eed1bdb5d2a03c064b5a7e3db181f8" + "591ccb10d410ed26dc5ba74a31362870" + "b6ed21b99ca6f4f9f153e7b1beafed1d" + "23304b7a39f9f3ff067d8d8f9e24ecc7")); + + /* Test aes_invert_key with src != dst */ + test_invert(HL("0001020305060708 0A0B0C0D0F101112"), + HL("506812A45F08C889 B97F5980038B8359"), + H("D8F532538289EF7D 06B506A4FD5BE9C9")); + test_invert(HL("0001020305060708 0A0B0C0D0F101112" + "14151617191A1B1C"), + HL("2D33EEF2C0430A8A 9EBF45E809C40BB6"), + H("DFF4945E0336DF4C 1C56BC700EFF837F")); + test_invert(HL("0001020305060708 0A0B0C0D0F101112" + "14151617191A1B1C 1E1F202123242526"), + HL("834EADFCCAC7E1B30664B1ABA44815AB"), + H("1946DABF6A03A2A2 C3D0B05080AED6FC")); + + SUCCESS(); +} + +/* Internal state for the first test case: + + 0: a7106950 81cf0e5a 8d5574b3 4b929b0c + 1: aa1e31c4 c19a8917 12282e4 b23e51eb + 2: 14be6dac fede8fdc 8fb98878 a27dfb5c + 3: e80a6f32 431515bb 72e8a651 7daf188b + 4: c50438c0 d464b2b6 76b875e9 b2b5f574 + 5: d81ab740 746b4d89 ff033aac 44d5ffa2 + 6: 52e6bb4a edadc170 24867df4 6e2ad5d5 + 7: ab1c7365 64d09f00 7718d521 46a3df32 + 8: f1eaad16 1aefdfb 7ba5724d d8499631 + 9: 1020300 2030001 3000102 10203 + 99: 5332f5d8 7def8982 a406b506 c9e95bfd + +*/ diff --git a/testsuite/arcfour-test.c b/testsuite/arcfour-test.c new file mode 100644 index 0000000..6027c54 --- /dev/null +++ b/testsuite/arcfour-test.c @@ -0,0 +1,97 @@ +#include "testutils.h" +#include "arcfour.h" + +int +test_main(void) +{ + test_cipher_stream(&nettle_arcfour128, + HL("01234567 89ABCDEF 00000000 00000000"), + HL("01234567 89ABCDEF"), + H("69723659 1B5242B1")); + + /* More data. This ensures that we get some collisions between the S + accesses at index i,j and the access at si + sj. I.e. the cases + where the ordering of loads and stores matter. */ + test_cipher_stream(&nettle_arcfour128, + HL("aaaaaaaa bbbbbbbb cccccccc dddddddd"), + HL("00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000" + "00000000 00000000 00000000 00000000"), + H("a2b35dc7 bf95ae1e 1c432d15 f4fb8c1c" + "f264e1d0 bd090831 6caa7d17 5401ae67" + "3cfbd140 fd3dee42 1012d674 2fb69fa3" + "6522631e bb3d4703 535de1ce 4a81ddce" + + "5780cfe0 b5fc9fae ebe14c96 26451bd9" + "992f2204 119cbe37 cbdc453c 7afa08c7" + "1380ccf8 48f81e53 a535cdfb 96c64faa" + "c3f759d0 fa1ff920 008d95cf 39d52324" + + "d0aac3f9 749b22e2 6a065145 06fb249d" + "ffb8e05e cb0381fe 5346a04a 63dac61c" + "10b6683e 3ab427de d4c6bc60 6366545e" + "77d0e121 96037717 a745d49e e72a70aa" + + "a50a612d 879b0580 fd4a89ae 3ee49871" + "2cf6c98d a62dfbc7 d7b2d901 2c3aaf27" + "42b7e089 ef2466ac 450b440c 138daa1a" + "cf9ebef6 f66a7a64 2677b213 06640130" + + "de6651df 0065180d 4db366ba 9c377712" + "53d21cac 82ed72a4 c6c4d81e 4375fea3" + "1f935909 95322c83 13c64d8e 829c93a6" + "d540a1b3 20f41541 96800888 1a7afc9b" + + "e39e89fc 3ac78be5 cdbbf774 33c36863" + "da2a3b1b d06e54a9 aa4b7edd 70b34941" + "b886f7db f36c3def f9fc4c80 7ce55ea5" + "98a7257b f68a9e1d caf4bfd6 43bd9853" + + "c966629d 54e34221 6e140780 d48c69bb" + "5e77e886 86f2ebcb 807732d5 d29bc384" + "a4ca1c31 c7c1b5b9 85dbfcf1 8d845905" + "a0ff487a b4a3f252 a75caebf 857ba48b" + + "613e3067 92cada3e 0e07f599 2f4794f3" + "af01f15a 491732fb 22aa09a3 d2e1e408" + "fe94bdb4 993c68b1 1bb79eb1 bb7ec446" + "760ef7bf 2caa8713 479760e5 a6e143cd")); + + SUCCESS(); +} diff --git a/testsuite/arctwo-test.c b/testsuite/arctwo-test.c new file mode 100644 index 0000000..17c3503 --- /dev/null +++ b/testsuite/arctwo-test.c @@ -0,0 +1,115 @@ +/* nettle, low-level cryptographics library + * + * Copyright (C) 2004 Simon Josefsson + * Copyright (C) 2004 Niels Möller + * + * The nettle 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 nettle 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 nettle 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 "testutils.h" +#include "arctwo.h" + +/* For tests with obscure values of ebk. */ +static void +test_arctwo(unsigned ekb, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext) +{ + struct arctwo_ctx ctx; + uint8_t *data = xalloc(length); + + arctwo_set_key_ekb(&ctx, key_length, key, ekb); + arctwo_encrypt(&ctx, length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + FAIL(); + + arctwo_decrypt(&ctx, length, data, data); + + if (!MEMEQ(length, data, cleartext)) + FAIL(); + + free(data); +} + +int +test_main(void) +{ + /* Test vectors from Peter Gutmann's paper. */ + test_cipher(&nettle_arctwo_gutmann128, + HL("00000000 00000000 00000000 00000000"), + HL("00000000 00000000"), + H ("1c198a83 8df028b7")); + + test_cipher(&nettle_arctwo_gutmann128, + HL("00010203 04050607 08090a0b 0c0d0e0f"), + HL("00000000 00000000"), + H ("50dc0162 bd757f31")); + + /* This one was checked against libmcrypt's RFC2268. */ + test_cipher(&nettle_arctwo_gutmann128, + HL("30000000 00000000 00000000 00000000"), + HL("10000000 00000000"), + H ("8fd10389 336bf95e")); + + /* Test vectors from RFC 2268. */ + test_cipher(&nettle_arctwo64, + HL("ffffffff ffffffff"), + HL("ffffffff ffffffff"), + H ("278b27e4 2e2f0d49")); + + test_cipher(&nettle_arctwo64, + HL("30000000 00000000"), + HL("10000000 00000001"), + H ("30649edf 9be7d2c2")); + + test_cipher(&nettle_arctwo128, + HL("88bca90e 90875a7f 0f79c384 627bafb2"), + HL("00000000 00000000"), + H ("2269552a b0f85ca6")); + + /* More obscure tests from RFC 2286 */ + test_arctwo(63, + HL("00000000 00000000"), + HL("00000000 00000000"), + H ("ebb773f9 93278eff")); + + test_arctwo(64, + HL("88"), + HL("00000000 00000000"), + H ("61a8a244 adacccf0")); + + test_arctwo(64, + HL("88bca90e 90875a"), + HL("00000000 00000000"), + H ("6ccf4308 974c267f")); + + test_arctwo(64, + HL("88bca90e 90875a7f 0f79c384 627bafb2"), + HL("00000000 00000000"), + H ("1a807d27 2bbe5db1")); + + test_arctwo(129, + HL("88bca90e 90875a7f 0f79c384 627bafb2" + "16f80a6f 85920584 c42fceb0 be255daf 1e"), + HL("00000000 00000000"), + H ("5b78d3a4 3dfff1f1")); + + SUCCESS (); +} diff --git a/testsuite/base16-test.c b/testsuite/base16-test.c new file mode 100644 index 0000000..fe8fe92 --- /dev/null +++ b/testsuite/base16-test.c @@ -0,0 +1,27 @@ +#include "testutils.h" +#include "base16.h" + +int +test_main(void) +{ + ASSERT(BASE16_ENCODE_LENGTH(0) == 0); + ASSERT(BASE16_ENCODE_LENGTH(1) == 2); + ASSERT(BASE16_ENCODE_LENGTH(2) == 4); + + ASSERT(BASE16_DECODE_LENGTH(0) == 0); + ASSERT(BASE16_DECODE_LENGTH(1) == 1); + ASSERT(BASE16_DECODE_LENGTH(2) == 1); + ASSERT(BASE16_DECODE_LENGTH(3) == 2); + ASSERT(BASE16_DECODE_LENGTH(4) == 2); + + test_armor(&nettle_base16, 0, "", ""); + test_armor(&nettle_base16, 1, "H", "48"); + test_armor(&nettle_base16, 2, "He", "4865"); + test_armor(&nettle_base16, 3, "Hel", "48656c"); + test_armor(&nettle_base16, 4, "Hell", "48656c6c"); + test_armor(&nettle_base16, 5, "Hello", "48656c6c6f"); + test_armor(&nettle_base16, 6, "Hello", "48656c6c6f00"); + + SUCCESS(); +} + diff --git a/testsuite/base64-test.c b/testsuite/base64-test.c new file mode 100644 index 0000000..b4d0917 --- /dev/null +++ b/testsuite/base64-test.c @@ -0,0 +1,50 @@ +#include "testutils.h" +#include "base64.h" + +int +test_main(void) +{ + ASSERT(BASE64_ENCODE_LENGTH(0) == 0); /* At most 4 bits */ + ASSERT(BASE64_ENCODE_LENGTH(1) == 2); /* At most 12 bits */ + ASSERT(BASE64_ENCODE_LENGTH(2) == 3); /* At most 20 bits */ + ASSERT(BASE64_ENCODE_LENGTH(3) == 4); /* At most 28 bits */ + ASSERT(BASE64_ENCODE_LENGTH(4) == 6); /* At most 36 bits */ + ASSERT(BASE64_ENCODE_LENGTH(5) == 7); /* At most 44 bits */ + ASSERT(BASE64_ENCODE_LENGTH(12) == 16); /* At most 100 bits */ + ASSERT(BASE64_ENCODE_LENGTH(13) == 18); /* At most 108 bits */ + + ASSERT(BASE64_DECODE_LENGTH(0) == 0); /* At most 6 bits */ + ASSERT(BASE64_DECODE_LENGTH(1) == 1); /* At most 12 bits */ + ASSERT(BASE64_DECODE_LENGTH(2) == 2); /* At most 18 bits */ + ASSERT(BASE64_DECODE_LENGTH(3) == 3); /* At most 24 bits */ + ASSERT(BASE64_DECODE_LENGTH(4) == 3); /* At most 30 bits */ + + test_armor(&nettle_base64, 0, "", ""); + test_armor(&nettle_base64, 1, "H", "SA=="); + test_armor(&nettle_base64, 2, "He", "SGU="); + test_armor(&nettle_base64, 3, "Hel", "SGVs"); + test_armor(&nettle_base64, 4, "Hell", "SGVsbA=="); + test_armor(&nettle_base64, 5, "Hello", "SGVsbG8="); + test_armor(&nettle_base64, 6, "Hello", "SGVsbG8A"); + test_armor(&nettle_base64, 4, "\xff\xff\xff\xff", "/////w=="); + + { + /* Test overlapping areas */ + uint8_t buffer[] = "Helloxxxx"; + struct base64_decode_ctx ctx; + unsigned dst_length; + + ASSERT(BASE64_ENCODE_RAW_LENGTH(5) == 8); + base64_encode_raw(buffer, 5, buffer); + ASSERT(MEMEQ(9, buffer, "SGVsbG8=x")); + + base64_decode_init(&ctx); + dst_length = 8; + ASSERT(base64_decode_update(&ctx, &dst_length, buffer, 8, buffer)); + ASSERT(dst_length == 5); + + ASSERT(MEMEQ(9, buffer, "HelloG8=x")); + } + + SUCCESS(); +} diff --git a/testsuite/bignum-test.c b/testsuite/bignum-test.c new file mode 100644 index 0000000..84e0483 --- /dev/null +++ b/testsuite/bignum-test.c @@ -0,0 +1,97 @@ +#include "testutils.h" + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#if HAVE_LIBGMP +#include "bignum.h" + +static void +test_bignum(const char *hex, unsigned length, const uint8_t *base256) +{ + mpz_t a; + mpz_t b; + uint8_t *buf; + + mpz_init_set_str(a, hex, 16); + nettle_mpz_init_set_str_256_s(b, length, base256); + + if (mpz_cmp(a, b)) + FAIL(); + + buf = xalloc(length + 1); + memset(buf, 17, length + 1); + + nettle_mpz_get_str_256(length, buf, a); + if (!MEMEQ(length, buf, base256)) + FAIL(); + + if (buf[length] != 17) + FAIL(); + + mpz_clear(a); mpz_clear(b); + free(buf); +} + +static void +test_size(long x, unsigned size) +{ + mpz_t t; + + mpz_init_set_si(t, x); + ASSERT(nettle_mpz_sizeinbase_256_s(t) == size); + mpz_clear(t); +} +#endif /* HAVE_LIBGMP */ + + +int +test_main(void) +{ +#if HAVE_LIBGMP + test_size(0, 1); + test_size(1, 1); + test_size(0x7f, 1); + test_size(0x80, 2); + test_size(0x81, 2); + test_size(0xff, 2); + test_size(0x100, 2); + test_size(0x101, 2); + test_size(0x1111, 2); + test_size(0x7fff, 2); + test_size(0x8000, 3); + test_size(0x8001, 3); + + test_size(- 1, 1); /* ff */ + test_size(- 0x7f, 1); /* 81 */ + test_size(- 0x80, 1); /* 80 */ + test_size(- 0x81, 2); /* ff7f */ + test_size(- 0xff, 2); /* ff01 */ + test_size(- 0x100, 2); /* ff00 */ + test_size(- 0x101, 2); /* feff */ + test_size(- 0x1111, 2); /* eeef */ + test_size(- 0x7fff, 2); /* 8001 */ + test_size(- 0x8000, 2); /* 8000 */ + test_size(- 0x8001, 3); /* ff7fff */ + + test_bignum("0", HL("00")); + test_bignum("010203040506", HL("010203040506")); + test_bignum("80010203040506", HL("0080010203040506")); + + test_bignum( "-1", HL( "ff")); + test_bignum( "-7f", HL( "81")); + test_bignum( "-80", HL( "80")); + test_bignum( "-81", HL( "ff7f")); + test_bignum("-7fff", HL( "8001")); + test_bignum("-8000", HL( "8000")); + test_bignum("-8001", HL("ff7fff")); + + SUCCESS(); +#else /* !HAVE_LIBGMP */ + SKIP(); +#endif /* !HAVE_LIBGMP */ +} diff --git a/testsuite/blowfish-test.c b/testsuite/blowfish-test.c new file mode 100644 index 0000000..c4311bb --- /dev/null +++ b/testsuite/blowfish-test.c @@ -0,0 +1,89 @@ +#include "testutils.h" +#include "nettle-internal.h" +#include "blowfish.h" + +int +test_main(void) +{ + /* 208 bit key. Test from GNUPG. */ + test_cipher(&nettle_blowfish128, + 26, "abcdefghijklmnopqrstuvwxyz", + BLOWFISH_BLOCK_SIZE, "BLOWFISH", + H("32 4E D0 FE F4 13 A2 03")); + + SUCCESS(); +} +/* FIXME: All values below are bogus. */ +#if 0 + +/* 128 bit keys */ +H(msg, "506812A45F08C889 B97F5980038B8359"); + +blowfish_set_key(&ctx, 16, H("0001020305060708 0A0B0C0D0F101112")); +blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg); +if (!MEMEQ(16, cipher, H("D8F532538289EF7D 06B506A4FD5BE9C9"))) + FAIL; + +blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher); +if (!MEMEQ(16, msg, clear)) + FAIL; + +H(msg, "5C6D71CA30DE8B8B 00549984D2EC7D4B"); + +blowfish_set_key(&ctx, 16, H("14151617191A1B1C 1E1F202123242526")); +blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg); +if (!MEMEQ(16, cipher, H("59AB30F4D4EE6E4F F9907EF65B1FB68C"))) + FAIL; + +blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher); +if (!MEMEQ(16, msg, clear)) + FAIL; + +H(msg, "53F3F4C64F8616E4 E7C56199F48F21F6"); + +blowfish_set_key(&ctx, 16, H("28292A2B2D2E2F30 323334353738393A")); +blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg); +if (!MEMEQ(16, cipher, H("BF1ED2FCB2AF3FD4 1443B56D85025CB1"))) + FAIL; + +blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher); +if (!MEMEQ(16, msg, clear)) + FAIL; + +H(msg, "F5F4F7F684878689 A6A7A0A1D2CDCCCF"); + +blowfish_set_key(&ctx, 16, H("A0A1A2A3A5A6A7A8 AAABACADAFB0B1B2")); +blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg); +if (!MEMEQ(16, cipher, H("CE52AF650D088CA5 59425223F4D32694"))) + FAIL; + +blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher); +if (!MEMEQ(16, msg, clear)) + FAIL; + +/* 192 bit keys */ +H(msg, "2D33EEF2C0430A8A 9EBF45E809C40BB6"); + +blowfish_set_key(&ctx, 24, H("0001020305060708 0A0B0C0D0F101112" + "14151617191A1B1C")); +blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg); +if (!MEMEQ(16, cipher, H("DFF4945E0336DF4C 1C56BC700EFF837F"))) + FAIL; + +blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher); +if (!MEMEQ(16, msg, clear)) + FAIL; + +/* 256 bit keys */ +H(msg, "834EADFCCAC7E1B30664B1ABA44815AB"); + +blowfish_set_key(&ctx, 32, H("0001020305060708 0A0B0C0D0F101112" + "14151617191A1B1C 1E1F202123242526")); +blowfish_encrypt(&ctx, BLOWFISH_BLOCK_SIZE, cipher, msg); +if (!MEMEQ(16, cipher, H("1946DABF6A03A2A2 C3D0B05080AED6FC"))) + FAIL; + +blowfish_decrypt(&ctx, BLOWFISH_BLOCK_SIZE, clear, cipher); +if (!MEMEQ(16, msg, clear)) + FAIL; +#endif diff --git a/testsuite/buffer-test.c b/testsuite/buffer-test.c new file mode 100644 index 0000000..3ac4b20 --- /dev/null +++ b/testsuite/buffer-test.c @@ -0,0 +1,29 @@ +#include "testutils.h" +#include "buffer.h" + +int +test_main(void) +{ + struct nettle_buffer buffer; + uint8_t s[5]; + + nettle_buffer_init(&buffer); + ASSERT(nettle_buffer_write(&buffer, LDATA("foo"))); + + ASSERT(NETTLE_BUFFER_PUTC(&buffer, 'x')); + + ASSERT(buffer.size == 4); + ASSERT(buffer.alloc >= 4); + ASSERT(MEMEQ(4, buffer.contents, "foox")); + + nettle_buffer_clear(&buffer); + + nettle_buffer_init_size(&buffer, sizeof(s), s); + ASSERT(buffer.alloc == sizeof(s)); + ASSERT(nettle_buffer_write(&buffer, LDATA("foo"))); + ASSERT(buffer.size == 3); + + ASSERT(!nettle_buffer_write(&buffer, LDATA("bar"))); + + SUCCESS(); +} diff --git a/testsuite/camellia-test.c b/testsuite/camellia-test.c new file mode 100644 index 0000000..4f1d118 --- /dev/null +++ b/testsuite/camellia-test.c @@ -0,0 +1,84 @@ +#include "testutils.h" +#include "camellia.h" + +static void +test_invert(unsigned key_length, const uint8_t *key, + unsigned length, const uint8_t *cleartext, + const uint8_t *ciphertext) +{ + struct camellia_ctx encrypt; + struct camellia_ctx decrypt; + uint8_t *data = xalloc(length); + + camellia_set_encrypt_key (&encrypt, key_length, key); + camellia_crypt (&encrypt, length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + { + fprintf(stderr, "test_invert: Encrypt failed:\nInput:"); + print_hex(length, cleartext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, ciphertext); + fprintf(stderr, "\n"); + FAIL(); + } + + camellia_invert_key (&decrypt, &encrypt); + camellia_crypt (&decrypt, length, data, data); + + if (!MEMEQ(length, data, cleartext)) + { + fprintf(stderr, "test_invert: Decrypt failed:\nInput:"); + print_hex(length, ciphertext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, cleartext); + fprintf(stderr, "\n"); + FAIL(); + } + free (data); +} + +int +test_main(void) +{ + /* Test vectors from RFC 3713 */ + /* 128 bit keys */ + test_cipher(&nettle_camellia128, + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + H("67 67 31 38 54 96 69 73 08 57 06 56 48 ea be 43")); + + /* 192 bit keys */ + test_cipher(&nettle_camellia192, + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10" + "00 11 22 33 44 55 66 77"), + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + H("b4 99 34 01 b3 e9 96 f8 4e e5 ce e7 d7 9b 09 b9")); + + /* 256 bit keys */ + test_cipher(&nettle_camellia256, + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10" + "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"), + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + H("9a cc 23 7d ff 16 d7 6c 20 ef 7c 91 9e 3a 75 09")); + + /* Test camellia_invert_key with src != dst */ + test_invert(HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + H("67 67 31 38 54 96 69 73 08 57 06 56 48 ea be 43")); + + test_invert(HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10" + "00 11 22 33 44 55 66 77"), + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + H("b4 99 34 01 b3 e9 96 f8 4e e5 ce e7 d7 9b 09 b9")); + + test_invert(HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10" + "00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"), + HL("01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10"), + H("9a cc 23 7d ff 16 d7 6c 20 ef 7c 91 9e 3a 75 09")); + SUCCESS(); +} diff --git a/testsuite/cast128-test.c b/testsuite/cast128-test.c new file mode 100644 index 0000000..e4b7830 --- /dev/null +++ b/testsuite/cast128-test.c @@ -0,0 +1,30 @@ +#include "testutils.h" +#include "cast128.h" + +int +test_main(void) +{ + /* Test vectors from B.1. Single Plaintext-Key-Ciphertext Sets, RFC + * 2144 */ + + /* 128 bit key */ + test_cipher(&nettle_cast128, + HL("01 23 45 67 12 34 56 78" + "23 45 67 89 34 56 78 9A"), + HL("01 23 45 67 89 AB CD EF"), + H("23 8B 4F E5 84 7E 44 B2")); + + /* 80 bit key */ + test_cipher(&nettle_cast128, + HL("01 23 45 67 12 34 56 78 23 45"), + HL("01 23 45 67 89 AB CD EF"), + H("EB 6A 71 1A 2C 02 27 1B")); + + /* 40 bit key */ + test_cipher(&nettle_cast128, + HL("01 23 45 67 12"), + HL("01 23 45 67 89 AB CD EF"), + H("7A C8 16 D1 6E 9B 30 2E")); + + SUCCESS(); +} diff --git a/testsuite/cbc-test.c b/testsuite/cbc-test.c new file mode 100644 index 0000000..b7bd2dd --- /dev/null +++ b/testsuite/cbc-test.c @@ -0,0 +1,329 @@ +#include "testutils.h" +#include "aes.h" +#include "cbc.h" +#include "knuth-lfib.h" + +/* Test with more data and inplace decryption, to check that the + * cbc_decrypt buffering works. */ +#define CBC_BULK_DATA 0x2710 /* 10000 */ + +static void +test_cbc_bulk(void) +{ + struct knuth_lfib_ctx random; + + uint8_t clear[CBC_BULK_DATA]; + + uint8_t cipher[CBC_BULK_DATA + 1]; + + const uint8_t *key = H("966c7bf00bebe6dc 8abd37912384958a" + "743008105a08657d dcaad4128eee38b3"); + + const uint8_t *start_iv = H("11adbff119749103 207619cfa0e8d13a"); + const uint8_t *end_iv = H("c7a42a569b421224 d0c23e52f46f97f5"); + + struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes; + + knuth_lfib_init(&random, CBC_BULK_DATA); + knuth_lfib_random(&random, CBC_BULK_DATA, clear); + + /* Byte that should not be overwritten */ + cipher[CBC_BULK_DATA] = 17; + + aes_set_encrypt_key(&aes.ctx, 32, key); + CBC_SET_IV(&aes, start_iv); + + CBC_ENCRYPT(&aes, aes_encrypt, CBC_BULK_DATA, cipher, clear); + + if (cipher[CBC_BULK_DATA] != 17) + FAIL(); + + if (verbose) + { + printf("IV after bulk encryption: "); + print_hex(AES_BLOCK_SIZE, aes.iv); + printf("\n"); + } + + if (!MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv)) + FAIL(); + + /* Decrypt, in place */ + aes_set_decrypt_key(&aes.ctx, 32, key); + CBC_SET_IV(&aes, start_iv); + CBC_DECRYPT(&aes, aes_decrypt, CBC_BULK_DATA, cipher, cipher); + + if (cipher[CBC_BULK_DATA] != 17) + FAIL(); + + if (verbose) + { + printf("IV after bulk decryption: "); + print_hex(AES_BLOCK_SIZE, aes.iv); + printf("\n"); + } + + if (!MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv)) + FAIL(); + + if (!MEMEQ(CBC_BULK_DATA, clear, cipher)) + FAIL(); +} + +int +test_main(void) +{ + static const uint8_t msg[2 * AES_BLOCK_SIZE] = "Listen, I'll say this only once!"; + + /* Intermediate values: + * iv XOR first message block: + * "a5 ce 55 d4 21 15 a1 c6 4a a4 0c b2 ca a6 d1 37" + * First ciphertext block, c1: + * "1f 94 fc 85 f2 36 21 06 4a ea e3 c9 cc 38 01 0e" + * c1 XOR second message block: + * "3f e0 94 ec 81 16 4e 68 26 93 c3 a6 a2 5b 64 2f" + * Second ciphertext block, c1: + * "7b f6 5f c5 02 59 2e 71 af bf 34 87 c0 36 2a 16" + */ + + test_cipher_cbc(&nettle_aes256, + HL("8d ae 93 ff fc 78 c9 44" + "2a bd 0c 1e 68 bc a6 c7" + "05 c7 84 e3 5a a9 11 8b" + "d3 16 aa 54 9b 44 08 9e"), + 2 * AES_BLOCK_SIZE, msg, + H("1f 94 fc 85 f2 36 21 06" + "4a ea e3 c9 cc 38 01 0e" + "7b f6 5f c5 02 59 2e 71" + "af bf 34 87 c0 36 2a 16"), + H("e9 a7 26 a0 44 7b 8d e6 03 83 60 de ea d5 b0 4e")); + + /* From NIST spec 800-38a on AES modes. + * + * F.2 CBC Example Vectors + * F.2.1 CBC-AES128.Encrypt + */ + + /* Intermediate values, blocks input to AES: + * + * 6bc0bce12a459991e134741a7f9e1925 + * d86421fb9f1a1eda505ee1375746972c + * 604ed7ddf32efdff7020d0238b7c2a5d + * 8521f2fd3c8eef2cdc3da7e5c44ea206 + */ + test_cipher_cbc(&nettle_aes128, + HL("2b7e151628aed2a6abf7158809cf4f3c"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("7649abac8119b246cee98e9b12e9197d" + "5086cb9b507219ee95db113a917678b2" + "73bed6b8e3c1743b7116e69e22229516" + "3ff1caa1681fac09120eca307586e1a7"), + H("000102030405060708090a0b0c0d0e0f")); + + /* F.2.3 CBC-AES192.Encrypt */ + + /* Intermediate values, blcoks input to AES: + * + * 6bc0bce12a459991e134741a7f9e1925 + * e12f97e55dbfcfa1efcf7796da0fffb9 + * 8411b1ef0e2109e5001cf96f256346b5 + * a1840065cdb4e1f7d282fbd7db9d35f0 + */ + + test_cipher_cbc(&nettle_aes192, + HL("8e73b0f7da0e6452c810f32b809079e5" + "62f8ead2522c6b7b"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("4f021db243bc633d7178183a9fa071e8" + "b4d9ada9ad7dedf4e5e738763f69145a" + "571b242012fb7ae07fa9baac3df102e0" + "08b0e27988598881d920a9e64f5615cd"), + H("000102030405060708090a0b0c0d0e0f")); + + /* F.2.5 CBC-AES256.Encrypt */ + + /* Intermediate values, blcoks input to AES: + * + * 6bc0bce12a459991e134741a7f9e1925 + * 5ba1c653c8e65d26e929c4571ad47587 + * ac3452d0dd87649c8264b662dc7a7e92 + * cf6d172c769621d8081ba318e24f2371 + */ + + test_cipher_cbc(&nettle_aes256, + HL("603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("f58c4c04d6e5f1ba779eabfb5f7bfbd6" + "9cfc4e967edb808d679f777bc6702c7d" + "39f23369a9d9bacfa530e26304231461" + "b2eb05e2c39be9fcda6c19078c6a9d1b"), + H("000102030405060708090a0b0c0d0e0f")); + + test_cbc_bulk(); + + SUCCESS(); +} + +/* +IV + 000102030405060708090a0b0c0d0e0f +Block #1 +Plaintext 6bc1bee22e409f96e93d7e117393172a +Input Block 6bc0bce12a459991e134741a7f9e1925 +Output Block 7649abac8119b246cee98e9b12e9197d +Ciphertext 7649abac8119b246cee98e9b12e9197d +Block #2 +Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +Input Block d86421fb9f1a1eda505ee1375746972c +Output Block 5086cb9b507219ee95db113a917678b2 +Ciphertext 5086cb9b507219ee95db113a917678b2 +Block #3 +Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +Input Block 604ed7ddf32efdff7020d0238b7c2a5d +Output Block 73bed6b8e3c1743b7116e69e22229516 +Ciphertext 73bed6b8e3c1743b7116e69e22229516 +Block #4 +Plaintext f69f2445df4f9b17ad2b417be66c3710 +Input Block 8521f2fd3c8eef2cdc3da7e5c44ea206 +Output Block 3ff1caa1681fac09120eca307586e1a7 +Ciphertext 3ff1caa1681fac09120eca307586e1a7 + F.2.2 CBC-AES128.Decrypt +Key + 2b7e151628aed2a6abf7158809cf4f3c +IV + 000102030405060708090a0b0c0d0e0f +Block #1 +Ciphertext 7649abac8119b246cee98e9b12e9197d +Input Block 7649abac8119b246cee98e9b12e9197d +Output Block 6bc0bce12a459991e134741a7f9e1925 +Plaintext 6bc1bee22e409f96e93d7e117393172a +Block #2 +Ciphertext 5086cb9b507219ee95db113a917678b2 +Input Block 5086cb9b507219ee95db113a917678b2 +Output Block d86421fb9f1a1eda505ee1375746972c +Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +Block #3 +Ciphertext 73bed6b8e3c1743b7116e69e22229516 +Input Block 73bed6b8e3c1743b7116e69e22229516 +Output Block 604ed7ddf32efdff7020d0238b7c2a5d +Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +Block #4 +Ciphertext 3ff1caa1681fac09120eca307586e1a7 +Input Block 3ff1caa1681fac09120eca307586e1a7 + + +Output Block 8521f2fd3c8eef2cdc3da7e5c44ea206 +Plaintext f69f2445df4f9b17ad2b417be66c3710 + F.2.3 CBC-AES192.Encrypt +Key + 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b +IV + 000102030405060708090a0b0c0d0e0f +Block #1 +Plaintext 6bc1bee22e409f96e93d7e117393172a +Input Block 6bc0bce12a459991e134741a7f9e1925 +Output Block 4f021db243bc633d7178183a9fa071e8 +Ciphertext 4f021db243bc633d7178183a9fa071e8 +Block #2 +Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +Input Block e12f97e55dbfcfa1efcf7796da0fffb9 +Output Block b4d9ada9ad7dedf4e5e738763f69145a +Ciphertext b4d9ada9ad7dedf4e5e738763f69145a +Block #3 +Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +Input Block 8411b1ef0e2109e5001cf96f256346b5 +Output Block 571b242012fb7ae07fa9baac3df102e0 +Ciphertext 571b242012fb7ae07fa9baac3df102e0 +Block #4 +Plaintext f69f2445df4f9b17ad2b417be66c3710 +Input Block a1840065cdb4e1f7d282fbd7db9d35f0 +Output Block 08b0e27988598881d920a9e64f5615cd +Ciphertext 08b0e27988598881d920a9e64f5615cd + F.2.4 CBC-AES192.Decrypt +Key + 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b +IV + 000102030405060708090a0b0c0d0e0f +Block #1 +Ciphertext 4f021db243bc633d7178183a9fa071e8 +Input Block 4f021db243bc633d7178183a9fa071e8 +Output Block 6bc0bce12a459991e134741a7f9e1925 +Plaintext 6bc1bee22e409f96e93d7e117393172a +Block #2 +Ciphertext b4d9ada9ad7dedf4e5e738763f69145a +Input Block b4d9ada9ad7dedf4e5e738763f69145a +Output Block e12f97e55dbfcfa1efcf7796da0fffb9 +Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +Block #3 +Ciphertext 571b242012fb7ae07fa9baac3df102e0 +Input Block 571b242012fb7ae07fa9baac3df102e0 +Output Block 8411b1ef0e2109e5001cf96f256346b5 +Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +Block #4 +Ciphertext 08b0e27988598881d920a9e64f5615cd +Input Block 08b0e27988598881d920a9e64f5615cd +Output Block a1840065cdb4e1f7d282fbd7db9d35f0 +Plaintext f69f2445df4f9b17ad2b417be66c3710 + F.2.5 CBC-AES256.Encrypt +Key + 603deb1015ca71be2b73aef0857d7781 +1f352c073b6108d72d9810a30914dff4 + IV + 000102030405060708090a0b0c0d0e0f +Block #1 +Plaintext 6bc1bee22e409f96e93d7e117393172a +Input Block 6bc0bce12a459991e134741a7f9e1925 +Output Block f58c4c04d6e5f1ba779eabfb5f7bfbd6 +Ciphertext f58c4c04d6e5f1ba779eabfb5f7bfbd6 +Block #2 +Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +Input Block 5ba1c653c8e65d26e929c4571ad47587 +Output Block 9cfc4e967edb808d679f777bc6702c7d +Ciphertext 9cfc4e967edb808d679f777bc6702c7d +Block #3 +Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +Input Block ac3452d0dd87649c8264b662dc7a7e92 +Output Block 39f23369a9d9bacfa530e26304231461 +Ciphertext 39f23369a9d9bacfa530e26304231461 +Block #4 +Plaintext f69f2445df4f9b17ad2b417be66c3710 +Input Block cf6d172c769621d8081ba318e24f2371 +Output Block b2eb05e2c39be9fcda6c19078c6a9d1b +Ciphertext b2eb05e2c39be9fcda6c19078c6a9d1b + F.2.6 CBC-AES256.Decrypt +Key + 603deb1015ca71be2b73aef0857d7781 + 1f352c073b6108d72d9810a30914dff4 +IV + 000102030405060708090a0b0c0d0e0f +Block #1 +Ciphertext f58c4c04d6e5f1ba779eabfb5f7bfbd6 +Input Block f58c4c04d6e5f1ba779eabfb5f7bfbd6 +Output Block 6bc0bce12a459991e134741a7f9e1925 +Plaintext 6bc1bee22e409f96e93d7e117393172a +Block #2 +Ciphertext 9cfc4e967edb808d679f777bc6702c7d +Input Block 9cfc4e967edb808d679f777bc6702c7d +Output Block 5ba1c653c8e65d26e929c4571ad47587 +Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +Block #3 +Ciphertext 39f23369a9d9bacfa530e26304231461 +Input Block 39f23369a9d9bacfa530e26304231461 +Output Block ac3452d0dd87649c8264b662dc7a7e92 +Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +Block #4 +Ciphertext b2eb05e2c39be9fcda6c19078c6a9d1b +Input Block b2eb05e2c39be9fcda6c19078c6a9d1b +Output Block cf6d172c769621d8081ba318e24f2371 +Plaintext f69f2445df4f9b17ad2b417be66c3710 +*/ diff --git a/testsuite/ctr-test.c b/testsuite/ctr-test.c new file mode 100644 index 0000000..15c74d5 --- /dev/null +++ b/testsuite/ctr-test.c @@ -0,0 +1,204 @@ +#include "testutils.h" +#include "aes.h" +#include "ctr.h" + +int +test_main(void) +{ + /* From NIST spec 800-38a on AES modes, + * + * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf + * + * F.5 CTR Example Vectors + */ + + /* F.5.1 CTR-AES128.Encrypt */ + test_cipher_ctr(&nettle_aes128, + HL("2b7e151628aed2a6abf7158809cf4f3c"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("874d6191b620e3261bef6864990db6ce" + "9806f66b7970fdff8617187bb9fffdff" + "5ae4df3edbd5d35e5b4f09020db03eab" + "1e031dda2fbe03d1792170a0f3009cee"), + H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); + + /* F.5.3 CTR-AES192.Encrypt */ + test_cipher_ctr(&nettle_aes192, + HL("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("1abc932417521ca24f2b0459fe7e6e0b" + "090339ec0aa6faefd5ccc2c6f4ce8e94" + "1e36b26bd1ebc670d1bd1d665620abf7" + "4f78a7f6d29809585a97daec58c6b050"), + H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); + + /* F.5.5 CTR-AES256.Encrypt */ + test_cipher_ctr(&nettle_aes256, + HL("603deb1015ca71be2b73aef0857d7781" + "1f352c073b6108d72d9810a30914dff4"), + HL("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + H("601ec313775789a5b7a7f504bbf3d228" + "f443e3ca4d62b59aca84e990cacaf5c5" + "2b0930daa23de94ce87017ba2d84988d" + "dfc9c58db67aada613c2dd08457941a6"), + H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); + + SUCCESS(); +} + +/* + F.5.1 CTR-AES128.Encrypt + Key 2b7e151628aed2a6abf7158809cf4f3c + Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Block #1 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Output Block ec8cdf7398607cb0f2d21675ea9ea1e4 + Plaintext 6bc1bee22e409f96e93d7e117393172a + Ciphertext 874d6191b620e3261bef6864990db6ce + Block #2 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 + Output Block 362b7c3c6773516318a077d7fc5073ae + Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + Ciphertext 9806f66b7970fdff8617187bb9fffdff + Block #3 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 + Output Block 6a2cc3787889374fbeb4c81b17ba6c44 + Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + Ciphertext 5ae4df3edbd5d35e5b4f09020db03eab + Block #4 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 + Output Block e89c399ff0f198c6d40a31db156cabfe + Plaintext f69f2445df4f9b17ad2b417be66c3710 + Ciphertext 1e031dda2fbe03d1792170a0f3009cee + + F.5.2 CTR-AES128.Decrypt + Key 2b7e151628aed2a6abf7158809cf4f3c + Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Block #1 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Output Block ec8cdf7398607cb0f2d21675ea9ea1e4 + Ciphertext 874d6191b620e3261bef6864990db6ce + Plaintext 6bc1bee22e409f96e93d7e117393172a + Block #2 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 + Output Block 362b7c3c6773516318a077d7fc5073ae + Ciphertext 9806f66b7970fdff8617187bb9fffdff + Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + Block #3 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 + Output Block 6a2cc3787889374fbeb4c81b17ba6c44 + Ciphertext 5ae4df3edbd5d35e5b4f09020db03eab + Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + Block #4 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 + Output Block e89c399ff0f198c6d40a31db156cabfe + Ciphertext 1e031dda2fbe03d1792170a0f3009cee + Plaintext f69f2445df4f9b17ad2b417be66c3710 + + F.5.3 CTR-AES192.Encrypt + Key 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b + Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Block #1 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Output Block 717d2dc639128334a6167a488ded7921 + Plaintext 6bc1bee22e409f96e93d7e117393172a + Ciphertext 1abc932417521ca24f2b0459fe7e6e0b + Block #2 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 + Output Block a72eb3bb14a556734b7bad6ab16100c5 + Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + Ciphertext 090339ec0aa6faefd5ccc2c6f4ce8e94 + Block #3 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 + Output Block 2efeae2d72b722613446dc7f4c2af918 + Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + Ciphertext 1e36b26bd1ebc670d1bd1d665620abf7 + Block #4 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 + Output Block b9e783b30dd7924ff7bc9b97beaa8740 + Plaintext f69f2445df4f9b17ad2b417be66c3710 + Ciphertext 4f78a7f6d29809585a97daec58c6b050 + + F.5.4 CTR-AES192.Decrypt + Key 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b + Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Block #1 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Output Block 717d2dc639128334a6167a488ded7921 + Ciphertext 1abc932417521ca24f2b0459fe7e6e0b + Plaintext 6bc1bee22e409f96e93d7e117393172a + Block #2 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 + Output Block a72eb3bb14a556734b7bad6ab16100c5 + Ciphertext 090339ec0aa6faefd5ccc2c6f4ce8e94 + Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + Block #3 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 + Output Block 2efeae2d72b722613446dc7f4c2af918 + Ciphertext 1e36b26bd1ebc670d1bd1d665620abf7 + Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + Block #4 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 + Output Block b9e783b30dd7924ff7bc9b97beaa8740 + Ciphertext 4f78a7f6d29809585a97daec58c6b050 + Plaintext f69f2445df4f9b17ad2b417be66c3710 + + F.5.5 CTR-AES256.Encrypt + Key 603deb1015ca71be2b73aef0857d7781 + 1f352c073b6108d72d9810a30914dff4 + Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Block #1 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Output Block 0bdf7df1591716335e9a8b15c860c502 + Plaintext 6bc1bee22e409f96e93d7e117393172a + Ciphertext 601ec313775789a5b7a7f504bbf3d228 + Block #2 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 + Output Block 5a6e699d536119065433863c8f657b94 + Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + Ciphertext f443e3ca4d62b59aca84e990cacaf5c5 + Block #3 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 + Output Block 1bc12c9c01610d5d0d8bd6a3378eca62 + Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + Ciphertext 2b0930daa23de94ce87017ba2d84988d + Block #4 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 + Output Block 2956e1c8693536b1bee99c73a31576b6 + Plaintext f69f2445df4f9b17ad2b417be66c3710 + Ciphertext dfc9c58db67aada613c2dd08457941a6 + + F.5.6 CTR-AES256.Decrypt + Key 603deb1015ca71be2b73aef0857d7781 + 1f352c073b6108d72d9810a30914dff4 + Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Block #1 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + Output Block 0bdf7df1591716335e9a8b15c860c502 + Ciphertext 601ec313775789a5b7a7f504bbf3d228 + Plaintext 6bc1bee22e409f96e93d7e117393172a + Block #2 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00 + Output Block 5a6e699d536119065433863c8f657b94 + Ciphertext f443e3ca4d62b59aca84e990cacaf5c5 + Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 + Block #3 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01 + Output Block 1bc12c9c01610d5d0d8bd6a3378eca62 + Ciphertext 2b0930daa23de94ce87017ba2d84988d + Plaintext 30c81c46a35ce411e5fbc1191a0a52ef + Block #4 + Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02 + Output Block 2956e1c8693536b1bee99c73a31576b6 + Ciphertext dfc9c58db67aada613c2dd08457941a6 + Plaintext f69f2445df4f9b17ad2b417be66c3710 +*/ diff --git a/testsuite/cxx-test.cxx b/testsuite/cxx-test.cxx new file mode 100644 index 0000000..b5635fb --- /dev/null +++ b/testsuite/cxx-test.cxx @@ -0,0 +1,108 @@ +/* For FILE, used by gmp.h */ +#include + +#include "testutils.h" +#include "md5.h" + +/* Test C++ linkage */ +int +test_main(void) +{ + struct md5_ctx md5; + uint8_t digest[MD5_DIGEST_SIZE]; + + md5_init (&md5); + md5_update (&md5, 14, reinterpret_cast ("message digest")); + md5_digest (&md5, MD5_DIGEST_SIZE, digest); + + if (!MEMEQH (MD5_DIGEST_SIZE, digest, + "F96B697D7CB7938D 525A2F31AAF161D0")) + FAIL(); + +#if WITH_PUBLIC_KEY + + struct rsa_public_key pub; + struct rsa_private_key key; + + mpz_t expected; + + mpz_init(expected); + + rsa_private_key_init(&key); + rsa_public_key_init(&pub); + + mpz_set_str(pub.n, + "69abd505285af665" "36ddc7c8f027e6f0" "ed435d6748b16088" + "4fd60842b3a8d7fb" "bd8a3c98f0cc50ae" "4f6a9f7dd73122cc" + "ec8afa3f77134406" "f53721973115fc2d" "8cfbba23b145f28d" + "84f81d3b6ae8ce1e" "2850580c026e809b" "cfbb52566ea3a3b3" + "df7edf52971872a7" "e35c1451b8636d22" "279a8fb299368238" + "e545fbb4cf", 16); + mpz_set_str(pub.e, "0db2ad57", 16); + + if (!rsa_public_key_prepare(&pub)) + FAIL(); + + mpz_set_str(key.p, + "0a66399919be4b4d" "e5a78c5ea5c85bf9" "aba8c013cb4a8732" + "14557a12bd67711e" "bb4073fd39ad9a86" "f4e80253ad809e5b" + "f2fad3bc37f6f013" "273c9552c9f489", 16); + + mpz_set_str(key.q, + "0a294f069f118625" "f5eae2538db9338c" "776a298eae953329" + "9fd1eed4eba04e82" "b2593bc98ba8db27" "de034da7daaea795" + "2d55b07b5f9a5875" "d1ca5f6dcab897", 16); + + mpz_set_str(key.a, + "011b6c48eb592eee" "e85d1bb35cfb6e07" "344ea0b5e5f03a28" + "5b405396cbc78c5c" "868e961db160ba8d" "4b984250930cf79a" + "1bf8a9f28963de53" "128aa7d690eb87", 16); + + mpz_set_str(key.b, + "0409ecf3d2557c88" "214f1af5e1f17853" "d8b2d63782fa5628" + "60cf579b0833b7ff" "5c0529f2a97c6452" "2fa1a8878a9635ab" + "ce56debf431bdec2" "70b308fa5bf387", 16); + + mpz_set_str(key.c, + "04e103ee925cb5e6" "6653949fa5e1a462" "c9e65e1adcd60058" + "e2df9607cee95fa8" "daec7a389a7d9afc" "8dd21fef9d83805a" + "40d46f49676a2f6b" "2926f70c572c00", 16); + + if (!rsa_private_key_prepare(&key)) + FAIL(); + + if (pub.size != key.size) + FAIL(); + + mpz_set_str(expected, + "53bf517009fa956e" "3daa6adc95e8663d" "3759002f488bbbad" + "e49f62792d85dbcc" "293f68e2b68ef89a" "c5bd42d98f845325" + "3e6c1b76fc337db5" "e0053f255c55faf3" "eb6cc568ad7f5013" + "5b269a64acb9eaa7" "b7f09d9bd90310e6" "4c58f6dbe673ada2" + "67c97a9d99e19f9d" "87960d9ce3f0d5ce" "84f401fe7e10fa24" + "28b9bffcf9", 16); + + mpz_t signature; + mpz_init(signature); + + /* Create signature */ + md5_update (&md5, 39, reinterpret_cast + ("The magic words are squeamish ossifrage")); + ASSERT (rsa_md5_sign (&key, &md5, signature)); + + /* Verify it */ + md5_update (&md5, 39, reinterpret_cast + ("The magic words are squeamish ossifrage")); + if (!rsa_md5_verify (&pub, &md5, signature)) + FAIL(); + + /* Try bad data */ + md5_update (&md5, 39, reinterpret_cast + ("The magik words are squeamish ossifrage")); + if (rsa_md5_verify (&pub, &md5, signature)) + FAIL(); + +#endif /* WITH_PUBLIC_KEY */ + + SUCCESS(); +} diff --git a/testsuite/des-compat-test.c b/testsuite/des-compat-test.c new file mode 100644 index 0000000..c820c4e --- /dev/null +++ b/testsuite/des-compat-test.c @@ -0,0 +1,874 @@ +/* crypto/des/destest.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution 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 copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "des-compat.h" +#include "testutils.h" + +/* tisk tisk - the test keys don't all have odd parity :-( */ +/* test data */ +#define NUM_TESTS 34 +static const_des_cblock key_data[NUM_TESTS] = { + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, + {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, + {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, + {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, + {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, + {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, + {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, + {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, + {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, + {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, + {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, + {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, + {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, + {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, + {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, + {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, + {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, + {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, + {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, + {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, + {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, + {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; + +static unsigned char plain_data[NUM_TESTS][8]={ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, + {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, + {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, + {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, + {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, + {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, + {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, + {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, + {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, + {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, + {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, + {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, + {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, + {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, + {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, + {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, + {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, + {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, + {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; + +static unsigned char cipher_data[NUM_TESTS][8]={ + {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, + {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, + {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, + {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, + {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, + {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, + {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, + {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, + {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, + {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, + {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, + {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, + {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, + {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, + {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, + {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, + {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, + {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, + {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, + {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, + {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, + {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, + {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, + {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, + {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, + {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, + {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, + {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, + {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, + {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, + {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, + {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, + {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, + {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; + +static unsigned char cipher_ecb2[NUM_TESTS-1][8]={ + {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E}, + {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16}, + {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27}, + {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6}, + {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25}, + {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A}, + {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74}, + {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6}, + {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67}, + {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10}, + {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85}, + {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA}, + {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3}, + {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3}, + {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A}, + {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69}, + {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1}, + {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7}, + {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F}, + {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87}, + {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A}, + {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE}, + {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3}, + {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD}, + {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84}, + {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85}, + {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC}, + {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89}, + {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E}, + {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89}, + {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7}, + {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8}, + {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}}; + +static const_des_cblock cbc_key = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static const_des_cblock cbc2_key = {0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; +static const_des_cblock cbc3_key = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +static const_des_cblock cbc_iv = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +static const_des_cblock cbc_data[4] ={ "7654321 ", "Now is t", "he time ", "for " }; + +static unsigned char cbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, + 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, + 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +#if 0 +static unsigned char xcbc_ok[32]={ + 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48, + 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD, + 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76, + 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2, + }; +#endif + +static unsigned char cbc3_ok[32]={ + 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0, + 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC, + 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4, + 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75}; + +#if 0 +static unsigned char pcbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, + 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, + 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; +#endif + +#if 0 +static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; +static unsigned char plain[24]= + { + 0x4e,0x6f,0x77,0x20,0x69,0x73, + 0x20,0x74,0x68,0x65,0x20,0x74, + 0x69,0x6d,0x65,0x20,0x66,0x6f, + 0x72,0x20,0x61,0x6c,0x6c,0x20 + }; +static unsigned char cfb_cipher8[24]= { + 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, + 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 }; +static unsigned char cfb_cipher16[24]={ + 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70, + 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B }; +static unsigned char cfb_cipher32[24]={ + 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD, + 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 }; +static unsigned char cfb_cipher48[24]={ + 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85, + 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F }; +static unsigned char cfb_cipher64[24]={ + 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B, + 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 }; + +static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; +static unsigned char ofb_cipher[24]= + { + 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, + 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, + 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 + }; +#endif + +DES_LONG cbc_cksum_ret=0xB462FEF7L; +unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +#ifndef NOPROTO +static char *pt(const unsigned char *p); +static int cfb_test(int bits, unsigned char *cfb_cipher); +static int cfb64_test(unsigned char *cfb_cipher); +static int ede_cfb64_test(unsigned char *cfb_cipher); +#else +static char *pt(); +static int cfb_test(); +static int cfb64_test(); +static int ede_cfb64_test(); +#endif + +int +test_main(void) + { + int i,j,err=0; + des_cblock in, out, outin, iv3; + des_key_schedule ks,ks2,ks3; + des_cblock cbc_in[5]; + des_cblock cbc_out[5]; + DES_LONG cs; + unsigned char qret[4][4],cret[8]; + DES_LONG lqret[4]; + int num; + char *str; + + printf("Doing ecb\n"); + for (i=0; i>4)&0xf]; + ret[i*2+1]=f[p[i]&0xf]; + } + ret[16]='\0'; + return(ret); + } + +#ifndef LIBDES_LIT +#if 0 +static int cfb_test(bits, cfb_cipher) +int bits; +unsigned char *cfb_cipher; + { + des_key_schedule ks; + int i,err=0; + + des_key_sched((C_Block *)cfb_key,ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks, + (C_Block *)cfb_tmp,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks, + (C_Block *)cfb_tmp,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + return(err); + } + +static int cfb64_test(cfb_cipher) +unsigned char *cfb_cipher; + { + des_key_schedule ks; + int err=0,i,n; + + des_key_sched((C_Block *)cfb_key,ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), + (long)sizeof(plain)-12,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), + (long)sizeof(plain)-17,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf2[i]))); + } + return(err); + } + +static int ede_cfb64_test(cfb_cipher) +unsigned char *cfb_cipher; + { + des_key_schedule ks; + int err=0,i,n; + + des_key_sched((C_Block *)cfb_key,ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), + (long)sizeof(plain)-12,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("ede_cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), + (long)sizeof(plain)-17,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("ede_cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf2[i]))); + } + return(err); + } +#endif +#endif /* LIBDES_LIT */ + diff --git a/testsuite/des-test.c b/testsuite/des-test.c new file mode 100644 index 0000000..244e5aa --- /dev/null +++ b/testsuite/des-test.c @@ -0,0 +1,122 @@ +#include "testutils.h" +#include "nettle-internal.h" +#include "des.h" + +static void +test_des(const uint8_t *key, int expected_parity, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext) +{ + struct des_ctx ctx; + uint8_t *data = xalloc(length); + + if (des_check_parity(8, key) != expected_parity) + FAIL(); + + if (!des_set_key(&ctx, key)) + FAIL(); + + des_encrypt(&ctx, length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + { + fprintf(stderr, "Encrypt failed:\nInput:"); + print_hex(length, cleartext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, ciphertext); + fprintf(stderr, "\n"); + FAIL(); + } + + des_decrypt(&ctx, length, data, data); + + if (!MEMEQ(length, data, cleartext)) + { + fprintf(stderr, "Decrypt failed:\nInput:"); + print_hex(length, ciphertext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, cleartext); + fprintf(stderr, "\n"); + FAIL(); + } + + free(data); +} + +static void +test_weak(const uint8_t *key) +{ + struct des_ctx ctx; + + if (des_set_key(&ctx, key)) + FAIL(); +} + +int +test_main(void) +{ + /* From Applied Cryptography */ + test_des(H("01234567 89ABCDEF"), 1, + HL("01234567 89ABCDE7"), + H("C9574425 6A5ED31D")); + + test_des(H("01 01 01 01 01 01 01 80"), 1, + HL("00 00 00 00 00 00 00 00"), + H("9C C6 2D F4 3B 6E ED 74")); + + test_des(H("80 01 01 01 01 01 01 01"), 1, + HL("00 00 00 00 00 00 00 40"), + H("A3 80 E0 2A 6B E5 46 96")); + + test_des(H("08 19 2A 3B 4C 5D 6E 7F"), 1, + HL("00 00 00 00 00 00 00 00"), + H("25 DD AC 3E 96 17 64 67")); + + test_des(H("01 23 45 67 89 AB CD EF"), 1, + DES_BLOCK_SIZE, "Now is t", + H("3F A4 0E 8A 98 4D 48 15")); + + /* Same key, but with one bad parity bit, */ + test_des(H("01 23 45 66 89 AB CD EF"), 0, + DES_BLOCK_SIZE, "Now is t", + H("3F A4 0E 8A 98 4D 48 15")); + + /* Parity check */ + if (des_check_parity(HL("01 01 01 01 01 01 01 00"))) + FAIL(); + + /* The four weak keys */ + test_weak(H("01 01 01 01 01 01 01 01")); + test_weak(H("FE FE FE FE FE FE FE FE")); + test_weak(H("1F 1F 1F 1F 0E 0E 0E 0E")); + test_weak(H("E0 E0 E0 E0 F1 F1 F1 F1")); + + /* Same weak key, but different parity. */ + test_weak(H("E0 E0 E0 E0 F0 F1 F1 F1")); + + /* The six pairs of semiweak keys */ + test_weak(H("01 FE 01 FE 01 FE 01 FE")); + test_weak(H("FE 01 FE 01 FE 01 FE 01")); + + test_weak(H("1F E0 1F E0 0E F1 0E F1")); + test_weak(H("E0 1F E0 1F F1 0E F1 0E")); + + test_weak(H("01 E0 01 E0 01 F1 01 F1")); + test_weak(H("E0 01 E0 01 F1 01 F1 01")); + + test_weak(H("1F FE 1F FE 0E FE 0E FE")); + test_weak(H("FE 1F FE 1F FE 0E FE 0E")); + + test_weak(H("01 1F 01 1F 01 0E 01 0E")); + test_weak(H("1F 01 1F 01 0E 01 0E 01")); + + test_weak(H("E0 FE E0 FE F1 FE F1 FE")); + test_weak(H("FE E0 FE E0 FE F1 FE F1")); + + SUCCESS(); +} diff --git a/testsuite/des3-test.c b/testsuite/des3-test.c new file mode 100644 index 0000000..678a235 --- /dev/null +++ b/testsuite/des3-test.c @@ -0,0 +1,21 @@ +#include "testutils.h" +#include "nettle-internal.h" +#include "des.h" + +int +test_main(void) +{ + /* Intermediate values: + * After first DES encryption: "cd ea 2a 20 c2 e0 9e 48" + * After second DES decryption: "69 52 6e 95 8b ea 49 bd" + */ + + test_cipher(&nettle_des3, + HL("3e 0b 10 b0 5d 49 c2 54" + "6b 46 e0 75 8a 91 61 85" + "cb 04 07 d3 20 16 cb a2"), + DES_BLOCK_SIZE, "Now is t", + H("0a 5d b5 2d 85 74 d1 c9")); + + SUCCESS(); +} diff --git a/testsuite/dsa-keygen-test.c b/testsuite/dsa-keygen-test.c new file mode 100644 index 0000000..12dc309 --- /dev/null +++ b/testsuite/dsa-keygen-test.c @@ -0,0 +1,46 @@ +#include "testutils.h" + +#include "knuth-lfib.h" + +static void +progress(void *ctx UNUSED, int c) +{ + fputc(c, stderr); +} + +int +test_main(void) +{ + struct dsa_public_key pub; + struct dsa_private_key key; + + struct knuth_lfib_ctx lfib; + + dsa_private_key_init(&key); + dsa_public_key_init(&pub); + + knuth_lfib_init(&lfib, 13); + + if (!dsa_generate_keypair(&pub, &key, + &lfib, (nettle_random_func *) knuth_lfib_random, + NULL, verbose ? progress : NULL, + 1024, 160)) + FAIL(); + + test_dsa_key(&pub, &key, 160); + test_dsa160(&pub, &key, NULL); + + if (!dsa_generate_keypair(&pub, &key, + &lfib, (nettle_random_func *) knuth_lfib_random, + NULL, verbose ? progress : NULL, + 2048, 256)) + FAIL(); + + test_dsa_key(&pub, &key, 256); + test_dsa256(&pub, &key, NULL); + + dsa_public_key_clear(&pub); + dsa_private_key_clear(&key); + + SUCCESS(); +} diff --git a/testsuite/dsa-test.c b/testsuite/dsa-test.c new file mode 100644 index 0000000..3698d1b --- /dev/null +++ b/testsuite/dsa-test.c @@ -0,0 +1,105 @@ +#include "testutils.h" + +int +test_main(void) +{ + struct dsa_public_key pub; + struct dsa_private_key key; + struct dsa_signature expected; + + dsa_public_key_init(&pub); + dsa_private_key_init(&key); + dsa_signature_init(&expected); + + mpz_set_str(pub.p, + "83d9a7c2ce2a9179f43cdb3bffe7de0f0eef26dd5dfae44d" + "531bc0de45634d2c07cb929b0dbe10da580070e6abfbb841" + "5c44bff570b8ad779df653aad97dc7bdeb815d7e88103e61" + "606ed3d8a295fbfd340d2d49e220833ebace5511e22c4f02" + "97ed351e9948fa848e9c8fadb7b47bcc47def4255b5e1d5e" + "10215b3b55a0b85f", 16); + mpz_set_str(pub.q, + "8266e0deaf46020ba48d410ca580f3a978629b5d", 16); + mpz_set_str(pub.g, + "30d34bb9f376bec947154afe4076bc7d359c9d32f5471ddb" + "be8d6a941c47fa9dc4f32573151dbb4aa59eb989b74ac36b" + "b6310a5e8b580501655d91f393daa193ae1303049b87febb" + "093dc0404b53b4c5da2463300f9c5b156d788c4ace8ecbb9" + "dd00c18d99537f255ac025d074d894a607cbe3023a1276ef" + "556916a33f7de543", 16); + mpz_set_str(pub.y, + "64402048b27f39f404a546a84909c9c0e9e2dd153a849946" + "1062892598d30af27ae3cefc2b700fb6d077390a83bdcad7" + "8a1299487c9623bb62af0c85a3df9ef1ee2c0d66658e1fd3" + "283b5407f6cd30ee7e6154fad41a6a8b0f5c86c5accc1127" + "bf7c9a5d6badcb012180cb62a55c5e17d6d3528cdbe002cc" + "ee131c1b86867f7a", 16); + mpz_set_str(key.x, + "56c6efaf878d06eef21dc070fab71da6ec1e30a6", 16); + + test_dsa_key(&pub, &key, 160); + + mpz_set_str(expected.r, "373999e9ee0a84a9983e528ee266938091e4c55c", 16); + mpz_set_str(expected.s, "8017d54592bde7353f6558b3090d12ed8367e2ba", 16); + + test_dsa160(&pub, &key, &expected); + + mpz_set_str(pub.p, + "fda45d8f1df8f2b84fb3cf9ae69f93b087d98bea282f643e" + "23472c5b57605952010e4c846d711f2783e8ad4e1447698e" + "2e328fdb1d411ccb0f3caef5b8fc0b9dcecfadf022ecc7de" + "5c153c8f10fe88d63abf7d296ad485dfd6eead595fc1c36b" + "8bd42e8668b55b2bb0f1a6aecbe678df504880de2481a5e4" + "97d1b7d92ee48ffeb083a1833094a0418ec0d914409c720c" + "87ea63c164ec448c471b574a8f88073ebeb44dc6d6b98260" + "46126f03022ff04dcb6a2381a09b0a227d3c57cfbfd48e4a" + "19cbb0a35242c9e234ebe105ae26cab01ede40aa2869fad8" + "6bff57a19ec87b8de294ca03269c268c10813f18169beac5" + "ac97c0e748ccb244282c50c670e1bccb", 16); + mpz_set_str(pub.q, + "bd612630da4d930779a32546dc413efd299111b443c7355d" + "65d991163cc3cd9d", 16); + mpz_set_str(pub.g, + "050c56e14adb03e47d3902852f5b21c96c28a2aa89619c8b" + "78a98aa5083700994f99184588d2cefaf2a3ea213dd2d084" + "0e682a52357d5fefaef44520622f021855744d638e792f21" + "89543f9770aa1960da4d7b325a37a2922b035c8da3d71543" + "5d7a6ddefc62e84fe76fecbbf9667c6a1781a84aa434548b" + "bdc315f2fb0a420d65c1f72911845b148e994660138052a1" + "fce1c6f933be155b2af8c0177277cd3b75d9477ddbcb77bc" + "f5cccea915a2f3750ba41f337edd44f768cb3d24b17e299d" + "5cebe5e78cbaf5ad41e815edfc71df3131bd5359c653a224" + "bd3ac6a27bad7efff11b24fad0109ee26e4df76fc99e150d" + "666a9294bab8a03f113d228bfad349f4", 16); + mpz_set_str(pub.y, + "da7f9abb0b554afaa926c9cffa897239bfdbc58ed9981748" + "edb1e38f42dea0560a407a48b509a5cb460bf31dee9057a0" + "b41d468698fa82ff03c47e8f3f6564c74d6f1daa5f84ad25" + "b937317f861fa68c19e20d6b855e85cd94d5af95b968416e" + "6d43711f24d5497f018b7627d2bed25dc793ddb897fdcc34" + "5d183e43a80205483dea7a12185be3b185a7d84d3385b962" + "4485882722d177ccd8f49c5b519fb96b9b59fcfc63422f25" + "88fb8ff00bce46acb7c80d105c31414ecf5be0a0dad975bd" + "dcd83d6f063f9bce562fdd5b68e18fc2159dbb2457adc7a7" + "ee5bc0796eff370908f866a41b9a8873f89e1904925141f8" + "e574df25bd869f43a184a804e8ce5fcc", 16); + mpz_set_str(key.x, + "39f84f88569da55c6bee7e18175b539ea9b7ee24fabd85a7" + "1fa8c93b7181545b", 16); + + test_dsa_key(&pub, &key, 256); + + mpz_set_str(expected.r, + "af30ed0383ea9eaca2fe6244adb86b5ffa80b62cd1687571" + "eb75c2a4fff413fb", 16); + mpz_set_str(expected.s, + "2761c5340430a9b003cd8ba72b1c2cd68644bfa23ae4c40f" + "9250dee3ef0e7c35", 16); + + test_dsa256(&pub, &key, NULL); + + dsa_public_key_clear(&pub); + dsa_private_key_clear(&key); + dsa_signature_clear(&expected); + SUCCESS(); +} diff --git a/testsuite/gold-bug.txt b/testsuite/gold-bug.txt new file mode 100644 index 0000000..be3a2a0 --- /dev/null +++ b/testsuite/gold-bug.txt @@ -0,0 +1,1598 @@ +Edgar Allan Poe + +The Gold-Bug + + +What ho! what ho! this fellow is dancing mad! +He hath been bitten by the Tarantula. + --All in the Wrong. + + +Many years ago, I contracted an intimacy with a Mr. William +Legrand. He was of an ancient Huguenot family, and had once been +wealthy: but a series of misfortunes had reduced him to want. To +avoid the mortification consequent upon his disasters, he left New +Orleans, the city of his forefathers, and took up his residence at +Sullivan's Island, near Charleston, South Carolina. + +This island is a very singular one. It consists of little else +than the sea sand, and is about three miles long. Its breadth at +no point exceeds a quarter of a mile. It is separated from the +mainland by a scarcely perceptible creek, oozing its way through a +wilderness of reeds and slime, a favorite resort of the marsh hen. +The vegetation, as might be supposed, is scant, or at least +dwarfish. No trees of any magnitude are to be seen. Near the +western extremity, where Fort Moultrie stands, and where are some +miserable frame buildings, tenanted, during summer, by the +fugitives from Charleston dust and fever, may be found, indeed, the +bristly palmetto; but the whole island, with the exception of this +western point, and a line of hard, white beach on the seacoast, is +covered with a dense undergrowth of the sweet myrtle so much prized +by the horticulturists of England. The shrub here often attains +the height of fifteen or twenty feet, and forms an almost +impenetrable coppice, burdening the air with its fragrance. + +In the inmost recesses of this coppice, not far from the eastern or +more remote end of the island, Legrand had built himself a small +hut, which he occupied when I first, by mere accident, made his +acquaintance. This soon ripened into friendship--for there was +much in the recluse to excite interest and esteem. I found him +well educated, with unusual powers of mind, but infected with +misanthropy, and subject to perverse moods of alternate enthusiasm +and melancholy. He had with him many books, but rarely employed +them. His chief amusements were gunning and fishing, or sauntering +along the beach and through the myrtles, in quest of shells or +entomological specimens--his collection of the latter might have +been envied by a Swammerdamm. In these excursions he was usually +accompanied by an old negro, called Jupiter, who had been +manumitted before the reverses of the family, but who could be +induced, neither by threats nor by promises, to abandon what he +considered his right of attendance upon the footsteps of his young +"Massa Will." It is not improbable that the relatives of Legrand, +conceiving him to be somewhat unsettled in intellect, had contrived +to instill this obstinacy into Jupiter, with a view to the +supervision and guardianship of the wanderer. + +The winters in the latitude of Sullivan's Island are seldom very +severe, and in the fall of the year it is a rare event indeed when +a fire is considered necessary. About the middle of October, 18--, +there occurred, however, a day of remarkable chilliness. Just +before sunset I scrambled my way through the evergreens to the hut +of my friend, whom I had not visited for several weeks--my +residence being, at that time, in Charleston, a distance of nine +miles from the island, while the facilities of passage and +repassage were very far behind those of the present day. Upon +reaching the hut I rapped, as was my custom, and getting no reply, +sought for the key where I knew it was secreted, unlocked the door, +and went in. A fine fire was blazing upon the hearth. It was a +novelty, and by no means an ungrateful one. I threw off an +overcoat, took an armchair by the crackling logs, and awaited +patiently the arrival of my hosts. + +Soon after dark they arrived, and gave me a most cordial welcome. +Jupiter, grinning from ear to ear, bustled about to prepare some +marsh hens for supper. Legrand was in one of his fits--how else +shall I term them?--of enthusiasm. He had found an unknown +bivalve, forming a new genus, and, more than this, he had hunted +down and secured, with Jupiter's assistance, a scarabaeus which he +believed to be totally new, but in respect to which he wished to +have my opinion on the morrow. + +"And why not to-night?" I asked, rubbing my hands over the blaze, +and wishing the whole tribe of scarabaei at the devil. + +"Ah, if I had only known you were here!" said Legrand, "but it's so +long since I saw you; and how could I foresee that you would pay me +a visit this very night of all others? As I was coming home I met +Lieutenant G----, from the fort, and, very foolishly, I lent him +the bug; so it will be impossible for you to see it until the +morning. Stay here to-night, and I will send Jup down for it at +sunrise. It is the loveliest thing in creation!" + +"What?--sunrise?" + +"Nonsense! no!--the bug. It is of a brilliant gold color--about +the size of a large hickory nut--with two jet black spots near one +extremity of the back, and another, somewhat longer, at the other. +The antennae are--" + +"Dey ain't NO tin in him, Massa Will, I keep a tellin' on you," +here interrupted Jupiter; "de bug is a goole-bug, solid, ebery bit +of him, inside and all, sep him wing--neber feel half so hebby a +bug in my life." + +"Well, suppose it is, Jup," replied Legrand, somewhat more +earnestly, it seemed to me, than the case demanded; "is that any +reason for your letting the birds burn? The color"--here he turned +to me--"is really almost enough to warrant Jupiter's idea. You +never saw a more brilliant metallic luster than the scales emit-- +but of this you cannot judge till to-morrow. In the meantime I can +give you some idea of the shape." Saying this, he seated himself +at a small table, on which were a pen and ink, but no paper. He +looked for some in a drawer, but found none. + +"Never mind," he said at length, "this will answer;" and he drew +from his waistcoat pocket a scrap of what I took to be very dirty +foolscap, and made upon it a rough drawing with the pen. While he +did this, I retained my seat by the fire, for I was still chilly. +When the design was complete, he handed it to me without rising. +As I received it, a loud growl was heard, succeeded by a scratching +at the door. Jupiter opened it, and a large Newfoundland, +belonging to Legrand, rushed in, leaped upon my shoulders, and +loaded me with caresses; for I had shown him much attention during +previous visits. When his gambols were over, I looked at the +paper, and, to speak the truth, found myself not a little puzzled +at what my friend had depicted. + +"Well!" I said, after contemplating it for some minutes, "this IS a +strange scarabaeus, I must confess; new to me; never saw anything +like it before--unless it was a skull, or a death's head, which it +more nearly resembles than anything else that has come under MY +observation." + +"A death's head!" echoed Legrand. "Oh--yes--well, it has something +of that appearance upon paper, no doubt. The two upper black spots +look like eyes, eh? and the longer one at the bottom like a mouth-- +and then the shape of the whole is oval." + +"Perhaps so," said I; "but, Legrand, I fear you are no artist. I +must wait until I see the beetle itself, if I am to form any idea +of its personal appearance." + +"Well, I don't know," said he, a little nettled, "I draw tolerably-- +SHOULD do it at least--have had good masters, and flatter myself +that I am not quite a blockhead." + +"But, my dear fellow, you are joking then," said I, "this is a very +passable SKULL--indeed, I may say that it is a very EXCELLENT +skull, according to the vulgar notions about such specimens of +physiology--and your scarabaeus must be the queerest scarabaeus in +the world if it resembles it. Why, we may get up a very thrilling +bit of superstition upon this hint. I presume you will call the +bug Scarabaeus caput hominis, or something of that kind--there are +many similar titles in the Natural Histories. But where are the +antennae you spoke of?" + +"The antennae!" said Legrand, who seemed to be getting +unaccountably warm upon the subject; "I am sure you must see the +antennae. I made them as distinct as they are in the original +insect, and I presume that is sufficient." + +"Well, well," I said, "perhaps you have--still I don't see them;" +and I handed him the paper without additional remark, not wishing +to ruffle his temper; but I was much surprised at the turn affairs +had taken; his ill humor puzzled me--and, as for the drawing of the +beetle, there were positively NO antennae visible, and the whole +DID bear a very close resemblance to the ordinary cuts of a death's +head. + +He received the paper very peevishly, and was about to crumple it, +apparently to throw it in the fire, when a casual glance at the +design seemed suddenly to rivet his attention. In an instant his +face grew violently red--in another excessively pale. For some +minutes he continued to scrutinize the drawing minutely where he +sat. At length he arose, took a candle from the table, and +proceeded to seat himself upon a sea chest in the farthest corner +of the room. Here again he made an anxious examination of the +paper, turning it in all directions. He said nothing, however, and +his conduct greatly astonished me; yet I thought it prudent not to +exacerbate the growing moodiness of his temper by any comment. +Presently he took from his coat pocket a wallet, placed the paper +carefully in it, and deposited both in a writing desk, which he +locked. He now grew more composed in his demeanor; but his +original air of enthusiasm had quite disappeared. Yet he seemed +not so much sulky as abstracted. As the evening wore away he +became more and more absorbed in reverie, from which no sallies of +mine could arouse him. It had been my intention to pass the night +at the hut, as I had frequently done before, but, seeing my host in +this mood, I deemed it proper to take leave. He did not press me +to remain, but, as I departed, he shook my hand with even more than +his usual cordiality. + +It was about a month after this (and during the interval I had seen +nothing of Legrand) when I received a visit, at Charleston, from +his man, Jupiter. I had never seen the good old negro look so +dispirited, and I feared that some serious disaster had befallen my +friend. + +"Well, Jup," said I, "what is the matter now?--how is your master?" + +"Why, to speak the troof, massa, him not so berry well as mought +be." + +"Not well! I am truly sorry to hear it. What does he complain +of?" + +"Dar! dot's it!--him neber 'plain of notin'--but him berry sick for +all dat." + +"VERY sick, Jupiter!--why didn't you say so at once? Is he +confined to bed?" + +"No, dat he aint!--he aint 'fin'd nowhar--dat's just whar de shoe +pinch--my mind is got to be berry hebby 'bout poor Massa Will." + +"Jupiter, I should like to understand what it is you are talking +about. You say your master is sick. Hasn't he told you what ails +him?" + +"Why, massa, 'taint worf while for to git mad about de matter-- +Massa Will say noffin at all aint de matter wid him--but den what +make him go about looking dis here way, wid he head down and he +soldiers up, and as white as a goose? And den he keep a syphon all +de time--" + +"Keeps a what, Jupiter?" + +"Keeps a syphon wid de figgurs on de slate--de queerest figgurs I +ebber did see. Ise gittin' to be skeered, I tell you. Hab for to +keep mighty tight eye 'pon him 'noovers. Todder day he gib me slip +'fore de sun up and was gone de whole ob de blessed day. I had a +big stick ready cut for to gib him deuced good beating when he did +come--but Ise sich a fool dat I hadn't de heart arter all--he +looked so berry poorly." + +"Eh?--what?--ah yes!--upon the whole I think you had better not be +too severe with the poor fellow--don't flog him, Jupiter--he can't +very well stand it--but can you form no idea of what has occasioned +this illness, or rather this change of conduct? Has anything +unpleasant happened since I saw you?" + +"No, massa, dey aint bin noffin onpleasant SINCE den--'twas 'FORE +den I'm feared--'twas de berry day you was dare." + +"How? what do you mean." + +"Why, massa, I mean de bug--dare now." + +"The what?" + +"De bug--I'm berry sartin dat Massa Will bin bit somewhere 'bout de +head by dat goole-bug." + +"And what cause have you, Jupiter, for such a supposition?" + +"Claws enuff, massa, and mouff, too. I nebber did see sich a +deuced bug--he kick and he bite eberyting what cum near him. Massa +Will cotch him fuss, but had for to let him go 'gin mighty quick, I +tell you--den was de time he must ha' got de bite. I didn't like +de look ob de bug mouff, myself, nohow, so I wouldn't take hold oh +him wid my finger, but I cotch him wid a piece oh paper dat I +found. I rap him up in de paper and stuff a piece of it in he +mouff--dat was de way." + +"And you think, then, that your master was really bitten by the +beetle, and that the bite made him sick?" + +"I don't think noffin about it--I nose it. What make him dream +'bout de goole so much, if 'taint cause he bit by the goole-bug? +Ise heered 'bout dem goole-bugs 'fore dis." + +"But how do you know he dreams about gold?" + +"How I know? why, 'cause he talk about it in he sleep--dat's how I +nose." + +"Well, Jup, perhaps you are right; but to what fortunate +circumstance am I to attribute the honor of a visit from you to- +day?" + +"What de matter, massa?" + +"Did you bring any message from Mr. Legrand?" + +"No, massa, I bring dis here pissel;" and here Jupiter handed me a +note which ran thus: + + +"MY DEAR ---- + +"Why have I not seen you for so long a time? I hope you have not +been so foolish as to take offense at any little brusquerie of +mine; but no, that is improbable. + +"Since I saw you I have had great cause for anxiety. I have +something to tell you, yet scarcely know how to tell it, or whether +I should tell it at all. + +"I have not been quite well for some days past, and poor old Jup +annoys me, almost beyond endurance, by his well-meant attentions. +Would you believe it?--he had prepared a huge stick, the other day, +with which to chastise me for giving him the slip, and spending the +day, solus, among the hills on the mainland. I verily believe that +my ill looks alone saved me a flogging. + +"I have made no addition to my cabinet since we met. "If you can, +in any way, make it convenient, come over with Jupiter. DO come. +I wish to see you TO-NIGHT, upon business of importance. I assure +you that it is of the HIGHEST importance. + +"Ever yours, + +"WILLIAM LEGRAND." + + +There was something in the tone of this note which gave me great +uneasiness. Its whole style differed materially from that of +Legrand. What could he be dreaming of? What new crotchet +possessed his excitable brain? What "business of the highest +importance" could HE possibly have to transact? Jupiter's account +of him boded no good. I dreaded lest the continued pressure of +misfortune had, at length, fairly unsettled the reason of my +friend. Without a moment's hesitation, therefore, I prepared to +accompany the negro. + +Upon reaching the wharf, I noticed a scythe and three spades, all +apparently new, lying in the bottom of the boat in which we were to +embark. + +"What is the meaning of all this, Jup?" I inquired. + +"Him syfe, massa, and spade." + +"Very true; but what are they doing here?" + +"Him de syfe and de spade what Massa Will sis 'pon my buying for +him in de town, and de debbil's own lot of money I had to gib for +em." + +"But what, in the name of all that is mysterious, is your 'Massa +Will' going to do with scythes and spades?" + +"Dat's more dan I know, and debbil take me if I don't b'lieve 'tis +more dan he know too. But it's all cum ob de bug." + +Finding that no satisfaction was to be obtained of Jupiter, whose +whole intellect seemed to be absorbed by "de bug," I now stepped +into the boat, and made sail. With a fair and strong breeze we +soon ran into the little cove to the northward of Fort Moultrie, +and a walk of some two miles brought us to the hut. It was about +three in the afternoon when we arrived. Legrand had been awaiting +us in eager expectation. He grasped my hand with a nervous +empressement which alarmed me and strengthened the suspicions +already entertained. His countenance was pale even to ghastliness, +and his deep-set eyes glared with unnatural luster. After some +inquiries respecting his health, I asked him, not knowing what +better to say, if he had yet obtained the scarabaeus from +Lieutenant G----. + +"Oh, yes," he replied, coloring violently, "I got it from him the +next morning. Nothing should tempt me to part with that +scarabaeus. Do you know that Jupiter is quite right about it?" + +"In what way?" I asked, with a sad foreboding at heart. + +"In supposing it to be a bug of REAL GOLD." He said this with an +air of profound seriousness, and I felt inexpressibly shocked. + +"This bug is to make my fortune," he continued, with a triumphant +smile; "to reinstate me in my family possessions. Is it any +wonder, then, that I prize it? Since Fortune has thought fit to +bestow it upon me, I have only to use it properly, and I shall +arrive at the gold of which it is the index. Jupiter, bring me +that scarabaeus!" + +"What! de bug, massa? I'd rudder not go fer trubble dat bug; you +mus' git him for your own self." Hereupon Legrand arose, with a +grave and stately air, and brought me the beetle from a glass case +in which it was enclosed. It was a beautiful scarabaeus, and, at +that time, unknown to naturalists--of course a great prize in a +scientific point of view. There were two round black spots near +one extremity of the back, and a long one near the other. The +scales were exceedingly hard and glossy, with all the appearance of +burnished gold. The weight of the insect was very remarkable, and, +taking all things into consideration, I could hardly blame Jupiter +for his opinion respecting it; but what to make of Legrand's +concordance with that opinion, I could not, for the life of me, +tell. + +"I sent for you," said he, in a grandiloquent tone, when I had +completed my examination of the beetle, "I sent for you that I +might have your counsel and assistance in furthering the views of +Fate and of the bug--" + +"My dear Legrand," I cried, interrupting him, "you are certainly +unwell, and had better use some little precautions. You shall go +to bed, and I will remain with you a few days, until you get over +this. You are feverish and--" + +"Feel my pulse," said he. + +I felt it, and, to say the truth, found not the slightest +indication of fever. + +"But you may be ill and yet have no fever. Allow me this once to +prescribe for you. In the first place go to bed. In the next--" + +"You are mistaken," he interposed, "I am as well as I can expect to +be under the excitement which I suffer. If you really wish me +well, you will relieve this excitement." + +"And how is this to be done?" + +"Very easily. Jupiter and myself are going upon an expedition into +the hills, upon the mainland, and, in this expedition, we shall +need the aid of some person in whom we can confide. You are the +only one we can trust. Whether we succeed or fail, the excitement +which you now perceive in me will be equally allayed." + +"I am anxious to oblige you in any way," I replied; "but do you +mean to say that this infernal beetle has any connection with your +expedition into the hills?" + +"It has." + +"Then, Legrand, I can become a party to no such absurd proceeding." + +"I am sorry--very sorry--for we shall have to try it by ourselves." + +"Try it by yourselves! The man is surely mad!--but stay!--how long +do you propose to be absent?" + +"Probably all night. We shall start immediately, and be back, at +all events, by sunrise." + +"And will you promise me, upon your honor, that when this freak of +yours is over, and the bug business (good God!) settled to your +satisfaction, you will then return home and follow my advice +implicitly, as that of your physician?" + +"Yes; I promise; and now let us be off, for we have no time to +lose." + +With a heavy heart I accompanied my friend. We started about four +o'clock--Legrand, Jupiter, the dog, and myself. Jupiter had with +him the scythe and spades--the whole of which he insisted upon +carrying--more through fear, it seemed to me, of trusting either of +the implements within reach of his master, than from any excess of +industry or complaisance. His demeanor was dogged in the extreme, +and "dat deuced bug" were the sole words which escaped his lips +during the journey. For my own part, I had charge of a couple of +dark lanterns, while Legrand contented himself with the scarabaeus, +which he carried attached to the end of a bit of whipcord; twirling +it to and fro, with the air of a conjurer, as he went. When I +observed this last, plain evidence of my friend's aberration of +mind, I could scarcely refrain from tears. I thought it best, +however, to humor his fancy, at least for the present, or until I +could adopt some more energetic measures with a chance of success. +In the meantime I endeavored, but all in vain, to sound him in +regard to the object of the expedition. Having succeeded in +inducing me to accompany him, he seemed unwilling to hold +conversation upon any topic of minor importance, and to all my +questions vouchsafed no other reply than "we shall see!" + +We crossed the creek at the head of the island by means of a skiff, +and, ascending the high grounds on the shore of the mainland, +proceeded in a northwesterly direction, through a tract of country +excessively wild and desolate, where no trace of a human footstep +was to be seen. Legrand led the way with decision; pausing only +for an instant, here and there, to consult what appeared to be +certain landmarks of his own contrivance upon a former occasion. + +In this manner we journeyed for about two hours, and the sun was +just setting when we entered a region infinitely more dreary than +any yet seen. It was a species of table-land, near the summit of +an almost inaccessible hill, densely wooded from base to pinnacle, +and interspersed with huge crags that appeared to lie loosely upon +the soil, and in many cases were prevented from precipitating +themselves into the valleys below, merely by the support of the +trees against which they reclined. Deep ravines, in various +directions, gave an air of still sterner solemnity to the scene. + +The natural platform to which we had clambered was thickly +overgrown with brambles, through which we soon discovered that it +would have been impossible to force our way but for the scythe; and +Jupiter, by direction of his master, proceeded to clear for us a +path to the foot of an enormously tall tulip tree, which stood, +with some eight or ten oaks, upon the level, and far surpassed them +all, and all other trees which I had then ever seen, in the beauty +of its foliage and form, in the wide spread of its branches, and in +the general majesty of its appearance. When we reached this tree, +Legrand turned to Jupiter, and asked him if he thought he could +climb it. The old man seemed a little staggered by the question, +and for some moments made no reply. At length he approached the +huge trunk, walked slowly around it, and examined it with minute +attention. When he had completed his scrutiny, he merely said: + +"Yes, massa, Jup climb any tree he ebber see in he life." + +"Then up with you as soon as possible, for it will soon be too dark +to see what we are about." + +"How far mus' go up, massa?" inquired Jupiter. + +"Get up the main trunk first, and then I will tell you which way to +go--and here--stop! take this beetle with you." + +"De bug, Massa Will!--de goole-bug!" cried the negro, drawing back +in dismay--"what for mus' tote de bug way up de tree?--d--n if I +do!" + +"If you are afraid, Jup, a great big negro like you, to take hold +of a harmless little dead beetle, why you can carry it up by this +string--but, if you do not take it up with you in some way, I shall +be under the necessity of breaking your head with this shovel." + +"What de matter now, massa?" said Jup, evidently shamed into +compliance; "always want for to raise fuss wid old nigger. Was +only funnin anyhow. ME feered de bug! what I keer for de bug?" +Here he took cautiously hold of the extreme end of the string, and, +maintaining the insect as far from his person as circumstances +would permit, prepared to ascend the tree. + +In youth, the tulip tree, or Liriodendron tulipiferum, the most +magnificent of American foresters, has a trunk peculiarly smooth, +and often rises to a great height without lateral branches; but, in +its riper age, the bark becomes gnarled and uneven, while many +short limbs make their appearance on the stem. Thus the difficulty +of ascension, in the present case, lay more in semblance than in +reality. Embracing the huge cylinder, as closely as possible, with +his arms and knees, seizing with his hands some projections, and +resting his naked toes upon others, Jupiter, after one or two +narrow escapes from falling, at length wriggled himself into the +first great fork, and seemed to consider the whole business as +virtually accomplished. The RISK of the achievement was, in fact, +now over, although the climber was some sixty or seventy feet from +the ground. + +"Which way mus' go now, Massa Will?" he asked. + +"Keep up the largest branch--the one on this side," said Legrand. +The negro obeyed him promptly, and apparently with but little +trouble; ascending higher and higher, until no glimpse of his squat +figure could be obtained through the dense foliage which enveloped +it. Presently his voice was heard in a sort of halloo. + +"How much fudder is got to go?" + +"How high up are you?" asked Legrand. + +"Ebber so fur," replied the negro; "can see de sky fru de top oh de +tree." + +"Never mind the sky, but attend to what I say. Look down the trunk +and count the limbs below you on this side. How many limbs have +you passed?" + +"One, two, tree, four, fibe--I done pass fibe big limb, massa, 'pon +dis side." + +"Then go one limb higher." + +In a few minutes the voice was heard again, announcing that the +seventh limb was attained. + +"Now, Jup," cried Legrand, evidently much excited, "I want you to +work your way out upon that limb as far as you can. If you see +anything strange let me know." + +By this time what little doubt I might have entertained of my poor +friend's insanity was put finally at rest. I had no alternative +but to conclude him stricken with lunacy, and I became seriously +anxious about getting him home. While I was pondering upon what +was best to be done, Jupiter's voice was again heard. + +"Mos feered for to ventur pon dis limb berry far--'tis dead limb +putty much all de way." + +"Did you say it was a DEAD limb, Jupiter?" cried Legrand in a +quavering voice. + +"Yes, massa, him dead as de door-nail--done up for sartin--done +departed dis here life." + +"What in the name of heaven shall I do?" asked Legrand, seemingly +in the greatest distress. + +"Do!" said I, glad of an opportunity to interpose a word, "why come +home and go to bed. Come now!--that's a fine fellow. It's getting +late, and, besides, you remember your promise." + +"Jupiter," cried he, without heeding me in the least, "do you hear +me?" + +"Yes, Massa Will, hear you ebber so plain." + +"Try the wood well, then, with your knife, and see if you think it +VERY rotten." + +"Him rotten, massa, sure nuff," replied the negro in a few moments, +"but not so berry rotten as mought be. Mought venture out leetle +way pon de limb by myself, dat's true." + +"By yourself!--what do you mean?" + +"Why, I mean de bug. 'Tis BERRY hebby bug. Spose I drop him down +fuss, an den de limb won't break wid just de weight of one nigger." + +"You infernal scoundrel!" cried Legrand, apparently much relieved, +"what do you mean by telling me such nonsense as that? As sure as +you drop that beetle I'll break your neck. Look here, Jupiter, do +you hear me?" + +"Yes, massa, needn't hollo at poor nigger dat style." + +"Well! now listen!--if you will venture out on the limb as far as +you think safe, and not let go the beetle, I'll make you a present +of a silver dollar as soon as you get down." + +"I'm gwine, Massa Will--deed I is," replied the negro very +promptly--"mos out to the eend now." + +"OUT TO THE END!" here fairly screamed Legrand; "do you say you are +out to the end of that limb?" + +"Soon be to de eend, massa--o-o-o-o-oh! Lor-gol-a-marcy! what IS +dis here pon de tree?" + +"Well!" cried Legrand, highly delighted, "what is it?" + +"Why 'taint noffin but a skull--somebody bin lef him head up de +tree, and de crows done gobble ebery bit ob de meat off." + +"A skull, you say!--very well,--how is it fastened to the limb?-- +what holds it on?" + +"Sure nuff, massa; mus look. Why dis berry curious sarcumstance, +pon my word--dare's a great big nail in de skull, what fastens ob +it on to de tree." + +"Well now, Jupiter, do exactly as I tell you--do you hear?" + +"Yes, massa." + +"Pay attention, then--find the left eye of the skull." + +"Hum! hoo! dat's good! why dey ain't no eye lef at all." + +"Curse your stupidity! do you know your right hand from your left?" + +"Yes, I knows dat--knows all about dat--'tis my lef hand what I +chops de wood wid." + +"To be sure! you are left-handed; and your left eye is on the same +side as your left hand. Now, I suppose, you can find the left eye +of the skull, or the place where the left eye has been. Have you +found it?" + +Here was a long pause. At length the negro asked: + +"Is de lef eye of de skull pon de same side as de lef hand of de +skull too?--cause de skull aint got not a bit oh a hand at all-- +nebber mind! I got de lef eye now--here de lef eye! what mus do +wid it?" + +Let the beetle drop through it, as far as the string will reach-- +but be careful and not let go your hold of the string." + +"All dat done, Massa Will; mighty easy ting for to put de bug fru +de hole--look out for him dare below!" + +During this colloquy no portion of Jupiter's person could be seen; +but the beetle, which he had suffered to descend, was now visible +at the end of the string, and glistened, like a globe of burnished +gold, in the last rays of the setting sun, some of which still +faintly illumined the eminence upon which we stood. The scarabaeus +hung quite clear of any branches, and, if allowed to fall, would +have fallen at our feet. Legrand immediately took the scythe, and +cleared with it a circular space, three or four yards in diameter, +just beneath the insect, and, having accomplished this, ordered +Jupiter to let go the string and come down from the tree. + +Driving a peg, with great nicety, into the ground, at the precise +spot where the beetle fell, my friend now produced from his pocket +a tape measure. Fastening one end of this at that point of the +trunk of the tree which was nearest the peg, he unrolled it till it +reached the peg and thence further unrolled it, in the direction +already established by the two points of the tree and the peg, for +the distance of fifty feet--Jupiter clearing away the brambles with +the scythe. At the spot thus attained a second peg was driven, and +about this, as a center, a rude circle, about four feet in +diameter, described. Taking now a spade himself, and giving one to +Jupiter and one to me, Legrand begged us to set about digging as +quickly as possible. + +To speak the truth, I had no especial relish for such amusement at +any time, and, at that particular moment, would willingly have +declined it; for the night was coming on, and I felt much fatigued +with the exercise already taken; but I saw no mode of escape, and +was fearful of disturbing my poor friend's equanimity by a refusal. +Could I have depended, indeed, upon Jupiter's aid, I would have had +no hesitation in attempting to get the lunatic home by force; but I +was too well assured of the old negro's disposition, to hope that +he would assist me, under any circumstances, in a personal contest +with his master. I made no doubt that the latter had been infected +with some of the innumerable Southern superstitions about money +buried, and that his fantasy had received confirmation by the +finding of the scarabaeus, or, perhaps, by Jupiter's obstinacy in +maintaining it to be "a bug of real gold." A mind disposed to +lunacy would readily be led away by such suggestions--especially if +chiming in with favorite preconceived ideas--and then I called to +mind the poor fellow's speech about the beetle's being "the index +of his fortune." Upon the whole, I was sadly vexed and puzzled, +but, at length, I concluded to make a virtue of necessity--to dig +with a good will, and thus the sooner to convince the visionary, by +ocular demonstration, of the fallacy of the opinion he entertained. + +The lanterns having been lit, we all fell to work with a zeal +worthy a more rational cause; and, as the glare fell upon our +persons and implements, I could not help thinking how picturesque a +group we composed, and how strange and suspicious our labors must +have appeared to any interloper who, by chance, might have stumbled +upon our whereabouts. + +We dug very steadily for two hours. Little was said; and our chief +embarrassment lay in the yelpings of the dog, who took exceeding +interest in our proceedings. He, at length, became so obstreperous +that we grew fearful of his giving the alarm to some stragglers in +the vicinity,--or, rather, this was the apprehension of Legrand;-- +for myself, I should have rejoiced at any interruption which might +have enabled me to get the wanderer home. The noise was, at +length, very effectually silenced by Jupiter, who, getting out of +the hole with a dogged air of deliberation, tied the brute's mouth +up with one of his suspenders, and then returned, with a grave +chuckle, to his task. + +When the time mentioned had expired, we had reached a depth of five +feet, and yet no signs of any treasure became manifest. A general +pause ensued, and I began to hope that the farce was at an end. +Legrand, however, although evidently much disconcerted, wiped his +brow thoughtfully and recommenced. We had excavated the entire +circle of four feet diameter, and now we slightly enlarged the +limit, and went to the farther depth of two feet. Still nothing +appeared. The gold-seeker, whom I sincerely pitied, at length +clambered from the pit, with the bitterest disappointment imprinted +upon every feature, and proceeded, slowly and reluctantly, to put +on his coat, which he had thrown off at the beginning of his labor. +In the meantime I made no remark. Jupiter, at a signal from his +master, began to gather up his tools. This done, and the dog +having been unmuzzled, we turned in profound silence toward home. + +We had taken, perhaps, a dozen steps in this direction, when, with +a loud oath, Legrand strode up to Jupiter, and seized him by the +collar. The astonished negro opened his eyes and mouth to the +fullest extent, let fall the spades, and fell upon his knees. + +"You scoundrel!" said Legrand, hissing out the syllables from +between his clenched teeth--"you infernal black villain!--speak, I +tell you!--answer me this instant, without prevarication!--which-- +which is your left eye?" + +"Oh, my golly, Massa Will! aint dis here my lef eye for sartain?" +roared the terrified Jupiter, placing his hand upon his RIGHT organ +of vision, and holding it there with a desperate pertinacity, as if +in immediate, dread of his master's attempt at a gouge. + +"I thought so!--I knew it! hurrah!" vociferated Legrand, letting +the negro go and executing a series of curvets and caracols, much +to the astonishment of his valet, who, arising from his knees, +looked, mutely, from his master to myself, and then from myself to +his master. + +"Come! we must go back," said the latter, "the game's not up yet;" +and he again led the way to the tulip tree. + +"Jupiter," said he, when we reached its foot, "come here! was the +skull nailed to the limb with the face outward, or with the face to +the limb?" + +"De face was out, massa, so dat de crows could get at de eyes good, +widout any trouble." + +"Well, then, was it this eye or that through which you dropped the +beetle?" here Legrand touched each of Jupiter's eyes. + +"'Twas dis eye, massa--de lef eye--jis as you tell me," and here it +was his right eye that the negro indicated. + +"That will do--we must try it again." + +Here my friend, about whose madness I now saw, or fancied that I +saw, certain indications of method, removed the peg which marked +the spot where the beetle fell, to a spot about three inches to the +westward of its former position. Taking, now, the tape measure +from the nearest point of the trunk to the peg, as before, and +continuing the extension in a straight line to the distance of +fifty feet, a spot was indicated, removed, by several yards, from +the point at which we had been digging. + +Around the new position a circle, somewhat larger than in the +former instance, was now described, and we again set to work with +the spade. I was dreadfully weary, but, scarcely understanding +what had occasioned the change in my thoughts, I felt no longer any +great aversion from the labor imposed. I had become most +unaccountably interested--nay, even excited. Perhaps there was +something, amid all the extravagant demeanor of Legrand--some air +of forethought, or of deliberation, which impressed me. I dug +eagerly, and now and then caught myself actually looking, with +something that very much resembled expectation, for the fancied +treasure, the vision of which had demented my unfortunate +companion. At a period when such vagaries of thought most fully +possessed me, and when we had been at work perhaps an hour and a +half, we were again interrupted by the violent howlings of the dog. +His uneasiness, in the first instance, had been, evidently, but the +result of playfulness or caprice, but he now assumed a bitter and +serious tone. Upon Jupiter's again attempting to muzzle him, he +made furious resistance, and, leaping into the hole, tore up the +mold frantically with his claws. In a few seconds he had uncovered +a mass of human bones, forming two complete skeletons, intermingled +with several buttons of metal, and what appeared to be the dust of +decayed woolen. One or two strokes of a spade upturned the blade +of a large Spanish knife, and, as we dug farther, three or four +loose pieces of gold and silver coin came to light. + +At sight of these the joy of Jupiter could scarcely be restrained, +but the countenance of his master wore an air of extreme +disappointment. He urged us, however, to continue our exertions, +and the words were hardly uttered when I stumbled and fell forward, +having caught the toe of my boot in a large ring of iron that lay +half buried in the loose earth. + +We now worked in earnest, and never did I pass ten minutes of more +intense excitement. During this interval we had fairly unearthed +an oblong chest of wood, which, from its perfect preservation and +wonderful hardness, had plainly been subjected to some mineralizing +process--perhaps that of the bichloride of mercury. This box was +three feet and a half long, three feet broad, and two and a half +feet deep. It was firmly secured by bands of wrought iron, +riveted, and forming a kind of open trelliswork over the whole. On +each side of the chest, near the top, were three rings of iron--six +in all--by means of which a firm hold could be obtained by six +persons. Our utmost united endeavors served only to disturb the +coffer very slightly in its bed. We at once saw the impossibility +of removing so great a weight. Luckily, the sole fastenings of the +lid consisted of two sliding bolts. These we drew back--trembling +and panting with anxiety. In an instant, a treasure of +incalculable value lay gleaming before us. As the rays of the +lanterns fell within the pit, there flashed upward a glow and a +glare, from a confused heap of gold and of jewels, that absolutely +dazzled our eyes. + +I shall not pretend to describe the feelings with which I gazed. +Amazement was, of course, predominant. Legrand appeared exhausted +with excitement, and spoke very few words. Jupiter's countenance +wore, for some minutes, as deadly a pallor as it is possible, in +the nature of things, for any negro's visage to assume. He seemed +stupefied--thunderstricken. Presently he fell upon his knees in +the pit, and burying his naked arms up to the elbows in gold, let +them there remain, as if enjoying the luxury of a bath. At length, +with a deep sigh, he exclaimed, as if in a soliloquy: + +"And dis all cum of de goole-bug! de putty goole-bug! de poor +little goole-bug, what I boosed in that sabage kind oh style! +Ain't you shamed oh yourself, nigger?--answer me dat!" + +It became necessary, at last, that I should arouse both master and +valet to the expediency of removing the treasure. It was growing +late, and it behooved us to make exertion, that we might get +everything housed before daylight. It was difficult to say what +should he done, and much time was spent in deliberation--so +confused were the ideas of all. We, finally, lightened the box by +removing two thirds of its contents, when we were enabled, with +some trouble, to raise it from the hole. The articles taken out +were deposited among the brambles, and the dog left to guard them, +with strict orders from Jupiter neither, upon any pretense, to stir +from the spot, nor to open his mouth until our return. We then +hurriedly made for home with the chest; reaching the hut in safety, +but after excessive toil, at one o'clock in the morning. Worn out +as we were, it was not in human nature to do more immediately. We +rested until two, and had supper; starting for the hills +immediately afterwards, armed with three stout sacks, which, by +good luck, were upon the premises. A little before four we arrived +at the pit, divided the remainder of the booty, as equally as might +be, among us, and, leaving the holes unfilled, again set out for +the hut, at which, for the second time, we deposited our golden +burdens, just as the first faint streaks of the dawn gleamed from +over the treetops in the east. + +We were now thoroughly broken down; but the intense excitement of +the time denied us repose. After an unquiet slumber of some three +or four hours' duration, we arose, as if by preconcert, to make +examination of our treasure. + +The chest had been full to the brim, and we spent the whole day, +and the greater part of the next night, in a scrutiny of its +contents. There had been nothing like order or arrangement. +Everything had been heaped in promiscuously. Having assorted all +with care, we found ourselves possessed of even vaster wealth than +we had at first supposed. In coin there was rather more than four +hundred and fifty thousand dollars--estimating the value of the +pieces, as accurately as we could, by the tables of the period. +There was not a particle of silver. All was gold of antique date +and of great variety--French, Spanish, and German money, with a few +English guineas, and some counters, of which we had never seen +specimens before. There were several very large and heavy coins, +so worn that we could make nothing of their inscriptions. There +was no American money. The value of the jewels we found more +difficulty in estimating. There were diamonds--some of them +exceedingly large and fine--a hundred and ten in all, and not one +of them small; eighteen rubies of remarkable brilliancy;--three +hundred and ten emeralds, all very beautiful; and twenty-one +sapphires, with an opal. These stones had all been broken from +their settings and thrown loose in the chest. The settings +themselves, which we picked out from among the other gold, appeared +to have been beaten up with hammers, as if to prevent +identification. Besides all this, there was a vast quantity of +solid gold ornaments; nearly two hundred massive finger and ears +rings; rich chains--thirty of these, if I remember; eighty-three +very large and heavy crucifixes; five gold censers of great value; +a prodigious golden punch bowl, ornamented with richly chased vine +leaves and Bacchanalian figures; with two sword handles exquisitely +embossed, and many other smaller articles which I cannot recollect. +The weight of these valuables exceeded three hundred and fifty +pounds avoirdupois; and in this estimate I have not included one +hundred and ninety-seven superb gold watches; three of the number +being worth each five hundred dollars, if one. Many of them were +very old, and as timekeepers valueless; the works having suffered, +more or less, from corrosion--but all were richly jeweled and in +cases of great worth. We estimated the entire contents of the +chest, that night, at a million and a half of dollars; and upon the +subsequent disposal of the trinkets and jewels (a few being +retained for our own use), it was found that we had greatly +undervalued the treasure. + +When, at length, we had concluded our examination, and the intense +excitement of the time had, in some measure, subsided, Legrand, who +saw that I was dying with impatience for a solution of this most +extraordinary riddle, entered into a full detail of all the +circumstances connected with it. + +"You remember," said he, "the night when I handed you the rough +sketch I had made of the scarabaeus. You recollect, also, that I +became quite vexed at you for insisting that my drawing resembled a +death's head. When you first made this assertion I thought you +were jesting; but afterwards I called to mind the peculiar spots on +the back of the insect, and admitted to myself that your remark had +some little foundation in fact. Still, the sneer at my graphic +powers irritated me--for I am considered a good artist--and, +therefore, when you handed me the scrap of parchment, I was about +to crumple it up and throw it angrily into the fire." + +"The scrap of paper, you mean," said I. + +"No; it had much of the appearance of paper, and at first I +supposed it to be such, but when I came to draw upon it, I +discovered it at once to be a piece of very thin parchment. It was +quite dirty, you remember. Well, as I was in the very act of +crumpling it up, my glance fell upon the sketch at which you had +been looking, and you may imagine my astonishment when I perceived, +in fact, the figure of a death's head just where, it seemed to me, +I had made the drawing of the beetle. For a moment I was too much +amazed to think with accuracy. I knew that my design was very +different in detail from this--although there was a certain +similarity in general outline. Presently I took a candle, and +seating myself at the other end of the room, proceeded to +scrutinize the parchment more closely. Upon turning it over, I saw +my own sketch upon the reverse, just as I had made it. My first +idea, now, was mere surprise at the really remarkable similarity of +outline--at the singular coincidence involved in the fact that, +unknown to me, there should have been a skull upon the other side +of the parchment, immediately beneath my figure of the scarabaeus, +and that this skull, not only in outline, but in size, should so +closely resemble my drawing. I say the singularity of this +coincidence absolutely stupefied me for a time. This is the usual +effect of such coincidences. The mind struggles to establish a +connection--a sequence of cause and effect--and, being unable to do +so, suffers a species of temporary paralysis. But, when I +recovered from this stupor, there dawned upon me gradually a +conviction which startled me even far more than the coincidence. I +began distinctly, positively, to remember that there had been NO +drawing upon the parchment, when I made my sketch of the +scarabaeus. I became perfectly certain of this; for I recollected +turning up first one side and then the other, in search of the +cleanest spot. Had the skull been then there, of course I could +not have failed to notice it. Here was indeed a mystery which I +felt it impossible to explain; but, even at that early moment, +there seemed to glimmer, faintly, within the most remote and secret +chambers of my intellect, a glow-wormlike conception of that truth +which last night's adventure brought to so magnificent a +demonstration. I arose at once, and putting the parchment securely +away, dismissed all further reflection until I should be alone. + +"When you had gone, and when Jupiter was fast asleep, I betook +myself to a more methodical investigation of the affair. In the +first place I considered the manner in which the parchment had come +into my possession. The spot where we discovered the scarabaeus +was on the coast of the mainland, about a mile eastward of the +island, and but a short distance above high-water mark. Upon my +taking hold of it, it gave me a sharp bite, which caused me to let +it drop. Jupiter, with his accustomed caution, before seizing the +insect, which had flown toward him, looked about him for a leaf, or +something of that nature, by which to take hold of it. It was at +this moment that his eyes, and mine also, fell upon the scrap of +parchment, which I then supposed to be paper. It was lying half +buried in the sand, a corner sticking up. Near the spot where we +found it, I observed the remnants of the hull of what appeared to +have been a ship's longboat. The wreck seemed to have been there +for a very great while, for the resemblance to boat timbers could +scarcely be traced. + +"Well, Jupiter picked up the parchment, wrapped the beetle in it, +and gave it to me. Soon afterwards we turned to go home, and on +the way met Lieutenant G----. I showed him the insect, and he +begged me to let him take it to the fort. Upon my consenting, he +thrust it forthwith into his waistcoat pocket, without the +parchment in which it had been wrapped, and which I had continued +to hold in my hand during his inspection. Perhaps he dreaded my +changing my mind, and thought it best to make sure of the prize at +once--you know how enthusiastic he is on all subjects connected +with Natural History. At the same time, without being conscious of +it, I must have deposited the parchment in my own pocket. + +"You remember that when I went to the table, for the purpose of +making a sketch of the beetle, I found no paper where it was +usually kept. I looked in the drawer, and found none there. I +searched my pockets, hoping to find an old letter, when my hand +fell upon the parchment. I thus detail the precise mode in which +it came into my possession, for the circumstances impressed me with +peculiar force. + +"No doubt you will think me fanciful--but I had already established +a kind of CONNECTION. I had put together two links of a great +chain. There was a boat lying upon a seacoast, and not far from +the boat was a parchment--NOT A PAPER--with a skull depicted upon +it. You will, of course, ask 'where is the connection?' I reply +that the skull, or death's head, is the well-known emblem of the +pirate. The flag of the death's head is hoisted in all +engagements. + +"I have said that the scrap was parchment, and not paper. +Parchment is durable--almost imperishable. Matters of little +moment are rarely consigned to parchment; since, for the mere +ordinary purposes of drawing or writing, it is not nearly so well +adapted as paper. This reflection suggested some meaning--some +relevancy--in the death's head. I did not fail to observe, also, +the FORM of the parchment. Although one of its corners had been, +by some accident, destroyed, it could be seen that the original +form was oblong. It was just such a slip, indeed, as might have +been chosen for a memorandum--for a record of something to be long +remembered, and carefully preserved." + +"But," I interposed, "you say that the skull was NOT upon the +parchment when you made the drawing of the beetle. How then do you +trace any connection between the boat and the skull--since this +latter, according to your own admission, must have been designed +(God only knows how or by whom) at some period subsequent to your +sketching the scarabaeus?" + +"Ah, hereupon turns the whole mystery; although the secret, at this +point, I had comparatively little difficulty in solving. My steps +were sure, and could afford but a single result. I reasoned, for +example, thus: When I drew the scarabaeus, there was no skull +apparent upon the parchment. When I had completed the drawing I +gave it to you, and observed you narrowly until you returned it. +YOU, therefore, did not design the skull, and no one else was +present to do it. Then it was not done by human agency. And +nevertheless it was done. + +"At this stage of my reflections I endeavored to remember, and DID +remember, with entire distinctness, every incident which occurred +about the period in question. The weather was chilly (oh, rare and +happy accident!), and a fire was blazing upon the hearth. I was +heated with exercise and sat near the table. You, however, had +drawn a chair close to the chimney. Just as I placed the parchment +in your hand, and as you were in the act of inspecting it, Wolf, +the Newfoundland, entered, and leaped upon your shoulders. With +your left hand you caressed him and kept him off, while your right, +holding the parchment, was permitted to fall listlessly between +your knees, and in close proximity to the fire. At one moment I +thought the blaze had caught it, and was about to caution you, but, +before I could speak, you had withdrawn it, and were engaged in its +examination. When I considered all these particulars, I doubted +not for a moment that HEAT had been the agent in bringing to light, +upon the parchment, the skull which I saw designed upon it. You +are well aware that chemical preparations exist, and have existed +time out of mind, by means of which it is possible to write upon +either paper or vellum, so that the characters shall become visible +only when subjected to the action of fire. Zaffre, digested in +aqua regia, and diluted with four times its weight of water, is +sometimes employed; a green tint results. The regulus of cobalt, +dissolved in spirit of niter, gives a red. These colors disappear +at longer or shorter intervals after the material written upon +cools, but again become apparent upon the reapplication of heat. + +"I now scrutinized the death's head with care. Its outer edges-- +the edges of the drawing nearest the edge of the vellum--were far +more DISTINCT than the others. It was clear that the action of the +caloric had been imperfect or unequal. I immediately kindled a +fire, and subjected every portion of the parchment to a glowing +heat. At first, the only effect was the strengthening of the faint +lines in the skull; but, upon persevering in the experiment, there +became visible, at the corner of the slip, diagonally opposite to +the spot in which the death's head was delineated, the figure of +what I at first supposed to be a goat. A closer scrutiny, however, +satisfied me that it was intended for a kid." + +"Ha! ha!" said I, "to be sure I have no right to laugh at you--a +million and a half of money is too serious a matter for mirth--but +you are not about to establish a third link in your chain--you will +not find any especial connection between your pirates and a goat-- +pirates, you know, have nothing to do with goats; they appertain to +the farming interest." + +"But I have just said that the figure was NOT that of a goat." + +"Well, a kid then--pretty much the same thing." + +"Pretty much, but not altogether," said Legrand. "You may have +heard of one CAPTAIN Kidd. I at once looked upon the figure of the +animal as a kind of punning or hieroglyphical signature. I say +signature; because its position upon the vellum suggested this +idea. The death's head at the corner diagonally opposite, had, in +the same manner, the air of a stamp, or seal. But I was sorely put +out by the absence of all else--of the body to my imagined +instrument--of the text for my context." + +"I presume you expected to find a letter between the stamp and the +signature." + +"Something of that kind. The fact is, I felt irresistibly +impressed with a presentiment of some vast good fortune impending. +I can scarcely say why. Perhaps, after all, it was rather a desire +than an actual belief;--but do you know that Jupiter's silly words, +about the bug being of solid gold, had a remarkable effect upon my +fancy? And then the series of accidents and coincidents--these +were so VERY extraordinary. Do you observe how mere an accident it +was that these events should have occurred upon the SOLE day of all +the year in which it has been, or may be sufficiently cool for +fire, and that without the fire, or without the intervention of the +dog at the precise moment in which he appeared, I should never have +become aware of the death's head, and so never the possessor of the +treasure?" + +"But proceed--I am all impatience." + +"Well; you have heard, of course, the many stories current--the +thousand vague rumors afloat about money buried, somewhere upon the +Atlantic coast, by Kidd and his associates. These rumors must have +had some foundation in fact. And that the rumors have existed so +long and so continuous, could have resulted, it appeared to me, +only from the circumstance of the buried treasures still REMAINING +entombed. Had Kidd concealed his plunder for a time, and +afterwards reclaimed it, the rumors would scarcely have reached us +in their present unvarying form. You will observe that the stories +told are all about money-seekers, not about money-finders. Had the +pirate recovered his money, there the affair would have dropped. +It seemed to me that some accident--say the loss of a memorandum +indicating its locality--had deprived him of the means of +recovering it, and that this accident had become known to his +followers, who otherwise might never have heard that the treasure +had been concealed at all, and who, busying themselves in vain, +because unguided, attempts to regain it, had given first birth, and +then universal currency, to the reports which are now so common. +Have you ever heard of any important treasure being unearthed along +the coast?" + +"Never." + +"But that Kidd's accumulations were immense, is well known. I took +it for granted, therefore, that the earth still held them; and you +will scarcely be surprised when I tell you that I felt a hope, +nearly amounting to certainty, that the parchment so strangely +found involved a lost record of the place of deposit." + +"But how did you proceed?" + +"I held the vellum again to the fire, after increasing the heat, +but nothing appeared. I now thought it possible that the coating +of dirt might have something to do with the failure: so I carefully +rinsed the parchment by pouring warm water over it, and, having +done this, I placed it in a tin pan, with the skull downward, and +put the pan upon a furnace of lighted charcoal. In a few minutes, +the pan having become thoroughly heated, I removed the slip, and, +to my inexpressible joy, found it spotted, in several places, with +what appeared to be figures arranged in lines. Again I placed it +in the pan, and suffered it to remain another minute. Upon taking +it off, the whole was just as you see it now." + +Here Legrand, having reheated the parchment, submitted it to my +inspection. The following characters were rudely traced, in a red +tint, between the death's head and the goat: + + +"53++!305))6*;4826)4+)4+).;806*;48!8]60))85;1+8*:+(;:+*8!83(88)5*!; +46(;88*96*?;8)*+(;485);5*!2:*+(;4956*2(5*-4)8]8*;4069285);)6!8)4++; +1(+9;48081;8:8+1;48!85;4)485!528806*81(+9;48;(88;4(+?34;48)4+;161;: +188;+?;" + + +"But," said I, returning him the slip, "I am as much in the dark as +ever. Were all the jewels of Golconda awaiting me upon my solution +of this enigma, I am quite sure that I should be unable to earn +them." + +"And yet," said Legrand, "the solution is by no means so difficult +as you might be led to imagine from the first hasty inspection of +the characters. These characters, as anyone might readily guess, +form a cipher--that is to say, they convey a meaning; but then from +what is known of Kidd, I could not suppose him capable of +constructing any of the more abstruse cryptographs. I made up my +mind, at once, that this was of a simple species--such, however, as +would appear, to the crude intellect of the sailor, absolutely +insoluble without the key." + +"And you really solved it?" + +"Readily; I have solved others of an abstruseness ten thousand +times greater. Circumstances, and a certain bias of mind, have led +me to take interest in such riddles, and it may well be doubted +whether human ingenuity can construct an enigma of the kind which +human ingenuity may not, by proper application, resolve. In fact, +having once established connected and legible characters, I +scarcely gave a thought to the mere difficulty of developing their +import. + +"In the present case--indeed in all cases of secret writing--the +first question regards the LANGUAGE of the cipher; for the +principles of solution, so far, especially, as the more simple +ciphers are concerned, depend upon, and are varied by, the genius +of the particular idiom. In general, there is no alternative but +experiment (directed by probabilities) of every tongue known to him +who attempts the solution, until the true one be attained. But, +with the cipher now before us, all difficulty was removed by the +signature. The pun upon the word 'Kidd' is appreciable in no other +language than the English. But for this consideration I should +have begun my attempts with the Spanish and French, as the tongues +in which a secret of this kind would most naturally have been +written by a pirate of the Spanish main. As it was, I assumed the +cryptograph to be English. + +"You observe there are no divisions between the words. Had there +been divisions the task would have been comparatively easy. In +such cases I should have commenced with a collation and analysis of +the shorter words, and, had a word of a single letter occurred, as +is most likely, (a or I, for example,) I should have considered the +solution as assured. But, there being no division, my first step +was to ascertain the predominant letters, as well as the least +frequent. Counting all, I constructed a table thus: + + +Of the character 8 there are 33. + ; " 26. + 4 " 19. + +) " 16. + * " 13. + 5 " 12. + 6 " 11. + !1 " 8. + 0 " 6. + 92 " 5. + :3 " 4. + ? " 3. + ] " 2. + -. " 1. + + +"Now, in English, the letter which most frequently occurs is e. +Afterwards, the succession runs thus: a o i d h n r s t u y c f g l +m w b k p q x z. E predominates so remarkably, that an individual +sentence of any length is rarely seen, in which it is not the +prevailing character. + +"Here, then, we have, in the very beginning, the groundwork for +something more than a mere guess. The general use which may be +made of the table is obvious--but, in this particular cipher, we +shall only very partially require its aid. As our predominant +character is 8, we will commence by assuming it as the e of the +natural alphabet. To verify the supposition, let us observe if the +8 be seen often in couples--for e is doubled with great frequency +in English--in such words, for example, as 'meet,' 'fleet,' +'speed,' 'seen,' 'been,' 'agree,' etc. In the present instance we +see it doubled no less than five times, although the cryptograph is +brief. + +"Let us assume 8, then, as e. Now, of all WORDS in the language, +'the' is most usual; let us see, therefore, whether there are not +repetitions of any three characters, in the same order of +collocation, the last of them being 8. If we discover repetitions +of such letters, so arranged, they will most probably represent the +word 'the.' Upon inspection, we find no less than seven such +arrangements, the characters being ;48. We may, therefore, assume +that ; represents t, 4 represents h, and 8 represents e--the last +being now well confirmed. Thus a great step has been taken. + +"But, having established a single word, we are enabled to establish +a vastly important point; that is to say, several commencements and +terminations of other words. Let us refer, for example, to the +last instance but one, in which the combination ;48 occurs--not far +from the end of the cipher. We know that the ; immediately ensuing +is the commencement of a word, and, of the six characters +succeeding this 'the,' we are cognizant of no less than five. Let +us set these characters down, thus, by the letters we know them to +represent, leaving a space for the unknown-- + + +t eeth. + + +"Here we are enabled, at once, to discard the 'th,' as forming no +portion of the word commencing with the first t; since, by +experiment of the entire alphabet for a letter adapted to the +vacancy, we perceive that no word can be formed of which this th +can be a part. We are thus narrowed into + + +t ee, + + +and, going through the alphabet, if necessary, as before, we arrive +at the word 'tree,' as the sole possible reading. We thus gain +another letter, r, represented by (, with the words 'the tree' in +juxtaposition. + +"Looking beyond these words, for a short distance, we again see the +combination ;48, and employ it by way of TERMINATION to what +immediately precedes. We have thus this arrangement: + + +the tree ;4(4+?34 the, + + +or, substituting the natural letters, where known, it reads thus: + + +the tree thr+?3h the. + + +"Now, if, in place of the unknown characters, we leave blank +spaces, or substitute dots, we read thus: + + +the tree thr...h the, + + +when the word 'through' makes itself evident at once. But this +discovery gives us three new letters, o, u, and g, represented by ++, ?, and 3. + +"Looking now, narrowly, through the cipher for combinations of +known characters, we find, not very far from the beginning, this +arrangement, + + +83(88, or egree, + + +which plainly, is the conclusion of the word 'degree,' and gives us +another letter, d, represented by !. + +"Four letters beyond the word 'degree,' we perceive the combination + + +;46(;88. + + +"Translating the known characters, and representing the unknown by +dots, as before, we read thus: + + +th.rtee, + + +an arrangement immediately suggestive of the word thirteen,' and +again furnishing us with two new characters, i and n, represented +by 6 and *. + +"Referring, now, to the beginning of the cryptograph, we find the +combination, + + +53++!. + + +"Translating as before, we obtain + + +.good, + + +which assures us that the first letter is A, and that the first two +words are 'A good.' + +"It is now time that we arrange our key, as far as discovered, in a +tabular form, to avoid confusion. It will stand thus: + + +5 represents a +! " d +8 " e +3 " g +4 " h +6 " i +* " n ++ " o +( " r +; " t +? " u + + +"We have, therefore, no less than eleven of the most important +letters represented, and it will be unnecessary to proceed with the +details of the solution. I have said enough to convince you that +ciphers of this nature are readily soluble, and to give you some +insight into the rationale of their development. But be assured +that the specimen before us appertains to the very simplest species +of cryptograph. It now only remains to give you the full +translation of the characters upon the parchment, as unriddled. +Here it is: + + +"'A good glass in the bishop's hostel in the devil's seat forty-one +degrees and thirteen minutes northeast and by north main branch +seventh limb east side shoot from the left eye of the death's head +a bee-line from the tree through the shot fifty feet out.'" + + +"But," said I, "the enigma seems still in as bad a condition as +ever. How is it possible to extort a meaning from all this jargon +about 'devil's seats,' 'death's heads,' and 'bishop's hostels'?" + +"I confess," replied Legrand, "that the matter still wears a +serious aspect, when regarded with a casual glance. My first +endeavor was to divide the sentence into the natural division +intended by the cryptographist." + +"You mean, to punctuate it?" + +"Something of that kind." + +"But how was it possible to effect this?" + +"I reflected that it had been a POINT with the writer to run his +words together without division, so as to increase the difficulty +of solution. Now, a not overacute man, in pursuing such an object, +would be nearly certain to overdo the matter. When, in the course +of his composition, he arrived at a break in his subject which +would naturally require a pause, or a point, he would be +exceedingly apt to run his characters, at this place, more than +usually close together. If you will observe the MS., in the +present instance, you will easily detect five such cases of unusual +crowding. Acting upon this hint I made the division thus: + + +"'A good glass in the bishop's hostel in the devil's seat--forty- +one degrees and thirteen minutes--northeast and by north--main +branch seventh limb east side--shoot from the left eye of the +death's head--a bee-line from the tree through the shot fifty feet +out.'" + + +"Even this division," said I, "leaves me still in the dark." + +"It left me also in the dark," replied Legrand, "for a few days; +during which I made diligent inquiry in the neighborhood of +Sullivan's Island, for any building which went by name of the +'Bishop's Hotel'; for, of course, I dropped the obsolete word +'hostel.' Gaining no information on the subject, I was on the +point of extending my sphere of search, and proceeding in a more +systematic manner, when, one morning, it entered into my head, +quite suddenly, that this 'Bishop's Hostel' might have some +reference to an old family, of the name of Bessop, which, time out +of mind, had held possession of an ancient manor house, about four +miles to the northward of the island. I accordingly went over to +the plantation, and reinstituted my inquiries among the older +negroes of the place. At length one of the most aged of the women +said that she had heard of such a place as Bessop's Castle, and +thought that she could guide me to it, but that it was not a +castle, nor a tavern, but a high rock. + +"I offered to pay her well for her trouble, and, after some demur, +she consented to accompany me to the spot. We found it without +much difficulty, when, dismissing her, I proceeded to examine the +place. The 'castle' consisted of an irregular assemblage of cliffs +and rocks--one of the latter being quite remarkable for its height +as well as for its insulated and artificial appearance. I +clambered to its apex, and then felt much at a loss as to what +should be next done. + +"While I was busied in reflection, my eyes fell upon a narrow ledge +in the eastern face of the rock, perhaps a yard below the summit +upon which I stood. This ledge projected about eighteen inches, +and was not more than a foot wide, while a niche in the cliff just +above it gave it a rude resemblance to one of the hollow-backed +chairs used by our ancestors. I made no doubt that here was the +'devil's seat' alluded to in the MS., and now I seemed to grasp the +full secret of the riddle. + +"The 'good glass,' I knew, could have reference to nothing but a +telescope; for the word 'glass' is rarely employed in any other +sense by seamen. Now here, I at once saw, was a telescope to be +used, and a definite point of view, ADMITTING NO VARIATION, from +which to use it. Nor did I hesitate to believe that the phrases, +'forty-one degrees and thirteen minutes,' and 'northeast and by +north,' were intended as directions for the leveling of the glass. +Greatly excited by these discoveries, I hurried home, procured a +telescope, and returned to the rock. + +"I let myself down to the ledge, and found that it was impossible +to retain a seat upon it except in one particular position. This +fact confirmed my preconceived idea. I proceeded to use the glass. +Of course, the 'forty-one degrees and thirteen minutes' could +allude to nothing but elevation above the visible horizon, since +the horizontal direction was clearly indicated by the words, +'northeast and by north.' This latter direction I at once +established by means of a pocket compass; then, pointing the glass +as nearly at an angle of forty-one degrees of elevation as I could +do it by guess, I moved it cautiously up or down, until my +attention was arrested by a circular rift or opening in the foliage +of a large tree that overtopped its fellows in the distance. In +the center of this rift I perceived a white spot, but could not, at +first, distinguish what it was. Adjusting the focus of the +telescope, I again looked, and now made it out to be a human skull. + +"Upon this discovery I was so sanguine as to consider the enigma +solved; for the phrase 'main branch, seventh limb, east side,' +could refer only to the position of the skull upon the tree, while +'shoot from the left eye of the death's head' admitted, also, of +but one interpretation, in regard to a search for buried treasure. +I perceived that the design was to drop a bullet from the left eye +of the skull, and that a bee-line, or, in other words, a straight +line, drawn from the nearest point of the trunk 'through the shot' +(or the spot where the bullet fell), and thence extended to a +distance of fifty feet, would indicate a definite point--and +beneath this point I thought it at least POSSIBLE that a deposit of +value lay concealed." + +"All this," I said, "is exceedingly clear, and, although ingenious, +still simple and explicit. When you left the Bishop's Hotel, what +then?" + +"Why, having carefully taken the bearings of the tree, I turned +homeward. The instant that I left 'the devil's seat,' however, the +circular rift vanished; nor could I get a glimpse of it afterwards, +turn as I would. What seems to me the chief ingenuity in this +whole business, is the fact (for repeated experiment has convinced +me it IS a fact) that the circular opening in question is visible +from no other attainable point of view than that afforded by the +narrow ledge upon the face of the rock. + +"In this expedition to the 'Bishop's Hotel' I had been attended by +Jupiter, who had, no doubt, observed, for some weeks past, the +abstraction of my demeanor, and took especial care not to leave me +alone. But, on the next day, getting up very early, I contrived to +give him the slip, and went into the hills in search of the tree. +After much toil I found it. When I came home at night my valet +proposed to give me a flogging. With the rest of the adventure I +believe you are as well acquainted as myself." + +"I suppose," said I, "you missed the spot, in the first attempt at +digging, through Jupiter's stupidity in letting the bug fall +through the right instead of through the left eye of the skull." + +"Precisely. This mistake made a difference of about two inches and +a half in the 'shot'--that is to say, in the position of the peg +nearest the tree; and had the treasure been BENEATH the 'shot,' the +error would have been of little moment; but 'the shot,' together +with the nearest point of the tree, were merely two points for the +establishment of a line of direction; of course the error, however +trivial in the beginning, increased as we proceeded with the line, +and by the time we had gone fifty feet threw us quite off the +scent. But for my deep-seated impressions that treasure was here +somewhere actually buried, we might have had all our labor in +vain." + +"But your grandiloquence, and your conduct in swinging the beetle-- +how excessively odd! I was sure you were mad. And why did you +insist upon letting fall the bug, instead of a bullet, from the +skull?" + +"Why, to be frank, I felt somewhat annoyed by your evident +suspicions touching my sanity, and so resolved to punish you +quietly, in my own way, by a little bit of sober mystification. +For this reason I swung the beetle, and for this reason I let it +fall from the tree. An observation of yours about its great weight +suggested the latter idea." + +"Yes, I perceive; and now there is only one point which puzzles me. +What are we to make of the skeletons found in the hole?" + +"That is a question I am no more able to answer than yourself. +There seems, however, only one plausible way of accounting for +them--and yet it is dreadful to believe in such atrocity as my +suggestion would imply. It is clear that Kidd--if Kidd indeed +secreted this treasure, which I doubt not--it is clear that he must +have had assistance in the labor. But this labor concluded, he may +have thought it expedient to remove all participants in his secret. +Perhaps a couple of blows with a mattock were sufficient, while his +coadjutors were busy in the pit; perhaps it required a dozen--who +shall tell?" diff --git a/testsuite/hmac-test.c b/testsuite/hmac-test.c new file mode 100644 index 0000000..d3068d9 --- /dev/null +++ b/testsuite/hmac-test.c @@ -0,0 +1,831 @@ +#include "testutils.h" +#include "hmac.h" + +/* KEY and MSG are supposed to expand to length, data */ +#define HMAC_TEST(alg, length, key, msg, mac) do { \ + hmac_##alg##_set_key(&alg, key); \ + hmac_##alg##_update(&alg, msg); \ + digest[length] = 17; \ + hmac_##alg##_digest(&alg, length, digest); \ + ASSERT(MEMEQ (length, digest, mac)); \ + ASSERT(digest[length] == 17); \ +} while (0) + +int +test_main(void) +{ + struct hmac_md5_ctx md5; + struct hmac_sha1_ctx sha1; + struct hmac_sha224_ctx sha224; + struct hmac_sha256_ctx sha256; + struct hmac_sha384_ctx sha384; + struct hmac_sha512_ctx sha512; + + /* sha512's digests are longest */ + uint8_t digest[SHA512_DIGEST_SIZE+1]; + + memset(digest, 0, sizeof(digest)); + + /* Test vectors for md5, from RFC-2202 */ + + /* md5 - 1 */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b"), + LDATA("Hi There"), + H("9294727a3638bb1c 13f48ef8158bfc9d")); + + + /* md5 - 2 */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("Jefe"), + LDATA("what do ya want for nothing?"), + H("750c783e6ab0b503 eaa86e310a5db738")); + + /* md5 - 3 */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + HL("dddddddddddddddd dddddddddddddddd" + "dddddddddddddddd dddddddddddddddd" + "dddddddddddddddd dddddddddddddddd" + "dddd"), + H("56be34521d144c88 dbb8c733f0e8b3f6")); + + /* md5 - 4 */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + HL("0102030405060708 090a0b0c0d0e0f10" + "1112131415161718 19"), + HL("cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcd"), + H("697eaf0aca3a3aea 3a75164746ffaa79")); + + /* md5 - 5 */ + HMAC_TEST(md5, 12, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c"), + LDATA("Test With Truncation"), + H("56461ef2342edc00 f9bab995")); + + /* md5 - 6 */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("6b1ab7fe4bd7bf8f 0b62e6ce61b9d0cd")); + + /* md5 - 7 */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + LDATA("Test Using Larger Than Block-Size Key and Larger " + "Than One Block-Size Data"), + H("6f630fad67cda0ee 1fb1f562db3aa53e")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA(""), + H("e84db42a188813f30a15e611d64c7869")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("a"), + H("123662062e67c2aab371cc49db0df134")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("38"), + H("0a46cc10a49d4b7025c040c597bf5d76")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abc"), + H("d1f4d89f0e8b2b6ed0623c99ec298310")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("message digest"), + H("1627207b9bed5009a4f6e9ca8d2ca01e")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abcdefghijklmnopqrstuvwxyz"), + H("922aae6ab3b3a29202e21ce5f916ae9a")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), + H("ede9cb83679ba82d88fbeae865b3f8fc")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), + H("939dd45512ee3a594b6654f6b8de27f7")); + + /* Test vectors for sha1, from RFC-2202 */ + + /* sha1 - 1 */ + HMAC_TEST(sha1, SHA1_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b 0b0b0b0b"), + LDATA("Hi There"), + H("b617318655057264 e28bc0b6fb378c8e f146be00")); + + /* sha1 - 2 */ + HMAC_TEST(sha1, SHA1_DIGEST_SIZE, + LDATA("Jefe"), + LDATA("what do ya want for nothing?"), + H("effcdf6ae5eb2fa2 d27416d5f184df9c 259a7c79")); + + /* sha1 - 3 */ + HMAC_TEST(sha1, SHA1_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaa"), + HL("dddddddddddddddd dddddddddddddddd" + "dddddddddddddddd dddddddddddddddd" + "dddddddddddddddd dddddddddddddddd" + "dddd"), + H("125d7342b9ac11cd 91a39af48aa17b4f 63f175d3")); + + /* sha1 - 4 */ + HMAC_TEST(sha1, SHA1_DIGEST_SIZE, + HL("0102030405060708 090a0b0c0d0e0f10" + "1112131415161718 19"), + HL("cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcd"), + H("4c9007f4026250c6 bc8414f9bf50c86c 2d7235da")); + + /* sha1 - 5 */ + HMAC_TEST(sha1, 12, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"), + LDATA("Test With Truncation"), + H("4c1a03424b55e07f e7f27be1")); + + /* sha1 - 6 */ + HMAC_TEST(sha1, SHA1_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("aa4ae5e15272d00e 95705637ce8a3b55 ed402112")); + + /* sha1 - 7 */ + HMAC_TEST(sha1, SHA1_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + LDATA("Test Using Larger Than Block-Size Key and Larger " + "Than One Block-Size Data"), + H("e8e99d0f45237d78 6d6bbaa7965c7808 bbff1a91")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA(""), + H("e84db42a188813f30a15e611d64c7869")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("a"), + H("123662062e67c2aab371cc49db0df134")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("38"), + H("0a46cc10a49d4b7025c040c597bf5d76")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abc"), + H("d1f4d89f0e8b2b6ed0623c99ec298310")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("message digest"), + H("1627207b9bed5009a4f6e9ca8d2ca01e")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abcdefghijklmnopqrstuvwxyz"), + H("922aae6ab3b3a29202e21ce5f916ae9a")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), + H("ede9cb83679ba82d88fbeae865b3f8fc")); + + HMAC_TEST(md5, MD5_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), + H("939dd45512ee3a594b6654f6b8de27f7")); + + /* Test vectors for sha224, from RFC 4231 */ + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b"), + LDATA("Hi There"), + H("896fb1128abbdf196832107cd49df33f" + "47b4b1169912ba4f53684b22")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("Jefe"), + LDATA("what do ya want for nothing?"), + H("a30e01098bc6dbbf45690f3a7e9e6d0f" + "8bbea2a39e6148008fd05e44")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaa"), + HL("dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd"), + H("7fb3cb3588c6c1f6ffa9694d7d6ad264" + "9365b0c1f65d69d1ec8333ea")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + HL("0102030405060708090a0b0c0d0e0f10" + "111213141516171819"), + HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcd"), + H("6c11506874013cac6a2abc1bb382627c" + "ec6a90d86efc012de7afec5a")); + + HMAC_TEST(sha224, 16, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"), + LDATA("Test With Truncation"), + H("0e2aea68a90c8d37c988bcdb9fca6fa8")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("95e9a0db962095adaebe9b2d6f0dbce2" + "d499f112f2d2b7273fa6870e")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("This is a test using a larger than block-size ke" + "y and a larger than block-size data. The key nee" + "ds to be hashed before being used by the HMAC al" + "gorithm."), + H("3a854166ac5d9f023f54d517d0b39dbd" + "946770db9c2b95c9f6f565d1")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA(""), + H("d12a49ae38177ffeaa548b2148bb5238" + "60849772d9391e675b103d89")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("a"), + H("b04ff8522f904f553970bfa8ad3f0086" + "bce1e8580affd8a12c94e31a")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("38"), + H("afcfb5511f710334f9350f57faec3c08" + "764b4bd126a6840f4347f116")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abc"), + H("9df9907af127900c909376893565c6cf" + "2d7db244fdc4277da1e0b679")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("message digest"), + H("254ebf6b8ddd7a3271b3d9aca1699b0c" + "0bfb7df61e8a114922c88d27")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abcdefghijklmnopqrstuvwxyz"), + H("6ec5bffba5880c3234a6cf257816e4d5" + "35ab178a7f12929769e378fb")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), + H("5f768179dbb29ca722875d0f461a2e2f" + "597d0210340a84df1a8e9c63")); + + HMAC_TEST(sha224, SHA224_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), + H("c7667b0d7e56b2b4f6fcc1d8da9e22da" + "a1556f44c47132a87303c6a2")); + + /* Test vectors for sha256, from RFC 4231 */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b"), + LDATA("Hi There"), + H("b0344c61d8db38535ca8afceaf0bf12b" + "881dc200c9833da726e9376c2e32cff7")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("Jefe"), + LDATA("what do ya want for nothing?"), + H("5bdcc146bf60754e6a042426089575c7" + "5a003f089d2739839dec58b964ec3843")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaa"), + HL("dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd"), + H("773ea91e36800e46854db8ebd09181a7" + "2959098b3ef8c122d9635514ced565fe")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0102030405060708090a0b0c0d0e0f10" + "111213141516171819"), + HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcd"), + H("82558a389a443c0ea4cc819899f2083a" + "85f0faa3e578f8077a2e3ff46729665b")); + + HMAC_TEST(sha256, 16, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"), + LDATA("Test With Truncation"), + H("a3b6167473100ee06e0c796c2955552b")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("60e431591ee0b67f0d8a26aacbf5b77f" + "8e0bc6213728c5140546040f0ee37f54")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("This is a test using a larger than block-size ke" + "y and a larger than block-size data. The key nee" + "ds to be hashed before being used by the HMAC al" + "gorithm."), + H("9b09ffa71b942fcb27635fbcd5b0e944" + "bfdc63644f0713938a7f51535c3a35e2")); + + /* Additional test vectors for sha256, from + draft-ietf-ipsec-ciph-sha-256-01.txt */ + + /* Test Case #1: HMAC-SHA-256 with 3-byte input and 32-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0102030405060708 090a0b0c0d0e0f10" + "1112131415161718 191a1b1c1d1e1f20"), + LDATA("abc"), + H("a21b1f5d4cf4f73a 4dd939750f7a066a" + "7f98cc131cb16a66 92759021cfab8181")); + + /* Test Case #2: HMAC-SHA-256 with 56-byte input and 32-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0102030405060708 090a0b0c0d0e0f10" + "1112131415161718 191a1b1c1d1e1f20"), + LDATA("abcdbcdecdefdefgefghfghighijhijk" + "ijkljklmklmnlmnomnopnopq"), + H("104fdc1257328f08 184ba73131c53cae" + "e698e36119421149 ea8c712456697d30")); + + /* Test Case #3: HMAC-SHA-256 with 112-byte (multi-block) input + and 32-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0102030405060708 090a0b0c0d0e0f10" + "1112131415161718 191a1b1c1d1e1f20"), + LDATA("abcdbcdecdefdefgefghfghighijhijk" + "ijkljklmklmnlmnomnopnopqabcdbcde" + "cdefdefgefghfghighijhijkijkljklm" + "klmnlmnomnopnopq"), + H("470305fc7e40fe34 d3eeb3e773d95aab" + "73acf0fd060447a5 eb4595bf33a9d1a3")); + + /* Test Case #4: HMAC-SHA-256 with 8-byte input and 32-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b" + "0b0b0b0b0b0b0b0b 0b0b0b0b0b0b0b0b"), + LDATA("Hi There"), + H("198a607eb44bfbc6 9903a0f1cf2bbdc5" + "ba0aa3f3d9ae3c1c 7a3b1696a0b68cf7")); + + /* Test Case #6: HMAC-SHA-256 with 50-byte input and 32-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + HL("dddddddddddddddd dddddddddddddddd" + "dddddddddddddddd dddddddddddddddd" + "dddddddddddddddd dddddddddddddddd" + "dddd"), + H("cdcb1220d1ecccea 91e53aba3092f962" + "e549fe6ce9ed7fdc 43191fbde45c30b0")); + + /* Test Case #7: HMAC-SHA-256 with 50-byte input and 37-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("0102030405060708 090a0b0c0d0e0f10" + "1112131415161718 191a1b1c1d1e1f20" + "2122232425"), + HL("cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcd" + "cdcd"), + H("d4633c17f6fb8d74 4c66dee0f8f07455" + "6ec4af55ef079985 41468eb49bd2e917")); + + /* Test Case #8: HMAC-SHA-256 with 20-byte input and 32-byte key */ + HMAC_TEST(sha256, 16, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c" + "0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c"), + LDATA("Test With Truncation"), + H("7546af01841fc09b 1ab9c3749a5f1c17")); + + /* Test Case #9: HMAC-SHA-256 with 54-byte input and 80-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("6953025ed96f0c09 f80a96f78e6538db" + "e2e7b820e3dd970e 7ddd39091b32352f")); + + /* Test Case #10: HMAC-SHA-256 with 73-byte (multi-block) input + and 80-byte key */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa"), + LDATA("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"), + H("6355ac22e890d0a3 c8481a5ca4825bc8" + "84d3e7a1ff98a2fc 2ac7d8e064c3b2e6")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA(""), + H("5c780648c90d121c50091c3a0c3afc1f" + "4ab847528005d99d9821ad3f341b651a")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("a"), + H("6142364c0646b0cfe426866f21d613e0" + "55a136a7d9b45d85685e080a09cec463")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("38"), + H("e49aa7839977e130ad87b63da9d4eb7b" + "263cd5a27c54a7604b6044eb35901171")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abc"), + H("e5ef49f545c7af933a9d18c7c562bc91" + "08583fd5cf00d9e0db351d6d8f8e41bc")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("message digest"), + H("373b04877180fea27a41a8fb8f88201c" + "a6268411ee3c80b01a424483eb9156e1")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abcdefghijklmnopqrstuvwxyz"), + H("eb5945d56eefbdb41602946ea6448d53" + "86b08d7d801a87f439fab52f8bb9736e")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), + H("3798f363c57afa6edaffe39016ca7bad" + "efd1e670afb0e3987194307dec3197db")); + + HMAC_TEST(sha256, SHA256_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), + H("c89a7039a62985ff813fe4509b918a43" + "6d7b1ffd8778e2c24dec464849fb6128")); + + /* Test vectors for sha384, from RFC 4231 */ + HMAC_TEST(sha384, SHA384_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b"), + LDATA("Hi There"), + H("afd03944d84895626b0825f4ab46907f" + "15f9dadbe4101ec682aa034c7cebc59c" + "faea9ea9076ede7f4af152e8b2fa9cb6")); + + HMAC_TEST(sha384, SHA384_DIGEST_SIZE, + LDATA("Jefe"), + LDATA("what do ya want for nothing?"), + H("af45d2e376484031617f78d2b58a6b1b" + "9c7ef464f5a01b47e42ec3736322445e" + "8e2240ca5e69e2c78b3239ecfab21649")); + + HMAC_TEST(sha384, SHA384_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaa"), + HL("dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd"), + H("88062608d3e6ad8a0aa2ace014c8a86f" + "0aa635d947ac9febe83ef4e55966144b" + "2a5ab39dc13814b94e3ab6e101a34f27")); + + HMAC_TEST(sha384, SHA384_DIGEST_SIZE, + HL("0102030405060708090a0b0c0d0e0f10" + "111213141516171819"), + HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcd"), + H("3e8a69b7783c25851933ab6290af6ca7" + "7a9981480850009cc5577c6e1f573b4e" + "6801dd23c4a7d679ccf8a386c674cffb")); + + HMAC_TEST(sha384, 16, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"), + LDATA("Test With Truncation"), + H("3abf34c3503b2a23a46efc619baef897")); + + HMAC_TEST(sha384, SHA384_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("4ece084485813e9088d2c63a041bc5b4" + "4f9ef1012a2b588f3cd11f05033ac4c6" + "0c2ef6ab4030fe8296248df163f44952")); + + HMAC_TEST(sha384, SHA384_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("This is a test using a larger than block-size ke" + "y and a larger than block-size data. The key nee" + "ds to be hashed before being used by the HMAC al" + "gorithm."), + H("6617178e941f020d351e2f254e8fd32c" + "602420feb0b8fb9adccebb82461e99c5" + "a678cc31e799176d3860e6110c46523e")); + + /* Test vectors for sha512, from RFC 4231 */ + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b"), + LDATA("Hi There"), + H("87aa7cdea5ef619d4ff0b4241a1d6cb0" + "2379f4e2ce4ec2787ad0b30545e17cde" + "daa833b7d6b8a702038b274eaea3f4e4" + "be9d914eeb61f1702e696c203a126854")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("Jefe"), + LDATA("what do ya want for nothing?"), + H("164b7a7bfcf819e2e395fbe73b56e0a3" + "87bd64222e831fd610270cd7ea250554" + "9758bf75c05a994a6d034f65f8f0e6fd" + "caeab1a34d4a6b4b636e070a38bce737")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaa"), + HL("dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd"), + H("fa73b0089d56a284efb0f0756c890be9" + "b1b5dbdd8ee81a3655f83e33b2279d39" + "bf3e848279a722c806b485a47e67c807" + "b946a337bee8942674278859e13292fb")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("0102030405060708090a0b0c0d0e0f10" + "111213141516171819"), + HL("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcd"), + H("b0ba465637458c6990e5a8c5f61d4af7" + "e576d97ff94b872de76f8050361ee3db" + "a91ca5c11aa25eb4d679275cc5788063" + "a5f19741120c4f2de2adebeb10a298dd")); + + HMAC_TEST(sha512, 16, + HL("0c0c0c0c0c0c0c0c 0c0c0c0c0c0c0c0c 0c0c0c0c"), + LDATA("Test With Truncation"), + H("415fad6271580a531d4179bc891d87a6")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("Test Using Larger Than Block-Size Key - Hash Key First"), + H("80b24263c7c1a3ebb71493c1dd7be8b4" + "9b46d1f41b4aeec1121b013783f8f352" + "6b56d037e05f2598bd0fd2215d6a1e52" + "95e64f73f63f0aec8b915a985d786598")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa"), + LDATA("This is a test using a larger than block-size ke" + "y and a larger than block-size data. The key nee" + "ds to be hashed before being used by the HMAC al" + "gorithm."), + H("e37b6a775dc87dbaa4dfa9f96e5e3ffd" + "debd71f8867289865df5a32d20cdc944" + "b6022cac3c4982b10d5eeb55c3e4de15" + "134676fb6de0446065c97440fa8c6a58")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA(""), + H("34316413c2d6940572d0bbbf099d529d" + "148b424533cf562bc1b365f530e21a31" + "799fc51cef78060cc6f448a8e5d780c2" + "6cdf20d4c3e6f27fe5ef576bbd05e855")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("a"), + H("cf1948507378bc3ab58cb6ec87f4d456" + "b90d3298395c29873f1ded1e111b50fe" + "c336ed24684bf19716efc309212f37aa" + "715cfb9ecccf3af13691ded167b4b336")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("38"), + H("b8201784216ce01b83cdd282616c6e89" + "644c6dfd1269ed8580bbc39b92add364" + "c2b2a2018cffb1915e8625e473b67d0f" + "e54a50e475dfa0e2b1a97bac1383792c")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abc"), + H("f097ee08b8c44e847a384f9fd645e35e" + "4816baa9791ba39d3dc611210500b044" + "873ee296bf1047dc06daa201a5767192" + "5b73b4ea59c60114881c8287d0699c83")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("message digest"), + H("921a441a884b83c76a8526da8e60d60d" + "17ded4eee5c29375e0d93717669a4c3e" + "eba7473e95f7c1a2a85afc24a0adbc4d" + "6c2bdd6ca6cab8b18d19f82d4a6c51bc")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("abcdefghijklmnopqrstuvwxyz"), + H("640054c96f35815095617d0a8c956066" + "1a6ff46bfb39110333b2c52c8866abfb" + "59d9152c9b0948c1ed65c3fd72a8fb82" + "190acc8830770afe5b0c5b6414c75a77")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), + H("835a4f5b3750b4c1fccfa88da2f746a4" + "900160c9f18964309bb736c13b59491b" + "8e32d37b724cc5aebb0f554c6338a3b5" + "94c4ba26862b2dadb59b7ede1d08d53e")); + + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("monkey monkey monkey monkey"), + LDATA("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), + H("fdf83dc879e3476c8e8aceff2bf6fece" + "2e4f39c7e1a167845465bb549dfa5ffe" + "997e6c7cf3720eae51ed2b00ad2a8225" + "375092290edfa9d48ec7e4bc8e276088")); + + /* Additional test vectors, from + draft-kelly-ipsec-ciph-sha2-01.txt */ + + /* Test case AUTH512-1: */ + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), + LDATA("Hi There"), + H("637edc6e01dce7e6742a99451aae82df" + "23da3e92439e590e43e761b33e910fb8" + "ac2878ebd5803f6f0b61dbce5e251ff8" + "789a4722c1be65aea45fd464e89f8f5b")); + + /* Test case AUTH512-2: */ + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + LDATA("JefeJefeJefeJefe" + "JefeJefeJefeJefe" + "JefeJefeJefeJefe" + "JefeJefeJefeJefe"), + LDATA("what do ya want for nothing?"), + H("cb370917ae8a7ce28cfd1d8f4705d614" + "1c173b2a9362c15df235dfb251b15454" + "6aa334ae9fb9afc2184932d8695e397b" + "fa0ffb93466cfcceaae38c833b7dba38")); + + /* Test case AUTH512-3: */ + HMAC_TEST(sha512, SHA512_DIGEST_SIZE, + HL("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + HL("dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd"), + H("2ee7acd783624ca9398710f3ee05ae41" + "b9f9b0510c87e49e586cc9bf961733d8" + "623c7b55cebefccf02d5581acc1c9d5f" + "b1ff68a1de45509fbe4da9a433922655")); + + /* Test case AUTH512-3 from same document seems broken. */ + + SUCCESS(); +} diff --git a/testsuite/knuth-lfib-test.c b/testsuite/knuth-lfib-test.c new file mode 100644 index 0000000..218894f --- /dev/null +++ b/testsuite/knuth-lfib-test.c @@ -0,0 +1,22 @@ +#include "testutils.h" +#include "knuth-lfib.h" + +int +test_main(void) +{ + struct knuth_lfib_ctx ctx; + + uint32_t a[2009]; + uint32_t x; + unsigned m; + + knuth_lfib_init(&ctx, 310952); + for (m = 0; m<2009; m++) + knuth_lfib_get_array(&ctx, 1009, a); + + x = knuth_lfib_get(&ctx); + if (x != 461390032) + FAIL(); + + SUCCESS(); +} diff --git a/testsuite/md2-test.c b/testsuite/md2-test.c new file mode 100644 index 0000000..8ab45c1 --- /dev/null +++ b/testsuite/md2-test.c @@ -0,0 +1,27 @@ +#include "testutils.h" +#include "md2.h" + +int +test_main(void) +{ + /* Testcases from RFC 1319 */ + test_hash(&nettle_md2, 0, "", + H("8350e5a3e24c153df2275c9f80692773")); + test_hash(&nettle_md2, LDATA("a"), + H("32ec01ec4a6dac72c0ab96fb34c0b5d1")); + test_hash(&nettle_md2, LDATA("abc"), + H("da853b0d3f88d99b30283a69e6ded6bb")); + test_hash(&nettle_md2, LDATA("message digest"), + H("ab4f496bfb2a530b219ff33031fe06b0")); + test_hash(&nettle_md2, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("4e8ddff3650292ab5a4108c3aa47940b")); + test_hash(&nettle_md2, + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789"), + H("da33def2a42df13975352846c30338cd")); + test_hash(&nettle_md2, LDATA("1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890"), + H("d5976f79d83d3a0dc9806c3c66f3efd8")); + + SUCCESS(); +} diff --git a/testsuite/md4-test.c b/testsuite/md4-test.c new file mode 100644 index 0000000..208456d --- /dev/null +++ b/testsuite/md4-test.c @@ -0,0 +1,38 @@ +#include "testutils.h" +#include "md4.h" + +int +test_main(void) +{ + /* Testcases from RFC 1320 */ + test_hash(&nettle_md4, LDATA(""), + H("31d6cfe0d16ae931b73c59d7e0c089c0")); + test_hash(&nettle_md4, LDATA("a"), + H("bde52cb31de33e46245e05fbdbd6fb24")); + test_hash(&nettle_md4, LDATA("abc"), + H("a448017aaf21d8525fc10ae87aa6729d")); + test_hash(&nettle_md4, LDATA("message digest"), + H("d9130a8164549fe818874806e1c7014b")); + test_hash(&nettle_md4, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("d79e1c308aa5bbcdeea8ed63df412da9")); + test_hash(&nettle_md4, + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789"), + H("043f8582f241db351ce627e153e7f0e4")); + test_hash(&nettle_md4, + LDATA("12345678901234567890123456789012345678901234567890" + "123456789012345678901234567890"), + H("e33b4ddc9c38f2199c3e7b164fcc0536")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + test_hash(&nettle_md4, LDATA("38"), + H("ae9c7ebfb68ea795483d270f5934b71d")); + test_hash(&nettle_md4, LDATA("abc"), + H("a448017aaf21d8525fc10ae87aa6729d")); + test_hash(&nettle_md4, LDATA("message digest"), + H("d9130a8164549fe818874806e1c7014b")); + test_hash(&nettle_md4, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("d79e1c308aa5bbcdeea8ed63df412da9")); + + SUCCESS(); +} diff --git a/testsuite/md5-compat-test.c b/testsuite/md5-compat-test.c new file mode 100644 index 0000000..bffb623 --- /dev/null +++ b/testsuite/md5-compat-test.c @@ -0,0 +1,60 @@ +#include "testutils.h" +#include "md5-compat.h" + +int +test_main(void) +{ + MD5_CTX ctx; + unsigned char digest[MD5_DIGEST_SIZE]; + + MD5Init(&ctx); + MD5Final(digest, &ctx); + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("D41D8CD98F00B204 E9800998ECF8427E"))) + FAIL(); + + MD5Init(&ctx); + MD5Update(&ctx, "a", 1); + MD5Final(digest, &ctx); + + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("0CC175B9C0F1B6A8 31C399E269772661"))) + FAIL(); + + MD5Init(&ctx); + MD5Update(&ctx, "abc", 3); + MD5Final(digest, &ctx); + + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("900150983cd24fb0 D6963F7D28E17F72"))) + FAIL(); + + MD5Init(&ctx); + MD5Update(&ctx, "message digest", 14); + MD5Final(digest, &ctx); + + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("F96B697D7CB7938D 525A2F31AAF161D0"))) + FAIL(); + + MD5Init(&ctx); + MD5Update(&ctx, "abcdefghijklmnopqrstuvwxyz", 26); + MD5Final(digest, &ctx); + + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("C3FCD3D76192E400 7DFB496CCA67E13B"))) + FAIL(); + + MD5Init(&ctx); + MD5Update(&ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62); + MD5Final(digest, &ctx); + + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("D174AB98D277D9F5 A5611C2C9F419D9F"))) + FAIL(); + + MD5Init(&ctx); + MD5Update(&ctx, "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + 80); + MD5Final(digest, &ctx); + + if (!MEMEQ(MD5_DIGEST_SIZE, digest, H("57EDF4A22BE3C955 AC49DA2E2107B67A"))) + FAIL(); + + SUCCESS(); +} diff --git a/testsuite/md5-test.c b/testsuite/md5-test.c new file mode 100644 index 0000000..995f304 --- /dev/null +++ b/testsuite/md5-test.c @@ -0,0 +1,120 @@ +#include "testutils.h" +#include "md5.h" + +int +test_main(void) +{ + test_hash(&nettle_md5, 0, "", + H("D41D8CD98F00B204 E9800998ECF8427E")); + + test_hash(&nettle_md5, 1, "a", + H("0CC175B9C0F1B6A8 31C399E269772661")); + + test_hash(&nettle_md5, 3, "abc", + H("900150983cd24fb0 D6963F7D28E17F72")); + + test_hash(&nettle_md5, 14, "message digest", + H("F96B697D7CB7938D 525A2F31AAF161D0")); + + test_hash(&nettle_md5, 26, "abcdefghijklmnopqrstuvwxyz", + H("C3FCD3D76192E400 7DFB496CCA67E13B")); + + test_hash(&nettle_md5, 62, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789", + H("D174AB98D277D9F5 A5611C2C9F419D9F")); + + test_hash(&nettle_md5, 80, + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + H("57EDF4A22BE3C955 AC49DA2E2107B67A")); + + /* Additional test vector, from Daniel Kahn Gillmor */ + test_hash(&nettle_md5, LDATA("38"), + H("a5771bce93e200c3 6f7cd9dfd0e5deaa")); + + /* Collisions, reported by Xiaoyun Wang1, Dengguo Feng2, Xuejia + Lai3, Hongbo Yu1, http://eprint.iacr.org/2004/199. */ + +#define M0 \ + /* vv */ \ + "d131dd02 c5e6eec4 693d9a06 98aff95c 2fcab5 87 12467eab 4004583e b8fb7f89" \ + "55ad3406 09f4b302 83e48883 25 71 415a 085125e8 f7cdc99f d91dbd f2 80373c5b" \ + /* ^^ ^^ */ + +#define M1 \ + /* vv */ \ + "d131dd02 c5e6eec4 693d9a06 98aff95c 2fcab5 07 12467eab 4004583e b8fb7f89" \ + "55ad3406 09f4b302 83e48883 25 f1 415a 085125e8 f7cdc99f d91dbd 72 80373c5b" \ + /* ^^ ^^ */ + +#define N0 \ + /* vv */ \ + "960b1dd1 dc417b9c e4d897f4 5a6555d5 35739a c7 f0ebfd0c 3029f166 d109b18f" \ + "75277f79 30d55ceb 22e8adba 79 cc 155c ed74cbdd 5fc5d36d b19b0a d8 35cca7e3" \ + /* ^^ ^^ */ + +#define N1 \ + /* vv */ \ + "960b1dd1 dc417b9c e4d897f4 5a6555d5 35739a 47 f0ebfd0c 3029f166 d109b18f" \ + "75277f79 30d55ceb 22e8adba 79 4c 155c ed74cbdd 5fc5d36d b19b0a 58 35cca7e3" \ + /* ^^ ^^ */ + + /* Note: The checksum in the paper, 1f160396 efc71ff4 bcff659f + bf9d0fa3, is incorrect. */ + +#define H0 "a4c0d35c 95a63a80 5915367d cfe6b751" + +#define N2 \ + /* vv */ \ + "d8823e31 56348f5b ae6dacd4 36c919c6 dd53e2 b4 87da03fd 02396306 d248cda0" \ + "e99f3342 0f577ee8 ce54b670 80 a8 0d1e c69821bc b6a88393 96f965 2b 6ff72a70" \ + /* ^^ ^^ */ + +#define N3 \ + /* vv */ \ + "d8823e31 56348f5b ae6dacd4 36c919c6 dd53e2 34 87da03fd 02396306 d248cda0" \ + "e99f3342 0f577ee8 ce54b670 80 28 0d1e c69821bc b6a88393 96f965 ab 6ff72a70" \ + /* ^^ ^^ */ + + /* Note: Also different from the checksum in the paper */ + +#define H1 "79054025 255fb1a2 6e4bc422 aef54eb4" + + test_hash(&nettle_md5, + HL(M0 N0), H(H0)); + + test_hash(&nettle_md5, + HL(M1 N1), H(H0)); + + test_hash(&nettle_md5, + HL(M0 N2), H(H1)); + + test_hash(&nettle_md5, + HL(M1 N3), H(H1)); + + SUCCESS(); +} + +/* Intermediate values for the single _nettle_md5_compress call for + the first test case. Each row gives the values for a, b, c, d after + the i:th round. The row i = -1 gives the initial values, and i = 99 + gives the output values. + + i a b c d + -1: 67452301 efcdab89 98badcfe 10325476 + 0: a5202774 efcdab89 98badcfe 10325476 + 1: a5202774 efcdab89 98badcfe f59592dd + 15: f56c7cf1 d6819c6a 5aa53f75 374943a7 + 16: 1c7d7513 d6819c6a 5aa53f75 374943a7 + 17: 1c7d7513 d6819c6a 5aa53f75 7bd57a3a + 31: 13707036 a2205f1f 1c31c384 ae7813db + 32: df63eaa1 a2205f1f 1c31c384 ae7813db + 33: df63eaa1 a2205f1f 1c31c384 c3689f5b + 47: 3f55edfd ca7d2dbd 68d84ea2 22a31f54 + 48: 93aa2577 ca7d2dbd 68d84ea2 22a31f54 + 49: 93aa2577 ca7d2dbd 68d84ea2 1688dc85 + 63: 7246fad3 14e45506 ff4ea3eb 6e10a476 + 99: d98c1dd4 4b2008f 980980e9 7e42f8ec +*/ diff --git a/testsuite/pkcs1-conv-test b/testsuite/pkcs1-conv-test new file mode 100755 index 0000000..e1ce3db --- /dev/null +++ b/testsuite/pkcs1-conv-test @@ -0,0 +1,51 @@ +#! /bin/sh + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +[ -x ../tools/pkcs1-conv ] || exit 77 + +# Private RSA key, generated by openssl +../tools/pkcs1-conv >testkey.priv <testkey.pub <testsignature < testsignature2 <&2 'Unknown option `'"$1'" + exit 1 + ;; + *) + break + ;; + esac + shift +done + +if [ $# -eq 0 ] ; then + for f in *-test; do test_program "./$f"; done +else + for f in "$@" ; do test_program `find_program "$f"`; done +fi + +if [ $failed -eq 0 ] ; then + banner="All $all tests passed" +else + banner="$failed of $all tests failed" +fi +dashes=`echo "$banner" | sed s/./=/g` +echo "$dashes" +echo "$banner" +echo "$dashes" + +if [ "x$debug" = xno ] ; then + env_program `find_program teardown-env` +fi + +[ "$failed" -eq 0 ] + diff --git a/testsuite/serpent-test.c b/testsuite/serpent-test.c new file mode 100644 index 0000000..b1101ea --- /dev/null +++ b/testsuite/serpent-test.c @@ -0,0 +1,57 @@ +#include "testutils.h" +#include "serpent.h" + +int +test_main(void) +{ + /* The first test for each key size from the ecb_vk.txt and ecb_vt.txt + * files in the serpent package. */ + + /* 128 bit key */ + + /* vk, 1 */ + test_cipher(&nettle_serpent128, + HL("8000000000000000 0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("49AFBFAD9D5A3405 2CD8FFA5986BD2DD")); + + /* vt, 1 */ + test_cipher(&nettle_serpent128, + HL("0000000000000000 0000000000000000"), + HL("8000000000000000 0000000000000000"), + H("10B5FFB720B8CB90 02A1142B0BA2E94A")); + + /* 192 bit key */ + + /* vk, 1 */ + test_cipher(&nettle_serpent192, + HL("8000000000000000 0000000000000000" + "0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("E78E5402C7195568 AC3678F7A3F60C66")); + + /* vt, 1 */ + test_cipher(&nettle_serpent192, + HL("0000000000000000 0000000000000000" + "0000000000000000"), + HL("8000000000000000 0000000000000000"), + H("B10B271BA25257E1 294F2B51F076D0D9")); + + /* 256 bit key */ + + /* vk, 1 */ + test_cipher(&nettle_serpent256, + HL("8000000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("ABED96E766BF28CB C0EBD21A82EF0819")); + + /* vt, 1 */ + test_cipher(&nettle_serpent256, + HL("0000000000000000 0000000000000000" + "0000000000000000 0000000000000000"), + HL("8000000000000000 0000000000000000"), + H("DA5A7992B1B4AE6F 8C004BC8A7DE5520")); + + SUCCESS(); +} diff --git a/testsuite/sexp-conv-test b/testsuite/sexp-conv-test new file mode 100755 index 0000000..a3470ab --- /dev/null +++ b/testsuite/sexp-conv-test @@ -0,0 +1,124 @@ +#! /bin/sh + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +print_raw () { + printf "%s" "$1" > "$2" +} + +print_nl () { + printf "%s\n" "$1" > "$2" +} + +test_advanced () { + print_raw "$1" test.in + if ../tools/sexp-conv -s advanced test1.out ; then + true + else + exit 1 + fi + print_nl "$2" test2.out + + if cmp test1.out test2.out ; then + true + else + exit 1; + fi +} + +test_advanced_hex () { + print_raw "$1" test.in + if ../tools/sexp-conv -s hex test1.out ; then + true + else + exit 1 + fi + print_nl "$2" test2.out + + if cmp test1.out test2.out ; then + true + else + exit 1; + fi +} + +test_transport () { + print_raw "$1" test.in + if ../tools/sexp-conv -s transport test1.out ; then + true + else + exit 1 + fi + print_nl "$2" test2.out + + if cmp test1.out test2.out ; then + true + else + exit 1; + fi +} + +test_canonical () { + print_raw "$1" test.in + if ../tools/sexp-conv -s canonical test1.out ; then + true + else + exit 1 + fi + print_raw "$2" test2.out + + if cmp test1.out test2.out ; then + true + else + exit 1; + fi +} + +test_advanced '0:' '""' +test_advanced '3:foo' 'foo' +test_advanced '12:fooooooooooo' 'fooooooooooo' +test_advanced '10:fooooooooo' 'fooooooooo' +test_advanced '4:3des' '"3des"' +test_advanced '"foo"' 'foo' +test_advanced '4:foo +' '"foo\n"' +# Having the string end with a \ breaks with sysv echo. \x seems harmless. +test_advanced '3:"\x' '"\"\\x"' +test_advanced '()' '()' +test_advanced '(foo bar baz)' '(foo bar + baz)' +test_advanced '; comment +()' '; comment +()' +test_advanced '(foo ; gazonk +bar)' '(foo ; gazonk + bar)' + +test_advanced '(foo[bar]foo)' '(foo [bar]foo)' + +test_advanced '(#aabb#)' '(|qrs=|)' +test_advanced '(|qrs=|)' '(|qrs=|)' +test_advanced_hex '(|qrs=|)' '(#aabb#)' +test_advanced_hex '(#aabb#)' '(#aabb#)' +test_advanced_hex '{MToR}' '#11#' +test_advanced_hex '|EQ==|' '#11#' + +test_transport '0:' '{MDo=}' +test_transport '()' '{KCk=}' +test_transport '1:A' '{MTpB}' +test_transport 'foo' '{Mzpmb28=}' +test_transport '(foo bar baz)' '{KDM6Zm9vMzpiYXIzOmJheik=}' + +test_canonical '""' '0:' +test_canonical '{MDo=}' '0:' +test_canonical '{KCk=}' '()' +test_canonical '{MTpB}' '1:A' +test_canonical 'foo' '3:foo' +test_canonical 'fooooooooooo' '12:fooooooooooo' +test_canonical 'fooooooooo' '10:fooooooooo' +test_canonical '(foo bar baz)' '(3:foo3:bar3:baz)' +test_canonical '{KDM6Zm9vMzpiYXIzOmJheik=}' '(3:foo3:bar3:baz)' + +exit 0 diff --git a/testsuite/sexp-format-test.c b/testsuite/sexp-format-test.c new file mode 100644 index 0000000..33c585f --- /dev/null +++ b/testsuite/sexp-format-test.c @@ -0,0 +1,160 @@ +#include "testutils.h" +#include "sexp.h" + +#include "buffer.h" + +#if HAVE_LIBGMP +# include "bignum.h" +#endif + +int +test_main(void) +{ + struct nettle_buffer buffer; + + { + const uint8_t e[] = "(3:foo(3:bar17:xxxxxxxxxxxxxxxxx))"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "(%0s(%0s%0s))", + "foo", "bar", "xxxxxxxxxxxxxxxxx") + == strlen(e)); + + ASSERT(sexp_format(NULL, "(%0s(%0s%0s))", + "foo", "bar", "xxxxxxxxxxxxxxxxx") + == strlen(e)); + + ASSERT(buffer.size == strlen(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + { + const uint8_t e[] = "{KDM6Zm9vKDM6YmFyMTc6eHh4eHh4eHh4eHh4eHh4eHgpKQ==}"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_transport_format(&buffer, "(%0s(%0s%0s))", + "foo", "bar", "xxxxxxxxxxxxxxxxx") + == strlen(e)); + + ASSERT(sexp_transport_format(NULL, "(%0s(%0s%0s))", + "foo", "bar", "xxxxxxxxxxxxxxxxx") + == strlen(e)); + + ASSERT(buffer.size == strlen(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + { + const uint8_t e[] = "1:\0""1:a2:bc3:def4:ghij5:\x00\xDE\xAD\xBE\xEF"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "%i%i%i%i%i%i", + 0, 0x61, 0x6263, 0x646566, 0x6768696a, 0xDEADBEEF) + == LLENGTH(e)); + + ASSERT(buffer.size == LLENGTH(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + + { + const uint8_t e[] = "(3:foo(4:bar))"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "(%0s%l)", + "foo", 7, "(4:bar)") + == strlen(e)); + + ASSERT(buffer.size == strlen(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + + { + const uint8_t e[] = "([1:t]3:foo3:bar[6:gazonk]3:baz1:q)"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "(%0t%0s%0s%0t%0s%0t%0s)", + "t", "foo", "bar", "gazonk", "baz", NULL, "q") + == strlen(e)); + + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + + /* Try literals */ + { + const uint8_t e[] = "(3:foo(3:bar17:xxxxxxxxxxxxxxxxx))"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "(%0s(bar%0s))", + "foo", "xxxxxxxxxxxxxxxxx") + == strlen(e)); + + ASSERT(sexp_format(NULL, "(%0s(bar %0s))", + "foo", "xxxxxxxxxxxxxxxxx") + == strlen(e)); + + ASSERT(buffer.size == strlen(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + { + const uint8_t e[] = "(3:foo(3:bar17:xxxxxxxxxxxxxxxxx))"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "(%0s(bar xxxxxxxxxxxxxxxxx))", + "foo") + == strlen(e)); + + ASSERT(sexp_format(NULL, "(%0s(bar xxxxxxxxxxxxxxxxx))", + "foo") + == strlen(e)); + + ASSERT(buffer.size == strlen(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + + /* Literal parenthesis */ + { + const uint8_t e[] = ")3:foo(3:bar"; + + nettle_buffer_init(&buffer); + ASSERT(sexp_format(&buffer, "%)foo%(%s", 3, "bar") + == strlen(e)); + + ASSERT(sexp_format(NULL, "%)foo%(%s", 3, "bar") + == strlen(e)); + + ASSERT(buffer.size == strlen(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + } + +#if HAVE_LIBGMP + { + mpz_t x; + mpz_t y; + mpz_t z; + + const uint8_t e[] = + "(3:foo(3:bar1:\xff""11:abcdefghijk13:\0\x81""abcdefghijk))"; + + nettle_buffer_clear(&buffer); + + mpz_init_set_si(x, -1); + nettle_mpz_init_set_str_256_u(y, 11, "abcdefghijk"); + nettle_mpz_init_set_str_256_u(z, 12, "\x81""abcdefghijk"); + nettle_buffer_init(&buffer); + + ASSERT(sexp_format(&buffer, "(%0s(%0s%b%b%b))", + "foo", "bar", x, y, z) + == LLENGTH(e)); + + ASSERT(sexp_format(NULL, "(%0s(%0s%b%b%b))", + "foo", "bar", x, y, z) + == LLENGTH(e)); + + ASSERT(buffer.size == LLENGTH(e)); + ASSERT(MEMEQ(buffer.size, buffer.contents, e)); + + nettle_buffer_clear(&buffer); + mpz_clear(x); + } +#endif /* HAVE_LIBGMP */ + + SUCCESS(); +} diff --git a/testsuite/sexp-test.c b/testsuite/sexp-test.c new file mode 100644 index 0000000..4e68f56 --- /dev/null +++ b/testsuite/sexp-test.c @@ -0,0 +1,99 @@ +#include "testutils.h" +#include "sexp.h" + +int +test_main(void) +{ + struct sexp_iterator i; + uint32_t x; + + ASSERT(sexp_iterator_first(&i, LDATA(""))); + ASSERT(i.type == SEXP_END); + + ASSERT(sexp_iterator_first(&i, LDATA("()"))); + ASSERT(i.type == SEXP_LIST + && sexp_iterator_enter_list(&i) + && i.type == SEXP_END + && sexp_iterator_exit_list(&i) + && i.type == SEXP_END); + + ASSERT(sexp_iterator_first(&i, LDATA("("))); + ASSERT(i.type == SEXP_LIST + && !sexp_iterator_enter_list(&i)); + + /* Check integers. */ + ASSERT(sexp_iterator_first(&i, LDATA("1:\0" + "1:\x11" + "2:\x00\x11" + "2:\x00\x80" + "5:\x00\xaa\xbb\xcc\xdd"))); + ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0); + ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11); + ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11); + ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x80); + ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0xaabbccdd); + + ASSERT(sexp_iterator_first(&i, LDATA("3:foo0:[3:bar]12:xxxxxxxxxxxx"))); + ASSERT(i.type == SEXP_ATOM + && !i.display_length && !i.display + && i.atom_length == 3 && MEMEQ(3, "foo", i.atom) + + && sexp_iterator_next(&i) && i.type == SEXP_ATOM + && !i.display_length && !i.display + && !i.atom_length && i.atom + + && sexp_iterator_next(&i) && i.type == SEXP_ATOM + && i.display_length == 3 && MEMEQ(3, "bar", i.display) + && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom) + + && sexp_iterator_next(&i) && i.type == SEXP_END); + + /* Same data, transport encoded. */ + + ASSERT(sexp_transport_iterator_first + (&i, LDUP("{Mzpmb28=} {MDo=} {WzM6YmFyXTEyOnh4eHh4eHh4eHh4eA==}"))); + ASSERT(i.type == SEXP_ATOM + && !i.display_length && !i.display + && i.atom_length == 3 && MEMEQ(3, "foo", i.atom) + + && sexp_iterator_next(&i) && i.type == SEXP_ATOM + && !i.display_length && !i.display + && !i.atom_length && i.atom + + && sexp_iterator_next(&i) && i.type == SEXP_ATOM + && i.display_length == 3 && MEMEQ(3, "bar", i.display) + && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom) + + && sexp_iterator_next(&i) && i.type == SEXP_END); + + { + static const uint8_t *keys[2] = { "n", "e" }; + struct sexp_iterator v[2]; + + ASSERT(sexp_iterator_first(&i, LDATA("((1:n2:xx3:foo)0:(1:y)(1:e))"))); + ASSERT(sexp_iterator_enter_list(&i) + && sexp_iterator_assoc(&i, 2, keys, v)); + + ASSERT(v[0].type == SEXP_ATOM + && !v[0].display_length && !v[0].display + && v[0].atom_length == 2 && MEMEQ(2, "xx", v[0].atom) + + && sexp_iterator_next(&v[0]) && v[0].type == SEXP_ATOM + && !v[0].display_length && !v[0].display + && v[0].atom_length == 3 && MEMEQ(3, "foo", v[0].atom) + + && sexp_iterator_next(&v[0]) && v[0].type == SEXP_END); + + ASSERT(v[1].type == SEXP_END); + + ASSERT(sexp_iterator_first(&i, LDATA("((1:n))"))); + ASSERT(sexp_iterator_enter_list(&i) + && !sexp_iterator_assoc(&i, 2, keys, v)); + + ASSERT(sexp_iterator_first(&i, LDATA("((1:n)(1:n3:foo))"))); + ASSERT(sexp_iterator_enter_list(&i) + && !sexp_iterator_assoc(&i, 2, keys, v)); + } + + SUCCESS(); +} diff --git a/testsuite/sexp2rsa-test.c b/testsuite/sexp2rsa-test.c new file mode 100644 index 0000000..2e7cd91 --- /dev/null +++ b/testsuite/sexp2rsa-test.c @@ -0,0 +1,46 @@ +#include "testutils.h" + +int +test_main(void) +{ + struct rsa_public_key pub; + struct rsa_private_key priv; + + rsa_public_key_init(&pub); + rsa_private_key_init(&priv); + + ASSERT(rsa_keypair_from_sexp + (&pub, &priv, 0, + HL("2831313a707269766174652d6b657928" + "333a72736128313a6e36333a085c3408" + "989acae4faec3cbbad91c90d34c1d259" + "cd74121a36f38b0b51424a9b2be514a0" + "4377113a6cdafe79dd7d5f2ecc8b5e96" + "61189b86a7b22239907c252928313a65" + "343a36ad4b1d2928313a6436333a06ee" + "6d4ff3c239e408150daf8117abfa36a4" + "0ad4455d9059a86d52f33a2de07418a0" + "a699594588c64810248c9412d554f74a" + "f947c73c32007e87c92f0937ed292831" + "3a7033323a03259879b24315e9cf1425" + "4824c7935d807cdb6990f414a0f65e60" + "65130a611f2928313a7133323a02a81b" + "a73bad45fc73b36deffce52d1b73e074" + "7f4d8a82648cecd310448ea63b292831" + "3a6133323a026cbdad5dd0046e093f06" + "0ecd5b4ac918e098b0278bb752b7cadd" + "6a8944f0b92928313a6233323a014875" + "1e622d6d58e3bb094afd6edacf737035" + "1d068e2ce9f565c5528c4a7473292831" + "3a6333323a00f8a458ea73a018dc6fa5" + "6863e3bc6de405f364f77dee6f096267" + "9ea1a8282e292929"))); + + test_rsa_key(&pub, &priv); + + rsa_public_key_clear(&pub); + rsa_private_key_clear(&priv); + + SUCCESS(); +} + diff --git a/testsuite/sha1-huge-test.c b/testsuite/sha1-huge-test.c new file mode 100644 index 0000000..4f1b4dc --- /dev/null +++ b/testsuite/sha1-huge-test.c @@ -0,0 +1,15 @@ +#include "testutils.h" +#include "sha.h" + +int +test_main(void) +{ + /* Hashes 10 000 000 x 30 000 bytes > 64 * 2^32. This overflows the + low word of the block counter. This test vector is not cross + checked with any other sha1 implementation. */ + test_hash_large(&nettle_sha1, 10000000, 30000, 'a', + H("0ba79364dc64648f 2074fb4bc5c28bcf" + "b7a787b0")); + + SUCCESS(); +} diff --git a/testsuite/sha1-test.c b/testsuite/sha1-test.c new file mode 100644 index 0000000..8319086 --- /dev/null +++ b/testsuite/sha1-test.c @@ -0,0 +1,67 @@ +#include "testutils.h" +#include "sha.h" + +int +test_main(void) +{ + test_hash(&nettle_sha1, 0, "", + H("DA39A3EE5E6B4B0D 3255BFEF95601890 AFD80709")); + + test_hash(&nettle_sha1, 1, "a", + H("86F7E437FAA5A7FC E15D1DDCB9EAEAEA 377667B8")); + + test_hash(&nettle_sha1, 3, "abc", + H("A9993E364706816A BA3E25717850C26C 9CD0D89D")); + + test_hash(&nettle_sha1, 26, "abcdefghijklmnopqrstuvwxyz", + H("32D10C7B8CF96570 CA04CE37F2A19D84 240D3A89")); + + test_hash(&nettle_sha1, 14, "message digest", + H("C12252CEDA8BE899 4D5FA0290A47231C 1D16AAE3")); + + test_hash(&nettle_sha1, 62, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789", + H("761C457BF73B14D2 7E9E9265C46F4B4D DA11F940")); + + test_hash(&nettle_sha1, 80, + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + H("50ABF5706A150990 A08B2C5EA40FA0E5 85554732")); + + /* Additional test vector, from Daniel Kahn Gillmor */ + test_hash(&nettle_sha1, LDATA("38"), + H("5b384ce32d8cdef02bc3a139d4cac0a22bb029e8")); + + SUCCESS(); +} + +/* These are intermediate values for the single sha1_compress call + that results from the first testcase, SHA1(""). Each row is the + values for A, B, C, D, E after the i:th round. The row i = -1 gives + the initial values, and i = 99 gives the output values. + + i A B C D E + -1: 67452301 efcdab89 98badcfe 10325476 c3d2e1f0 + 0: 67452301 7bf36ae2 98badcfe 10325476 1fb498b3 + 1: 59d148c0 7bf36ae2 98badcfe 5d43e370 1fb498b3 + 15: 40182905 4544b22e a13017ac ab703832 d8fd6547 + 16: 50060a41 4544b22e a13017ac 6bf9173 d8fd6547 + 17: 50060a41 4544b22e 28a9520e 6bf9173 f63f5951 + 18: 50060a41 b3088dd 28a9520e c1afe45c f63f5951 + 19: e758e8da b3088dd 8a2a5483 c1afe45c f63f5951 + 20: e758e8da 42cc2237 8a2a5483 c1afe45c 90eb9850 + 21: b9d63a36 42cc2237 8a2a5483 7dbb787d 90eb9850 + 38: e47bc31 62273351 b201788b 413c1d9a 2aeeae62 + 39: 9bdbdd71 62273351 ec805e22 413c1d9a 2aeeae62 + 40: 9bdbdd71 5889ccd4 ec805e22 413c1d9a 95aa398b + 41: 66f6f75c 5889ccd4 ec805e22 5e28e858 95aa398b + 58: 2164303a 982bcbca e1afab22 c5a3382e af9292fa + 59: 9b9d2913 982bcbca b86beac8 c5a3382e af9292fa + 60: 9b9d2913 a60af2f2 b86beac8 c5a3382e d37db937 + 61: e6e74a44 a60af2f2 b86beac8 85b9d227 d37db937 + 78: c57a6345 6e9d9f84 666b8bc6 852dc41a ec052519 + 79: 72f480ed 6e9d9f84 999ae2f1 852dc41a ec052519 + 99: da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709 + +*/ diff --git a/testsuite/sha224-test.c b/testsuite/sha224-test.c new file mode 100644 index 0000000..cef82af --- /dev/null +++ b/testsuite/sha224-test.c @@ -0,0 +1,48 @@ +#include "testutils.h" +#include "sha.h" + +int +test_main(void) +{ + /* From FIPS180-2 addendum + (http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf) */ + test_hash(&nettle_sha224, 3, "abc", + H("23097d22 3405d822 8642a477 bda255b3" + "2aadbce4 bda0b3f7 e36c9da7")); + + test_hash(&nettle_sha224, 56, + "abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq", + H("75388b16 512776cc 5dba5da1 fd890150" + "b0c6455c b4f58b19 52522525")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + test_hash(&nettle_sha224, LDATA(""), + H("d14a028c2a3a2bc9 476102bb288234c4" + "15a2b01f828ea62a c5b3e42f")); + test_hash(&nettle_sha224, LDATA("a"), + H("abd37534c7d9a2ef b9465de931cd7055" + "ffdb8879563ae980 78d6d6d5")); + test_hash(&nettle_sha224, LDATA("38"), + H("4cfca6da32da6471 98225460722b7ea1" + "284f98c4b179e8db ae3f93d5")); + test_hash(&nettle_sha224, LDATA("message digest"), + H("2cb21c83ae2f004d e7e81c3c7019cbcb" + "65b71ab656b22d6d 0c39b8eb")); + test_hash(&nettle_sha224, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("45a5f72c39c5cff2 522eb3429799e49e" + "5f44b356ef926bcf 390dccc2")); + test_hash(&nettle_sha224, + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" + "ghijklmnopqrstuvwxyz0123456789"), + H("bff72b4fcb7d75e5 632900ac5f90d219" + "e05e97a7bde72e74 0db393d9")); + test_hash(&nettle_sha224, + LDATA("12345678901234567890123456789012" + "34567890123456789012345678901234" + "5678901234567890"), + H("b50aecbe4e9bb0b5 7bc5f3ae760a8e01" + "db24f203fb3cdcd1 3148046e")); + + SUCCESS(); +} diff --git a/testsuite/sha256-test.c b/testsuite/sha256-test.c new file mode 100644 index 0000000..7499521 --- /dev/null +++ b/testsuite/sha256-test.c @@ -0,0 +1,55 @@ +#include "testutils.h" +#include "sha.h" + +int +test_main(void) +{ + /* From FIPS180-2 */ + test_hash(&nettle_sha256, 3, "abc", + H("ba7816bf8f01cfea 414140de5dae2223" + "b00361a396177a9c b410ff61f20015ad")); + + test_hash(&nettle_sha256, 56, + "abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq", + H("248d6a61d20638b8 e5c026930c3e6039" + "a33ce45964ff2167 f6ecedd419db06c1")); + + test_hash(&nettle_sha256, 112, + "abcdefghbcdefghicdefghijdefg" + "hijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmn" + "opqrlmnopqrsmnopqrstnopqrstu", + H("cf5b16a778af8380 036ce59e7b049237" + "0b249b11e8f07a51 afac45037afee9d1")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + test_hash(&nettle_sha256, LDATA(""), + H("e3b0c44298fc1c14 9afbf4c8996fb924" + "27ae41e4649b934c a495991b7852b855")); + test_hash(&nettle_sha256, LDATA("a"), + H("ca978112ca1bbdca fac231b39a23dc4d" + "a786eff8147c4e72 b9807785afee48bb")); + test_hash(&nettle_sha256, LDATA("38"), + H("aea92132c4cbeb26 3e6ac2bf6c183b5d" + "81737f179f21efdc 5863739672f0f470")); + test_hash(&nettle_sha256, LDATA("message digest"), + H("f7846f55cf23e14e ebeab5b4e1550cad" + "5b509e3348fbc4ef a3a1413d393cb650")); + test_hash(&nettle_sha256, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("71c480df93d6ae2f 1efad1447c66c952" + "5e316218cf51fc8d 9ed832f2daf18b73")); + test_hash(&nettle_sha256, + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" + "ghijklmnopqrstuvwxyz0123456789"), + H("db4bfcbd4da0cd85 a60c3c37d3fbd880" + "5c77f15fc6b1fdfe 614ee0a7c8fdb4c0")); + test_hash(&nettle_sha256, + LDATA("12345678901234567890123456789012" + "34567890123456789012345678901234" + "5678901234567890"), + H("f371bc4a311f2b00 9eef952dd83ca80e" + "2b60026c8e935592 d0f9c308453c813e")); + + SUCCESS(); +} diff --git a/testsuite/sha384-test.c b/testsuite/sha384-test.c new file mode 100644 index 0000000..086e115 --- /dev/null +++ b/testsuite/sha384-test.c @@ -0,0 +1,57 @@ +#include "testutils.h" +#include "sha.h" + +int +test_main(void) +{ + test_hash(&nettle_sha384, 3, "abc", + H("cb00753f45a35e8b b5a03d699ac65007" + "272c32ab0eded163 1a8b605a43ff5bed" + "8086072ba1e7cc23 58baeca134c825a7")); + + test_hash(&nettle_sha384, 112, + "abcdefghbcdefghicdefghijdefg" + "hijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmn" + "opqrlmnopqrsmnopqrstnopqrstu", + H("09330c33f71147e8 3d192fc782cd1b47" + "53111b173b3b05d2 2fa08086e3b0f712" + "fcc7c71a557e2db9 66c3e9fa91746039")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + test_hash(&nettle_sha384, LDATA(""), + H("38b060a751ac9638 4cd9327eb1b1e36a" + "21fdb71114be0743 4c0cc7bf63f6e1da" + "274edebfe76f65fb d51ad2f14898b95b")); + test_hash(&nettle_sha384, LDATA("a"), + H("54a59b9f22b0b808 80d8427e548b7c23" + "abd873486e1f035d ce9cd697e8517503" + "3caa88e6d57bc35e fae0b5afd3145f31")); + test_hash(&nettle_sha384, LDATA("38"), + H("c071d202ad950b6a 04a5f15c24596a99" + "3af8b212467958d5 70a3ffd478006063" + "8e3a3d06637691d3 012bd31122071b2c")); + test_hash(&nettle_sha384, LDATA("message digest"), + H("473ed35167ec1f5d 8e550368a3db39be" + "54639f828868e945 4c239fc8b52e3c61" + "dbd0d8b4de1390c2 56dcbb5d5fd99cd5")); + test_hash(&nettle_sha384, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("feb67349df3db6f5 924815d6c3dc133f" + "091809213731fe5c 7b5f4999e463479f" + "f2877f5f2936fa63 bb43784b12f3ebb4")); + test_hash(&nettle_sha384, + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" + "ghijklmnopqrstuvwxyz0123456789"), + H("1761336e3f7cbfe5 1deb137f026f89e0" + "1a448e3b1fafa640 39c1464ee8732f11" + "a5341a6f41e0c202 294736ed64db1a84")); + test_hash(&nettle_sha384, + LDATA("12345678901234567890123456789012" + "34567890123456789012345678901234" + "5678901234567890"), + H("b12932b0627d1c06 0942f54477641556" + "55bd4da0c9afa6dd 9b9ef53129af1b8f" + "b0195996d2de9ca0 df9d821ffee67026")); + + SUCCESS(); +} diff --git a/testsuite/sha512-test.c b/testsuite/sha512-test.c new file mode 100644 index 0000000..97bde53 --- /dev/null +++ b/testsuite/sha512-test.c @@ -0,0 +1,66 @@ +#include "testutils.h" +#include "sha.h" + +int +test_main(void) +{ + test_hash(&nettle_sha512, 3, "abc", + H("ddaf35a193617aba cc417349ae204131" + "12e6fa4e89a97ea2 0a9eeee64b55d39a" + "2192992a274fc1a8 36ba3c23a3feebbd" + "454d4423643ce80e 2a9ac94fa54ca49f")); + + test_hash(&nettle_sha512, 112, + "abcdefghbcdefghicdefghijdefg" + "hijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmn" + "opqrlmnopqrsmnopqrstnopqrstu", + H("8e959b75dae313da 8cf4f72814fc143f" + "8f7779c6eb9f7fa1 7299aeadb6889018" + "501d289e4900f7e4 331b99dec4b5433a" + "c7d329eeb6dd2654 5e96e55b874be909")); + + /* Additional test vectors, from Daniel Kahn Gillmor */ + test_hash(&nettle_sha512, LDATA(""), + H("cf83e1357eefb8bd f1542850d66d8007" + "d620e4050b5715dc 83f4a921d36ce9ce" + "47d0d13c5d85f2b0 ff8318d2877eec2f" + "63b931bd47417a81 a538327af927da3e")); + test_hash(&nettle_sha512, LDATA("a"), + H("1f40fc92da241694 750979ee6cf582f2" + "d5d7d28e18335de0 5abc54d0560e0f53" + "02860c652bf08d56 0252aa5e74210546" + "f369fbbbce8c12cf c7957b2652fe9a75")); + test_hash(&nettle_sha512, LDATA("38"), + H("caae34a5e8103126 8bcdaf6f1d8c04d3" + "7b7f2c349afb705b 575966f63e2ebf0f" + "d910c3b05160ba08 7ab7af35d40b7c71" + "9c53cd8b947c9611 1f64105fd45cc1b2")); + test_hash(&nettle_sha512, LDATA("message digest"), + H("107dbf389d9e9f71 a3a95f6c055b9251" + "bc5268c2be16d6c1 3492ea45b0199f33" + "09e16455ab1e9611 8e8a905d5597b720" + "38ddb372a8982604 6de66687bb420e7c")); + test_hash(&nettle_sha512, LDATA("abcdefghijklmnopqrstuvwxyz"), + H("4dbff86cc2ca1bae 1e16468a05cb9881" + "c97f1753bce36190 34898faa1aabe429" + "955a1bf8ec483d74 21fe3c1646613a59" + "ed5441fb0f321389 f77f48a879c7b1f1")); + test_hash(&nettle_sha512, + LDATA("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" + "ghijklmnopqrstuvwxyz0123456789"), + H("1e07be23c26a86ea 37ea810c8ec78093" + "52515a970e9253c2 6f536cfc7a9996c4" + "5c8370583e0a78fa 4a90041d71a4ceab" + "7423f19c71b9d5a3 e01249f0bebd5894")); + test_hash(&nettle_sha512, + LDATA("12345678901234567890123456789012" + "34567890123456789012345678901234" + "5678901234567890"), + H("72ec1ef1124a45b0 47e8b7c75a932195" + "135bb61de24ec0d1 914042246e0aec3a" + "2354e093d76f3048 b456764346900cb1" + "30d2a4fd5dd16abb 5e30bcb850dee843")); + + SUCCESS(); +} diff --git a/testsuite/symbols-test b/testsuite/symbols-test new file mode 100755 index 0000000..b487126 --- /dev/null +++ b/testsuite/symbols-test @@ -0,0 +1,42 @@ +#! /bin/sh + +# Check that all exported symbols use the nettle prefix. + +if [ -z "$srcdir" ] ; then + srcdir=`pwd` +fi + +# FIXME: Check libhogweed.a too. + +# * nm on aix seems to generate bogus outbut including random binary +# data. Using -g is a workaround to get rid of that. But nm -g +# doesn't work on Solaris-2.4, so try nm -g first, and plain nm if +# -g isn't recognized. +# +# * gcc on x86 generates functions like __i686.get_pc_thunk.bx in pic +# code. + +( nm -g ../libnettle.a || nm ../libnettle.a ) \ + | grep ' [DRT] ' | egrep -v '( |^)\.?_?(_?nettle_|memxor)|get_pc_thunk' \ + | sort -k3 > test1.out + +if [ -s test1.out ] ; then + echo Exported symbols in libnettle.a, lacking the nettle prefix: + cat test1.out + exit 1 +fi + +if [ -s ../libhogweed.a ] ; then + ( nm -g ../libhogweed.a || nm ../libhogweed.a ) \ + | grep ' [DRT] ' | egrep -v '( |^)\.?_?_?nettle_|get_pc_thunk' \ + | sort -k3 > test1.out + + if [ -s test1.out ] ; then + echo Exported symbols in libhogweed.a, lacking the nettle prefix: + cat test1.out + exit 1 + fi +fi + +exit 0 + diff --git a/testsuite/teardown-env b/testsuite/teardown-env new file mode 100755 index 0000000..2c547ad --- /dev/null +++ b/testsuite/teardown-env @@ -0,0 +1,3 @@ +#! /bin/sh + +rm -rf testkey.priv testkey.pub testsignature testsignature2 diff --git a/testsuite/testutils.c b/testsuite/testutils.c new file mode 100644 index 0000000..eea8037 --- /dev/null +++ b/testsuite/testutils.c @@ -0,0 +1,961 @@ +/* testutils.c */ + +#include "testutils.h" + +#include "cbc.h" +#include "ctr.h" +#include "knuth-lfib.h" + +#include +#include +#include +#include + +/* -1 means invalid */ +static const signed char hex_digits[0x100] = + { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + +void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (size && !p) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + +unsigned +decode_hex_length(const char *h) +{ + const unsigned char *hex = (const unsigned char *) h; + unsigned count; + unsigned i; + + for (count = i = 0; hex[i]; i++) + { + if (isspace(hex[i])) + continue; + if (hex_digits[hex[i]] < 0) + abort(); + count++; + } + + if (count % 2) + abort(); + return count / 2; +} + +int +decode_hex(uint8_t *dst, const char *h) +{ + const unsigned char *hex = (const unsigned char *) h; + unsigned i = 0; + + for (;;) + { + int high, low; + + while (*hex && isspace(*hex)) + hex++; + + if (!*hex) + return 1; + + high = hex_digits[*hex++]; + if (high < 0) + return 0; + + while (*hex && isspace(*hex)) + hex++; + + if (!*hex) + return 0; + + low = hex_digits[*hex++]; + if (low < 0) + return 0; + + dst[i++] = (high << 4) | low; + } +} + +const uint8_t * +decode_hex_dup(const char *hex) +{ + uint8_t *p; + unsigned length = decode_hex_length(hex); + + p = xalloc(length); + + if (decode_hex(p, hex)) + return p; + else + { + free(p); + return NULL; + } +} + +void +print_hex(unsigned length, const uint8_t *data) +{ + unsigned i; + + for (i = 0; i < length; i++) + { + switch (i % 16) + { + default: + break; + case 0: + printf("\n"); + break; + case 8: + printf(" "); + break; + } + printf("%02x", data[i]); + } + printf("\n"); +} + +int verbose = 0; + +int +main(int argc, char **argv) +{ + if (argc > 1) + { + if (argc == 2 && !strcmp(argv[1], "-v")) + verbose = 1; + else + { + fprintf(stderr, "Invalid argument `%s', only accepted option is `-v'.\n", + argv[1]); + return 1; + } + } + + return test_main(); +} + +void +test_cipher(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext) +{ + void *ctx = xalloc(cipher->context_size); + uint8_t *data = xalloc(length); + + cipher->set_encrypt_key(ctx, key_length, key); + cipher->encrypt(ctx, length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + { + fprintf(stderr, "Encrypt failed:\nInput:"); + print_hex(length, cleartext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, ciphertext); + fprintf(stderr, "\n"); + FAIL(); + } + cipher->set_decrypt_key(ctx, key_length, key); + cipher->decrypt(ctx, length, data, data); + + if (!MEMEQ(length, data, cleartext)) + { + fprintf(stderr, "Decrypt failed:\nInput:"); + print_hex(length, ciphertext); + fprintf(stderr, "\nOutput: "); + print_hex(length, data); + fprintf(stderr, "\nExpected:"); + print_hex(length, cleartext); + fprintf(stderr, "\n"); + FAIL(); + } + + free(ctx); + free(data); +} + +void +test_cipher_cbc(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext, + const uint8_t *iiv) +{ + void *ctx = xalloc(cipher->context_size); + uint8_t *data = xalloc(length); + uint8_t *iv = xalloc(cipher->block_size); + + cipher->set_encrypt_key(ctx, key_length, key); + memcpy(iv, iiv, cipher->block_size); + + cbc_encrypt(ctx, cipher->encrypt, + cipher->block_size, iv, + length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + FAIL(); + + cipher->set_decrypt_key(ctx, key_length, key); + memcpy(iv, iiv, cipher->block_size); + + cbc_decrypt(ctx, cipher->decrypt, + cipher->block_size, iv, + length, data, data); + + if (!MEMEQ(length, data, cleartext)) + FAIL(); + + free(ctx); + free(data); + free(iv); +} + +void +test_cipher_ctr(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext, + const uint8_t *ictr) +{ + void *ctx = xalloc(cipher->context_size); + uint8_t *data = xalloc(length); + uint8_t *ctr = xalloc(cipher->block_size); + + cipher->set_encrypt_key(ctx, key_length, key); + memcpy(ctr, ictr, cipher->block_size); + + ctr_crypt(ctx, cipher->encrypt, + cipher->block_size, ctr, + length, data, cleartext); + + if (!MEMEQ(length, data, ciphertext)) + FAIL(); + + memcpy(ctr, ictr, cipher->block_size); + + ctr_crypt(ctx, cipher->encrypt, + cipher->block_size, ctr, + length, data, data); + + if (!MEMEQ(length, data, cleartext)) + FAIL(); + + free(ctx); + free(data); + free(ctr); +} + +void +test_cipher_stream(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext) +{ + unsigned block; + + void *ctx = xalloc(cipher->context_size); + uint8_t *data = xalloc(length + 1); + + for (block = 1; block <= length; block++) + { + unsigned i; + + memset(data, 0x17, length + 1); + cipher->set_encrypt_key(ctx, key_length, key); + + for (i = 0; i + block < length; i += block) + { + cipher->encrypt(ctx, block, data + i, cleartext + i); + if (data[i + block] != 0x17) + FAIL(); + } + cipher->encrypt(ctx, length - i, data + i, cleartext + i); + if (data[length] != 0x17) + FAIL(); + + if (!MEMEQ(length, data, ciphertext)) + FAIL(); + } + + cipher->set_decrypt_key(ctx, key_length, key); + cipher->decrypt(ctx, length, data, data); + + if (data[length] != 0x17) + FAIL(); + + if (!MEMEQ(length, data, cleartext)) + FAIL(); + + free(ctx); + free(data); +} + +void +test_hash(const struct nettle_hash *hash, + unsigned length, + const uint8_t *data, + const uint8_t *digest) +{ + void *ctx = xalloc(hash->context_size); + uint8_t *buffer = xalloc(hash->digest_size); + + hash->init(ctx); + hash->update(ctx, length, data); + hash->digest(ctx, hash->digest_size, buffer); + + if (!MEMEQ(hash->digest_size, digest, buffer)) + FAIL(); + + memset(buffer, 0, hash->digest_size); + + hash->init(ctx); + hash->update(ctx, length, data); + hash->digest(ctx, hash->digest_size - 1, buffer); + + if (!MEMEQ(hash->digest_size - 1, digest, buffer)) + FAIL(); + + if (buffer[hash->digest_size - 1]) + FAIL(); + + free(ctx); + free(buffer); +} + +void +test_hash_large(const struct nettle_hash *hash, + unsigned count, unsigned length, + uint8_t c, + const uint8_t *digest) +{ + void *ctx = xalloc(hash->context_size); + uint8_t *buffer = xalloc(hash->digest_size); + uint8_t *data = xalloc(length); + unsigned i; + + memset(data, c, length); + + hash->init(ctx); + for (i = 0; i < count; i++) + hash->update(ctx, length, data); + hash->digest(ctx, hash->digest_size, buffer); + + print_hex(hash->digest_size, buffer); + + if (!MEMEQ(hash->digest_size, digest, buffer)) + FAIL(); + + free(ctx); + free(buffer); + free(data); +} + +void +test_mac(const struct nettle_mac *mac, + unsigned key_length, const uint8_t *key, + unsigned msg_length, const uint8_t *msg, + const uint8_t *digest) +{ + void *ctx = xalloc(mac->context_size); + uint8_t *buffer = xalloc(mac->digest_size); + + mac->set_key(ctx, key_length, key); + mac->update(ctx, msg_length, msg); + mac->digest(ctx, mac->digest_size, buffer); + ASSERT(MEMEQ(mac->digest_size, digest, buffer)); + + free(ctx); + free(buffer); +} + +void +test_armor(const struct nettle_armor *armor, + unsigned data_length, + const uint8_t *data, + const uint8_t *ascii) +{ + unsigned ascii_length = strlen(ascii); + uint8_t *buffer = xalloc(1 + ascii_length); + uint8_t *check = xalloc(1 + armor->decode_length(ascii_length)); + void *encode = xalloc(armor->encode_context_size); + void *decode = xalloc(armor->decode_context_size); + unsigned done; + + ASSERT(ascii_length + <= (armor->encode_length(data_length) + armor->encode_final_length)); + ASSERT(data_length <= armor->decode_length(ascii_length)); + + memset(buffer, 0x33, 1 + ascii_length); + memset(check, 0x55, 1 + data_length); + + armor->encode_init(encode); + + done = armor->encode_update(encode, buffer, data_length, data); + done += armor->encode_final(encode, buffer + done); + ASSERT(done == ascii_length); + + if (!MEMEQ(ascii_length, buffer, ascii)) + FAIL(); + + if (0x33 != buffer[strlen(ascii)]) + FAIL(); + + armor->decode_init(decode); + done = armor->decode_length(ascii_length); + + ASSERT(armor->decode_update(decode, &done, check, ascii_length, buffer)); + ASSERT(done == data_length); + ASSERT(armor->decode_final(decode)); + + if (!MEMEQ(data_length, check, data)) + FAIL(); + + if (0x55 != check[data_length]) + FAIL(); + + free(buffer); + free(check); + free(encode); + free(decode); +} + +#if HAVE_LIBGMP +/* Missing in current gmp */ +static void +mpz_togglebit (mpz_t x, unsigned long int bit) +{ + if (mpz_tstbit(x, bit)) + mpz_clrbit(x, bit); + else + mpz_setbit(x, bit); +} +#endif /* HAVE_LIBGMP */ + +#if WITH_HOGWEED +#define SIGN(key, hash, msg, signature) do { \ + hash##_update(&hash, LDATA(msg)); \ + ASSERT(rsa_##hash##_sign(key, &hash, signature)); \ +} while(0) + +#define VERIFY(key, hash, msg, signature) ( \ + hash##_update(&hash, LDATA(msg)), \ + rsa_##hash##_verify(key, &hash, signature) \ +) + +void +test_rsa_set_key_1(struct rsa_public_key *pub, + struct rsa_private_key *key) +{ + /* Initialize key pair for test programs */ + /* 1000-bit key, generated by + * + * lsh-keygen -a rsa -l 1000 -f advanced-hex + * + * (private-key (rsa-pkcs1 + * (n #69abd505285af665 36ddc7c8f027e6f0 ed435d6748b16088 + * 4fd60842b3a8d7fb bd8a3c98f0cc50ae 4f6a9f7dd73122cc + * ec8afa3f77134406 f53721973115fc2d 8cfbba23b145f28d + * 84f81d3b6ae8ce1e 2850580c026e809b cfbb52566ea3a3b3 + * df7edf52971872a7 e35c1451b8636d22 279a8fb299368238 + * e545fbb4cf#) + * (e #0db2ad57#) + * (d #3240a56f4cd0dcc2 4a413eb4ea545259 5c83d771a1c2ba7b + * ec47c5b43eb4b374 09bd2aa1e236dd86 481eb1768811412f + * f8d91be3545912af b55c014cb55ceac6 54216af3b85d5c4f + * 4a32894e3b5dfcde 5b2875aa4dc8d9a8 6afd0ca92ef50d35 + * bd09f1c47efb4c8d c631e07698d362aa 4a83fd304e66d6c5 + * 468863c307#) + * (p #0a66399919be4b4d e5a78c5ea5c85bf9 aba8c013cb4a8732 + * 14557a12bd67711e bb4073fd39ad9a86 f4e80253ad809e5b + * f2fad3bc37f6f013 273c9552c9f489#) + * (q #0a294f069f118625 f5eae2538db9338c 776a298eae953329 + * 9fd1eed4eba04e82 b2593bc98ba8db27 de034da7daaea795 + * 2d55b07b5f9a5875 d1ca5f6dcab897#) + * (a #011b6c48eb592eee e85d1bb35cfb6e07 344ea0b5e5f03a28 + * 5b405396cbc78c5c 868e961db160ba8d 4b984250930cf79a + * 1bf8a9f28963de53 128aa7d690eb87#) + * (b #0409ecf3d2557c88 214f1af5e1f17853 d8b2d63782fa5628 + * 60cf579b0833b7ff 5c0529f2a97c6452 2fa1a8878a9635ab + * ce56debf431bdec2 70b308fa5bf387#) + * (c #04e103ee925cb5e6 6653949fa5e1a462 c9e65e1adcd60058 + * e2df9607cee95fa8 daec7a389a7d9afc 8dd21fef9d83805a + * 40d46f49676a2f6b 2926f70c572c00#))) + */ + + mpz_set_str(pub->n, + "69abd505285af665" "36ddc7c8f027e6f0" "ed435d6748b16088" + "4fd60842b3a8d7fb" "bd8a3c98f0cc50ae" "4f6a9f7dd73122cc" + "ec8afa3f77134406" "f53721973115fc2d" "8cfbba23b145f28d" + "84f81d3b6ae8ce1e" "2850580c026e809b" "cfbb52566ea3a3b3" + "df7edf52971872a7" "e35c1451b8636d22" "279a8fb299368238" + "e545fbb4cf", 16); + mpz_set_str(pub->e, "0db2ad57", 16); + + if (!rsa_public_key_prepare(pub)) + FAIL(); + + /* d is not used */ +#if 0 + mpz_set_str(key->d, + "3240a56f4cd0dcc2" "4a413eb4ea545259" "5c83d771a1c2ba7b" + "ec47c5b43eb4b374" "09bd2aa1e236dd86" "481eb1768811412f" + "f8d91be3545912af" "b55c014cb55ceac6" "54216af3b85d5c4f" + "4a32894e3b5dfcde" "5b2875aa4dc8d9a8" "6afd0ca92ef50d35" + "bd09f1c47efb4c8d" "c631e07698d362aa" "4a83fd304e66d6c5" + "468863c307", 16); +#endif + + mpz_set_str(key->p, + "0a66399919be4b4d" "e5a78c5ea5c85bf9" "aba8c013cb4a8732" + "14557a12bd67711e" "bb4073fd39ad9a86" "f4e80253ad809e5b" + "f2fad3bc37f6f013" "273c9552c9f489", 16); + + mpz_set_str(key->q, + "0a294f069f118625" "f5eae2538db9338c" "776a298eae953329" + "9fd1eed4eba04e82" "b2593bc98ba8db27" "de034da7daaea795" + "2d55b07b5f9a5875" "d1ca5f6dcab897", 16); + + mpz_set_str(key->a, + "011b6c48eb592eee" "e85d1bb35cfb6e07" "344ea0b5e5f03a28" + "5b405396cbc78c5c" "868e961db160ba8d" "4b984250930cf79a" + "1bf8a9f28963de53" "128aa7d690eb87", 16); + + mpz_set_str(key->b, + "0409ecf3d2557c88" "214f1af5e1f17853" "d8b2d63782fa5628" + "60cf579b0833b7ff" "5c0529f2a97c6452" "2fa1a8878a9635ab" + "ce56debf431bdec2" "70b308fa5bf387", 16); + + mpz_set_str(key->c, + "04e103ee925cb5e6" "6653949fa5e1a462" "c9e65e1adcd60058" + "e2df9607cee95fa8" "daec7a389a7d9afc" "8dd21fef9d83805a" + "40d46f49676a2f6b" "2926f70c572c00", 16); + + if (!rsa_private_key_prepare(key)) + FAIL(); + + if (pub->size != key->size) + FAIL(); +} + +void +test_rsa_md5(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct md5_ctx md5; + mpz_t signature; + + md5_init(&md5); + mpz_init(signature); + + SIGN(key, md5, "The magic words are squeamish ossifrage", signature); + + if (verbose) + { + fprintf(stderr, "rsa-md5 signature: "); + mpz_out_str(stderr, 16, signature); + fprintf(stderr, "\n"); + } + + if (mpz_cmp(signature, expected)) + FAIL(); + + /* Try bad data */ + if (VERIFY(pub, md5, + "The magick words are squeamish ossifrage", signature)) + FAIL(); + + /* Try correct data */ + if (!VERIFY(pub, md5, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + /* Try bad signature */ + mpz_togglebit(signature, 17); + + if (VERIFY(pub, md5, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + mpz_clear(signature); +} + +void +test_rsa_sha1(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct sha1_ctx sha1; + mpz_t signature; + + sha1_init(&sha1); + mpz_init(signature); + + SIGN(key, sha1, "The magic words are squeamish ossifrage", signature); + + if (verbose) + { + fprintf(stderr, "rsa-sha1 signature: "); + mpz_out_str(stderr, 16, signature); + fprintf(stderr, "\n"); + } + + if (mpz_cmp(signature, expected)) + FAIL(); + + /* Try bad data */ + if (VERIFY(pub, sha1, + "The magick words are squeamish ossifrage", signature)) + FAIL(); + + /* Try correct data */ + if (!VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + /* Try bad signature */ + mpz_togglebit(signature, 17); + + if (VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + mpz_clear(signature); +} + +void +test_rsa_sha256(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct sha256_ctx sha256; + mpz_t signature; + + sha256_init(&sha256); + mpz_init(signature); + + SIGN(key, sha256, "The magic words are squeamish ossifrage", signature); + + if (verbose) + { + fprintf(stderr, "rsa-sha256 signature: "); + mpz_out_str(stderr, 16, signature); + fprintf(stderr, "\n"); + } + + if (mpz_cmp(signature, expected)) + FAIL(); + + /* Try bad data */ + if (VERIFY(pub, sha256, + "The magick words are squeamish ossifrage", signature)) + FAIL(); + + /* Try correct data */ + if (!VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + /* Try bad signature */ + mpz_togglebit(signature, 17); + + if (VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + mpz_clear(signature); +} + +void +test_rsa_sha512(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected) +{ + struct sha512_ctx sha512; + mpz_t signature; + + sha512_init(&sha512); + mpz_init(signature); + + SIGN(key, sha512, "The magic words are squeamish ossifrage", signature); + + if (verbose) + { + fprintf(stderr, "rsa-sha512 signature: "); + mpz_out_str(stderr, 16, signature); + fprintf(stderr, "\n"); + } + + if (mpz_cmp(signature, expected)) + FAIL(); + + /* Try bad data */ + if (VERIFY(pub, sha512, + "The magick words are squeamish ossifrage", signature)) + FAIL(); + + /* Try correct data */ + if (!VERIFY(pub, sha512, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + /* Try bad signature */ + mpz_togglebit(signature, 17); + + if (VERIFY(pub, sha512, + "The magic words are squeamish ossifrage", signature)) + FAIL(); + + mpz_clear(signature); +} + +#undef SIGN +#undef VERIFY + +void +test_rsa_key(struct rsa_public_key *pub, + struct rsa_private_key *key) +{ + mpz_t tmp; + mpz_t phi; + + mpz_init(tmp); mpz_init(phi); + + if (verbose) + { + /* FIXME: Use gmp_printf */ + fprintf(stderr, "Public key: n="); + mpz_out_str(stderr, 16, pub->n); + fprintf(stderr, "\n e="); + mpz_out_str(stderr, 16, pub->e); + + fprintf(stderr, "\n\nPrivate key: d="); + mpz_out_str(stderr, 16, key->d); + fprintf(stderr, "\n p="); + mpz_out_str(stderr, 16, key->p); + fprintf(stderr, "\n q="); + mpz_out_str(stderr, 16, key->q); + fprintf(stderr, "\n a="); + mpz_out_str(stderr, 16, key->a); + fprintf(stderr, "\n b="); + mpz_out_str(stderr, 16, key->b); + fprintf(stderr, "\n c="); + mpz_out_str(stderr, 16, key->c); + fprintf(stderr, "\n\n"); + } + + /* Check n = p q */ + mpz_mul(tmp, key->p, key->q); + if (mpz_cmp(tmp, pub->n)) + FAIL(); + + /* Check c q = 1 mod p */ + mpz_mul(tmp, key->c, key->q); + mpz_fdiv_r(tmp, tmp, key->p); + if (mpz_cmp_ui(tmp, 1)) + FAIL(); + + /* Check ed = 1 (mod phi) */ + mpz_sub_ui(phi, key->p, 1); + mpz_sub_ui(tmp, key->q, 1); + + mpz_mul(phi, phi, tmp); + + mpz_mul(tmp, pub->e, key->d); + mpz_fdiv_r(tmp, tmp, phi); + if (mpz_cmp_ui(tmp, 1)) + FAIL(); + + /* Check a e = 1 (mod (p-1) ) */ + mpz_sub_ui(phi, key->p, 1); + mpz_mul(tmp, pub->e, key->a); + mpz_fdiv_r(tmp, tmp, phi); + if (mpz_cmp_ui(tmp, 1)) + FAIL(); + + /* Check b e = 1 (mod (q-1) ) */ + mpz_sub_ui(phi, key->q, 1); + mpz_mul(tmp, pub->e, key->b); + mpz_fdiv_r(tmp, tmp, phi); + if (mpz_cmp_ui(tmp, 1)) + FAIL(); + + mpz_clear(tmp); mpz_clear(phi); +} + +/* Requires that the context is named like the hash algorithm. */ +#define DSA_VERIFY(key, hash, msg, signature) \ + (hash##_update(&hash, LDATA(msg)), \ + dsa_##hash##_verify(key, &hash, signature)) + +void +test_dsa160(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected) +{ + struct sha1_ctx sha1; + struct dsa_signature signature; + struct knuth_lfib_ctx lfib; + + sha1_init(&sha1); + dsa_signature_init(&signature); + knuth_lfib_init(&lfib, 1111); + + sha1_update(&sha1, LDATA("The magic words are squeamish ossifrage")); + ASSERT (dsa_sha1_sign(pub, key, + &lfib, (nettle_random_func *) knuth_lfib_random, + &sha1, &signature)); + + if (verbose) + { + fprintf(stderr, "dsa160 signature: "); + mpz_out_str(stderr, 16, signature.r); + fprintf(stderr, ", "); + mpz_out_str(stderr, 16, signature.s); + fprintf(stderr, "\n"); + } + + if (expected) + if (mpz_cmp (signature.r, expected->r) + || mpz_cmp (signature.s, expected->s)) + FAIL(); + + /* Try bad data */ + if (DSA_VERIFY(pub, sha1, + "The magick words are squeamish ossifrage", &signature)) + FAIL(); + + /* Try correct data */ + if (!DSA_VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", &signature)) + FAIL(); + + /* Try bad signature */ + mpz_togglebit(signature.r, 17); + + if (DSA_VERIFY(pub, sha1, + "The magic words are squeamish ossifrage", &signature)) + FAIL(); + + dsa_signature_clear(&signature); +} + +void +test_dsa256(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected) +{ + struct sha256_ctx sha256; + struct dsa_signature signature; + struct knuth_lfib_ctx lfib; + + sha256_init(&sha256); + dsa_signature_init(&signature); + knuth_lfib_init(&lfib, 1111); + + sha256_update(&sha256, LDATA("The magic words are squeamish ossifrage")); + ASSERT (dsa_sha256_sign(pub, key, + &lfib, (nettle_random_func *) knuth_lfib_random, + &sha256, &signature)); + + if (verbose) + { + fprintf(stderr, "dsa256 signature: "); + mpz_out_str(stderr, 16, signature.r); + fprintf(stderr, ", "); + mpz_out_str(stderr, 16, signature.s); + fprintf(stderr, "\n"); + } + + if (expected) + if (mpz_cmp (signature.r, expected->r) + || mpz_cmp (signature.s, expected->s)) + FAIL(); + + /* Try bad data */ + if (DSA_VERIFY(pub, sha256, + "The magick words are squeamish ossifrage", &signature)) + FAIL(); + + /* Try correct data */ + if (!DSA_VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", &signature)) + FAIL(); + + /* Try bad signature */ + mpz_togglebit(signature.r, 17); + + if (DSA_VERIFY(pub, sha256, + "The magic words are squeamish ossifrage", &signature)) + FAIL(); + + dsa_signature_clear(&signature); +} + +void +test_dsa_key(struct dsa_public_key *pub, + struct dsa_private_key *key, + unsigned q_size) +{ + mpz_t t; + + mpz_init(t); + + ASSERT(mpz_sizeinbase(pub->q, 2) == q_size); + ASSERT(mpz_sizeinbase(pub->p, 2) >= DSA_SHA1_MIN_P_BITS); + + ASSERT(mpz_probab_prime_p(pub->p, 10)); + + ASSERT(mpz_probab_prime_p(pub->q, 10)); + + mpz_fdiv_r(t, pub->p, pub->q); + + ASSERT(0 == mpz_cmp_ui(t, 1)); + + ASSERT(mpz_cmp_ui(pub->g, 1) > 0); + + mpz_powm(t, pub->g, pub->q, pub->p); + ASSERT(0 == mpz_cmp_ui(t, 1)); + + mpz_powm(t, pub->g, key->x, pub->p); + ASSERT(0 == mpz_cmp(t, pub->y)); +}; + +#endif /* WITH_HOGWEED */ + diff --git a/testsuite/testutils.h b/testsuite/testutils.h new file mode 100644 index 0000000..91ec496 --- /dev/null +++ b/testsuite/testutils.h @@ -0,0 +1,210 @@ +#ifndef NETTLE_TESTUTILS_H_INCLUDED +#define NETTLE_TESTUTILS_H_INCLUDED + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-types.h" + +#include +#include +#include + +#if HAVE_LIBGMP +# include "bignum.h" +#endif + +#if WITH_HOGWEED +# include "rsa.h" +# include "dsa.h" +#endif + +#include "nettle-meta.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void * +xalloc(size_t size); + +/* Decodes a NUL-terminated hex string. */ + +unsigned +decode_hex_length(const char *hex); + +int +decode_hex(uint8_t *dst, const char *hex); + +/* Allocates space */ +const uint8_t * +decode_hex_dup(const char *hex); + +void +print_hex(unsigned length, const uint8_t *data); + +/* The main program */ +int +test_main(void); + +extern int verbose; + +/* FIXME: When interface stabilizes, move to nettle-meta.h */ +struct nettle_mac +{ + const char *name; + + /* Size of the context struct */ + unsigned context_size; + + /* Size of digests */ + unsigned digest_size; + + /* Suggested key size; other sizes are sometimes possible. */ + unsigned key_size; + + nettle_set_key_func *set_key; + nettle_hash_update_func *update; + nettle_hash_digest_func *digest; +}; + +#define _NETTLE_HMAC(name, NAME, keysize) { \ + #name, \ + sizeof(struct hmac_##name##_ctx), \ + NAME##_DIGEST_SIZE, \ + NAME##_DIGEST_SIZE, \ + hmac_##name##_set_key, \ + hmac_##name##_update, \ + hmac_##name##_digest, \ +} + +void +test_cipher(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext); + +void +test_cipher_cbc(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext, + const uint8_t *iv); + +void +test_cipher_ctr(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext, + const uint8_t *iv); + +void +test_cipher_stream(const struct nettle_cipher *cipher, + unsigned key_length, + const uint8_t *key, + unsigned length, + const uint8_t *cleartext, + const uint8_t *ciphertext); + +void +test_hash(const struct nettle_hash *hash, + unsigned length, + const uint8_t *data, + const uint8_t *digest); + +void +test_hash_large(const struct nettle_hash *hash, + unsigned count, unsigned length, + uint8_t c, + const uint8_t *digest); + +void +test_mac(const struct nettle_mac *mac, + unsigned key_length, const uint8_t *key, + unsigned msg_length, const uint8_t *msg, + const uint8_t *digest); + +void +test_armor(const struct nettle_armor *armor, + unsigned data_length, + const uint8_t *data, + const uint8_t *ascii); + +#if WITH_HOGWEED +void +test_rsa_set_key_1(struct rsa_public_key *pub, + struct rsa_private_key *key); + +void +test_rsa_md5(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_sha1(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_sha256(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_sha512(struct rsa_public_key *pub, + struct rsa_private_key *key, + mpz_t expected); + +void +test_rsa_key(struct rsa_public_key *pub, + struct rsa_private_key *key); + +void +test_dsa160(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected); + +void +test_dsa256(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + const struct dsa_signature *expected); + +void +test_dsa_key(struct dsa_public_key *pub, + struct dsa_private_key *key, + unsigned q_size); + +#endif /* WITH_HOGWEED */ + +#ifdef __cplusplus +} +#endif + +#define H2(d, s) decode_hex((d), (s)) +#define H(x) decode_hex_dup(x) +#define HL(x) decode_hex_length(x), decode_hex_dup(x) + +/* LDATA needs to handle NUL characters. */ +#define LLENGTH(x) (sizeof(x) - 1) +#define LDATA(x) (sizeof(x) - 1), x +#define LDUP(x) strlen(x), strdup(x) + +#define MEMEQ(length, a, b) (!memcmp((a), (b), (length))) +#define MEMEQH(length, a, b) \ +((length) == decode_hex_length((b)) \ + && !memcmp((a), decode_hex_dup((b)), (length))) + +#define FAIL() abort() +#define SKIP() exit(77) +#define SUCCESS() return EXIT_SUCCESS + +#define ASSERT(x) do { if (!(x)) FAIL(); } while(0) + +#endif /* NETTLE_TESTUTILS_H_INCLUDED */ diff --git a/testsuite/twofish-test.c b/testsuite/twofish-test.c new file mode 100644 index 0000000..65558d3 --- /dev/null +++ b/testsuite/twofish-test.c @@ -0,0 +1,28 @@ +#include "testutils.h" +#include "twofish.h" + +int +test_main(void) +{ + /* 128 bit key */ + test_cipher(&nettle_twofish128, + HL("0000000000000000 0000000000000000"), + HL("0000000000000000 0000000000000000"), + H("9F589F5CF6122C32 B6BFEC2F2AE8C35A")); + + /* 192 bit key */ + test_cipher(&nettle_twofish192, + HL("0123456789ABCDEF FEDCBA9876543210" + "0011223344556677"), + HL("0000000000000000 0000000000000000"), + H("CFD1D2E5A9BE9CDF 501F13B892BD2248")); + + /* 256 bit key */ + test_cipher(&nettle_twofish256, + HL("0123456789ABCDEF FEDCBA9876543210" + "0011223344556677 8899AABBCCDDEEFF"), + HL("0000000000000000 0000000000000000"), + H("37527BE0052334B8 9F0CFCCAE87CFA20")); + + SUCCESS(); +} diff --git a/testsuite/yarrow-test.c b/testsuite/yarrow-test.c new file mode 100644 index 0000000..5f01e76 --- /dev/null +++ b/testsuite/yarrow-test.c @@ -0,0 +1,221 @@ +#include "testutils.h" +#include "yarrow.h" +#include "knuth-lfib.h" + +#include "macros.h" + +#include +#include +#include +#include +#include + +/* Lagged fibonacci sequence as described in Knuth 3.6 */ + +struct knuth_lfib_ctx lfib; + +static int +get_event(FILE *f, struct sha256_ctx *hash, + unsigned *key, unsigned *time) +{ + static int t = 0; + uint8_t buf[1]; + + int c = getc(f); + if (c == EOF) + return 0; + + buf[0] = c; + sha256_update(hash, sizeof(buf), buf); + + *key = c; + + t += (knuth_lfib_get(&lfib) % 10000); + *time = t; + + return 1; +} + +static FILE * +open_file(const char *name) +{ + /* Tries opening the file in $srcdir, if set, otherwise the current + * working directory */ + + const char *srcdir = getenv("srcdir"); + if (srcdir && srcdir[0]) + { + /* Leaks this name, but that doesn't matter. */ + char *buf = xalloc(strlen(name) + strlen(srcdir) + 10); + sprintf(buf, "%s/%s", srcdir, name); + name = buf; + } + + /* Opens the file in text mode. */ + return fopen(name, "r"); +} + +int +test_main(void) +{ + FILE *input; + + struct yarrow256_ctx yarrow; + struct yarrow_key_event_ctx estimator; + + struct yarrow_source sources[2]; + + struct sha256_ctx output_hash; + struct sha256_ctx input_hash; + uint8_t digest[SHA256_DIGEST_SIZE]; + + uint8_t seed_file[YARROW256_SEED_FILE_SIZE]; + + const uint8_t *expected_output + = decode_hex_dup("dd304aacac3dc95e 70d684a642967c89" + "58501f7c8eb88b79 43b2ffccde6f0f79"); + + const uint8_t *expected_input + = decode_hex_dup("e0596cf006025506 65d1195f32a87e4a" + "5c354910dfbd0a31 e2105b262f5ce3d8"); + + const uint8_t *expected_seed_file + = decode_hex_dup("b03518f32b1084dd 983e6a445d47bb6f" + "13bb7b998740d570 503d6aaa62e28901"); + + unsigned c; unsigned t; + + unsigned processed = 0; + unsigned output = 0; + + unsigned i; + + static const char zeroes[100]; + + yarrow256_init(&yarrow, 2, sources); + + yarrow_key_event_init(&estimator); + sha256_init(&input_hash); + sha256_init(&output_hash); + + knuth_lfib_init(&lfib, 31416); + + /* Fake input to source 0 */ + yarrow256_update(&yarrow, 0, 200, sizeof(zeroes), zeroes); + + if (verbose) + printf("source 0 entropy: %d\n", + sources[0].estimate[YARROW_SLOW]); + + assert(!yarrow256_is_seeded(&yarrow)); + + input = open_file("gold-bug.txt"); + + if (!input) + { + fprintf(stderr, "Couldn't open `gold-bug.txt', errno = %d\n", + errno); + return EXIT_FAILURE; + } + + while (get_event(input, &input_hash, &c, &t)) + { + uint8_t buf[8]; + + processed++; + + WRITE_UINT32(buf, c); + WRITE_UINT32(buf + 4, t); + yarrow256_update(&yarrow, 1, + yarrow_key_event_estimate(&estimator, c, t), + sizeof(buf), buf); + + if (yarrow256_is_seeded(&yarrow)) + { + static const unsigned sizes[4] = { 1, 16, 500, 37 }; + unsigned size = sizes[processed % 4]; + + uint8_t buf[500]; + + if (verbose && !output) + printf("Generator was seeded after %d events\n", + processed); + + yarrow256_random(&yarrow, size, buf); + + sha256_update(&output_hash, size, buf); + + if (verbose) + { + printf("%02x ", buf[0]); + if (! (processed % 16)) + printf("\n"); + } + output += size; + } + } + + if (verbose) + { + printf("\n"); + + for (i = 0; i<2; i++) + printf("source %d, (fast, slow) entropy: (%d, %d)\n", + i, + sources[i].estimate[YARROW_FAST], + sources[i].estimate[YARROW_SLOW]); + + printf("Processed input: %d octets\n", processed); + printf(" sha256:"); + } + + sha256_digest(&input_hash, sizeof(digest), digest); + + if (verbose) + { + print_hex(sizeof(digest), digest); + printf("\n"); + } + + if (memcmp(digest, expected_input, sizeof(digest))) + { + fprintf(stderr, "Failed.\n"); + return EXIT_FAILURE; + } + + yarrow256_random(&yarrow, sizeof(seed_file), seed_file); + if (verbose) + { + printf("New seed file: "); + print_hex(sizeof(seed_file), seed_file); + printf("\n"); + } + + if (memcmp(seed_file, expected_seed_file, sizeof(seed_file))) + { + fprintf(stderr, "Failed.\n"); + return EXIT_FAILURE; + } + + if (verbose) + { + printf("Generated output: %d octets\n", output); + printf(" sha256:"); + } + + sha256_digest(&output_hash, sizeof(digest), digest); + + if (verbose) + { + print_hex(sizeof(digest), digest); + printf("\n"); + } + + if (memcmp(digest, expected_output, sizeof(digest))) + { + fprintf(stderr, "Failed.\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/texinfo.tex b/texinfo.tex new file mode 100644 index 0000000..7f876b4 --- /dev/null +++ b/texinfo.tex @@ -0,0 +1,9287 @@ +% 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{2009-03-22.17} +% +% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007, 2008, 2009 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 3 of the +% License, 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 program. If not, see . +% +% 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} + + +\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 +\let\ptextop=\top +{\catcode`\'=\active +\global\let\ptexquoteright'}% Math-mode def from plain.tex. +\let\ptexraggedright=\raggedright + +% 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 + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. The solution is +% described on page 260 of The TeXbook. It involves outputting two +% marks for the sectioning macros, one before the section break, and +% one after. I won't pretend I can describe this better than DEK... +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 + \noexpand\or \the\toks4 \the\toks6 + \noexpand\else \the\toks8 + }% +} +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% 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). + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + \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\relax \unvbox#1\relax +\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 occurrence of `\^^M' or `\^^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. +% (Similarly, 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 environments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At run-time, 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 +} + +% Environment 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 \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \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 -- \input text of FILE. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \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 + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\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 + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% Some math mode symbols. +\def\bullet{$\ptexbullet$} +\def\geq{\ifmmode \ge\else $\ge$\fi} +\def\leq{\ifmmode \le\else $\le$\fi} +\def\minus{\ifmmode -\else $-$\fi} + +% @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, with minor +% changes for Texinfo. It is included here under the GPL by permission +% from the author, Heiko Oberdiek. +% +% #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}% +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros based on pdfcolor.tex. + \def\cmykDarkRed{0.28 1 1 0.35} + \def\cmykBlack{0 0 0 1} + % + % k sets the color for filling (usual text, etc.); + % K sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 k #1 K}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\cmykBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \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}% + % + % pdftex (and the PDF format) support .png, .jpg, .pdf (among + % others). Let's try in that order. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient 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.\pdfimgext + \else + {#1.\pdfimgext}% + \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. + \indexnofonts + \turnoffactive + \activebackslashdouble + \makevalueexpandable + \def\pdfdestname{#1}% + \backslashparens\pdfdestname + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + }} + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use a color that is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. + \def\urlcolor{\cmykDarkRed} + \def\linkcolor{\cmykDarkRed} + \def\endlink{\setcolor{\maincolor}\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 \tocreadfilename + \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 + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \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}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \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}} + +% Unfortunately, we have to override this for titles and the like, since +% in those cases "rm" is bold. Sigh. +\def\rmisbold{\rm\def\curfontstyle{bf}} + +% 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} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% PDF CMaps. See also LaTeX's t1.cmap. +% +% do nothing with this by default. +\expandafter\let\csname cmapOT1\endcsname\gobble +\expandafter\let\csname cmapOT1IT\endcsname\gobble +\expandafter\let\csname cmapOT1TT\endcsname\gobble + +% if we are producing pdf, and we have \pdffontattr, then define cmaps. +% (\pdffontattr was introduced many years ago, but people still run +% older pdftex's; it's easy to conditionalize, so we do.) +\ifpdf \ifx\pdffontattr\undefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\fi\fi + + +% 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, #5 is the CMap +% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass +% empty to omit). +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble +% emacs-page end of cmaps + +% 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}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\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}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acro in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +% 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}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\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}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acro in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +% 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\rmisbold #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}} + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + +% Define these just so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% 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 +% --karl, 24jan03. + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + + +\message{markup,} + +% 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 } + +% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +% define and register \INITMACRO to be called on markup style changes. +% \INITMACRO can check \currentmarkupstyle for the innermost +% style and the set of \ifmarkupSTYLE switches for all styles +% currently in effect. +\newif\ifmarkupvar +\newif\ifmarkupsamp +\newif\ifmarkupkey +%\newif\ifmarkupfile % @file == @samp. +%\newif\ifmarkupoption % @option == @samp. +\newif\ifmarkupcode +\newif\ifmarkupkbd +%\newif\ifmarkupenv % @env == @code. +%\newif\ifmarkupcommand % @command == @code. +\newif\ifmarkuptex % @tex (and part of @math, for now). +\newif\ifmarkupexample +\newif\ifmarkupverb +\newif\ifmarkupverbatim + +\let\currentmarkupstyle\empty + +\def\setupmarkupstyle#1{% + \csname markup#1true\endcsname + \def\currentmarkupstyle{#1}% + \markupstylesetup +} + +\let\markupstylesetup\empty + +\def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% +} + +% Markup style setup for left and right quotes. +\defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +} + +\defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +} + +{ +\catcode`\'=\active +\catcode`\`=\active + +\gdef\markupsetuplqdefault{\let`\lq} +\gdef\markupsetuprqdefault{\let'\rq} + +\gdef\markupsetcodequoteleft{\let`\codequoteleft} +\gdef\markupsetcodequoteright{\let'\codequoteright} + +\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft} +} + +\let\markupsetuplqcode \markupsetcodequoteleft +\let\markupsetuprqcode \markupsetcodequoteright +\let\markupsetuplqexample \markupsetcodequoteleft +\let\markupsetuprqexample \markupsetcodequoteright +\let\markupsetuplqverb \markupsetcodequoteleft +\let\markupsetuprqverb \markupsetcodequoteright +\let\markupsetuplqverbatim \markupsetcodequoteleft +\let\markupsetuprqverbatim \markupsetcodequoteright + +\let\markupsetuplqsamp \markupsetnoligaturesquoteleft +\let\markupsetuplqkbd \markupsetnoligaturesquoteleft + +% 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 SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \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 SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +\def\noligaturesquoteleft{\relax\lq} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +%% 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} + +% @cite is 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 +\def\var#1{{\setupmarkupstyle{var}\smartslanted{#1}}} +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% 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 + +% @b, explicit bold. Also @strong. +\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 + +% @t, explicit typewriter. +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} + +% @samp. +\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\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}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + +% ctrl is no longer a Texinfo command. +\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\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \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. +\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} + +% @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\setupmarkupstyle{kbd}\look}}\fi +\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi} + +% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. +\let\indicateurl=\code +\let\env=\code +\let\command=\code + +% @clicksequence{File @click{} Open ...} +\def\clicksequence#1{\begingroup #1\endgroup} + +% @clickstyle @arrow (by default) +\parseargdef\clickstyle{\def\click{#1}} +\def\click{\arrow} + +% @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 + +% 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} + +% @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} + +% @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 +} + + +\message{glyphs,} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, they should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\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} + +% @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 +} + +% Glyphs from the EC fonts. We don't use \let for the aliases, because +% sometimes we redefine the original macro, and the alias should reflect +% the redefinition. +% +% Use LaTeX names for the Icelandic letters. +\def\DH{{\ecfont \char"D0}} % Eth +\def\dh{{\ecfont \char"F0}} % eth +\def\TH{{\ecfont \char"DE}} % Thorn +\def\th{{\ecfont \char"FE}} % thorn +% +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +% This positioning is not perfect (see the ogonek LaTeX package), but +% we have the precomposed glyphs for the most common cases. We put the +% tests to use those glyphs in the single \ogonek macro so we have fewer +% dummy definitions to worry about for index entries, etc. +% +% ogonek is also used with other letters in Lithuanian (IOU), but using +% the precomposed glyphs for those is not so easy since they aren't in +% the same EC font. +\def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% +} +\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +% +% Use the ec* fonts (cm-super in outline format) for non-CM glyphs. +\def\ecfont{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \thisecfont +} + +% @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 + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + + +\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} + +\parseargdef\title{% + \checkenv\titlepage + \leftline{\titlefonts\rmisbold #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 + {\secfonts\rmisbold \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}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @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 + % + % Try typesetting the item mark that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @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 . + % + \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. \everycr resets \everytab so we don't have to +% undo it ourselves. +\def\headitemfont{\b}% for people to use in the template row; not changeable +\def\headitem{% + \checkenv\multitable + \crcr + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item +}% +% +% 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 again encounter the problem the 1sp was intended to solve. +% --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 \relax + % 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\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % 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\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\expansion + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \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\ogonek + \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\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{ZZZ}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{zzz}% + % + \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\guillemetleft{<<}% + \def\guillemetright{>>}% + \def\guilsinglleft{<}% + \def\guilsinglright{>}% + \def\expansion{==>}% + \def\minus{-}% + \def\pounds{pounds}% + \def\point{.}% + \def\print{-|}% + \def\quotedblbase{"}% + \def\quotedblleft{"}% + \def\quotedblright{"}% + \def\quoteleft{`}% + \def\quoteright{'}% + \def\quotesinglbase{,}% + \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}% + % + \safewhatsit\dosubindwrite + }% + \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/skips around a whatsit: +% +% 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 or \pdfdest 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} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{% +\ifhmode + #1% +\else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip 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-\whatsitskip + \fi + % + #1% + % + \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\whatsitpenalty>9999 \penalty\whatsitpenalty \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\whatsitskip + \fi +\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 + \plainfrenchspacing + \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 freezes 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. + \setbox\boxA = \hbox{#1}% + \ifdim\wd\boxA = 0pt + \ % + \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{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \pageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \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 these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\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 + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \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 calls appendixzzz +% +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \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 to achieve this: TeX expands \the only once, + % simply yielding the contents of . (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\ptexraggedright + \rmisbold #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} +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% + \hbox to 0pt{}% + \chappager + \endgroup + \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{% + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rmisbold + % + % Have to define \lastsection 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\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \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. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \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\ptexraggedright + \rmisbold #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 {\rmisbold #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\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rmisbold + % + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#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 \ptexraggedright + \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 \tocreadfilename +} + +\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 + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \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 +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \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 \tocreadfilename\space + \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. + +% @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{% + \setupmarkupstyle{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 + \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 + \expandafter \let\csname top\endcsname=\ptextop % outer + \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. +\newdimen\nonfillparindent +\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 + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \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 +} + +\begingroup +\obeyspaces +% We want to swallow spaces (but not other tokens) after the fake +% @indent in our nonfill-environments, where spaces are normally +% active and set to @tie, resulting in them not being ignored after +% @indent. +\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +\gdef\nonfillindentcheck{% +\ifx\temp % +\expandafter\nonfillindentgobble% +\else% +\leavevmode\nonfillindentbox% +\fi% +}% +\endgroup +\def\nonfillindentgobble#1{\nonfillindent} +\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + +% 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 + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \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\setupmarkupstyle{example}% + \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 + + +% @raggedright does more-or-less normal line breaking but no right +% justification. From plain.tex. +\envdef\raggedright{% + \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax +} +\let\Eraggedright\par + +\envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedleft\par + +\envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedcenter\par + + +% @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. +% +\def\quotationstart{% + {\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 +} + +\envdef\quotation{% + \setnormaldispenv + \quotationstart +} + +\envdef\smallquotation{% + \setsmalldispenv + \quotationstart +} +\let\Esmallquotation = \Equotation + +% 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{...} +% If we want to allow any 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\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% 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}% + \setupmarkupstyle{verb}% + \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} +% +\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 + }% + } +\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}% + \tabexpand + \setupmarkupstyle{verbatim}% + % 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'{'#1'}'{#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 + \indexnofonts % Allow `@@' and other weird things in file names. + \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 +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \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 \printdefunline, 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. + % + % As a minor refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \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 \else \defunpenalty=10002 \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\defunpenalty % 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 remaining 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. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #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 +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets 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 \. + +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. + +% 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 + \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi +} + +\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 +% 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 \lastsection, +% 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{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\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 + {\indexnofonts + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. + \getfilename{#4}% + % + % See comments at \activebackslashdouble. + {\activebackslashdouble \xdef\pdfxrefdest{#1}% + \backslashparens\pdfxrefdest}% + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfxrefdest}% + \else + goto name{\pdfmkpgn{\pdfxrefdest}}% + \fi + }% + \setcolor{\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{% + {% The node name might contain 8-bit characters, which in our current + % implementation are changed to commands like @'e. Don't let these + % mess up the control sequence name. + \indexnofonts + \turnoffactive + \xdef\safexrefname{#1}% + }% + % + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\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 + {\safexrefname}}% + \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. +% Similarly, 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\medskip + % 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 + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. On the other hand, if + % it's at the top level, we don't want the normal paragraph indentation. + \noindent + % + % 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 \medskip \fi % space after the standalone 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 \lastsection 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\lastsection{\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 +% \lastsection 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,} + +% For single-language documents, @documentlanguage is usually given very +% early, just after @documentencoding. Single argument is the language +% (de) or locale (de_DE) abbreviation. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{\begingroup + \let_=\normalunderscore % normal _ character for filenames + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore{#1_\finish}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX +\endgroup} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 +} +}% end of special _ catcode +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? Putting it in the current +directory should work if nowhere else does.} + +% This macro is called from txi-??.tex files; the first argument is the +% \language name to set (without the "\lang@" prefix), the second and +% third args are \{left,right}hyphenmin. +% +% The language names to pass are determined when the format is built. +% See the etex.log file created at that time, e.g., +% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +% +% With TeX Live 2008, etex now includes hyphenation patterns for all +% available languages. This means we can support hyphenation in +% Texinfo, at least to some extent. (This still doesn't solve the +% accented characters problem.) +% +\catcode`@=11 +\def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax +} + +% Helpers for encodings. +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\parseargdef\documentencoding{% + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \setnonasciicharscatcode\active + \utfeightchardefs + % + \else + \message{Unknown document encoding #1, ignoring.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii +} + +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdef^^a0{~} + \gdef^^a1{\exclamdown} + \gdef^^a2{\missingcharmsg{CENT SIGN}} + \gdef^^a3{{\pounds}} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\missingcharmsg{YEN SIGN}} + \gdef^^a6{\missingcharmsg{BROKEN BAR}} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\copyright} + \gdef^^aa{\ordf} + \gdef^^ab{\guillemetleft} + \gdef^^ac{$\lnot$} + \gdef^^ad{\-} + \gdef^^ae{\registeredsymbol} + \gdef^^af{\={}} + % + \gdef^^b0{\textdegree} + \gdef^^b1{$\pm$} + \gdef^^b2{$^2$} + \gdef^^b3{$^3$} + \gdef^^b4{\'{}} + \gdef^^b5{$\mu$} + \gdef^^b6{\P} + % + \gdef^^b7{$^.$} + \gdef^^b8{\cedilla\ } + \gdef^^b9{$^1$} + \gdef^^ba{\ordm} + % + \gdef^^bb{\guilletright} + \gdef^^bc{$1\over4$} + \gdef^^bd{$1\over2$} + \gdef^^be{$3\over4$} + \gdef^^bf{\questiondown} + % + \gdef^^c0{\`A} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\~A} + \gdef^^c4{\"A} + \gdef^^c5{\ringaccent A} + \gdef^^c6{\AE} + \gdef^^c7{\cedilla C} + \gdef^^c8{\`E} + \gdef^^c9{\'E} + \gdef^^ca{\^E} + \gdef^^cb{\"E} + \gdef^^cc{\`I} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\"I} + % + \gdef^^d0{\DH} + \gdef^^d1{\~N} + \gdef^^d2{\`O} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\~O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\O} + \gdef^^d9{\`U} + \gdef^^da{\'U} + \gdef^^db{\^U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\TH} + \gdef^^df{\ss} + % + \gdef^^e0{\`a} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\~a} + \gdef^^e4{\"a} + \gdef^^e5{\ringaccent a} + \gdef^^e6{\ae} + \gdef^^e7{\cedilla c} + \gdef^^e8{\`e} + \gdef^^e9{\'e} + \gdef^^ea{\^e} + \gdef^^eb{\"e} + \gdef^^ec{\`{\dotless i}} + \gdef^^ed{\'{\dotless i}} + \gdef^^ee{\^{\dotless i}} + \gdef^^ef{\"{\dotless i}} + % + \gdef^^f0{\dh} + \gdef^^f1{\~n} + \gdef^^f2{\`o} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\~o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\o} + \gdef^^f9{\`u} + \gdef^^fa{\'u} + \gdef^^fb{\^u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\th} + \gdef^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdef^^a4{\euro} + \gdef^^a6{\v S} + \gdef^^a8{\v s} + \gdef^^b4{\v Z} + \gdef^^b8{\v z} + \gdef^^bc{\OE} + \gdef^^bd{\oe} + \gdef^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdef^^a0{~} + \gdef^^a1{\ogonek{A}} + \gdef^^a2{\u{}} + \gdef^^a3{\L} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\v L} + \gdef^^a6{\'S} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\v S} + \gdef^^aa{\cedilla S} + \gdef^^ab{\v T} + \gdef^^ac{\'Z} + \gdef^^ad{\-} + \gdef^^ae{\v Z} + \gdef^^af{\dotaccent Z} + % + \gdef^^b0{\textdegree} + \gdef^^b1{\ogonek{a}} + \gdef^^b2{\ogonek{ }} + \gdef^^b3{\l} + \gdef^^b4{\'{}} + \gdef^^b5{\v l} + \gdef^^b6{\'s} + \gdef^^b7{\v{}} + \gdef^^b8{\cedilla\ } + \gdef^^b9{\v s} + \gdef^^ba{\cedilla s} + \gdef^^bb{\v t} + \gdef^^bc{\'z} + \gdef^^bd{\H{}} + \gdef^^be{\v z} + \gdef^^bf{\dotaccent z} + % + \gdef^^c0{\'R} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\u A} + \gdef^^c4{\"A} + \gdef^^c5{\'L} + \gdef^^c6{\'C} + \gdef^^c7{\cedilla C} + \gdef^^c8{\v C} + \gdef^^c9{\'E} + \gdef^^ca{\ogonek{E}} + \gdef^^cb{\"E} + \gdef^^cc{\v E} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\v D} + % + \gdef^^d0{\DH} + \gdef^^d1{\'N} + \gdef^^d2{\v N} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\H O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\v R} + \gdef^^d9{\ringaccent U} + \gdef^^da{\'U} + \gdef^^db{\H U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\cedilla T} + \gdef^^df{\ss} + % + \gdef^^e0{\'r} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\u a} + \gdef^^e4{\"a} + \gdef^^e5{\'l} + \gdef^^e6{\'c} + \gdef^^e7{\cedilla c} + \gdef^^e8{\v c} + \gdef^^e9{\'e} + \gdef^^ea{\ogonek{e}} + \gdef^^eb{\"e} + \gdef^^ec{\v e} + \gdef^^ed{\'\i} + \gdef^^ee{\^\i} + \gdef^^ef{\v d} + % + \gdef^^f0{\dh} + \gdef^^f1{\'n} + \gdef^^f2{\v n} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\H o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\v r} + \gdef^^f9{\ringaccent u} + \gdef^^fa{\'u} + \gdef^^fb{\H u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\cedilla t} + \gdef^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +\begingroup + \catcode`\~13 + \catcode`\"12 + + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiTwoOctets\string~}} + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiThreeOctets\string~}} + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiFourOctets\string~}} + \UTFviiiLoop +\endgroup + +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + + \gdef\DeclareUnicodeCharacter#1#2{% + \countUTFz = "#1\relax + \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + \begingroup + \parseXMLCharref + \def\UTFviiiTwoOctets##1##2{% + \csname u8:##1\string ##2\endcsname}% + \def\UTFviiiThreeOctets##1##2##3{% + \csname u8:##1\string ##2\string ##3\endcsname}% + \def\UTFviiiFourOctets##1##2##3##4{% + \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter + \gdef\UTFviiiTmp{#2}% + \endgroup} + + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctets.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% + \fi\fi\fi + } + + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz + \multiply\countUTFz by 64 + \advance\countUTFx by -\countUTFz + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +\def\utfeightchardefs{% + \DeclareUnicodeCharacter{00A0}{\tie} + \DeclareUnicodeCharacter{00A1}{\exclamdown} + \DeclareUnicodeCharacter{00A3}{\pounds} + \DeclareUnicodeCharacter{00A8}{\"{ }} + \DeclareUnicodeCharacter{00A9}{\copyright} + \DeclareUnicodeCharacter{00AA}{\ordf} + \DeclareUnicodeCharacter{00AB}{\guillemetleft} + \DeclareUnicodeCharacter{00AD}{\-} + \DeclareUnicodeCharacter{00AE}{\registeredsymbol} + \DeclareUnicodeCharacter{00AF}{\={ }} + + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} + \DeclareUnicodeCharacter{00B4}{\'{ }} + \DeclareUnicodeCharacter{00B8}{\cedilla{ }} + \DeclareUnicodeCharacter{00BA}{\ordm} + \DeclareUnicodeCharacter{00BB}{\guillemetright} + \DeclareUnicodeCharacter{00BF}{\questiondown} + + \DeclareUnicodeCharacter{00C0}{\`A} + \DeclareUnicodeCharacter{00C1}{\'A} + \DeclareUnicodeCharacter{00C2}{\^A} + \DeclareUnicodeCharacter{00C3}{\~A} + \DeclareUnicodeCharacter{00C4}{\"A} + \DeclareUnicodeCharacter{00C5}{\AA} + \DeclareUnicodeCharacter{00C6}{\AE} + \DeclareUnicodeCharacter{00C7}{\cedilla{C}} + \DeclareUnicodeCharacter{00C8}{\`E} + \DeclareUnicodeCharacter{00C9}{\'E} + \DeclareUnicodeCharacter{00CA}{\^E} + \DeclareUnicodeCharacter{00CB}{\"E} + \DeclareUnicodeCharacter{00CC}{\`I} + \DeclareUnicodeCharacter{00CD}{\'I} + \DeclareUnicodeCharacter{00CE}{\^I} + \DeclareUnicodeCharacter{00CF}{\"I} + + \DeclareUnicodeCharacter{00D0}{\DH} + \DeclareUnicodeCharacter{00D1}{\~N} + \DeclareUnicodeCharacter{00D2}{\`O} + \DeclareUnicodeCharacter{00D3}{\'O} + \DeclareUnicodeCharacter{00D4}{\^O} + \DeclareUnicodeCharacter{00D5}{\~O} + \DeclareUnicodeCharacter{00D6}{\"O} + \DeclareUnicodeCharacter{00D8}{\O} + \DeclareUnicodeCharacter{00D9}{\`U} + \DeclareUnicodeCharacter{00DA}{\'U} + \DeclareUnicodeCharacter{00DB}{\^U} + \DeclareUnicodeCharacter{00DC}{\"U} + \DeclareUnicodeCharacter{00DD}{\'Y} + \DeclareUnicodeCharacter{00DE}{\TH} + \DeclareUnicodeCharacter{00DF}{\ss} + + \DeclareUnicodeCharacter{00E0}{\`a} + \DeclareUnicodeCharacter{00E1}{\'a} + \DeclareUnicodeCharacter{00E2}{\^a} + \DeclareUnicodeCharacter{00E3}{\~a} + \DeclareUnicodeCharacter{00E4}{\"a} + \DeclareUnicodeCharacter{00E5}{\aa} + \DeclareUnicodeCharacter{00E6}{\ae} + \DeclareUnicodeCharacter{00E7}{\cedilla{c}} + \DeclareUnicodeCharacter{00E8}{\`e} + \DeclareUnicodeCharacter{00E9}{\'e} + \DeclareUnicodeCharacter{00EA}{\^e} + \DeclareUnicodeCharacter{00EB}{\"e} + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} + + \DeclareUnicodeCharacter{00F0}{\dh} + \DeclareUnicodeCharacter{00F1}{\~n} + \DeclareUnicodeCharacter{00F2}{\`o} + \DeclareUnicodeCharacter{00F3}{\'o} + \DeclareUnicodeCharacter{00F4}{\^o} + \DeclareUnicodeCharacter{00F5}{\~o} + \DeclareUnicodeCharacter{00F6}{\"o} + \DeclareUnicodeCharacter{00F8}{\o} + \DeclareUnicodeCharacter{00F9}{\`u} + \DeclareUnicodeCharacter{00FA}{\'u} + \DeclareUnicodeCharacter{00FB}{\^u} + \DeclareUnicodeCharacter{00FC}{\"u} + \DeclareUnicodeCharacter{00FD}{\'y} + \DeclareUnicodeCharacter{00FE}{\th} + \DeclareUnicodeCharacter{00FF}{\"y} + + \DeclareUnicodeCharacter{0100}{\=A} + \DeclareUnicodeCharacter{0101}{\=a} + \DeclareUnicodeCharacter{0102}{\u{A}} + \DeclareUnicodeCharacter{0103}{\u{a}} + \DeclareUnicodeCharacter{0104}{\ogonek{A}} + \DeclareUnicodeCharacter{0105}{\ogonek{a}} + \DeclareUnicodeCharacter{0106}{\'C} + \DeclareUnicodeCharacter{0107}{\'c} + \DeclareUnicodeCharacter{0108}{\^C} + \DeclareUnicodeCharacter{0109}{\^c} + \DeclareUnicodeCharacter{0118}{\ogonek{E}} + \DeclareUnicodeCharacter{0119}{\ogonek{e}} + \DeclareUnicodeCharacter{010A}{\dotaccent{C}} + \DeclareUnicodeCharacter{010B}{\dotaccent{c}} + \DeclareUnicodeCharacter{010C}{\v{C}} + \DeclareUnicodeCharacter{010D}{\v{c}} + \DeclareUnicodeCharacter{010E}{\v{D}} + + \DeclareUnicodeCharacter{0112}{\=E} + \DeclareUnicodeCharacter{0113}{\=e} + \DeclareUnicodeCharacter{0114}{\u{E}} + \DeclareUnicodeCharacter{0115}{\u{e}} + \DeclareUnicodeCharacter{0116}{\dotaccent{E}} + \DeclareUnicodeCharacter{0117}{\dotaccent{e}} + \DeclareUnicodeCharacter{011A}{\v{E}} + \DeclareUnicodeCharacter{011B}{\v{e}} + \DeclareUnicodeCharacter{011C}{\^G} + \DeclareUnicodeCharacter{011D}{\^g} + \DeclareUnicodeCharacter{011E}{\u{G}} + \DeclareUnicodeCharacter{011F}{\u{g}} + + \DeclareUnicodeCharacter{0120}{\dotaccent{G}} + \DeclareUnicodeCharacter{0121}{\dotaccent{g}} + \DeclareUnicodeCharacter{0124}{\^H} + \DeclareUnicodeCharacter{0125}{\^h} + \DeclareUnicodeCharacter{0128}{\~I} + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} + \DeclareUnicodeCharacter{012A}{\=I} + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} + \DeclareUnicodeCharacter{012C}{\u{I}} + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} + + \DeclareUnicodeCharacter{0130}{\dotaccent{I}} + \DeclareUnicodeCharacter{0131}{\dotless{i}} + \DeclareUnicodeCharacter{0132}{IJ} + \DeclareUnicodeCharacter{0133}{ij} + \DeclareUnicodeCharacter{0134}{\^J} + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} + \DeclareUnicodeCharacter{0139}{\'L} + \DeclareUnicodeCharacter{013A}{\'l} + + \DeclareUnicodeCharacter{0141}{\L} + \DeclareUnicodeCharacter{0142}{\l} + \DeclareUnicodeCharacter{0143}{\'N} + \DeclareUnicodeCharacter{0144}{\'n} + \DeclareUnicodeCharacter{0147}{\v{N}} + \DeclareUnicodeCharacter{0148}{\v{n}} + \DeclareUnicodeCharacter{014C}{\=O} + \DeclareUnicodeCharacter{014D}{\=o} + \DeclareUnicodeCharacter{014E}{\u{O}} + \DeclareUnicodeCharacter{014F}{\u{o}} + + \DeclareUnicodeCharacter{0150}{\H{O}} + \DeclareUnicodeCharacter{0151}{\H{o}} + \DeclareUnicodeCharacter{0152}{\OE} + \DeclareUnicodeCharacter{0153}{\oe} + \DeclareUnicodeCharacter{0154}{\'R} + \DeclareUnicodeCharacter{0155}{\'r} + \DeclareUnicodeCharacter{0158}{\v{R}} + \DeclareUnicodeCharacter{0159}{\v{r}} + \DeclareUnicodeCharacter{015A}{\'S} + \DeclareUnicodeCharacter{015B}{\'s} + \DeclareUnicodeCharacter{015C}{\^S} + \DeclareUnicodeCharacter{015D}{\^s} + \DeclareUnicodeCharacter{015E}{\cedilla{S}} + \DeclareUnicodeCharacter{015F}{\cedilla{s}} + + \DeclareUnicodeCharacter{0160}{\v{S}} + \DeclareUnicodeCharacter{0161}{\v{s}} + \DeclareUnicodeCharacter{0162}{\cedilla{t}} + \DeclareUnicodeCharacter{0163}{\cedilla{T}} + \DeclareUnicodeCharacter{0164}{\v{T}} + + \DeclareUnicodeCharacter{0168}{\~U} + \DeclareUnicodeCharacter{0169}{\~u} + \DeclareUnicodeCharacter{016A}{\=U} + \DeclareUnicodeCharacter{016B}{\=u} + \DeclareUnicodeCharacter{016C}{\u{U}} + \DeclareUnicodeCharacter{016D}{\u{u}} + \DeclareUnicodeCharacter{016E}{\ringaccent{U}} + \DeclareUnicodeCharacter{016F}{\ringaccent{u}} + + \DeclareUnicodeCharacter{0170}{\H{U}} + \DeclareUnicodeCharacter{0171}{\H{u}} + \DeclareUnicodeCharacter{0174}{\^W} + \DeclareUnicodeCharacter{0175}{\^w} + \DeclareUnicodeCharacter{0176}{\^Y} + \DeclareUnicodeCharacter{0177}{\^y} + \DeclareUnicodeCharacter{0178}{\"Y} + \DeclareUnicodeCharacter{0179}{\'Z} + \DeclareUnicodeCharacter{017A}{\'z} + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} + \DeclareUnicodeCharacter{017C}{\dotaccent{z}} + \DeclareUnicodeCharacter{017D}{\v{Z}} + \DeclareUnicodeCharacter{017E}{\v{z}} + + \DeclareUnicodeCharacter{01C4}{D\v{Z}} + \DeclareUnicodeCharacter{01C5}{D\v{z}} + \DeclareUnicodeCharacter{01C6}{d\v{z}} + \DeclareUnicodeCharacter{01C7}{LJ} + \DeclareUnicodeCharacter{01C8}{Lj} + \DeclareUnicodeCharacter{01C9}{lj} + \DeclareUnicodeCharacter{01CA}{NJ} + \DeclareUnicodeCharacter{01CB}{Nj} + \DeclareUnicodeCharacter{01CC}{nj} + \DeclareUnicodeCharacter{01CD}{\v{A}} + \DeclareUnicodeCharacter{01CE}{\v{a}} + \DeclareUnicodeCharacter{01CF}{\v{I}} + + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} + \DeclareUnicodeCharacter{01D1}{\v{O}} + \DeclareUnicodeCharacter{01D2}{\v{o}} + \DeclareUnicodeCharacter{01D3}{\v{U}} + \DeclareUnicodeCharacter{01D4}{\v{u}} + + \DeclareUnicodeCharacter{01E2}{\={\AE}} + \DeclareUnicodeCharacter{01E3}{\={\ae}} + \DeclareUnicodeCharacter{01E6}{\v{G}} + \DeclareUnicodeCharacter{01E7}{\v{g}} + \DeclareUnicodeCharacter{01E8}{\v{K}} + \DeclareUnicodeCharacter{01E9}{\v{k}} + + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} + \DeclareUnicodeCharacter{01F1}{DZ} + \DeclareUnicodeCharacter{01F2}{Dz} + \DeclareUnicodeCharacter{01F3}{dz} + \DeclareUnicodeCharacter{01F4}{\'G} + \DeclareUnicodeCharacter{01F5}{\'g} + \DeclareUnicodeCharacter{01F8}{\`N} + \DeclareUnicodeCharacter{01F9}{\`n} + \DeclareUnicodeCharacter{01FC}{\'{\AE}} + \DeclareUnicodeCharacter{01FD}{\'{\ae}} + \DeclareUnicodeCharacter{01FE}{\'{\O}} + \DeclareUnicodeCharacter{01FF}{\'{\o}} + + \DeclareUnicodeCharacter{021E}{\v{H}} + \DeclareUnicodeCharacter{021F}{\v{h}} + + \DeclareUnicodeCharacter{0226}{\dotaccent{A}} + \DeclareUnicodeCharacter{0227}{\dotaccent{a}} + \DeclareUnicodeCharacter{0228}{\cedilla{E}} + \DeclareUnicodeCharacter{0229}{\cedilla{e}} + \DeclareUnicodeCharacter{022E}{\dotaccent{O}} + \DeclareUnicodeCharacter{022F}{\dotaccent{o}} + + \DeclareUnicodeCharacter{0232}{\=Y} + \DeclareUnicodeCharacter{0233}{\=y} + \DeclareUnicodeCharacter{0237}{\dotless{j}} + + \DeclareUnicodeCharacter{02DB}{\ogonek{ }} + + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} + + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} + + \DeclareUnicodeCharacter{1E20}{\=G} + \DeclareUnicodeCharacter{1E21}{\=g} + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} + \DeclareUnicodeCharacter{1E26}{\"H} + \DeclareUnicodeCharacter{1E27}{\"h} + + \DeclareUnicodeCharacter{1E30}{\'K} + \DeclareUnicodeCharacter{1E31}{\'k} + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} + \DeclareUnicodeCharacter{1E3E}{\'M} + \DeclareUnicodeCharacter{1E3F}{\'m} + + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} + + \DeclareUnicodeCharacter{1E54}{\'P} + \DeclareUnicodeCharacter{1E55}{\'p} + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} + + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} + + \DeclareUnicodeCharacter{1E7C}{\~V} + \DeclareUnicodeCharacter{1E7D}{\~v} + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} + + \DeclareUnicodeCharacter{1E80}{\`W} + \DeclareUnicodeCharacter{1E81}{\`w} + \DeclareUnicodeCharacter{1E82}{\'W} + \DeclareUnicodeCharacter{1E83}{\'w} + \DeclareUnicodeCharacter{1E84}{\"W} + \DeclareUnicodeCharacter{1E85}{\"w} + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} + \DeclareUnicodeCharacter{1E8C}{\"X} + \DeclareUnicodeCharacter{1E8D}{\"x} + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} + + \DeclareUnicodeCharacter{1E90}{\^Z} + \DeclareUnicodeCharacter{1E91}{\^z} + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} + \DeclareUnicodeCharacter{1E97}{\"t} + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} + + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} + + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} + \DeclareUnicodeCharacter{1EBC}{\~E} + \DeclareUnicodeCharacter{1EBD}{\~e} + + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} + + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} + + \DeclareUnicodeCharacter{1EF2}{\`Y} + \DeclareUnicodeCharacter{1EF3}{\`y} + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} + + \DeclareUnicodeCharacter{1EF8}{\~Y} + \DeclareUnicodeCharacter{1EF9}{\~y} + + \DeclareUnicodeCharacter{2013}{--} + \DeclareUnicodeCharacter{2014}{---} + \DeclareUnicodeCharacter{2018}{\quoteleft} + \DeclareUnicodeCharacter{2019}{\quoteright} + \DeclareUnicodeCharacter{201A}{\quotesinglbase} + \DeclareUnicodeCharacter{201C}{\quotedblleft} + \DeclareUnicodeCharacter{201D}{\quotedblright} + \DeclareUnicodeCharacter{201E}{\quotedblbase} + \DeclareUnicodeCharacter{2022}{\bullet} + \DeclareUnicodeCharacter{2026}{\dots} + \DeclareUnicodeCharacter{2039}{\guilsinglleft} + \DeclareUnicodeCharacter{203A}{\guilsinglright} + \DeclareUnicodeCharacter{20AC}{\euro} + + \DeclareUnicodeCharacter{2192}{\expansion} + \DeclareUnicodeCharacter{21D2}{\result} + + \DeclareUnicodeCharacter{2212}{\minus} + \DeclareUnicodeCharacter{2217}{\point} + \DeclareUnicodeCharacter{2261}{\equiv} +}% end of \utfeightchardefs + + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\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, 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 + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \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{607.2pt}{6in}% that's 46 lines + {\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}% + {-.2in}{0in}% + {\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{673.2pt}{160mm}% that's 51 lines + {\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\relax + \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.} + +% DEL is a comment character, in case @c does not suffice. +\catcode`\^^? = 14 + +% 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 + @markupsetuplqdefault + @markupsetuprqdefault + @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 Finally, make ` and ' active, so that txicodequoteundirected and +@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +@c don't make ` and ' active, @code will not get them as active chars. +@c Do this last of all since we use ` in the previous @catcode assignments. +@catcode`@'=@active +@catcode`@`=@active +@markupsetuplqdefault +@markupsetuprqdefault + +@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 diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 0000000..4115b4e --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,80 @@ +@SET_MAKE@ + +srcdir = @srcdir@ +VPATH = @srcdir@ + +top_srcdir = @top_srcdir@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = $(INSTALL_PROGRAM) -s +MKDIR_P = @MKDIR_P@ + +include ../config.make + +PRE_CPPFLAGS = -I.. -I$(top_srcdir) +PRE_LDFLAGS = -L.. + +HOGWEED_TARGETS = pkcs1-conv$(EXEEXT) +TARGETS = sexp-conv$(EXEEXT) nettle-lfib-stream$(EXEEXT) \ + @IF_HOGWEED@ $(HOGWEED_TARGETS) + +all: $(TARGETS) + +sexp_conv_SOURCES = sexp-conv.c input.c output.c parse.c \ + getopt.c getopt1.c misc.c +pkcs1_conv_SOURCES = pkcs1-conv.c getopt.c getopt1.c misc.c + +SOURCES = $(sexp_conv_SOURCES) nettle-lfib-stream.c pkcs1-conv.c + +DISTFILES = $(SOURCES) Makefile.in getopt.h input.h misc.h output.h parse.h + +sexp_conv_OBJS = $(sexp_conv_SOURCES:.c=.$(OBJEXT)) +sexp-conv$(EXEEXT): $(sexp_conv_OBJS) ../libnettle.a + $(LINK) $(sexp_conv_OBJS) -lnettle $(LIBS) -o $@ + +nettle-lfib-stream$(EXEEXT): nettle-lfib-stream.$(OBJEXT) ../libnettle.a + $(LINK) nettle-lfib-stream.$(OBJEXT) -lnettle $(LIBS) -o $@ + +pkcs1_conv_OBJS = $(pkcs1_conv_SOURCES:.c=.$(OBJEXT)) +pkcs1-conv$(EXEEXT): $(pkcs1_conv_OBJS) ../libnettle.a ../libhogweed.a + $(LINK) $(pkcs1_conv_OBJS) -lhogweed -lnettle $(LIBS) -o $@ + +.c.$(OBJEXT): + $(COMPILE) -c $< && $(DEP_PROCESS) + + +Makefile: $(srcdir)/Makefile.in ../config.status + cd .. && $(SHELL) ./config.status tools/$@ + +check: + true + +install: $(TARGETS) + $(MKDIR_P) $(DESTDIR)$(bindir) + for f in $(TARGETS) ; do \ + $(INSTALL_PROGRAM) $$f $(DESTDIR)$(bindir) ; \ + done + +uninstall: + for f in $(TARGETS) ; do \ + rm -f $(DESTDIR)$(bindir)/$$f ; \ + done + +# NOTE: I'd like to use $^, but that's a GNU extension. $? should be +# more portable, equivalent for phony targets. +distdir: $(DISTFILES) + cp $? $(distdir) + +clean: + -rm -f $(TARGETS) *.o + +distclean: clean + -rm -f Makefile *.d + +tags: + etags -o $(srcdir)/TAGS --include $(top_srcdir) $(srcdir)/*.c $(srcdir)/*.h + +@DEP_INCLUDE@ $(SOURCES:.c=.$(OBJEXT).d) diff --git a/tools/getopt.c b/tools/getopt.c new file mode 100644 index 0000000..ed32692 --- /dev/null +++ b/tools/getopt.c @@ -0,0 +1,1067 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifndef _ +# define _(msgid) gettext (msgid) +# endif +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +#ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; +#endif + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/tools/getopt.h b/tools/getopt.h new file mode 100644 index 0000000..76cf5ee --- /dev/null +++ b/tools/getopt.h @@ -0,0 +1,179 @@ +/* Declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if (defined __STDC__ && __STDC__) || defined __cplusplus + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if (defined __STDC__ && __STDC__) || defined __cplusplus +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/tools/getopt1.c b/tools/getopt1.c new file mode 100644 index 0000000..62c55cf --- /dev/null +++ b/tools/getopt1.c @@ -0,0 +1,187 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/tools/input.c b/tools/input.c new file mode 100644 index 0000000..8dd7d0c --- /dev/null +++ b/tools/input.c @@ -0,0 +1,442 @@ +/* input.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "input.h" + +void +sexp_input_init(struct sexp_input *input, FILE *f) +{ + input->f = f; + input->coding = NULL; +} + +static void +sexp_get_raw_char(struct sexp_input *input) +{ + int c = getc(input->f); + + if (c < 0) + { + if (ferror(input->f)) + die("Read error: %s\n", strerror(errno)); + + input->ctype = SEXP_EOF_CHAR; + } + else + { + input->ctype = SEXP_NORMAL_CHAR; + input->c = c; + } +} + +void +sexp_get_char(struct sexp_input *input) +{ + if (input->coding) + for (;;) + { + unsigned done; + + sexp_get_raw_char(input); + if (input->ctype == SEXP_EOF_CHAR) + die("Unexpected end of file in coded data.\n"); + + if (input->c == input->terminator) + { + input->ctype = SEXP_END_CHAR; + return; + } + + done = 1; + + /* Decodes in place. Should always work, when we decode one + * character at a time. */ + if (!input->coding->decode_update(&input->state, + &done, &input->c, + 1, &input->c)) + die("Invalid coded data.\n"); + + if (done) + return; + } + else + sexp_get_raw_char(input); +} + +static uint8_t +sexp_next_char(struct sexp_input *input) +{ + sexp_get_char(input); + if (input->ctype != SEXP_NORMAL_CHAR) + die("Unexpected end of file.\n"); + + return input->c; +} + +static void +sexp_push_char(struct sexp_input *input, + struct nettle_buffer *string) +{ + assert(input->ctype == SEXP_NORMAL_CHAR); + + if (!NETTLE_BUFFER_PUTC(string, input->c)) + die("Virtual memory exhasuted.\n"); +} + +static void +sexp_input_start_coding(struct sexp_input *input, + const struct nettle_armor *coding, + uint8_t terminator) +{ + assert(!input->coding); + + input->coding = coding; + input->coding->decode_init(&input->state); + input->terminator = terminator; +} + +static void +sexp_input_end_coding(struct sexp_input *input) +{ + assert(input->coding); + + if (!input->coding->decode_final(&input->state)) + die("Invalid coded data.\n"); + + input->coding = NULL; +} + + +/* Return 0 at end-of-string */ +static int +sexp_get_quoted_char(struct sexp_input *input) +{ + sexp_next_char(input); + + for (;;) + switch (input->c) + { + default: + return 1; + case '\"': + return 0; + case '\\': + sexp_next_char(input); + + switch (input->c) + { + case 'b': input->c = '\b'; return 1; + case 't': input->c = '\t'; return 1; + case 'n': input->c = '\n'; return 1; + case 'f': input->c = '\f'; return 1; + case 'r': input->c = '\r'; return 1; + case '\\': input->c = '\\'; return 1; + case 'o': + case 'x': + /* FIXME: Not implemnted */ + abort(); + case '\n': + if (sexp_next_char(input) == '\r') + sexp_next_char(input); + + break; + case '\r': + if (sexp_next_char(input) == '\n') + sexp_next_char(input); + + break; + } + return 1; + } +} + +static void +sexp_get_token_string(struct sexp_input *input, + struct nettle_buffer *string) +{ + assert(!input->coding); + assert(input->ctype == SEXP_NORMAL_CHAR); + + if (!TOKEN_CHAR(input->c)) + die("Invalid token.\n"); + + do + { + sexp_push_char(input, string); + sexp_get_char(input); + } + while (input->ctype == SEXP_NORMAL_CHAR && TOKEN_CHAR(input->c)); + + assert (string->size); +} + +static void +sexp_get_string(struct sexp_input *input, + struct nettle_buffer *string) +{ + nettle_buffer_reset(string); + input->token = SEXP_STRING; + + switch (input->c) + { + case '\"': + while (sexp_get_quoted_char(input)) + sexp_push_char(input, string); + + sexp_get_char(input); + break; + + case '#': + sexp_input_start_coding(input, &nettle_base16, '#'); + goto decode; + + case '|': + sexp_input_start_coding(input, &nettle_base64, '|'); + + decode: + for (;;) + { + sexp_get_char(input); + switch (input->ctype) + { + case SEXP_NORMAL_CHAR: + sexp_push_char(input, string); + break; + case SEXP_EOF_CHAR: + die("Unexpected end of file in coded string.\n"); + case SEXP_END_CHAR: + sexp_input_end_coding(input); + sexp_get_char(input); + return; + } + } + + break; + + default: + sexp_get_token_string(input, string); + break; + } +} + +static void +sexp_get_string_length(struct sexp_input *input, enum sexp_mode mode, + struct nettle_buffer *string) +{ + unsigned length; + + nettle_buffer_reset(string); + input->token = SEXP_STRING; + + length = input->c - '0'; + + if (!length) + /* There must be no more digits */ + sexp_next_char(input); + + else + { + assert(length < 10); + /* Get rest of digits */ + for (;;) + { + sexp_next_char(input); + + if (input->c < '0' || input->c > '9') + break; + + /* FIXME: Check for overflow? */ + length = length * 10 + input->c - '0'; + } + } + + switch(input->c) + { + case ':': + /* Verbatim */ + for (; length; length--) + { + sexp_next_char(input); + sexp_push_char(input, string); + } + + break; + + case '"': + if (mode != SEXP_ADVANCED) + die("Encountered quoted string in canonical mode.\n"); + + for (; length; length--) + if (sexp_get_quoted_char(input)) + sexp_push_char(input, string); + else + die("Unexpected end of string.\n"); + + if (sexp_get_quoted_char(input)) + die("Quoted string longer than expected.\n"); + + break; + + case '#': + sexp_input_start_coding(input, &nettle_base16, '#'); + goto decode; + + case '|': + sexp_input_start_coding(input, &nettle_base64, '|'); + + decode: + for (; length; length--) + { + sexp_next_char(input); + sexp_push_char(input, string); + } + sexp_get_char(input); + if (input->ctype != SEXP_END_CHAR) + die("Coded string too long.\n"); + + sexp_input_end_coding(input); + + break; + + default: + die("Invalid string.\n"); + } + + /* Skip the ending character. */ + sexp_get_char(input); +} + +static void +sexp_get_comment(struct sexp_input *input, struct nettle_buffer *string) +{ + nettle_buffer_reset(string); + + assert(input->ctype == SEXP_NORMAL_CHAR); + assert(input->c == ';'); + + do + { + sexp_push_char(input, string); + sexp_get_raw_char(input); + } + while (input->ctype == SEXP_NORMAL_CHAR && input->c != '\n'); + + input->token = SEXP_COMMENT; +} + +/* When called, input->c should be the first character of the current + * token. + * + * When returning, input->c should be the first character of the next + * token. */ +void +sexp_get_token(struct sexp_input *input, enum sexp_mode mode, + struct nettle_buffer *string) +{ + for(;;) + switch(input->ctype) + { + case SEXP_EOF_CHAR: + input->token = SEXP_EOF; + return; + + case SEXP_END_CHAR: + input->token = SEXP_CODING_END; + sexp_input_end_coding(input); + sexp_get_char(input); + return; + + case SEXP_NORMAL_CHAR: + switch(input->c) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + sexp_get_string_length(input, mode, string); + return; + + case '(': + input->token = SEXP_LIST_START; + sexp_get_char(input); + return; + + case ')': + input->token = SEXP_LIST_END; + sexp_get_char(input); + return; + + case '[': + input->token = SEXP_DISPLAY_START; + sexp_get_char(input); + return; + + case ']': + input->token = SEXP_DISPLAY_END; + sexp_get_char(input); + return; + + case '{': + if (mode == SEXP_CANONICAL) + die("Unexpected transport data in canonical mode.\n"); + + sexp_input_start_coding(input, &nettle_base64, '}'); + sexp_get_char(input); + + input->token = SEXP_TRANSPORT_START; + + return; + + case ' ': /* SPC, TAB, LF, CR */ + case '\t': + case '\n': + case '\r': + if (mode == SEXP_CANONICAL) + die("Whitespace encountered in canonical mode.\n"); + + sexp_get_char(input); + break; + + case ';': /* Comments */ + if (mode == SEXP_CANONICAL) + die("Comment encountered in canonical mode.\n"); + + sexp_get_comment(input, string); + return; + + default: + /* Ought to be a string */ + if (mode != SEXP_ADVANCED) + die("Encountered advanced string in canonical mode.\n"); + + sexp_get_string(input, string); + return; + } + } +} diff --git a/tools/input.h b/tools/input.h new file mode 100644 index 0000000..5c59add --- /dev/null +++ b/tools/input.h @@ -0,0 +1,76 @@ +/* input.h */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_TOOLS_INPUT_H_INCLUDED +#define NETTLE_TOOLS_INPUT_H_INCLUDED + +#include "misc.h" + +#include "base16.h" +#include "base64.h" +#include "buffer.h" +#include "nettle-meta.h" + +#include + +/* Special marks in the input stream */ +enum sexp_char_type + { + SEXP_NORMAL_CHAR = 0, + SEXP_EOF_CHAR, SEXP_END_CHAR, + }; + +struct sexp_input +{ + FILE *f; + + /* Character stream, consisting of ordinary characters, + * SEXP_EOF_CHAR, and SEXP_END_CHAR. */ + enum sexp_char_type ctype; + uint8_t c; + + const struct nettle_armor *coding; + + union { + struct base64_decode_ctx base64; + struct base16_decode_ctx hex; + } state; + + /* Terminator for current coding */ + uint8_t terminator; + + /* Type of current token */ + enum sexp_token token; +}; + +void +sexp_input_init(struct sexp_input *input, FILE *f); + +void +sexp_get_char(struct sexp_input *input); + +void +sexp_get_token(struct sexp_input *input, enum sexp_mode mode, + struct nettle_buffer *string); + + +#endif /* NETTLE_TOOLS_INPUT_H_INCLUDED */ diff --git a/tools/misc.c b/tools/misc.c new file mode 100644 index 0000000..c49f81b --- /dev/null +++ b/tools/misc.c @@ -0,0 +1,73 @@ +/* misc.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "misc.h" + +void +die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(EXIT_FAILURE); +} + +void +werror(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(EXIT_FAILURE); +} + +const char +sexp_token_chars[0x80] = + { + /* 0, ... 0x1f */ + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +/* SPC ! " # $ % & ' ( ) * + , - . / */ + 0,0,0,0,0,0,0,0, 0,0,1,1,0,1,1,1, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + 1,1,1,1,1,1,1,1, 1,1,1,0,0,1,0,0, + /* @ A ... O */ + 0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + /* P ... Z [ \ ] ^ _ */ + 1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,1, + /* ` a, ... o */ + 0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + /* p ... z { | } ~ DEL */ + 1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,0, + }; diff --git a/tools/misc.h b/tools/misc.h new file mode 100644 index 0000000..ee5afcd --- /dev/null +++ b/tools/misc.h @@ -0,0 +1,75 @@ +/* misc.h */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_TOOLS_MISC_H_INCLUDED +#define NETTLE_TOOLS_MISC_H_INCLUDED + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +void +die(const char *format, ...) +#if __GNUC___ + __attribute__((__format__ (__printf__,1, 2))) + __attribute__((__noreturn__)) +#endif + ; + +void +werror(const char *format, ...) +#if __GNUC___ + __attribute__((__format__ (__printf__,1, 2))) + __attribute__((__noreturn__)) +#endif + ; + +enum sexp_mode + { + SEXP_CANONICAL = 0, + SEXP_ADVANCED = 1, + SEXP_TRANSPORT = 2, + }; + +enum sexp_token + { + SEXP_STRING, + SEXP_DISPLAY, /* Constructed by sexp_parse */ + SEXP_COMMENT, + SEXP_LIST_START, + SEXP_LIST_END, + SEXP_EOF, + + /* The below types are internal to the input parsing. sexp_parse + * should never return a token of this type. */ + SEXP_DISPLAY_START, + SEXP_DISPLAY_END, + SEXP_TRANSPORT_START, + SEXP_CODING_END, + }; + +extern const char +sexp_token_chars[0x80]; + +#define TOKEN_CHAR(c) ((c) < 0x80 && sexp_token_chars[(c)]) + +#endif /* NETTLE_TOOLS_MISC_H_INCLUDED */ diff --git a/tools/nettle-lfib-stream.c b/tools/nettle-lfib-stream.c new file mode 100644 index 0000000..f666900 --- /dev/null +++ b/tools/nettle-lfib-stream.c @@ -0,0 +1,81 @@ +/* lfib-stream.c + * + * Generates a pseudorandom stream, using the Knuth lfib + * (non-cryptographic) pseudorandom generator. + * + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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 "knuth-lfib.h" + +#include +#include +#include + +#include + +#define BUFSIZE 500 + +static void +usage(void) +{ + fprintf(stderr, "Usage: lfib-stream [SEED]\n"); +} + +int +main(int argc, char **argv) +{ + struct knuth_lfib_ctx ctx; + uint32_t seed; + + if (argc == 1) + seed = time(NULL); + + else if (argc == 2) + { + seed = atoi(argv[1]); + if (!seed) + { + usage(); + return EXIT_FAILURE; + } + } + else + { + usage(); + return EXIT_FAILURE; + } + + knuth_lfib_init(&ctx, seed); + + for (;;) + { + char buffer[BUFSIZE]; + knuth_lfib_random(&ctx, BUFSIZE, buffer); + + if (fwrite(buffer, 1, BUFSIZE, stdout) < BUFSIZE + || fflush(stdout) < 0) + return EXIT_FAILURE; + } + + /* Not reached. This program is usually terminated by SIGPIPE */ +} diff --git a/tools/output.c b/tools/output.c new file mode 100644 index 0000000..d491d9a --- /dev/null +++ b/tools/output.c @@ -0,0 +1,303 @@ +/* output.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "output.h" + +/* For TMP_ALLOC */ +#include "nettle-internal.h" + +void +sexp_output_init(struct sexp_output *output, FILE *f, + unsigned width, int prefer_hex) +{ + output->f = f; + output->line_width = width; + output->coding = NULL; + output->prefer_hex = prefer_hex; + output->hash = NULL; + output->ctx = NULL; + + output->pos = 0; + output->soft_newline = 0; +} + +void +sexp_output_hash_init(struct sexp_output *output, + const struct nettle_hash *hash, void *ctx) +{ + output->hash = hash; + output->ctx = ctx; + hash->init(ctx); +} + +static void +sexp_put_raw_char(struct sexp_output *output, uint8_t c) +{ + if (putc(c, output->f) < 0) + die("Write failed: %s\n", strerror(errno)); + + output->pos++; + output->soft_newline = 0; +} + +void +sexp_put_newline(struct sexp_output *output, + unsigned indent) +{ + if (output->soft_newline) + output->soft_newline = 0; + else + { + unsigned i; + + sexp_put_raw_char(output, '\n'); + output->pos = 0; + + for(i = 0; i < indent; i++) + sexp_put_raw_char(output, ' '); + + output->pos = indent; + } +} + +/* Put a newline, but only if it is followed by another newline, + collaps to one newline only. */ +void +sexp_put_soft_newline(struct sexp_output *output, + unsigned indent) +{ + sexp_put_newline(output, indent); + output->soft_newline = 1; +} + +void +sexp_put_char(struct sexp_output *output, uint8_t c) +{ + if (output->coding) + { + /* Two is enough for both base16 and base64. */ + uint8_t encoded[2]; + unsigned done; + + unsigned i; + + done = output->coding->encode_update(&output->base64, encoded, + 1, &c); + assert(done <= sizeof(encoded)); + + for (i = 0; iline_width + && output->pos >= output->line_width + && output->pos >= (output->coding_indent + 10)) + sexp_put_newline(output, output->coding_indent); + + sexp_put_raw_char(output, encoded[i]); + } + } + else if (output->hash) + output->hash->update(output->ctx, 1, &c); + else + sexp_put_raw_char(output, c); +} + +void +sexp_put_data(struct sexp_output *output, + unsigned length, const uint8_t *data) +{ + unsigned i; + + for (i = 0; i length) + break; + digit = next; + } + + for (; digit; length %= digit, digit /= 10) + sexp_put_char(output, '0' + length / digit); +} + +void +sexp_put_code_start(struct sexp_output *output, + const struct nettle_armor *coding) +{ + assert(!output->coding); + + output->coding_indent = output->pos; + + output->coding = coding; + output->coding->encode_init(&output->base64); +} + +void +sexp_put_code_end(struct sexp_output *output) +{ + /* Enough for both hex and base64 */ + uint8_t encoded[BASE64_ENCODE_FINAL_LENGTH]; + unsigned done; + + assert(output->coding); + + done = output->coding->encode_final(&output->base64, encoded); + + assert(done <= sizeof(encoded)); + + output->coding = NULL; + + sexp_put_data(output, done, encoded); +} + +void +sexp_put_string(struct sexp_output *output, enum sexp_mode mode, + struct nettle_buffer *string) +{ + if (!string->size) + sexp_put_data(output, 2, + (mode == SEXP_ADVANCED) ? "\"\"": "0:"); + + else if (mode == SEXP_ADVANCED) + { + unsigned i; + int token = (string->contents[0] < '0' || string->contents[0] > '9'); + int quote_friendly = 1; +#define CONTROL_SIZE 0x20 + static const char escape_names[CONTROL_SIZE] = + { + 0,0,0,0,0,0,0,0, 'b','t','n',0,'f','r',0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 + }; + + for (i = 0; isize; i++) + { + uint8_t c = string->contents[i]; + + if (token & !TOKEN_CHAR(c)) + token = 0; + + if (quote_friendly) + { + if (c >= 0x7f) + quote_friendly = 0; + else if (c < CONTROL_SIZE && !escape_names[c]) + quote_friendly = 0; + } + } + + if (token) + sexp_put_data(output, string->size, string->contents); + + else if (quote_friendly) + { + sexp_put_char(output, '"'); + + for (i = 0; isize; i++) + { + int escape = 0; + uint8_t c = string->contents[i]; + + assert(c < 0x7f); + + if (c == '\\' || c == '"') + escape = 1; + else if (c < CONTROL_SIZE) + { + escape = 1; + c = escape_names[c]; + assert(c); + } + if (escape) + sexp_put_char(output, '\\'); + + sexp_put_char(output, c); + } + + sexp_put_char(output, '"'); + } + else + { + uint8_t delimiter; + const struct nettle_armor *coding; + + if (output->prefer_hex) + { + delimiter = '#'; + coding = &nettle_base16; + } + else + { + delimiter = '|'; + coding = &nettle_base64; + } + + sexp_put_char(output, delimiter); + sexp_put_code_start(output, coding); + sexp_put_data(output, string->size, string->contents); + sexp_put_code_end(output); + sexp_put_char(output, delimiter); + } +#undef CONTROL_SIZE + } + else + { + sexp_put_length(output, string->size); + sexp_put_char(output, ':'); + sexp_put_data(output, string->size, string->contents); + } +} + +void +sexp_put_digest(struct sexp_output *output) +{ + TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_ALLOC(digest, output->hash->digest_size); + + assert(output->hash); + + output->hash->digest(output->ctx, output->hash->digest_size, digest); + + sexp_put_code_start(output, &nettle_base16); + sexp_put_data(output, output->hash->digest_size, digest); + sexp_put_code_end(output); +} + diff --git a/tools/output.h b/tools/output.h new file mode 100644 index 0000000..8ac5256 --- /dev/null +++ b/tools/output.h @@ -0,0 +1,93 @@ +/* output.h */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_TOOLS_OUTPUT_H_INCLUDED +#define NETTLE_TOOLS_OUTPUT_H_INCLUDED + +#include "misc.h" + +#include "base64.h" +#include "buffer.h" +#include "nettle-meta.h" + +#include + +struct sexp_output +{ + FILE *f; + + unsigned line_width; + + const struct nettle_armor *coding; + unsigned coding_indent; + + int prefer_hex; + + const struct nettle_hash *hash; + void *ctx; + + /* NOTE: There's no context for hex encoding, the state argument to + encode_update is ignored */ + struct base64_decode_ctx base64; + + unsigned pos; + int soft_newline; +}; + +void +sexp_output_init(struct sexp_output *output, FILE *f, + unsigned width, int prefer_hex); + +void +sexp_output_hash_init(struct sexp_output *output, + const struct nettle_hash *hash, void *ctx); + +void +sexp_put_newline(struct sexp_output *output, + unsigned indent); + +void +sexp_put_soft_newline(struct sexp_output *output, + unsigned indent); + +void +sexp_put_char(struct sexp_output *output, uint8_t c); + +void +sexp_put_data(struct sexp_output *output, + unsigned length, const uint8_t *data); + +void +sexp_put_code_start(struct sexp_output *output, + const struct nettle_armor *coding); + +void +sexp_put_code_end(struct sexp_output *output); + +void +sexp_put_string(struct sexp_output *output, enum sexp_mode mode, + struct nettle_buffer *string); + +void +sexp_put_digest(struct sexp_output *output); + +#endif /* NETTLE_TOOLS_OUTPUT_H_INCLUDED */ diff --git a/tools/parse.c b/tools/parse.c new file mode 100644 index 0000000..292c6ce --- /dev/null +++ b/tools/parse.c @@ -0,0 +1,164 @@ +/* parse.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "parse.h" + +#include "input.h" + +void +sexp_compound_token_init(struct sexp_compound_token *token) +{ + token->type = 0; + nettle_buffer_init(&token->display); + nettle_buffer_init(&token->string); +} + +void +sexp_compound_token_clear(struct sexp_compound_token *token) +{ + nettle_buffer_clear(&token->display); + nettle_buffer_clear(&token->string); +} + +void +sexp_parse_init(struct sexp_parser *parser, + struct sexp_input *input, + enum sexp_mode mode) +{ + parser->input = input; + parser->mode = mode; + + /* Start counting with 1 for the top level, to make comparisons + * between transport and level simpler. + * + * FIXME: Is that trick ugly? */ + parser->level = 1; + parser->transport = 0; +} + +/* Get next token, and check that it is of the expected kind. */ +static void +sexp_check_token(struct sexp_parser *parser, + enum sexp_token token, + struct nettle_buffer *string) +{ + sexp_get_token(parser->input, + parser->transport ? SEXP_CANONICAL : parser->mode, + string); + + if (parser->input->token != token) + die("Syntax error.\n"); +} + +/* Performs further processing of the input, in particular display + * types and transport decoding. + * + * This is complicated a little by the requirement that a + * transport-encoded block, {xxxxx}, must include exactly one + * expression. We check at the end of strings and list whether or not + * we should expect a SEXP_CODING_END as the next token. */ +void +sexp_parse(struct sexp_parser *parser, + struct sexp_compound_token *token) +{ + for (;;) + { + sexp_get_token(parser->input, + parser->transport ? SEXP_CANONICAL : parser->mode, + &token->string); + + switch(parser->input->token) + { + case SEXP_LIST_END: + if (parser->level == parser->transport) + die("Unmatched end of list in transport encoded data.\n"); + parser->level--; + + if (!parser->level) + die("Unmatched end of list.\n"); + + token->type = SEXP_LIST_END; + + check_transport_end: + if (parser->level == parser->transport) + { + sexp_check_token(parser, SEXP_CODING_END, &token->string); + assert(parser->transport); + assert(parser->level == parser->transport); + + parser->level--; + parser->transport = 0; + } + return; + + case SEXP_EOF: + if (parser->level > 1) + die("Unexpected end of file.\n"); + + token->type = SEXP_EOF; + return; + + case SEXP_LIST_START: + parser->level++; + token->type = SEXP_LIST_START; + return; + + case SEXP_DISPLAY_START: + sexp_check_token(parser, SEXP_STRING, &token->display); + sexp_check_token(parser, SEXP_DISPLAY_END, &token->display); + sexp_check_token(parser, SEXP_STRING, &token->string); + + token->type = SEXP_DISPLAY; + goto check_transport_end; + + case SEXP_STRING: + token->type = SEXP_STRING; + goto check_transport_end; + + case SEXP_COMMENT: + token->type = SEXP_COMMENT; + return; + + case SEXP_TRANSPORT_START: + if (parser->mode == SEXP_CANONICAL) + die("Base64 not allowed in canonical mode.\n"); + parser->level++; + parser->transport = parser->level; + + continue; + + case SEXP_CODING_END: + die("Unexpected end of transport encoding.\n"); + + default: + /* Internal error. */ + abort(); + } + } +} diff --git a/tools/parse.h b/tools/parse.h new file mode 100644 index 0000000..df6f8b4 --- /dev/null +++ b/tools/parse.h @@ -0,0 +1,65 @@ +/* parse.h */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_TOOLS_PARSE_H_INCLUDED +#define NETTLE_TOOLS_PARSE_H_INCLUDED + +#include "misc.h" +#include "buffer.h" + +struct sexp_compound_token +{ + enum sexp_token type; + struct nettle_buffer display; + struct nettle_buffer string; +}; + +void +sexp_compound_token_init(struct sexp_compound_token *token); + +void +sexp_compound_token_clear(struct sexp_compound_token *token); + +struct sexp_parser +{ + struct sexp_input *input; + enum sexp_mode mode; + + /* Nesting level of lists. Transport encoding counts as one + * level of nesting. */ + unsigned level; + + /* The nesting level where the transport encoding occured. + * Zero if we're not currently using tranport encoding. */ + unsigned transport; +}; + +void +sexp_parse_init(struct sexp_parser *parser, + struct sexp_input *input, + enum sexp_mode mode); + +void +sexp_parse(struct sexp_parser *parser, + struct sexp_compound_token *token); + +#endif /* NETTLE_TOOLS_PARSE_H_INCLUDED */ diff --git a/tools/pkcs1-conv.c b/tools/pkcs1-conv.c new file mode 100644 index 0000000..158df5d --- /dev/null +++ b/tools/pkcs1-conv.c @@ -0,0 +1,649 @@ +/* pkcs1-conv.c + * + * Converting pkcs#1 and similar keys to sexp format. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "asn1.h" +#include "base64.h" +#include "buffer.h" +#include "rsa.h" +#include "dsa.h" + +#include "getopt.h" +#include "misc.h" + +enum object_type + { + RSA_PRIVATE_KEY = 0x200, + RSA_PUBLIC_KEY, + DSA_PRIVATE_KEY, + /* DSA public keys only supported as part of a + SubjectPublicKeyInfo, i.e., the GENERAL_PUBLIC_KEY case. */ + GENERAL_PUBLIC_KEY, + }; + +static int +write_file(struct nettle_buffer *buffer, FILE *f) +{ + size_t res = fwrite(buffer->contents, 1, buffer->size, f); + if (res < buffer->size) + { + werror("Write failed: %s.\n", strerror(errno)); + return 0; + } + else + return 1; +} + +/* Return 1 on success, 0 on error, -1 on eof */ +static int +read_line(struct nettle_buffer *buffer, FILE *f) +{ + int c; + + while ((c = getc(f)) != EOF) + { + if (!NETTLE_BUFFER_PUTC(buffer, c)) + return 0; + + if (c == '\n') + return 1; + } + if (ferror(f)) + { + werror("Read failed: %s\n", strerror(errno)); + return 0; + } + + else + return -1; +} + +static int +read_file(struct nettle_buffer *buffer, FILE *f) +{ + int c; + + while ((c = getc(f)) != EOF) + if (!NETTLE_BUFFER_PUTC(buffer, c)) + return 0; + + if (ferror(f)) + { + werror("Read failed: %s\n", strerror(errno)); + return 0; + } + else + return 1; +} + +static const uint8_t +pem_start_pattern[11] = "-----BEGIN "; + +static const uint8_t +pem_end_pattern[9] = "-----END "; + +static const uint8_t +pem_trailer_pattern[5] = "-----"; + +static const char +pem_ws[33] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, /* \t, \n, \v, \f, \r */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1 /* SPC */ +}; + +#define PEM_IS_SPACE(c) ((c) < sizeof(pem_ws) && pem_ws[(c)]) + +/* Returns 1 on match, otherwise 0. */ +static int +match_pem_start(unsigned length, const uint8_t *line, + unsigned *marker_start, + unsigned *marker_length) +{ + while (length > 0 && PEM_IS_SPACE(line[length - 1])) + length--; + + if (length > (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern)) + && memcmp(line, pem_start_pattern, sizeof(pem_start_pattern)) == 0 + && memcmp(line + length - sizeof(pem_trailer_pattern), + pem_trailer_pattern, sizeof(pem_trailer_pattern)) == 0) + { + *marker_start = 11; + *marker_length = length - (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern)); + + return 1; + } + else + return 0; +} + +/* Returns 1 on match, -1 if the line is of the right form except for + the marker, otherwise 0. */ +static int +match_pem_end(unsigned length, const uint8_t *line, + unsigned marker_length, + const uint8_t *marker) +{ + while (length > 0 && PEM_IS_SPACE(line[length - 1])) + length--; + + if (length > (sizeof(pem_end_pattern) + sizeof(pem_trailer_pattern)) + && memcmp(line, pem_end_pattern, sizeof(pem_end_pattern)) == 0 + && memcmp(line + length - sizeof(pem_trailer_pattern), + pem_trailer_pattern, sizeof(pem_trailer_pattern)) == 0) + { + /* Right form. Check marker */ + if (length == marker_length + (sizeof(pem_end_pattern) + sizeof(pem_trailer_pattern)) + && memcmp(line + sizeof(pem_end_pattern), marker, marker_length) == 0) + return 1; + else + return -1; + } + else + return 0; +} + +struct pem_info +{ + /* The FOO part in "-----BEGIN FOO-----" */ + unsigned marker_start; + unsigned marker_length; + unsigned data_start; + unsigned data_length; +}; + +static int +read_pem(struct nettle_buffer *buffer, FILE *f, + struct pem_info *info) +{ + /* Find start line */ + for (;;) + { + int res; + + nettle_buffer_reset(buffer); + + res = read_line(buffer, f); + if (res != 1) + return res; + + if (match_pem_start(buffer->size, buffer->contents, + &info->marker_start, &info->marker_length)) + break; + } + + /* NUL-terminate the marker. Don't care to check for embedded NULs. */ + buffer->contents[info->marker_start + info->marker_length] = 0; + + info->data_start = buffer->size; + + for (;;) + { + unsigned line_start = buffer->size; + + if (read_line(buffer, f) != 1) + return 0; + + switch (match_pem_end(buffer->size - line_start, + buffer->contents + line_start, + info->marker_length, + buffer->contents + info->marker_start)) + { + case 0: + break; + case -1: + werror("PEM END line doesn't match BEGIN.\n"); + return 0; + case 1: + /* Return base 64 data; let caller do the decoding */ + info->data_length = line_start - info->data_start; + return 1; + } + } +} + +static int +decode_base64(struct nettle_buffer *buffer, + unsigned start, unsigned *length) +{ + struct base64_decode_ctx ctx; + + base64_decode_init(&ctx); + + /* Decode in place */ + if (base64_decode_update(&ctx, + length, buffer->contents + start, + *length, buffer->contents + start) + && base64_decode_final(&ctx)) + return 1; + + else + { + werror("Invalid base64 date.\n"); + return 0; + } +} + +static int +convert_rsa_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data) +{ + struct rsa_public_key pub; + int res; + + rsa_public_key_init(&pub); + + if (rsa_keypair_from_der(&pub, NULL, 0, + length, data)) + { + /* Reuses the buffer */ + nettle_buffer_reset(buffer); + res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL); + } + else + { + werror("Invalid PKCS#1 public key.\n"); + res = 0; + } + rsa_public_key_clear(&pub); + return res; +} + +static int +convert_rsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data) +{ + struct rsa_public_key pub; + struct rsa_private_key priv; + int res; + + rsa_public_key_init(&pub); + rsa_private_key_init(&priv); + + if (rsa_keypair_from_der(&pub, &priv, 0, + length, data)) + { + /* Reuses the buffer */ + nettle_buffer_reset(buffer); + res = rsa_keypair_to_sexp(buffer, NULL, &pub, &priv); + } + else + { + werror("Invalid PKCS#1 private key.\n"); + res = 0; + } + rsa_public_key_clear(&pub); + rsa_private_key_clear(&priv); + + return res; +} + +static int +convert_dsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data) +{ + struct dsa_public_key pub; + struct dsa_private_key priv; + int res; + + dsa_public_key_init(&pub); + dsa_private_key_init(&priv); + + if (dsa_openssl_private_key_from_der(&pub, &priv, 0, + length, data)) + { + /* Reuses the buffer */ + nettle_buffer_reset(buffer); + res = dsa_keypair_to_sexp(buffer, NULL, &pub, &priv); + } + else + { + werror("Invalid OpenSSL private key.\n"); + res = 0; + } + dsa_public_key_clear(&pub); + dsa_private_key_clear(&priv); + + return res; +} + +/* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */ +static int +convert_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data) +{ + /* SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING + } + + AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters OPTIONAL + } + */ + struct asn1_der_iterator i; + struct asn1_der_iterator j; + int res = 0; + + if (asn1_der_iterator_first(&i, length, data) == ASN1_ITERATOR_CONSTRUCTED + && i.type == ASN1_SEQUENCE + && asn1_der_decode_constructed_last(&i) == ASN1_ITERATOR_CONSTRUCTED + && i.type == ASN1_SEQUENCE + + /* Use the j iterator to parse the algorithm identifier */ + && asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE + && j.type == ASN1_IDENTIFIER + && asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE + && i.type == ASN1_BITSTRING + + /* Use i to parse the object wrapped in the bit string.*/ + && asn1_der_decode_bitstring_last(&i)) + { + /* pkcs-1 { + iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) + modules(0) pkcs-1(1) + } + + -- + -- When rsaEncryption is used in an AlgorithmIdentifier the + -- parameters MUST be present and MUST be NULL. + -- + rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } + */ + static const uint8_t id_rsaEncryption[9] = + { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; + /* + -- + -- When dsa is used in an AlgorithmIdentifier the + -- parameters MUST be present and MUST NOT be NULL. + -- + dsa OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } + */ + static const uint8_t id_dsa[7] = + { 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 }; + + switch (j.length) + { + unknown: + default: + werror("SubjectPublicKeyInfo: Unsupported algorithm.\n"); + res = -1; + break; + + case 7: + if (memcmp(j.data, id_dsa, 7) == 0) + { + if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_CONSTRUCTED + && asn1_der_decode_constructed_last(&j) == ASN1_ITERATOR_PRIMITIVE) + { + struct dsa_public_key pub; + + dsa_public_key_init(&pub); + + if (dsa_params_from_der_iterator(&pub, 0, &i) + && dsa_public_key_from_der_iterator(&pub, 0, &j)) + { + nettle_buffer_reset(buffer); + res = dsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0; + } + } + if (!res) + werror("SubjectPublicKeyInfo: Invalid DSA key.\n"); + break; + } + else goto unknown; + case 9: + if (memcmp(j.data, id_rsaEncryption, 9) == 0) + { + if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_PRIMITIVE + && j.type == ASN1_NULL + && j.length == 0 + && asn1_der_iterator_next(&j) == ASN1_ITERATOR_END) + { + struct rsa_public_key pub; + + rsa_public_key_init(&pub); + + if (rsa_public_key_from_der_iterator(&pub, 0, &i)) + { + nettle_buffer_reset(buffer); + res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0; + } + } + if (!res) + werror("SubjectPublicKeyInfo: Invalid RSA key.\n"); + break; + } + else goto unknown; + } + } + else + werror("SubjectPublicKeyInfo: Invalid object.\n"); + + return res; +} + +/* NOTE: Destroys contents of buffer */ +/* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */ +static int +convert_type(struct nettle_buffer *buffer, + enum object_type type, + unsigned length, const uint8_t *data) +{ + int res; + + switch(type) + { + default: + abort(); + + case GENERAL_PUBLIC_KEY: + res = convert_public_key(buffer, length, data); + break; + + case RSA_PUBLIC_KEY: + res = convert_rsa_public_key(buffer, length, data); + break; + + case RSA_PRIVATE_KEY: + res = convert_rsa_private_key(buffer, length, data); + break; + + case DSA_PRIVATE_KEY: + res = convert_dsa_private_key(buffer, length, data); + break; + } + + if (res > 0) + res = write_file(buffer, stdout); + + return res; +} + +static int +convert_file(struct nettle_buffer *buffer, + FILE *f, + enum object_type type, + int base64) +{ + if (type) + { + read_file(buffer, f); + if (base64 && !decode_base64(buffer, 0, &buffer->size)) + return 0; + + if (convert_type(buffer, type, + buffer->size, buffer->contents) != 1) + return 0; + + return 1; + } + else + { + /* PEM processing */ + for (;;) + { + struct pem_info info; + const uint8_t *marker; + + nettle_buffer_reset(buffer); + switch (read_pem(buffer, f, &info)) + { + default: + return 0; + case 1: + break; + case -1: + /* EOF */ + return 1; + } + + if (!decode_base64(buffer, info.data_start, &info.data_length)) + return 0; + + marker = buffer->contents + info.marker_start; + + type = 0; + switch (info.marker_length) + { + case 10: + if (memcmp(marker, "PUBLIC KEY", 10) == 0) + { + type = GENERAL_PUBLIC_KEY; + break; + } + case 14: + if (memcmp(marker, "RSA PUBLIC KEY", 14) == 0) + { + type = RSA_PUBLIC_KEY; + break; + } + + case 15: + if (memcmp(marker, "RSA PRIVATE KEY", 15) == 0) + { + type = RSA_PRIVATE_KEY; + break; + } + if (memcmp(marker, "DSA PRIVATE KEY", 15) == 0) + { + type = DSA_PRIVATE_KEY; + break; + } + } + + if (!type) + werror("Ignoring unsupported object type `%s'.\n", marker); + + else if (convert_type(buffer, type, + info.data_length, + buffer->contents + info.data_start) != 1) + return 0; + } + } +} + + +int +main(int argc, char **argv) +{ + struct nettle_buffer buffer; + enum object_type type = 0; + int base64 = 0; + int c; + + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "version", no_argument, NULL, 'V' }, + { "private-rsa-key", no_argument, NULL, RSA_PRIVATE_KEY }, + { "public-rsa-key", no_argument, NULL, RSA_PUBLIC_KEY }, + { "private-dsa-key", no_argument, NULL, DSA_PRIVATE_KEY }, + { "public-key-info", no_argument, NULL, GENERAL_PUBLIC_KEY }, + { "base-64", no_argument, NULL, 'b' }, + { NULL, 0, NULL, 0 } + }; + + while ( (c = getopt_long(argc, argv, "V?b", options, NULL)) != -1) + { + switch (c) + { + default: + abort(); + + case 'b': + base64 = 1; + break; + + case RSA_PRIVATE_KEY: + case RSA_PUBLIC_KEY: + case DSA_PRIVATE_KEY: + case GENERAL_PUBLIC_KEY: + type = c; + break; + + case '?': + printf("FIXME: Usage information.\n"); + return EXIT_SUCCESS; + + case 'V': + printf("pkcs1-conv (" PACKAGE_STRING ")\n"); + exit (EXIT_SUCCESS); + } + } + + nettle_buffer_init_realloc(&buffer, NULL, nettle_xrealloc); + + if (optind == argc) + { + if (!convert_file(&buffer, stdin, type, base64)) + return EXIT_FAILURE; + } + else + { + int i; + const char *mode = (type || base64) ? "r" : "rb"; + + for (i = optind; i < argc; i++) + { + FILE *f = fopen(argv[i], mode); + if (!f) + die("Failed to open `%s': %s.\n", argv[i], strerror(errno)); + + if (!convert_file(&buffer, f, type, base64)) + return EXIT_FAILURE; + + fclose(f); + } + } + return EXIT_SUCCESS; +} diff --git a/tools/sexp-conv.c b/tools/sexp-conv.c new file mode 100644 index 0000000..4b08a9c --- /dev/null +++ b/tools/sexp-conv.c @@ -0,0 +1,442 @@ +/* sexp-conv.c + * + * Conversion tool for handling the different flavours of sexp + * syntax. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#if HAVE_FCNTL_LOCKING +# if HAVE_SYS_TYPES_H +# include +# endif +# if HAVE_UNISTD_H +# include +# endif +# include +#endif + +#include "buffer.h" +#include "nettle-meta.h" + +#include "getopt.h" + +#include "input.h" +#include "output.h" +#include "parse.h" + +#define BUG_ADDRESS "nettle-bugs@lists.lysator.liu.se" + +static void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + { + fprintf(stderr, "Virtual memory exhausted.\n"); + abort(); + } + + return p; +} + + +/* Conversion functions. */ + +/* Should be called with input->token being the first token of the + * expression, to be converted, and return with input->token being the + * last token of the expression. */ +static void +sexp_convert_item(struct sexp_parser *parser, + struct sexp_compound_token *token, + struct sexp_output *output, enum sexp_mode mode_out, + unsigned indent) +{ + if (mode_out == SEXP_TRANSPORT) + { + sexp_put_char(output, '{'); + sexp_put_code_start(output, &nettle_base64); + sexp_convert_item(parser, token, output, SEXP_CANONICAL, 0); + sexp_put_code_end(output); + sexp_put_char(output, '}'); + } + else switch(token->type) + { + case SEXP_LIST_END: + die("Unmatched end of list.\n"); + case SEXP_EOF: + die("Unexpected end of file.\n"); + case SEXP_CODING_END: + die("Unexpected end of coding.\n"); + + case SEXP_LIST_START: + { + unsigned item; + + sexp_put_char(output, '('); + + for (item = 0; + sexp_parse(parser, token), token->type != SEXP_LIST_END; + item++) + { + if (mode_out == SEXP_ADVANCED) + { + /* FIXME: Adapt pretty printing to handle a big first + * element. */ + switch (item) + { + case 0: + if (token->type == SEXP_COMMENT) + { + indent = output->pos; + /* Disable the indentation setup for next item */ + item++; + } + break; + + case 1: + sexp_put_char(output, ' '); + indent = output->pos; + break; + + default: + sexp_put_newline(output, indent); + break; + } + } + + sexp_convert_item(parser, token, output, mode_out, indent); + } + sexp_put_char(output, ')'); + + break; + } + + case SEXP_STRING: + sexp_put_string(output, mode_out, &token->string); + break; + + case SEXP_DISPLAY: + sexp_put_char(output, '['); + sexp_put_string(output, mode_out, &token->display); + sexp_put_char(output, ']'); + sexp_put_string(output, mode_out, &token->string); + break; + + case SEXP_COMMENT: + if (mode_out == SEXP_ADVANCED) + { + sexp_put_data(output, token->string.size, token->string.contents); + sexp_put_soft_newline(output, indent); + } + break; + default: + /* Internal error */ + abort(); + } +} + + +/* Argument parsing and main program */ + +/* The old lsh sexp-conv program took the following options: + * + * Usage: sexp-conv [OPTION...] + * Conversion: sexp-conv [options] OUTPUT + * or: sexp-conv [OPTION...] + * Fingerprinting: sexp-conv --raw-hash [ --hash=ALGORITHM ] + * mode = SEXP_ADVANCED; + o->prefer_hex = 0; + o->once = 0; + o->lock = 0; + o->hash = NULL; + o->width = 72; + + for (;;) + { + static const struct nettle_hash *hashes[] = + { &nettle_md5, &nettle_sha1, &nettle_sha256, NULL }; + + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, '?' }, + { "version", no_argument, NULL, 'V' }, + { "once", no_argument, NULL, OPT_ONCE }, + { "syntax", required_argument, NULL, 's' }, + { "hash", optional_argument, NULL, OPT_HASH }, + { "raw-hash", optional_argument, NULL, OPT_HASH }, + { "width", required_argument, NULL, 'w' }, +#if HAVE_FCNTL_LOCKING + { "lock", no_argument, NULL, OPT_LOCK }, +#endif +#if 0 + /* Not yet implemented */ + { "replace", required_argument, NULL, OPT_REPLACE }, + { "select", required_argument, NULL, OPT_SELECT }, + { "spki-hash", optional_argument, NULL, OPT_SPKI_HASH }, +#endif + { NULL, 0, NULL, 0 } + }; + int c; + int option_index = 0; + unsigned i; + + c = getopt_long(argc, argv, "V?s:w:", options, &option_index); + + switch (c) + { + default: + abort(); + + case -1: + if (optind != argc) + die("sexp-conv: Command line takes no arguments, only options.\n"); + return; + + case 'w': + { + char *end; + int width = strtol(optarg, &end , 0); + if (!*optarg || *end || width < 0) + die("sexp-conv: Invalid width `%s'.\n", optarg); + + o->width = width; + break; + } + case 's': + if (o->hash) + werror("sexp-conv: Combining --hash and -s usually makes no sense.\n"); + if (match_argument(optarg, "advanced")) + o->mode = SEXP_ADVANCED; + else if (match_argument(optarg, "transport")) + o->mode = SEXP_TRANSPORT; + else if (match_argument(optarg, "canonical")) + o->mode = SEXP_CANONICAL; + else if (match_argument(optarg, "hex")) + { + o->mode = SEXP_ADVANCED; + o->prefer_hex = 1; + } + else + die("Available syntax variants: advanced, transport, canonical\n"); + break; + + case OPT_ONCE: + o->once = 1; + break; + + case OPT_HASH: + o->mode = SEXP_CANONICAL; + if (!optarg) + o->hash = &nettle_sha1; + else + for (i = 0;; i++) + { + if (!hashes[i]) + die("sexp_conv: Unknown hash algorithm `%s'\n", + optarg); + + if (match_argument(optarg, hashes[i]->name)) + { + o->hash = hashes[i]; + break; + } + } + break; +#if HAVE_FCNTL_LOCKING + case OPT_LOCK: + o->lock = 1; + break; +#endif + case '?': + printf("Usage: sexp-conv [OPTION...]\n" + " Conversion: sexp-conv [OPTION...] name); + } + printf(" (default is sha1).\n" + " -s, --syntax=SYNTAX The syntax used for the output. Available\n" + " variants: advanced, hex, transport, canonical\n" + " --once Process only the first s-expression.\n" + " -w, --width=WIDTH Linewidth for base64 encoded data.\n" + " Zero means no limit.\n" +#if HAVE_FCNTL_LOCKING + " --lock Lock output file.\n" +#endif + " --raw-hash Alias for --hash, for compatibility\n" + " with lsh-1.x.\n\n" + "Report bugs to " BUG_ADDRESS ".\n"); + exit(EXIT_SUCCESS); + + case 'V': + printf("sexp-conv (" PACKAGE_STRING ")\n"); + exit (EXIT_SUCCESS); + } + } +} + +int +main(int argc, char **argv) +{ + struct conv_options options; + struct sexp_input input; + struct sexp_parser parser; + struct sexp_compound_token token; + struct sexp_output output; + + parse_options(&options, argc, argv); + + sexp_input_init(&input, stdin); + sexp_parse_init(&parser, &input, SEXP_ADVANCED); + sexp_compound_token_init(&token); + sexp_output_init(&output, stdout, + options.width, options.prefer_hex); + +#if HAVE_FCNTL_LOCKING + if (options.lock) + { + struct flock fl; + + memset(&fl, 0, sizeof(fl)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; /* Means entire file. */ + + if (fcntl(STDOUT_FILENO, F_SETLKW, &fl) == -1) + die("Locking output file failed: %s\n", strerror(errno)); + } +#endif /* HAVE_FCNTL_LOCKING */ + if (options.hash) + { + /* Leaks the context, but that doesn't matter */ + void *ctx = xalloc(options.hash->context_size); + sexp_output_hash_init(&output, options.hash, ctx); + } + + sexp_get_char(&input); + + sexp_parse(&parser, &token); + + if (token.type == SEXP_EOF) + { + if (options.once) + die("sexp-conv: No input expression.\n"); + return EXIT_SUCCESS; + } + + do + { + sexp_convert_item(&parser, &token, &output, options.mode, 0); + if (options.hash) + { + sexp_put_digest(&output); + sexp_put_newline(&output, 0); + } + else if (options.mode != SEXP_CANONICAL) + sexp_put_newline(&output, 0); + + sexp_parse(&parser, &token); + } + while (!options.once && token.type != SEXP_EOF); + + sexp_compound_token_clear(&token); + + if (fflush(output.f) < 0) + die("Final fflush failed: %s.\n", strerror(errno)); + + return EXIT_SUCCESS; +} diff --git a/twofish-meta.c b/twofish-meta.c new file mode 100644 index 0000000..7e46325 --- /dev/null +++ b/twofish-meta.c @@ -0,0 +1,38 @@ +/* twofish-meta.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "twofish.h" + +const struct nettle_cipher nettle_twofish128 += _NETTLE_CIPHER(twofish, TWOFISH, 128); + +const struct nettle_cipher nettle_twofish192 += _NETTLE_CIPHER(twofish, TWOFISH, 192); + +const struct nettle_cipher nettle_twofish256 += _NETTLE_CIPHER(twofish, TWOFISH, 256); diff --git a/twofish.c b/twofish.c new file mode 100644 index 0000000..0e519ea --- /dev/null +++ b/twofish.c @@ -0,0 +1,464 @@ +/* twofish.c + * + * The twofish block cipher. + */ + +/* twofish - An implementation of the twofish cipher. + * Copyright (C) 1999 Ruud de Rooij + * + * Modifications for lsh, integrated testing + * Copyright (C) 1999 J.H.M. Dassen (Ray) + * + * Integrated with the nettle library, + * Copyright (C) 2001 Niels Möller + */ + +/* nettle, low-level cryptographics library + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "twofish.h" + +#include "macros.h" + +/* Bitwise rotations on 32-bit words. These are defined as macros that + * evaluate their argument twice, so do not apply to any expressions with + * side effects. + */ + +#define rol1(x) (((x) << 1) | (((x) & 0x80000000) >> 31)) +#define rol8(x) (((x) << 8) | (((x) & 0xFF000000) >> 24)) +#define rol9(x) (((x) << 9) | (((x) & 0xFF800000) >> 23)) +#define ror1(x) (((x) >> 1) | (((x) & 0x00000001) << 31)) + +/* ------------------------------------------------------------------------- */ + +/* The permutations q0 and q1. These are fixed permutations on 8-bit values. + * The permutations have been computed using the program generate_q + * which is distributed along with this file. + */ + +static const uint8_t q0[] = { 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 uint8_t q1[] = { 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, }; + +/* ------------------------------------------------------------------------- */ + +/* uint8_t gf_multiply(uint8_t p, uint8_t a, uint8_t b) + * + * Multiplication in GF(2^8). + * + * This function multiplies a times b in the Galois Field GF(2^8) with + * primitive polynomial p. + * The representation of the polynomials a, b, and p uses bits with + * values 2^i to represent the terms x^i. The polynomial p contains an + * implicit term x^8. + * + * Note that addition and subtraction in GF(2^8) is simply the XOR + * operation. + */ + +static uint8_t +gf_multiply(uint8_t p, uint8_t a, uint8_t b) +{ + uint32_t shift = b; + uint8_t result = 0; + while (a) + { + if (a & 1) result ^= shift; + a = a >> 1; + shift = shift << 1; + if (shift & 0x100) shift ^= p; + } + return result; +} + +/* ------------------------------------------------------------------------- */ + +/* The matrix RS as specified in section 4.3 the twofish paper. */ + +static const uint8_t rs_matrix[4][8] = { + { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E }, + { 0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5 }, + { 0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19 }, + { 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03 } }; + +/* uint32_t compute_s(uint32_t m1, uint32_t m2); + * + * Computes the value RS * M, where M is a byte vector composed of the + * bytes of m1 and m2. Arithmetic is done in GF(2^8) with primitive + * polynomial x^8 + x^6 + x^3 + x^2 + 1. + * + * This function is used to compute the sub-keys S which are in turn used + * to generate the S-boxes. + */ + +static uint32_t +compute_s(uint32_t m1, uint32_t m2) +{ + uint32_t s = 0; + int i; + for (i = 0; i < 4; i++) + s |= (( gf_multiply(0x4D, m1, rs_matrix[i][0]) + ^ gf_multiply(0x4D, m1 >> 8, rs_matrix[i][1]) + ^ gf_multiply(0x4D, m1 >> 16, rs_matrix[i][2]) + ^ gf_multiply(0x4D, m1 >> 24, rs_matrix[i][3]) + ^ gf_multiply(0x4D, m2, rs_matrix[i][4]) + ^ gf_multiply(0x4D, m2 >> 8, rs_matrix[i][5]) + ^ gf_multiply(0x4D, m2 >> 16, rs_matrix[i][6]) + ^ gf_multiply(0x4D, m2 >> 24, rs_matrix[i][7])) << (i*8)); + return s; +} + +/* ------------------------------------------------------------------------- */ + +/* This table describes which q S-boxes are used for each byte in each stage + * of the function h, cf. figure 2 of the twofish paper. + */ + +static const uint8_t * const q_table[4][5] = + { { q1, q1, q0, q0, q1 }, + { q0, q1, q1, q0, q0 }, + { q0, q0, q0, q1, q1 }, + { q1, q0, q1, q1, q0 } }; + +/* The matrix MDS as specified in section 4.3.2 of the twofish paper. */ + +static const uint8_t mds_matrix[4][4] = { { 0x01, 0xEF, 0x5B, 0x5B }, + { 0x5B, 0xEF, 0xEF, 0x01 }, + { 0xEF, 0x5B, 0x01, 0xEF }, + { 0xEF, 0x01, 0xEF, 0x5B } }; + +/* uint32_t h_uint8_t(int k, int i, uint8_t x, uint8_t l0, uint8_t l1, uint8_t l2, uint8_t l3); + * + * Perform the h function (section 4.3.2) on one byte. It consists of + * repeated applications of the q permutation, followed by a XOR with + * part of a sub-key. Finally, the value is multiplied by one column of + * the MDS matrix. To obtain the result for a full word, the results of + * h for the individual bytes are XORed. + * + * k is the key size (/ 64 bits), i is the byte number (0 = LSB), x is the + * actual byte to apply the function to; l0, l1, l2, and l3 are the + * appropriate bytes from the subkey. Note that only l0..l(k-1) are used. + */ + +static uint32_t +h_byte(int k, int i, uint8_t x, uint8_t l0, uint8_t l1, uint8_t l2, uint8_t l3) +{ + uint8_t y = q_table[i][4][l0 ^ + q_table[i][3][l1 ^ + q_table[i][2][k == 2 ? x : l2 ^ + q_table[i][1][k == 3 ? x : l3 ^ q_table[i][0][x]]]]]; + + return ( ((uint32_t)gf_multiply(0x69, mds_matrix[0][i], y)) + | ((uint32_t)gf_multiply(0x69, mds_matrix[1][i], y) << 8) + | ((uint32_t)gf_multiply(0x69, mds_matrix[2][i], y) << 16) + | ((uint32_t)gf_multiply(0x69, mds_matrix[3][i], y) << 24) ); +} + +/* uint32_t h(int k, uint8_t x, uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3); + * + * Perform the function h on a word. See the description of h_byte() above. + */ + +static uint32_t +h(int k, uint8_t x, uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) +{ + return ( h_byte(k, 0, x, l0, l1, l2, l3) + ^ h_byte(k, 1, x, l0 >> 8, l1 >> 8, l2 >> 8, l3 >> 8) + ^ h_byte(k, 2, x, l0 >> 16, l1 >> 16, l2 >> 16, l3 >> 16) + ^ h_byte(k, 3, x, l0 >> 24, l1 >> 24, l2 >> 24, l3 >> 24) ); +} + + +/* ------------------------------------------------------------------------- */ + +/* API */ + +/* Structure which contains the tables containing the subkeys and the + * key-dependent s-boxes. + */ + + +/* Set up internal tables required for twofish encryption and decryption. + * + * The key size is specified in bytes. Key sizes up to 32 bytes are + * supported. Larger key sizes are silently truncated. + */ + +void +twofish_set_key(struct twofish_ctx *context, + unsigned keysize, const uint8_t *key) +{ + uint8_t key_copy[32]; + uint32_t m[8], s[4], t; + int i, j, k; + + /* Extend key as necessary */ + + assert(keysize <= 32); + + /* We do a little more copying than necessary, but that doesn't + * really matter. */ + memset(key_copy, 0, 32); + memcpy(key_copy, key, keysize); + + for (i = 0; i<8; i++) + m[i] = LE_READ_UINT32(key_copy + i*4); + + if (keysize <= 16) + k = 2; + else if (keysize <= 24) + k = 3; + else + k = 4; + + /* Compute sub-keys */ + + for (i = 0; i < 20; i++) + { + t = h(k, 2*i+1, m[1], m[3], m[5], m[7]); + t = rol8(t); + t += (context->keys[2*i] = + t + h(k, 2*i, m[0], m[2], m[4], m[6])); + t = rol9(t); + context->keys[2*i+1] = t; + } + + /* Compute key-dependent S-boxes */ + + for (i = 0; i < k; i++) + s[k-1-i] = compute_s(m[2*i], m[2*i+1]); + + for (i = 0; i < 4; i++) + for (j = 0; j < 256; j++) + context->s_box[i][j] = h_byte(k, i, j, + s[0] >> (i*8), + s[1] >> (i*8), + s[2] >> (i*8), + s[3] >> (i*8)); +} + +/* Encrypt blocks of 16 bytes of data with the twofish algorithm. + * + * Before this function can be used, twofish_set_key() must be used in order to + * set up various tables required for the encryption algorithm. + * + * This function always encrypts 16 bytes of plaintext to 16 bytes of + * ciphertext. The memory areas of the plaintext and the ciphertext can + * overlap. + */ + +void +twofish_encrypt(const struct twofish_ctx *context, + unsigned length, + uint8_t *ciphertext, + const uint8_t *plaintext) +{ + const uint32_t * keys = context->keys; + const uint32_t (*s_box)[256] = context->s_box; + + assert( !(length % TWOFISH_BLOCK_SIZE) ); + for ( ; length; length -= TWOFISH_BLOCK_SIZE) + { + uint32_t words[4]; + uint32_t r0, r1, r2, r3, t0, t1; + int i; + + for (i = 0; i<4; i++, plaintext += 4) + words[i] = LE_READ_UINT32(plaintext); + + r0 = words[0] ^ keys[0]; + r1 = words[1] ^ keys[1]; + r2 = words[2] ^ keys[2]; + r3 = words[3] ^ keys[3]; + + for (i = 0; i < 8; i++) { + t1 = ( s_box[1][r1 & 0xFF] + ^ s_box[2][(r1 >> 8) & 0xFF] + ^ s_box[3][(r1 >> 16) & 0xFF] + ^ s_box[0][(r1 >> 24) & 0xFF]); + t0 = ( s_box[0][r0 & 0xFF] + ^ s_box[1][(r0 >> 8) & 0xFF] + ^ s_box[2][(r0 >> 16) & 0xFF] + ^ s_box[3][(r0 >> 24) & 0xFF]) + t1; + r3 = (t1 + t0 + keys[4*i+9]) ^ rol1(r3); + r2 = (t0 + keys[4*i+8]) ^ r2; + r2 = ror1(r2); + + t1 = ( s_box[1][r3 & 0xFF] + ^ s_box[2][(r3 >> 8) & 0xFF] + ^ s_box[3][(r3 >> 16) & 0xFF] + ^ s_box[0][(r3 >> 24) & 0xFF]); + t0 = ( s_box[0][r2 & 0xFF] + ^ s_box[1][(r2 >> 8) & 0xFF] + ^ s_box[2][(r2 >> 16) & 0xFF] + ^ s_box[3][(r2 >> 24) & 0xFF]) + t1; + r1 = (t1 + t0 + keys[4*i+11]) ^ rol1(r1); + r0 = (t0 + keys[4*i+10]) ^ r0; + r0 = ror1(r0); + } + + words[0] = r2 ^ keys[4]; + words[1] = r3 ^ keys[5]; + words[2] = r0 ^ keys[6]; + words[3] = r1 ^ keys[7]; + + for (i = 0; i<4; i++, ciphertext += 4) + LE_WRITE_UINT32(ciphertext, words[i]); + } +} + +/* Decrypt blocks of 16 bytes of data with the twofish algorithm. + * + * Before this function can be used, twofish_set_key() must be used in order to + * set up various tables required for the decryption algorithm. + * + * This function always decrypts 16 bytes of ciphertext to 16 bytes of + * plaintext. The memory areas of the plaintext and the ciphertext can + * overlap. + */ + +void +twofish_decrypt(const struct twofish_ctx *context, + unsigned length, + uint8_t *plaintext, + const uint8_t *ciphertext) + +{ + const uint32_t *keys = context->keys; + const uint32_t (*s_box)[256] = context->s_box; + + assert( !(length % TWOFISH_BLOCK_SIZE) ); + for ( ; length; length -= TWOFISH_BLOCK_SIZE) + { + uint32_t words[4]; + uint32_t r0, r1, r2, r3, t0, t1; + int i; + + for (i = 0; i<4; i++, ciphertext += 4) + words[i] = LE_READ_UINT32(ciphertext); + + r0 = words[2] ^ keys[6]; + r1 = words[3] ^ keys[7]; + r2 = words[0] ^ keys[4]; + r3 = words[1] ^ keys[5]; + + for (i = 0; i < 8; i++) { + t1 = ( s_box[1][r3 & 0xFF] + ^ s_box[2][(r3 >> 8) & 0xFF] + ^ s_box[3][(r3 >> 16) & 0xFF] + ^ s_box[0][(r3 >> 24) & 0xFF]); + t0 = ( s_box[0][r2 & 0xFF] + ^ s_box[1][(r2 >> 8) & 0xFF] + ^ s_box[2][(r2 >> 16) & 0xFF] + ^ s_box[3][(r2 >> 24) & 0xFF]) + t1; + r1 = (t1 + t0 + keys[39-4*i]) ^ r1; + r1 = ror1(r1); + r0 = (t0 + keys[38-4*i]) ^ rol1(r0); + + t1 = ( s_box[1][r1 & 0xFF] + ^ s_box[2][(r1 >> 8) & 0xFF] + ^ s_box[3][(r1 >> 16) & 0xFF] + ^ s_box[0][(r1 >> 24) & 0xFF]); + t0 = ( s_box[0][r0 & 0xFF] + ^ s_box[1][(r0 >> 8) & 0xFF] + ^ s_box[2][(r0 >> 16) & 0xFF] + ^ s_box[3][(r0 >> 24) & 0xFF]) + t1; + r3 = (t1 + t0 + keys[37-4*i]) ^ r3; + r3 = ror1(r3); + r2 = (t0 + keys[36-4*i]) ^ rol1(r2); + } + + words[0] = r0 ^ keys[0]; + words[1] = r1 ^ keys[1]; + words[2] = r2 ^ keys[2]; + words[3] = r3 ^ keys[3]; + + for (i = 0; i<4; i++, plaintext += 4) + LE_WRITE_UINT32(plaintext, words[i]); + } +} diff --git a/twofish.h b/twofish.h new file mode 100644 index 0000000..de5dc3c --- /dev/null +++ b/twofish.h @@ -0,0 +1,78 @@ +/* twofish.h + * + * The twofish block cipher. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +/* + * Twofish is a 128-bit block cipher that accepts a variable-length + * key up to 256 bits, designed by Bruce Schneier and others. See + * http://www.counterpane.com/twofish.html for details. + */ + +#ifndef NETTLE_TWOFISH_H_INCLUDED +#define NETTLE_TWOFISH_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define twofish_set_key nettle_twofish_set_key +#define twofish_encrypt nettle_twofish_encrypt +#define twofish_decrypt nettle_twofish_decrypt + +#define TWOFISH_BLOCK_SIZE 16 + +/* Variable key size between 128 and 256 bits. But the only valid + * values are 16 (128 bits), 24 (192 bits) and 32 (256 bits). */ +#define TWOFISH_MIN_KEY_SIZE 16 +#define TWOFISH_MAX_KEY_SIZE 32 + +#define TWOFISH_KEY_SIZE 32 + +struct twofish_ctx +{ + uint32_t keys[40]; + uint32_t s_box[4][256]; +}; + +void +twofish_set_key(struct twofish_ctx *ctx, + unsigned length, const uint8_t *key); + +void +twofish_encrypt(const struct twofish_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); +void +twofish_decrypt(const struct twofish_ctx *ctx, + unsigned length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_TWOFISH_H_INCLUDED */ diff --git a/write-be32.c b/write-be32.c new file mode 100644 index 0000000..e52e565 --- /dev/null +++ b/write-be32.c @@ -0,0 +1,68 @@ +/* write-be32.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-write.h" + +#include "macros.h" + +void +_nettle_write_be32(unsigned length, uint8_t *dst, + uint32_t *src) +{ + unsigned i; + unsigned words; + unsigned leftover; + + words = length / 4; + leftover = length % 4; + + for (i = 0; i < words; i++, dst += 4) + WRITE_UINT32(dst, src[i]); + + if (leftover) + { + uint32_t word; + unsigned j = leftover; + + word = src[i]; + + switch (leftover) + { + default: + abort(); + case 3: + dst[--j] = (word >> 8) & 0xff; + /* Fall through */ + case 2: + dst[--j] = (word >> 16) & 0xff; + /* Fall through */ + case 1: + dst[--j] = (word >> 24) & 0xff; + } + } +} diff --git a/x86/aes-decrypt-internal.asm b/x86/aes-decrypt-internal.asm new file mode 100644 index 0000000..0dc6f7b --- /dev/null +++ b/x86/aes-decrypt-internal.asm @@ -0,0 +1,166 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2001, 2002, 2005 Rafael R. Sevilla, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +include_src() + +C Register usage: + +C AES state +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +C Primary use of these registers. They're also used temporarily for other things. +define(,<%ebp>) +define(,<%edi>) +define(,<%esi>) + +define(, <40(%esp)>) +define(, <44(%esp)>) +define(, <48(%esp)>) +define(, <52(%esp)>) +define(, <56(%esp)>) + +define(, <16(%esp)>) +define(, <12(%esp)>) +define(, <8(%esp)>) +define(, <4(%esp)>) +define(, <(%esp)>) + +C The aes state is kept in %eax, %ebx, %ecx and %edx +C +C %esi is used as temporary, to point to the input, and to the +C subkeys, etc. +C +C %ebp is used as the round counter, and as a temporary in the final round. +C +C %edi is a temporary, often used as an accumulator. + + .file "aes-decrypt-internal.asm" + + C _aes_decrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_decrypt) + C save all registers that need to be saved + pushl %ebx C 20(%esp) + pushl %ebp C 16(%esp) + pushl %esi C 12(%esp) + pushl %edi C 8(%esp) + + subl $20, %esp C loop counter and save area for the key pointer + + movl FRAME_LENGTH, %ebp + testl %ebp,%ebp + jz .Lend + + shrl $4, FRAME_LENGTH + +.Lblock_loop: + movl FRAME_CTX,KEY C address of context struct ctx + + movl FRAME_SRC,TMP C address of plaintext + AES_LOAD(SA, SB, SC, SD, TMP, KEY) + addl $16, FRAME_SRC C Increment src pointer + movl FRAME_TABLE, T + + C get number of rounds to do from ctx struct + movl AES_NROUNDS (KEY),TMP + subl $1,TMP + + C Loop counter on stack + movl TMP, FRAME_COUNT + + addl $16,KEY C point to next key + movl KEY,FRAME_KEY + ALIGN(4) +.Lround_loop: + AES_ROUND(T, SA,SD,SC,SB, TMP, KEY) + movl TMP, TA + + AES_ROUND(T, SB,SA,SD,SC, TMP, KEY) + movl TMP, TB + + AES_ROUND(T, SC,SB,SA,SD, TMP, KEY) + movl TMP, TC + + AES_ROUND(T, SD,SC,SB,SA, SD, KEY) + + movl TA, SA + movl TB, SB + movl TC, SC + + movl FRAME_KEY, KEY + + xorl (KEY),SA C add current session key to plaintext + xorl 4(KEY),SB + xorl 8(KEY),SC + xorl 12(KEY),SD + addl $16,FRAME_KEY C point to next key + decl FRAME_COUNT + jnz .Lround_loop + + C last round + + AES_FINAL_ROUND(SA,SD,SC,SB,T, TMP, KEY) + movl TMP, TA + + AES_FINAL_ROUND(SB,SA,SD,SC,T, TMP, KEY) + movl TMP, TB + + AES_FINAL_ROUND(SC,SB,SA,SD,T, TMP, KEY) + movl TMP, TC + + AES_FINAL_ROUND(SD,SC,SB,SA,T, SD, KEY) + + movl TA, SA + movl TB, SB + movl TC, SC + + C Inverse S-box substitution + mov $3,TMP +.Lsubst: + AES_SUBST_BYTE(SA,SB,SC,SD,T, KEY) + + decl TMP + jnz .Lsubst + + C Add last subkey, and store decrypted data + movl FRAME_DST,TMP + movl FRAME_KEY, KEY + AES_STORE(SA,SB,SC,SD, KEY, TMP) + + addl $16, FRAME_DST C Increment destination pointer + decl FRAME_LENGTH + + jnz .Lblock_loop + +.Lend: + addl $20, %esp + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +EPILOGUE(_nettle_aes_decrypt) diff --git a/x86/aes-encrypt-internal.asm b/x86/aes-encrypt-internal.asm new file mode 100644 index 0000000..99620d4 --- /dev/null +++ b/x86/aes-encrypt-internal.asm @@ -0,0 +1,166 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2001, 2002, 2005 Rafael R. Sevilla, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +include_src() + +C Register usage: + +C AES state +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +C Primary use of these registers. They're also used temporarily for other things. +define(,<%ebp>) +define(,<%edi>) +define(,<%esi>) + +define(, <40(%esp)>) +define(, <44(%esp)>) +define(, <48(%esp)>) +define(, <52(%esp)>) +define(, <56(%esp)>) + +define(, <16(%esp)>) +define(, <12(%esp)>) +define(, <8(%esp)>) +define(, <4(%esp)>) +define(, <(%esp)>) + +C The aes state is kept in %eax, %ebx, %ecx and %edx +C +C %esi is used as temporary, to point to the input, and to the +C subkeys, etc. +C +C %ebp is used as the round counter, and as a temporary in the final round. +C +C %edi is a temporary, often used as an accumulator. + + .file "aes-encrypt-internal.asm" + + C _aes_encrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_encrypt) + C save all registers that need to be saved + pushl %ebx C 20(%esp) + pushl %ebp C 16(%esp) + pushl %esi C 12(%esp) + pushl %edi C 8(%esp) + + subl $20, %esp C loop counter and save area for the key pointer + + movl FRAME_LENGTH, %ebp + testl %ebp,%ebp + jz .Lend + + shrl $4, FRAME_LENGTH + +.Lblock_loop: + movl FRAME_CTX,KEY C address of context struct ctx + + movl FRAME_SRC,TMP C address of plaintext + AES_LOAD(SA, SB, SC, SD, TMP, KEY) + addl $16, FRAME_SRC C Increment src pointer + movl FRAME_TABLE, T + + C get number of rounds to do from ctx struct + movl AES_NROUNDS (KEY),TMP + subl $1,TMP + + C Loop counter on stack + movl TMP, FRAME_COUNT + + addl $16,KEY C point to next key + movl KEY,FRAME_KEY + ALIGN(4) +.Lround_loop: + AES_ROUND(T, SA,SB,SC,SD, TMP, KEY) + movl TMP, TA + + AES_ROUND(T, SB,SC,SD,SA, TMP, KEY) + movl TMP, TB + + AES_ROUND(T, SC,SD,SA,SB, TMP, KEY) + movl TMP, TC + + AES_ROUND(T, SD,SA,SB,SC, SD, KEY) + + movl TA, SA + movl TB, SB + movl TC, SC + + movl FRAME_KEY, KEY + + xorl (KEY),SA C add current session key to plaintext + xorl 4(KEY),SB + xorl 8(KEY),SC + xorl 12(KEY),SD + addl $16,FRAME_KEY C point to next key + decl FRAME_COUNT + jnz .Lround_loop + + C last round + + AES_FINAL_ROUND(SA,SB,SC,SD, T, TMP, KEY) + movl TMP, TA + + AES_FINAL_ROUND(SB,SC,SD,SA, T, TMP, KEY) + movl TMP, TB + + AES_FINAL_ROUND(SC,SD,SA,SB, T, TMP, KEY) + movl TMP, TC + + AES_FINAL_ROUND(SD,SA,SB,SC, T, SD, KEY) + + movl TA, SA + movl TB, SB + movl TC, SC + + C S-box substitution + mov $3,TMP +.Lsubst: + AES_SUBST_BYTE(SA,SB,SC,SD, T, KEY) + + decl TMP + jnz .Lsubst + + C Add last subkey, and store encrypted data + movl FRAME_DST,TMP + movl FRAME_KEY, KEY + AES_STORE(SA,SB,SC,SD, KEY, TMP) + + addl $16, FRAME_DST C Increment destination pointer + decl FRAME_LENGTH + + jnz .Lblock_loop + +.Lend: + addl $20, %esp + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +EPILOGUE(_nettle_aes_encrypt) diff --git a/x86/aes.m4 b/x86/aes.m4 new file mode 100644 index 0000000..3507e85 --- /dev/null +++ b/x86/aes.m4 @@ -0,0 +1,85 @@ +dnl AES_LOAD(a, b, c, d, src, key) +dnl Loads the next block of data from src, and add the subkey pointed +dnl to by key. +dnl Note that x86 allows unaligned accesses. +dnl Would it be preferable to interleave the loads and stores? +define(, < + movl ($5),$1 + movl 4($5),$2 + movl 8($5),$3 + movl 12($5),$4 + + xorl ($6),$1 + xorl 4($6),$2 + xorl 8($6),$3 + xorl 12($6),$4>)dnl + +dnl AES_STORE(a, b, c, d, key, dst) +dnl Adds the subkey to a, b, c, d, +dnl and stores the result in the area pointed to by dst. +dnl Note that x86 allows unaligned accesses. +dnl Would it be preferable to interleave the loads and stores? +define(, < + xorl ($5),$1 + xorl 4($5),$2 + xorl 8($5),$3 + xorl 12($5),$4 + + movl $1,($6) + movl $2,4($6) + movl $3,8($6) + movl $4,12($6)>)dnl + +dnl AES_ROUND(table,a,b,c,d,out,ptr) +dnl Computes one word of the AES round. Leaves result in $6. +define(, < + movzbl LREG($2), $7 + movl AES_TABLE0 ($1, $7, 4),$6 + movzbl HREG($3), $7 + xorl AES_TABLE1 ($1, $7, 4),$6 + movl $4,$7 + shrl <$>16,$7 + andl <$>0xff,$7 + xorl AES_TABLE2 ($1, $7, 4),$6 + movl $5,$7 + shrl <$>24,$7 + xorl AES_TABLE3 ($1, $7, 4),$6>)dnl + +dnl AES_FINAL_ROUND(a, b, c, d, table, out, tmp) +dnl Computes one word of the final round. +dnl Note that we have to quote $ in constants. +define(, < + movzbl LREG($1),$6 + movzbl ($5, $6), $6 + movl $2,$7 + andl <$>0x0000ff00,$7 + orl $7, $6 + movl $3,$7 + andl <$>0x00ff0000,$7 + orl $7, $6 + movl $4,$7 + andl <$>0xff000000,$7 + orl $7, $6 + roll <$>8, $6>)dnl + +dnl AES_SUBST_BYTE(A, B, C, D, table, ptr) +dnl Substitutes the least significant byte of +dnl each of eax, ebx, ecx and edx, and also rotates +dnl the words one byte to the left. +dnl Uses that AES_SBOX == 0 +define(, < + movzbl LREG($1),$6 + movb ($5, $6),LREG($1) + roll <$>8,$1 + + movzbl LREG($2),$6 + movb ($5, $6),LREG($2) + roll <$>8,$2 + + movzbl LREG($3),$6 + movb ($5, $6),LREG($3) + roll <$>8,$3 + + movzbl LREG($4),$6 + movb ($5, $6),LREG($4) + roll <$>8,$4>)dnl diff --git a/x86/arcfour-crypt.asm b/x86/arcfour-crypt.asm new file mode 100644 index 0000000..bdeb98f --- /dev/null +++ b/x86/arcfour-crypt.asm @@ -0,0 +1,112 @@ +C nettle, low-level cryptographics library +C +C Copyright (C) 2004, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + + .file "arcfour-crypt.asm" + + C arcfour_crypt(struct arcfour_ctx *ctx, + C unsigned length, uint8_t *dst, + C const uint8_t *src) + .text + ALIGN(4) +PROLOGUE(nettle_arcfour_crypt) + C save all registers that need to be saved + pushl %ebx C 12(%esp) + pushl %ebp C 8(%esp) + pushl %esi C 4(%esp) + pushl %edi C 0(%esp) + +C Input arguments: + C ctx = 20(%esp) + C length = 24(%esp) + C dst = 28(%esp) + C src = 32(%esp) +C Register usage: + C %ebp = ctx + C %esi = src + C %edi = dst + C %edx = loop counter + C %eax = i + C %ebx = j + C %cl = si + C %ch = sj + + movl 24(%esp), %edx C length + movl 20(%esp), %ebp C ctx + movl 28(%esp), %edi C dst + movl 32(%esp), %esi C src + + lea (%edx, %edi), %edi + lea (%edx, %esi), %esi + negl %edx + jnc .Lend + + movzbl ARCFOUR_I (%ebp), %eax C i + movzbl ARCFOUR_J (%ebp), %ebx C j + + incb %al + sarl $1, %edx + jc .Lloop_odd + + ALIGN(4) +.Lloop: + movb (%ebp, %eax), %cl C si. + addb %cl, %bl + movb (%ebp, %ebx), %ch C sj + movb %ch, (%ebp, %eax) C S[i] = sj + incl %eax + movzbl %al, %eax + movb %cl, (%ebp, %ebx) C S[j] = si + addb %ch, %cl + movzbl %cl, %ecx C Clear, so it can be used + C for indexing. + movb (%ebp, %ecx), %cl + xorb (%esi, %edx, 2), %cl + movb %cl, (%edi, %edx, 2) + + C FIXME: Could exchange cl and ch in the second half + C and try to interleave instructions better. +.Lloop_odd: + movb (%ebp, %eax), %cl C si. + addb %cl, %bl + movb (%ebp, %ebx), %ch C sj + movb %ch, (%ebp, %eax) C S[i] = sj + incl %eax + movzbl %al, %eax + movb %cl, (%ebp, %ebx) C S[j] = si + addb %ch, %cl + movzbl %cl, %ecx C Clear, so it can be used + C for indexing. + movb (%ebp, %ecx), %cl + xorb 1(%esi, %edx, 2), %cl + incl %edx + movb %cl, -1(%edi, %edx, 2) + + jnz .Lloop + +C .Lloop_done: + decb %al + movb %al, ARCFOUR_I (%ebp) C Store the new i and j. + movb %bl, ARCFOUR_J (%ebp) +.Lend: + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +EPILOGUE(nettle_arcfour_crypt) diff --git a/x86/camellia-crypt-internal.asm b/x86/camellia-crypt-internal.asm new file mode 100644 index 0000000..b5c491c --- /dev/null +++ b/x86/camellia-crypt-internal.asm @@ -0,0 +1,213 @@ +C -*- mode: asm; asm-comment-char: ?C; -*- +C nettle, low-level cryptographics library +C +C Copyright (C) 2010, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C Register usage: + +C Camellia state, 128-bit value in little endian order. +C L0, H0 corresponds to D1 in the spec and i0 in the C implementation. +C while L1, H1 corresponds to D2/i1. +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(

,<%edx>) + +define(,<%ebp>) +define(,<%esi>) +define(,<%edi>) + +C Locals on the stack + +define(, <(%esp)>) +define(, <4(%esp)>) +define(, <8(%esp)>) +define(, <12(%esp)>) +define(, <16(%esp)>) + +C Arguments on stack. +define(, <40(%esp)>) +define(, <44(%esp)>) +define(, <48(%esp)>) +define(, <52(%esp)>) +define(, <56(%esp)>) + +define(, <(T,$1,4)>) +define(, <1024(T,$1,4)>) +define(, <2048(T,$1,4)>) +define(, <3072(T,$1,4)>) + +C ROUND(xl, xh, yl, yh, key-offset) +C xl and xh are rotated 16 bits at the end +C yl and yh are read from stack, and left in registers +define(, < + movzbl LREG($1), TMP + movl SP1110(TMP), $4 + movzbl HREG($1), TMP + xorl SP4404(TMP), $4 + roll <$>16, $1 + + movzbl LREG($2), TMP + movl SP4404(TMP), $3 + movzbl HREG($2), TMP + xorl SP3033(TMP), $3 + roll <$>16, $2 + + movzbl LREG($1), TMP + xorl SP3033(TMP), $4 + movzbl HREG($1), TMP + xorl SP0222(TMP), $4 + + movzbl LREG($2), TMP + xorl SP0222(TMP), $3 + movzbl HREG($2), TMP + xorl SP1110(TMP), $3 + + xorl $5(KEY), $4 + xorl $5 + 4(KEY), $3 + + xorl $3, $4 + rorl <$>8, $3 + xorl $4, $3 + + xorl FRAME_$3, $3 + xorl FRAME_$4, $4 +>) + +C Six rounds, with inputs and outputs in registers. +define(, < + movl L0, FRAME_L0 + movl H0, FRAME_H0 + movl L1, FRAME_L1 + movl H1, FRAME_H1 + + ROUND(L0,H0,,

,0) + movl L1, FRAME_L1 + movl H1, FRAME_H1 + ROUND(L1,H1,,,8) + movl L0, FRAME_L0 + movl H0, FRAME_H0 + ROUND(L0,H0,,

,16) + movl L1, FRAME_L1 + movl H1, FRAME_H1 + ROUND(L1,H1,,,24) + movl L0, FRAME_L0 + movl H0, FRAME_H0 + ROUND(L0,H0,,

,32) + ROUND(L1,H1,,,40) + roll <$>16, L1 + roll <$>16, H1 +>) + +C FL(x0, x1, key-offset) +define(, < + movl $3 + 4(KEY), TMP + andl $2, TMP + roll <$>1, TMP + xorl TMP, $1 + movl $3(KEY), TMP + orl $1, TMP + xorl TMP, $2 +>) +C FLINV(x0, x1, key-offset) +define(, < + movl $3(KEY), TMP + orl $1, TMP + xorl TMP, $2 + movl $3 + 4(KEY), TMP + andl $2, TMP + roll <$>1, TMP + xorl TMP, $1 +>) + +.file "camellia-encrypt-internal.asm" + + C _camellia_crypt(struct camellia_context *ctx, + C const struct camellia_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_camellia_crypt) + C save all registers that need to be saved + pushl %ebx C 32(%esp) + pushl %ebp C 28(%esp) + pushl %esi C 24(%esp) + pushl %edi C 20(%esp) + + subl $20, %esp + + movl FRAME_LENGTH, %ebp + testl %ebp,%ebp + jz .Lend + +.Lblock_loop: + C Load data, note that we'll happily do unaligned loads + movl FRAME_SRC, TMP + movl (TMP), H0 + bswap H0 + movl 4(TMP), L0 + bswap L0 + movl 8(TMP), H1 + bswap H1 + movl 12(TMP), L1 + bswap L1 + addl $16, FRAME_SRC + movl FRAME_CTX, KEY + movl (KEY), TMP + subl $8, TMP + mov TMP, FRAME_CNT + C Whitening using first subkey + xor 4(KEY), L0 + xor 8(KEY), H0 + add $12, KEY + + movl FRAME_TABLE, T + + ROUND6 +.Lround_loop: + add $64, KEY + FL(L0, H0, -16) + FLINV(L1, H1, -8) + ROUND6 + sub $8, FRAME_CNT + ja .Lround_loop + + movl FRAME_DST, TMP + bswap H0 + movl H0,8(TMP) + bswap L0 + movl L0,12(TMP) + xorl 52(KEY), H1 + bswap H1 + movl H1, 0(TMP) + xorl 48(KEY), L1 + bswap L1 + movl L1, 4(TMP) + addl $16, FRAME_DST + subl $16, FRAME_LENGTH + ja .Lblock_loop + +.Lend: + addl $20, %esp + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +EPILOGUE(_nettle_camellia_crypt) diff --git a/x86/machine.m4 b/x86/machine.m4 new file mode 100644 index 0000000..38bee36 --- /dev/null +++ b/x86/machine.m4 @@ -0,0 +1,16 @@ +C OFFSET(i) +C Expands to 4*i, or to the empty string if i is zero +define(, ) + +dnl LREG(reg) gives the 8-bit register corresponding to the given 32-bit register. +define(,)dnl + +define(,)dnl diff --git a/x86/md5-compress.asm b/x86/md5-compress.asm new file mode 100644 index 0000000..44894e3 --- /dev/null +++ b/x86/md5-compress.asm @@ -0,0 +1,174 @@ +C nettle, low-level cryptographics library +C +C Copyright (C) 2005, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C Register usage +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) +define(,<%ebp>) +define(,<%esi>) + +C %edi is unused + +C F1(x,y,z) = (z ^ (x & (y ^ z))) +define(, < + movl $3, TMP + xorl $2, TMP + andl $1, TMP + xorl $3, TMP>) + +define(,) + +C F3(x,y,z) = x ^ y ^ z +define(,< + movl $1, TMP + xorl $2, TMP + xorl $3, TMP>) + +C F4(x,y,z) = y ^ (x | ~z) +define(,< + movl $3, TMP + notl TMP + orl $1, TMP + xorl $2, TMP>) + +define(,) + +C ROUND(f, w, x, y, z, k, data, s): +C w += f(x,y,z) + data + k +C w <<< s +C w += x +define(,< + addl $7, $2 + $1($3, $4, $5) + addl $6, $2 + addl TMP, $2 + roll <$>$8, $2 + addl $3, $2>) + + .file "md5-compress.asm" + + C _nettle_md5_compress(uint32_t *state, uint8_t *data) + + .text + ALIGN(4) +PROLOGUE(_nettle_md5_compress) + C save all registers that need to be saved + + C 24(%esp) input + C 20(%esp) state + C 16(%esp) Return address + pushl %ebx C 12(%esp) + pushl %ebp C 8(%esp) + pushl %esi C 4(%esp) + pushl %edi C (%esp) + + C load the state vector + movl 20(%esp),TMP + movl (TMP), SA + movl 4(TMP), SB + movl 8(TMP), SC + movl 12(TMP), SD + + C Pointer to source data. + C Note that if unaligned, we suffer unaligned accesses + movl 24(%esp), INPUT + + ROUND(, SA, SB, SC, SD, REF( 0), $0xd76aa478, 7) + ROUND(, SD, SA, SB, SC, REF( 1), $0xe8c7b756, 12) + ROUND(, SC, SD, SA, SB, REF( 2), $0x242070db, 17) + ROUND(, SB, SC, SD, SA, REF( 3), $0xc1bdceee, 22) + ROUND(, SA, SB, SC, SD, REF( 4), $0xf57c0faf, 7) + ROUND(, SD, SA, SB, SC, REF( 5), $0x4787c62a, 12) + ROUND(, SC, SD, SA, SB, REF( 6), $0xa8304613, 17) + ROUND(, SB, SC, SD, SA, REF( 7), $0xfd469501, 22) + ROUND(, SA, SB, SC, SD, REF( 8), $0x698098d8, 7) + ROUND(, SD, SA, SB, SC, REF( 9), $0x8b44f7af, 12) + ROUND(, SC, SD, SA, SB, REF(10), $0xffff5bb1, 17) + ROUND(, SB, SC, SD, SA, REF(11), $0x895cd7be, 22) + ROUND(, SA, SB, SC, SD, REF(12), $0x6b901122, 7) + ROUND(, SD, SA, SB, SC, REF(13), $0xfd987193, 12) + ROUND(, SC, SD, SA, SB, REF(14), $0xa679438e, 17) + ROUND(, SB, SC, SD, SA, REF(15), $0x49b40821, 22) + + ROUND(, SA, SB, SC, SD, REF( 1), $0xf61e2562, 5) + ROUND(, SD, SA, SB, SC, REF( 6), $0xc040b340, 9) + ROUND(, SC, SD, SA, SB, REF(11), $0x265e5a51, 14) + ROUND(, SB, SC, SD, SA, REF( 0), $0xe9b6c7aa, 20) + ROUND(, SA, SB, SC, SD, REF( 5), $0xd62f105d, 5) + ROUND(, SD, SA, SB, SC, REF(10), $0x02441453, 9) + ROUND(, SC, SD, SA, SB, REF(15), $0xd8a1e681, 14) + ROUND(, SB, SC, SD, SA, REF( 4), $0xe7d3fbc8, 20) + ROUND(, SA, SB, SC, SD, REF( 9), $0x21e1cde6, 5) + ROUND(, SD, SA, SB, SC, REF(14), $0xc33707d6, 9) + ROUND(, SC, SD, SA, SB, REF( 3), $0xf4d50d87, 14) + ROUND(, SB, SC, SD, SA, REF( 8), $0x455a14ed, 20) + ROUND(, SA, SB, SC, SD, REF(13), $0xa9e3e905, 5) + ROUND(, SD, SA, SB, SC, REF( 2), $0xfcefa3f8, 9) + ROUND(, SC, SD, SA, SB, REF( 7), $0x676f02d9, 14) + ROUND(, SB, SC, SD, SA, REF(12), $0x8d2a4c8a, 20) + + ROUND(, SA, SB, SC, SD, REF( 5), $0xfffa3942, 4) + ROUND(, SD, SA, SB, SC, REF( 8), $0x8771f681, 11) + ROUND(, SC, SD, SA, SB, REF(11), $0x6d9d6122, 16) + ROUND(, SB, SC, SD, SA, REF(14), $0xfde5380c, 23) + ROUND(, SA, SB, SC, SD, REF( 1), $0xa4beea44, 4) + ROUND(, SD, SA, SB, SC, REF( 4), $0x4bdecfa9, 11) + ROUND(, SC, SD, SA, SB, REF( 7), $0xf6bb4b60, 16) + ROUND(, SB, SC, SD, SA, REF(10), $0xbebfbc70, 23) + ROUND(, SA, SB, SC, SD, REF(13), $0x289b7ec6, 4) + ROUND(, SD, SA, SB, SC, REF( 0), $0xeaa127fa, 11) + ROUND(, SC, SD, SA, SB, REF( 3), $0xd4ef3085, 16) + ROUND(, SB, SC, SD, SA, REF( 6), $0x04881d05, 23) + ROUND(, SA, SB, SC, SD, REF( 9), $0xd9d4d039, 4) + ROUND(, SD, SA, SB, SC, REF(12), $0xe6db99e5, 11) + ROUND(, SC, SD, SA, SB, REF(15), $0x1fa27cf8, 16) + ROUND(, SB, SC, SD, SA, REF( 2), $0xc4ac5665, 23) + + ROUND(, SA, SB, SC, SD, REF( 0), $0xf4292244, 6) + ROUND(, SD, SA, SB, SC, REF( 7), $0x432aff97, 10) + ROUND(, SC, SD, SA, SB, REF(14), $0xab9423a7, 15) + ROUND(, SB, SC, SD, SA, REF( 5), $0xfc93a039, 21) + ROUND(, SA, SB, SC, SD, REF(12), $0x655b59c3, 6) + ROUND(, SD, SA, SB, SC, REF( 3), $0x8f0ccc92, 10) + ROUND(, SC, SD, SA, SB, REF(10), $0xffeff47d, 15) + ROUND(, SB, SC, SD, SA, REF( 1), $0x85845dd1, 21) + ROUND(, SA, SB, SC, SD, REF( 8), $0x6fa87e4f, 6) + ROUND(, SD, SA, SB, SC, REF(15), $0xfe2ce6e0, 10) + ROUND(, SC, SD, SA, SB, REF( 6), $0xa3014314, 15) + ROUND(, SB, SC, SD, SA, REF(13), $0x4e0811a1, 21) + ROUND(, SA, SB, SC, SD, REF( 4), $0xf7537e82, 6) + ROUND(, SD, SA, SB, SC, REF(11), $0xbd3af235, 10) + ROUND(, SC, SD, SA, SB, REF( 2), $0x2ad7d2bb, 15) + ROUND(, SB, SC, SD, SA, REF( 9), $0xeb86d391, 21) + + C Update the state vector + movl 20(%esp),TMP + addl SA, (TMP) + addl SB, 4(TMP) + addl SC, 8(TMP) + addl SD, 12(TMP) + + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +EPILOGUE(_nettle_md5_compress) diff --git a/x86/sha1-compress.asm b/x86/sha1-compress.asm new file mode 100644 index 0000000..f6fa347 --- /dev/null +++ b/x86/sha1-compress.asm @@ -0,0 +1,1541 @@ +C nettle, low-level cryptographics library +C +C Copyright (C) 2004, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C Register usage +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) +define(,<%ebp>) +define(,<%esp>) +define(,<%edi>) +define(,<%esi>) + +C Constants +define(, <0x5A827999>) C Rounds 0-19 +define(, <0x6ED9EBA1>) C Rounds 20-39 +define(, <0x8F1BBCDC>) C Rounds 40-59 +define(, <0xCA62C1D6>) C Rounds 60-79 + +C Reads the input via T2 into register, byteswaps it, and stores it in the DATA array. +C SWAP(index, register) +define(, < + movl OFFSET($1)(T2), $2 + bswap $2 + movl $2, OFFSET($1) (DATA) +>)dnl + +C The f functions, +C +C f1(x,y,z) = z ^ (x & (y ^ z)) +C f2(x,y,z) = x ^ y ^ z +C f3(x,y,z) = (x & (y ^ z)) + (y & z) +C f4 = f2 + +C This form for f3 was suggested by George Spelvin. The terms can be +C added into the result one at a time, saving one temporary. + +C The form of one sha1 round is +C +C a' = e + a <<< 5 + f( b, c, d ) + k + w; +C b' = a; +C c' = b <<< 30; +C d' = c; +C e' = d; +C +C where <<< denotes rotation. We permute our variables, so that we +C instead get +C +C e += a <<< 5 + f( b, c, d ) + k + w; +C b <<<= 30 + +dnl ROUND_F1(a, b, c, d, e, i) +define(, < + mov OFFSET(eval($6 % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 2) % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 8) % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 13) % 16)) (DATA), T1 + rol <$>1, T1 + mov T1, OFFSET(eval($6 % 16)) (DATA) + mov $4, T2 + xor $3, T2 + and $2, T2 + xor $4, T2 + rol <$>30, $2 + lea K1VALUE (T1, $5), $5 + mov $1, T1 + rol <$>5, T1 + add T1, $5 + add T2, $5 +>) + +dnl ROUND_F1_NOEXP(a, b, c, d, e, i) +define(, < + mov $4, T2 + xor $3, T2 + mov $1, T1 + and $2, T2 + add OFFSET($6) (DATA), $5 + xor $4, T2 + add T2, $5 + rol <$>30, $2 + rol <$>5, T1 + lea K1VALUE (T1, $5), $5 +>) + +dnl ROUND_F2(a, b, c, d, e, i, k) +define(, < + mov OFFSET(eval($6 % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 2) % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 8) % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 13) % 16)) (DATA), T1 + rol <$>1, T1 + mov T1, OFFSET(eval($6 % 16)) (DATA) + mov $4, T2 + xor $3, T2 + xor $2, T2 + rol <$>30, $2 + lea $7 (T1, $5), $5 + mov $1, T1 + rol <$>5, T1 + add T1, $5 + add T2, $5 +>) + +dnl ROUND_F3(a, b, c, d, e, i) +define(, < + mov OFFSET(eval($6 % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 2) % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 8) % 16)) (DATA), T1 + xor OFFSET(eval(($6 + 13) % 16)) (DATA), T1 + rol <$>1, T1 + mov T1, OFFSET(eval($6 % 16)) (DATA) + mov $4, T2 + and $3, T2 + lea K3VALUE (T1, $5), $5 + mov $4, T1 + xor $3, T1 + and $2, T1 + add T2, $5 + rol <$>30, $2 + mov $1, T2 + rol <$>5, T2 + add T1, $5 + add T2, $5 +>) + + .file "sha1-compress.asm" + + C _nettle_sha1_compress(uint32_t *state, uint8_t *data) + + .text + +PROLOGUE(_nettle_sha1_compress) + C save all registers that need to be saved + C 88(%esp) data + C 84(%esp) state + C 80(%esp) Return address + pushl %ebx C 76(%esp) + pushl %ebp C 72(%esp) + pushl %esi C 68(%esp) + pushl %edi C 64(%esp) + + subl $64, %esp C %esp = W + + C Loop-mixed to 520 cycles (for the complete function call) on + C AMD K7. +ALIGN(5) + mov 88(%esp), T2 + mov OFFSET(2)(T2), %ecx + mov OFFSET(0)(T2), %eax + bswap %ecx + bswap %eax + mov %ecx, OFFSET(2) (DATA) + mov %eax, OFFSET(0) (DATA) + mov OFFSET(3)(T2), %edx + mov OFFSET(6)(T2), %ecx + mov OFFSET(4)(T2), %eax + mov OFFSET(1)(T2), %ebx + bswap %ebx + bswap %eax + bswap %ecx + mov %ecx, OFFSET(6) (DATA) + mov %eax, OFFSET(4) (DATA) + bswap %edx + mov %edx, OFFSET(3) (DATA) + mov %ebx, OFFSET(1) (DATA) + mov OFFSET(10)(T2), %ecx + mov OFFSET(8)(T2), %eax + mov OFFSET(7)(T2), %edx + bswap %eax + bswap %edx + mov %edx, OFFSET(7) (DATA) + mov OFFSET(5)(T2), %ebx + mov %eax, OFFSET(8) (DATA) + mov OFFSET(11)(T2), %edx + bswap %ecx + bswap %edx + mov OFFSET(12)(T2), %eax + bswap %ebx + mov %ecx, OFFSET(10) (DATA) + mov %ebx, OFFSET(5) (DATA) + mov %edx, OFFSET(11) (DATA) + mov OFFSET(15)(T2), %edx + mov 84(%esp),T1 + mov OFFSET(9)(T2), %ebx + bswap %edx + bswap %ebx + bswap %eax + mov OFFSET(14)(T2), %ecx + mov %edx, OFFSET(15) (DATA) + bswap %ecx + mov %ecx, OFFSET(14) (DATA) + mov %ebx, OFFSET(9) (DATA) + mov OFFSET(13)(T2), %ebx + mov 12(T1), SD + bswap %ebx + mov %ebx, OFFSET(13) (DATA) + mov 8(T1), SC + mov 16(T1), SE + mov 4(T1), SB + mov SD, T2 + add OFFSET(0) (DATA), SE + xor SC, T2 + mov %eax, OFFSET(12) (DATA) + mov (T1), SA + and SB, T2 + xor SD, T2 + rol $30, SB + add T2, SE + mov SA, T1 + mov SC, T2 + add OFFSET(1) (DATA), SD + rol $5, T1 + xor SB, T2 + and SA, T2 + xor SC, T2 + lea K1VALUE (T1, SE), SE + add T2, SD + mov SB, T2 + rol $30, SA + xor SA, T2 + and SE, T2 + mov SE, T1 + add OFFSET(2) (DATA), SC + rol $30, SE + xor SB, T2 + rol $5, T1 + lea K1VALUE (T1, SD), SD + mov SD, T1 + rol $5, T1 + add T2, SC + mov SA, T2 + xor SE, T2 + lea K1VALUE (T1, SC), SC + and SD, T2 + xor SA, T2 + add OFFSET(3) (DATA), SB + mov SC, T1 + add T2, SB + mov SE, T2 + rol $30, SD + xor SD, T2 + and SC, T2 + rol $5, T1 + xor SE, T2 + add OFFSET(4) (DATA), SA + lea K1VALUE (T1, SB), SB + add T2, SA + rol $30, SC + mov SD, T2 + xor SC, T2 + and SB, T2 + mov SB, T1 + rol $5, T1 + add OFFSET(5) (DATA), SE + rol $30, SB + xor SD, T2 + add T2, SE + mov SC, T2 + xor SB, T2 + lea K1VALUE (T1, SA), SA + mov SA, T1 + add OFFSET(6) (DATA), SD + and SA, T2 + rol $5, T1 + xor SC, T2 + lea K1VALUE (T1, SE), SE + rol $30, SA + add T2, SD + mov SB, T2 + mov SE, T1 + xor SA, T2 + and SE, T2 + rol $5, T1 + lea K1VALUE (T1, SD), SD + xor SB, T2 + add OFFSET(7) (DATA), SC + rol $30, SE + add OFFSET(8) (DATA), SB + mov SD, T1 + add T2, SC + mov SA, T2 + xor SE, T2 + rol $5, T1 + and SD, T2 + lea K1VALUE (T1, SC), SC + xor SA, T2 + add T2, SB + mov SE, T2 + mov SC, T1 + rol $30, SD + xor SD, T2 + rol $5, T1 + lea K1VALUE (T1, SB), SB + and SC, T2 + xor SE, T2 + add OFFSET(10) (DATA), SE + add OFFSET(9) (DATA), SA + mov SB, T1 + add T2, SA + rol $5, T1 + lea K1VALUE (T1, SA), SA + mov SD, T2 + rol $30, SC + xor SC, T2 + and SB, T2 + xor SD, T2 + rol $30, SB + add T2, SE + mov SC, T2 + mov SA, T1 + xor SB, T2 + add OFFSET(11) (DATA), SD + and SA, T2 + rol $30, SA + rol $5, T1 + xor SC, T2 + lea K1VALUE (T1, SE), SE + add T2, SD + mov SB, T2 + xor SA, T2 + mov SE, T1 + rol $5, T1 + and SE, T2 + lea K1VALUE (T1, SD), SD + xor SB, T2 + add OFFSET(12) (DATA), SC + add T2, SC + rol $30, SE + mov SA, T2 + xor SE, T2 + mov SD, T1 + rol $5, T1 + and SD, T2 + add OFFSET(13) (DATA), SB + lea K1VALUE (T1, SC), SC + xor SA, T2 + add T2, SB + mov SE, T2 + rol $30, SD + xor SD, T2 + and SC, T2 + mov SC, T1 + rol $5, T1 + rol $30, SC + add OFFSET(14) (DATA), SA + xor SE, T2 + add T2, SA + mov SD, T2 + xor SC, T2 + lea K1VALUE (T1, SB), SB + and SB, T2 + mov SB, T1 + rol $5, T1 + lea K1VALUE (T1, SA), SA + mov SA, T1 + xor SD, T2 + add OFFSET(15) (DATA), SE + add T2, SE + rol $5, T1 + lea K1VALUE (T1, SE), SE + mov OFFSET(0) (DATA), T1 + xor OFFSET(2) (DATA), T1 + mov SC, T2 + xor OFFSET(8) (DATA), T1 + xor OFFSET(13) (DATA), T1 + rol $30, SB + xor SB, T2 + and SA, T2 + xor SC, T2 + rol $1, T1 + lea K1VALUE (T1, T2), T2 + mov T1, OFFSET(0) (DATA) + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(1) (DATA), T1 + xor OFFSET(3) (DATA), T1 + rol $30, SA + add T2, SD + mov SB, T2 + xor SA, T2 + and SE, T2 + xor OFFSET(9) (DATA), T1 + xor OFFSET(14) (DATA), T1 + xor SB, T2 + rol $1, T1 + mov T1, OFFSET(1) (DATA) + lea K1VALUE (T1, T2), T2 + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(2) (DATA), T1 + xor OFFSET(4) (DATA), T1 + rol $30, SE + add T2, SC + mov SA, T2 + xor SE, T2 + xor OFFSET(10) (DATA), T1 + xor OFFSET(15) (DATA), T1 + and SD, T2 + rol $1, T1 + xor SA, T2 + mov T1, OFFSET(2) (DATA) + lea K1VALUE (T1, T2), T2 + mov SC, T1 + rol $30, SD + rol $5, T1 + add T1, SB + add T2, SB + mov SE, T2 + mov OFFSET(3) (DATA), T1 + xor SD, T2 + xor OFFSET(5) (DATA), T1 + and SC, T2 + xor SE, T2 + xor OFFSET(11) (DATA), T1 + xor OFFSET(0) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(3) (DATA) + lea K1VALUE (T1, T2), T2 + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(4) (DATA), T1 + xor OFFSET(6) (DATA), T1 + rol $30, SC + xor OFFSET(12) (DATA), T1 + add T2, SA + xor OFFSET(1) (DATA), T1 + mov SD, T2 + xor SC, T2 + rol $1, T1 + xor SB, T2 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(4) (DATA) + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(5) (DATA), T1 + add T2, SE + mov SC, T2 + xor OFFSET(7) (DATA), T1 + rol $30, SB + xor OFFSET(13) (DATA), T1 + xor SB, T2 + xor OFFSET(2) (DATA), T1 + xor SA, T2 + rol $1, T1 + mov T1, OFFSET(5) (DATA) + lea K2VALUE (T1, T2), T2 + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(6) (DATA), T1 + xor OFFSET(8) (DATA), T1 + add T2, SD + rol $30, SA + xor OFFSET(14) (DATA), T1 + mov SB, T2 + xor OFFSET(3) (DATA), T1 + xor SA, T2 + rol $1, T1 + xor SE, T2 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(6) (DATA) + mov SD, T1 + rol $5, T1 + add T1, SC + add T2, SC + mov SA, T2 + rol $30, SE + mov OFFSET(7) (DATA), T1 + xor OFFSET(9) (DATA), T1 + xor SE, T2 + xor OFFSET(15) (DATA), T1 + xor OFFSET(4) (DATA), T1 + xor SD, T2 + rol $1, T1 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(7) (DATA) + mov SC, T1 + rol $5, T1 + add T1, SB + mov OFFSET(8) (DATA), T1 + xor OFFSET(10) (DATA), T1 + add T2, SB + rol $30, SD + mov SE, T2 + xor OFFSET(0) (DATA), T1 + xor OFFSET(5) (DATA), T1 + xor SD, T2 + xor SC, T2 + rol $1, T1 + mov T1, OFFSET(8) (DATA) + lea K2VALUE (T1, T2), T2 + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(9) (DATA), T1 + xor OFFSET(11) (DATA), T1 + xor OFFSET(1) (DATA), T1 + add T2, SA + xor OFFSET(6) (DATA), T1 + mov SD, T2 + rol $1, T1 + rol $30, SC + xor SC, T2 + mov T1, OFFSET(9) (DATA) + xor SB, T2 + lea K2VALUE (T1, T2), T2 + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(10) (DATA), T1 + xor OFFSET(12) (DATA), T1 + xor OFFSET(2) (DATA), T1 + add T2, SE + mov SC, T2 + rol $30, SB + xor OFFSET(7) (DATA), T1 + xor SB, T2 + rol $1, T1 + xor SA, T2 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(10) (DATA) + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(11) (DATA), T1 + xor OFFSET(13) (DATA), T1 + rol $30, SA + xor OFFSET(3) (DATA), T1 + add T2, SD + xor OFFSET(8) (DATA), T1 + mov SB, T2 + xor SA, T2 + rol $1, T1 + mov T1, OFFSET(11) (DATA) + xor SE, T2 + lea K2VALUE (T1, T2), T2 + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(12) (DATA), T1 + xor OFFSET(14) (DATA), T1 + rol $30, SE + add T2, SC + xor OFFSET(4) (DATA), T1 + mov SA, T2 + xor OFFSET(9) (DATA), T1 + xor SE, T2 + rol $1, T1 + xor SD, T2 + mov T1, OFFSET(12) (DATA) + lea K2VALUE (T1, T2), T2 + mov SC, T1 + rol $5, T1 + add T1, SB + rol $30, SD + mov OFFSET(13) (DATA), T1 + xor OFFSET(15) (DATA), T1 + add T2, SB + mov SE, T2 + xor OFFSET(5) (DATA), T1 + xor SD, T2 + xor OFFSET(10) (DATA), T1 + xor SC, T2 + rol $1, T1 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(13) (DATA) + mov SB, T1 + rol $5, T1 + add T1, SA + add T2, SA + mov SD, T2 + mov OFFSET(14) (DATA), T1 + xor OFFSET(0) (DATA), T1 + rol $30, SC + xor OFFSET(6) (DATA), T1 + xor OFFSET(11) (DATA), T1 + xor SC, T2 + xor SB, T2 + rol $1, T1 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(14) (DATA) + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(15) (DATA), T1 + xor OFFSET(1) (DATA), T1 + add T2, SE + mov SC, T2 + rol $30, SB + xor SB, T2 + xor OFFSET(7) (DATA), T1 + xor OFFSET(12) (DATA), T1 + xor SA, T2 + rol $1, T1 + mov T1, OFFSET(15) (DATA) + lea K2VALUE (T1, T2), T2 + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(0) (DATA), T1 + xor OFFSET(2) (DATA), T1 + xor OFFSET(8) (DATA), T1 + add T2, SD + mov SB, T2 + rol $30, SA + xor SA, T2 + xor OFFSET(13) (DATA), T1 + rol $1, T1 + xor SE, T2 + mov T1, OFFSET(0) (DATA) + lea K2VALUE (T1, T2), T2 + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(1) (DATA), T1 + xor OFFSET(3) (DATA), T1 + add T2, SC + mov SA, T2 + rol $30, SE + xor SE, T2 + xor OFFSET(9) (DATA), T1 + xor OFFSET(14) (DATA), T1 + rol $1, T1 + xor SD, T2 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(1) (DATA) + mov SC, T1 + rol $5, T1 + add T1, SB + mov OFFSET(2) (DATA), T1 + rol $30, SD + xor OFFSET(4) (DATA), T1 + add T2, SB + mov SE, T2 + xor OFFSET(10) (DATA), T1 + xor OFFSET(15) (DATA), T1 + xor SD, T2 + xor SC, T2 + rol $1, T1 + mov T1, OFFSET(2) (DATA) + lea K2VALUE (T1, T2), T2 + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(3) (DATA), T1 + xor OFFSET(5) (DATA), T1 + xor OFFSET(11) (DATA), T1 + xor OFFSET(0) (DATA), T1 + add T2, SA + rol $30, SC + mov SD, T2 + xor SC, T2 + rol $1, T1 + xor SB, T2 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(3) (DATA) + mov SA, T1 + rol $5, T1 + rol $30, SB + add T1, SE + mov OFFSET(4) (DATA), T1 + add T2, SE + xor OFFSET(6) (DATA), T1 + xor OFFSET(12) (DATA), T1 + xor OFFSET(1) (DATA), T1 + mov SC, T2 + xor SB, T2 + rol $1, T1 + xor SA, T2 + lea K2VALUE (T1, T2), T2 + mov T1, OFFSET(4) (DATA) + mov SE, T1 + rol $5, T1 + add T1, SD + add T2, SD + mov OFFSET(5) (DATA), T1 + mov SB, T2 + rol $30, SA + xor SA, T2 + xor SE, T2 + xor OFFSET(7) (DATA), T1 + xor OFFSET(13) (DATA), T1 + xor OFFSET(2) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(5) (DATA) + lea K2VALUE (T1, T2), T2 + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(6) (DATA), T1 + xor OFFSET(8) (DATA), T1 + add T2, SC + xor OFFSET(14) (DATA), T1 + xor OFFSET(3) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(6) (DATA) + mov SA, T2 + rol $30, SE + xor SE, T2 + xor SD, T2 + lea K2VALUE (T1, T2), T2 + mov SC, T1 + rol $5, T1 + add T1, SB + add T2, SB + mov OFFSET(7) (DATA), T1 + mov SE, T2 + rol $30, SD + xor OFFSET(9) (DATA), T1 + xor SD, T2 + xor SC, T2 + xor OFFSET(15) (DATA), T1 + xor OFFSET(4) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(7) (DATA) + lea K2VALUE (T1, T2), T2 + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(8) (DATA), T1 + xor OFFSET(10) (DATA), T1 + rol $30, SC + xor OFFSET(0) (DATA), T1 + add T2, SA + mov SD, T2 + xor OFFSET(5) (DATA), T1 + rol $1, T1 + and SC, T2 + mov T1, OFFSET(8) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SE + mov SA, T1 + mov SD, T2 + xor SC, T2 + and SB, T2 + rol $30, SB + rol $5, T1 + add T1, SE + mov OFFSET(9) (DATA), T1 + xor OFFSET(11) (DATA), T1 + xor OFFSET(1) (DATA), T1 + add T2, SE + mov SC, T2 + xor OFFSET(6) (DATA), T1 + rol $1, T1 + and SB, T2 + mov T1, OFFSET(9) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SD + mov SC, T2 + xor SB, T2 + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(10) (DATA), T1 + and SA, T2 + add T2, SD + xor OFFSET(12) (DATA), T1 + xor OFFSET(2) (DATA), T1 + rol $30, SA + mov SB, T2 + and SA, T2 + xor OFFSET(7) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(10) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SC + mov SD, T1 + rol $5, T1 + mov SB, T2 + add T1, SC + mov OFFSET(11) (DATA), T1 + xor SA, T2 + xor OFFSET(13) (DATA), T1 + xor OFFSET(3) (DATA), T1 + and SE, T2 + xor OFFSET(8) (DATA), T1 + add T2, SC + rol $1, T1 + mov SA, T2 + mov T1, OFFSET(11) (DATA) + rol $30, SE + and SE, T2 + lea K3VALUE (T1, T2), T1 + add T1, SB + mov SA, T2 + mov SC, T1 + xor SE, T2 + rol $5, T1 + add T1, SB + mov OFFSET(12) (DATA), T1 + xor OFFSET(14) (DATA), T1 + xor OFFSET(4) (DATA), T1 + xor OFFSET(9) (DATA), T1 + and SD, T2 + rol $30, SD + add T2, SB + rol $1, T1 + mov T1, OFFSET(12) (DATA) + mov SE, T2 + and SD, T2 + lea K3VALUE (T1, T2), T1 + add T1, SA + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(13) (DATA), T1 + xor OFFSET(15) (DATA), T1 + mov SE, T2 + xor OFFSET(5) (DATA), T1 + xor SD, T2 + and SC, T2 + xor OFFSET(10) (DATA), T1 + add T2, SA + rol $1, T1 + rol $30, SC + mov T1, OFFSET(13) (DATA) + mov SD, T2 + and SC, T2 + lea K3VALUE (T1, T2), T1 + mov SD, T2 + add T1, SE + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(14) (DATA), T1 + xor OFFSET(0) (DATA), T1 + xor SC, T2 + and SB, T2 + xor OFFSET(6) (DATA), T1 + rol $30, SB + xor OFFSET(11) (DATA), T1 + rol $1, T1 + add T2, SE + mov SC, T2 + mov T1, OFFSET(14) (DATA) + and SB, T2 + lea K3VALUE (T1, T2), T1 + mov SC, T2 + add T1, SD + mov SE, T1 + xor SB, T2 + rol $5, T1 + add T1, SD + mov OFFSET(15) (DATA), T1 + xor OFFSET(1) (DATA), T1 + and SA, T2 + xor OFFSET(7) (DATA), T1 + xor OFFSET(12) (DATA), T1 + add T2, SD + rol $30, SA + mov SB, T2 + rol $1, T1 + mov T1, OFFSET(15) (DATA) + and SA, T2 + lea K3VALUE (T1, T2), T1 + add T1, SC + mov SD, T1 + mov SB, T2 + rol $5, T1 + add T1, SC + mov OFFSET(0) (DATA), T1 + xor SA, T2 + xor OFFSET(2) (DATA), T1 + xor OFFSET(8) (DATA), T1 + xor OFFSET(13) (DATA), T1 + and SE, T2 + add T2, SC + rol $30, SE + rol $1, T1 + mov T1, OFFSET(0) (DATA) + mov SA, T2 + and SE, T2 + lea K3VALUE (T1, T2), T1 + add T1, SB + mov SC, T1 + mov SA, T2 + xor SE, T2 + rol $5, T1 + add T1, SB + mov OFFSET(1) (DATA), T1 + xor OFFSET(3) (DATA), T1 + xor OFFSET(9) (DATA), T1 + and SD, T2 + xor OFFSET(14) (DATA), T1 + add T2, SB + rol $30, SD + mov SE, T2 + rol $1, T1 + and SD, T2 + mov T1, OFFSET(1) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SA + mov SB, T1 + rol $5, T1 + add T1, SA + mov SE, T2 + mov OFFSET(2) (DATA), T1 + xor SD, T2 + xor OFFSET(4) (DATA), T1 + xor OFFSET(10) (DATA), T1 + and SC, T2 + add T2, SA + xor OFFSET(15) (DATA), T1 + rol $30, SC + mov SD, T2 + rol $1, T1 + mov T1, OFFSET(2) (DATA) + and SC, T2 + lea K3VALUE (T1, T2), T1 + add T1, SE + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(3) (DATA), T1 + xor OFFSET(5) (DATA), T1 + xor OFFSET(11) (DATA), T1 + xor OFFSET(0) (DATA), T1 + mov SD, T2 + rol $1, T1 + xor SC, T2 + and SB, T2 + mov T1, OFFSET(3) (DATA) + rol $30, SB + add T2, SE + mov SC, T2 + and SB, T2 + lea K3VALUE (T1, T2), T1 + add T1, SD + mov SE, T1 + mov SC, T2 + rol $5, T1 + add T1, SD + mov OFFSET(4) (DATA), T1 + xor OFFSET(6) (DATA), T1 + xor SB, T2 + and SA, T2 + add T2, SD + mov SB, T2 + xor OFFSET(12) (DATA), T1 + rol $30, SA + and SA, T2 + xor OFFSET(1) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(4) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SC + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(5) (DATA), T1 + xor OFFSET(7) (DATA), T1 + mov SB, T2 + xor OFFSET(13) (DATA), T1 + xor SA, T2 + xor OFFSET(2) (DATA), T1 + and SE, T2 + rol $30, SE + add T2, SC + rol $1, T1 + mov SA, T2 + mov T1, OFFSET(5) (DATA) + and SE, T2 + lea K3VALUE (T1, T2), T1 + add T1, SB + mov SA, T2 + mov SC, T1 + rol $5, T1 + add T1, SB + xor SE, T2 + and SD, T2 + mov OFFSET(6) (DATA), T1 + xor OFFSET(8) (DATA), T1 + xor OFFSET(14) (DATA), T1 + xor OFFSET(3) (DATA), T1 + rol $1, T1 + add T2, SB + rol $30, SD + mov SE, T2 + and SD, T2 + mov T1, OFFSET(6) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SA + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(7) (DATA), T1 + xor OFFSET(9) (DATA), T1 + mov SE, T2 + xor SD, T2 + xor OFFSET(15) (DATA), T1 + and SC, T2 + rol $30, SC + add T2, SA + mov SD, T2 + xor OFFSET(4) (DATA), T1 + rol $1, T1 + and SC, T2 + mov T1, OFFSET(7) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SE + mov SA, T1 + rol $5, T1 + mov SD, T2 + add T1, SE + mov OFFSET(8) (DATA), T1 + xor OFFSET(10) (DATA), T1 + xor SC, T2 + xor OFFSET(0) (DATA), T1 + and SB, T2 + add T2, SE + xor OFFSET(5) (DATA), T1 + rol $30, SB + mov SC, T2 + and SB, T2 + rol $1, T1 + mov T1, OFFSET(8) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SD + mov SE, T1 + rol $5, T1 + mov SC, T2 + xor SB, T2 + add T1, SD + and SA, T2 + mov OFFSET(9) (DATA), T1 + rol $30, SA + xor OFFSET(11) (DATA), T1 + xor OFFSET(1) (DATA), T1 + add T2, SD + mov SB, T2 + and SA, T2 + xor OFFSET(6) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(9) (DATA) + lea K3VALUE (T1, T2), T1 + add T1, SC + mov SD, T1 + rol $5, T1 + mov SB, T2 + xor SA, T2 + and SE, T2 + add T1, SC + mov OFFSET(10) (DATA), T1 + xor OFFSET(12) (DATA), T1 + xor OFFSET(2) (DATA), T1 + add T2, SC + mov SA, T2 + rol $30, SE + xor OFFSET(7) (DATA), T1 + rol $1, T1 + and SE, T2 + mov T1, OFFSET(10) (DATA) + lea K3VALUE (T1, T2), T1 + mov SA, T2 + xor SE, T2 + add T1, SB + mov SC, T1 + rol $5, T1 + add T1, SB + mov OFFSET(11) (DATA), T1 + xor OFFSET(13) (DATA), T1 + xor OFFSET(3) (DATA), T1 + xor OFFSET(8) (DATA), T1 + and SD, T2 + add T2, SB + mov SE, T2 + rol $1, T1 + mov T1, OFFSET(11) (DATA) + rol $30, SD + and SD, T2 + lea K3VALUE (T1, T2), T1 + mov SE, T2 + add T1, SA + xor SD, T2 + mov SB, T1 + and SC, T2 + rol $30, SC + rol $5, T1 + add T1, SA + mov OFFSET(12) (DATA), T1 + xor OFFSET(14) (DATA), T1 + add T2, SA + mov SD, T2 + xor OFFSET(4) (DATA), T1 + xor OFFSET(9) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(12) (DATA) + xor SC, T2 + xor SB, T2 + lea K4VALUE (T1, T2), T2 + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(13) (DATA), T1 + xor OFFSET(15) (DATA), T1 + add T2, SE + rol $30, SB + mov SC, T2 + xor OFFSET(5) (DATA), T1 + xor SB, T2 + xor OFFSET(10) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(13) (DATA) + xor SA, T2 + lea K4VALUE (T1, T2), T2 + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(14) (DATA), T1 + xor OFFSET(0) (DATA), T1 + rol $30, SA + add T2, SD + mov SB, T2 + xor SA, T2 + xor SE, T2 + xor OFFSET(6) (DATA), T1 + xor OFFSET(11) (DATA), T1 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(14) (DATA) + mov SD, T1 + rol $5, T1 + add T1, SC + add T2, SC + mov OFFSET(15) (DATA), T1 + mov SA, T2 + rol $30, SE + xor OFFSET(1) (DATA), T1 + xor OFFSET(7) (DATA), T1 + xor SE, T2 + xor SD, T2 + xor OFFSET(12) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(15) (DATA) + lea K4VALUE (T1, T2), T2 + mov SC, T1 + rol $5, T1 + add T1, SB + mov OFFSET(0) (DATA), T1 + add T2, SB + xor OFFSET(2) (DATA), T1 + mov SE, T2 + rol $30, SD + xor OFFSET(8) (DATA), T1 + xor SD, T2 + xor OFFSET(13) (DATA), T1 + xor SC, T2 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(0) (DATA) + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(1) (DATA), T1 + rol $30, SC + xor OFFSET(3) (DATA), T1 + xor OFFSET(9) (DATA), T1 + xor OFFSET(14) (DATA), T1 + add T2, SA + mov SD, T2 + xor SC, T2 + rol $1, T1 + xor SB, T2 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(1) (DATA) + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(2) (DATA), T1 + rol $30, SB + xor OFFSET(4) (DATA), T1 + add T2, SE + mov SC, T2 + xor SB, T2 + xor OFFSET(10) (DATA), T1 + xor OFFSET(15) (DATA), T1 + xor SA, T2 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(2) (DATA) + mov SE, T1 + rol $5, T1 + add T1, SD + mov OFFSET(3) (DATA), T1 + xor OFFSET(5) (DATA), T1 + xor OFFSET(11) (DATA), T1 + xor OFFSET(0) (DATA), T1 + rol $30, SA + add T2, SD + mov SB, T2 + rol $1, T1 + mov T1, OFFSET(3) (DATA) + xor SA, T2 + xor SE, T2 + lea K4VALUE (T1, T2), T2 + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(4) (DATA), T1 + add T2, SC + rol $30, SE + xor OFFSET(6) (DATA), T1 + mov SA, T2 + xor OFFSET(12) (DATA), T1 + xor SE, T2 + xor OFFSET(1) (DATA), T1 + rol $1, T1 + xor SD, T2 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(4) (DATA) + mov SC, T1 + rol $5, T1 + add T1, SB + rol $30, SD + mov OFFSET(5) (DATA), T1 + add T2, SB + xor OFFSET(7) (DATA), T1 + xor OFFSET(13) (DATA), T1 + mov SE, T2 + xor SD, T2 + xor OFFSET(2) (DATA), T1 + xor SC, T2 + rol $1, T1 + mov T1, OFFSET(5) (DATA) + lea K4VALUE (T1, T2), T2 + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(6) (DATA), T1 + xor OFFSET(8) (DATA), T1 + xor OFFSET(14) (DATA), T1 + add T2, SA + xor OFFSET(3) (DATA), T1 + mov SD, T2 + rol $30, SC + rol $1, T1 + xor SC, T2 + mov T1, OFFSET(6) (DATA) + xor SB, T2 + lea K4VALUE (T1, T2), T2 + mov SA, T1 + rol $5, T1 + add T1, SE + add T2, SE + mov OFFSET(7) (DATA), T1 + xor OFFSET(9) (DATA), T1 + xor OFFSET(15) (DATA), T1 + rol $30, SB + xor OFFSET(4) (DATA), T1 + mov SC, T2 + rol $1, T1 + mov T1, OFFSET(7) (DATA) + xor SB, T2 + xor SA, T2 + lea K4VALUE (T1, T2), T2 + mov SE, T1 + rol $5, T1 + add T1, SD + rol $30, SA + mov OFFSET(8) (DATA), T1 + xor OFFSET(10) (DATA), T1 + add T2, SD + xor OFFSET(0) (DATA), T1 + xor OFFSET(5) (DATA), T1 + rol $1, T1 + mov SB, T2 + mov T1, OFFSET(8) (DATA) + xor SA, T2 + xor SE, T2 + lea K4VALUE (T1, T2), T2 + mov SD, T1 + rol $5, T1 + add T1, SC + add T2, SC + mov SA, T2 + mov OFFSET(9) (DATA), T1 + rol $30, SE + xor OFFSET(11) (DATA), T1 + xor OFFSET(1) (DATA), T1 + xor OFFSET(6) (DATA), T1 + xor SE, T2 + xor SD, T2 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(9) (DATA) + mov SC, T1 + rol $5, T1 + add T1, SB + rol $30, SD + mov OFFSET(10) (DATA), T1 + xor OFFSET(12) (DATA), T1 + xor OFFSET(2) (DATA), T1 + add T2, SB + mov SE, T2 + xor SD, T2 + xor SC, T2 + xor OFFSET(7) (DATA), T1 + rol $1, T1 + mov T1, OFFSET(10) (DATA) + lea K4VALUE (T1, T2), T2 + mov SB, T1 + rol $5, T1 + add T1, SA + mov OFFSET(11) (DATA), T1 + xor OFFSET(13) (DATA), T1 + xor OFFSET(3) (DATA), T1 + add T2, SA + mov SD, T2 + rol $30, SC + xor SC, T2 + xor OFFSET(8) (DATA), T1 + rol $1, T1 + xor SB, T2 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(11) (DATA) + mov SA, T1 + rol $5, T1 + add T1, SE + mov OFFSET(12) (DATA), T1 + add T2, SE + xor OFFSET(14) (DATA), T1 + rol $30, SB + mov SC, T2 + xor OFFSET(4) (DATA), T1 + xor SB, T2 + xor SA, T2 + xor OFFSET(9) (DATA), T1 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(12) (DATA) + mov SE, T1 + rol $5, T1 + add T1, SD + add T2, SD + rol $30, SA + mov OFFSET(13) (DATA), T1 + xor OFFSET(15) (DATA), T1 + mov SB, T2 + xor OFFSET(5) (DATA), T1 + xor SA, T2 + xor OFFSET(10) (DATA), T1 + xor SE, T2 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(13) (DATA) + mov SD, T1 + rol $5, T1 + add T1, SC + mov OFFSET(14) (DATA), T1 + xor OFFSET(0) (DATA), T1 + xor OFFSET(6) (DATA), T1 + add T2, SC + rol $30, SE + mov SA, T2 + xor SE, T2 + xor OFFSET(11) (DATA), T1 + xor SD, T2 + rol $1, T1 + lea K4VALUE (T1, T2), T2 + mov T1, OFFSET(14) (DATA) + mov SC, T1 + rol $5, T1 + add T1, SB + mov OFFSET(15) (DATA), T1 + xor OFFSET(1) (DATA), T1 + xor OFFSET(7) (DATA), T1 + rol $30, SD + add T2, SB + xor OFFSET(12) (DATA), T1 + mov SE, T2 + xor SD, T2 + rol $1, T1 + xor SC, T2 + lea K4VALUE (T1, T2), T2 + rol $30, SC + mov T1, OFFSET(15) (DATA) + mov SB, T1 + rol $5, T1 + add T1, SA + add T2, SA + +C C Load and byteswap data +C movl 88(%esp), T2 +C +C SWAP( 0, %eax) SWAP( 1, %ebx) SWAP( 2, %ecx) SWAP( 3, %edx) +C SWAP( 4, %eax) SWAP( 5, %ebx) SWAP( 6, %ecx) SWAP( 7, %edx) +C SWAP( 8, %eax) SWAP( 9, %ebx) SWAP(10, %ecx) SWAP(11, %edx) +C SWAP(12, %eax) SWAP(13, %ebx) SWAP(14, %ecx) SWAP(15, %edx) +C +C C load the state vector +C movl 84(%esp),T1 +C movl (T1), SA +C movl 4(T1), SB +C movl 8(T1), SC +C movl 12(T1), SD +C movl 16(T1), SE +C +C ROUND_F1_NOEXP(SA, SB, SC, SD, SE, 0) +C ROUND_F1_NOEXP(SE, SA, SB, SC, SD, 1) +C ROUND_F1_NOEXP(SD, SE, SA, SB, SC, 2) +C ROUND_F1_NOEXP(SC, SD, SE, SA, SB, 3) +C ROUND_F1_NOEXP(SB, SC, SD, SE, SA, 4) +C +C ROUND_F1_NOEXP(SA, SB, SC, SD, SE, 5) +C ROUND_F1_NOEXP(SE, SA, SB, SC, SD, 6) +C ROUND_F1_NOEXP(SD, SE, SA, SB, SC, 7) +C ROUND_F1_NOEXP(SC, SD, SE, SA, SB, 8) +C ROUND_F1_NOEXP(SB, SC, SD, SE, SA, 9) +C +C ROUND_F1_NOEXP(SA, SB, SC, SD, SE, 10) +C ROUND_F1_NOEXP(SE, SA, SB, SC, SD, 11) +C ROUND_F1_NOEXP(SD, SE, SA, SB, SC, 12) +C ROUND_F1_NOEXP(SC, SD, SE, SA, SB, 13) +C ROUND_F1_NOEXP(SB, SC, SD, SE, SA, 14) +C +C ROUND_F1_NOEXP(SA, SB, SC, SD, SE, 15) +C ROUND_F1(SE, SA, SB, SC, SD, 16) +C ROUND_F1(SD, SE, SA, SB, SC, 17) +C ROUND_F1(SC, SD, SE, SA, SB, 18) +C ROUND_F1(SB, SC, SD, SE, SA, 19) +C +C ROUND_F2(SA, SB, SC, SD, SE, 20, K2VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 21, K2VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 22, K2VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 23, K2VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 24, K2VALUE) +C +C ROUND_F2(SA, SB, SC, SD, SE, 25, K2VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 26, K2VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 27, K2VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 28, K2VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 29, K2VALUE) +C +C ROUND_F2(SA, SB, SC, SD, SE, 30, K2VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 31, K2VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 32, K2VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 33, K2VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 34, K2VALUE) +C +C ROUND_F2(SA, SB, SC, SD, SE, 35, K2VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 36, K2VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 37, K2VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 38, K2VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 39, K2VALUE) +C +C ROUND_F3(SA, SB, SC, SD, SE, 40) +C ROUND_F3(SE, SA, SB, SC, SD, 41) +C ROUND_F3(SD, SE, SA, SB, SC, 42) +C ROUND_F3(SC, SD, SE, SA, SB, 43) +C ROUND_F3(SB, SC, SD, SE, SA, 44) +C +C ROUND_F3(SA, SB, SC, SD, SE, 45) +C ROUND_F3(SE, SA, SB, SC, SD, 46) +C ROUND_F3(SD, SE, SA, SB, SC, 47) +C ROUND_F3(SC, SD, SE, SA, SB, 48) +C ROUND_F3(SB, SC, SD, SE, SA, 49) +C +C ROUND_F3(SA, SB, SC, SD, SE, 50) +C ROUND_F3(SE, SA, SB, SC, SD, 51) +C ROUND_F3(SD, SE, SA, SB, SC, 52) +C ROUND_F3(SC, SD, SE, SA, SB, 53) +C ROUND_F3(SB, SC, SD, SE, SA, 54) +C +C ROUND_F3(SA, SB, SC, SD, SE, 55) +C ROUND_F3(SE, SA, SB, SC, SD, 56) +C ROUND_F3(SD, SE, SA, SB, SC, 57) +C ROUND_F3(SC, SD, SE, SA, SB, 58) +C ROUND_F3(SB, SC, SD, SE, SA, 59) +C +C ROUND_F2(SA, SB, SC, SD, SE, 60, K4VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 61, K4VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 62, K4VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 63, K4VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 64, K4VALUE) +C +C ROUND_F2(SA, SB, SC, SD, SE, 65, K4VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 66, K4VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 67, K4VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 68, K4VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 69, K4VALUE) +C +C ROUND_F2(SA, SB, SC, SD, SE, 70, K4VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 71, K4VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 72, K4VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 73, K4VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 74, K4VALUE) +C +C ROUND_F2(SA, SB, SC, SD, SE, 75, K4VALUE) +C ROUND_F2(SE, SA, SB, SC, SD, 76, K4VALUE) +C ROUND_F2(SD, SE, SA, SB, SC, 77, K4VALUE) +C ROUND_F2(SC, SD, SE, SA, SB, 78, K4VALUE) +C ROUND_F2(SB, SC, SD, SE, SA, 79, K4VALUE) + + C Update the state vector + movl 84(%esp),T1 + addl SA, (T1) + addl SB, 4(T1) + addl SC, 8(T1) + addl SD, 12(T1) + addl SE, 16(T1) + + addl $64, %esp + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +EPILOGUE(_nettle_sha1_compress) + +C TODO: + +C * Extend loopmixer so that it can exploit associativity, and for +C example reorder +C +C add %eax, %ebx +C add %ecx, %ebx + +C * Use mmx instructions for the data expansion, doing two words at a +C time. diff --git a/x86_64/aes-decrypt-internal.asm b/x86_64/aes-decrypt-internal.asm new file mode 100644 index 0000000..8f0df73 --- /dev/null +++ b/x86_64/aes-decrypt-internal.asm @@ -0,0 +1,133 @@ +C nettle, low-level cryptographics library +C +C Copyright (C) 2001, 2002, 2005, 2008 Rafael R. Sevilla, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +include_src() + +C Register usage: + +C AES state, use two of them +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +define(,<%r10d>) +define(,<%r11d>) +define(,<%r12d>) + +define(, <%rdi>) +define(, <%rsi>) +define(,<%edx>) C Length is only 32 bits +define(, <%rcx>) +define(, <%r8>) + +define(, <%r9>) +define(,<%r14>) +define(, <%r15d>) +define(, <%r13d>) + +C Must correspond to an old-style register, for movzb from %ah--%dh to +C work. +define(,<%rbp>) + + .file "aes-decrypt-internal.asm" + + C _aes_decrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_decrypt) + test PARAM_LENGTH, PARAM_LENGTH + jz .Lend + + C save all registers that need to be saved + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + mov PARAM_DST, DST + movl PARAM_LENGTH, BLOCK_COUNT + shrl $4, BLOCK_COUNT +.Lblock_loop: + mov CTX,KEY + + AES_LOAD(SA, SB, SC, SD, SRC, KEY) + add $16, SRC C Increment src pointer + + C get number of rounds to do from ctx struct + movl AES_NROUNDS (CTX), COUNT + subl $1, COUNT + + add $16,KEY C point to next key + ALIGN(4) +.Lround_loop: + AES_ROUND(TABLE, SA,SD,SC,SB, TA, TMP) + AES_ROUND(TABLE, SB,SA,SD,SC, TB, TMP) + AES_ROUND(TABLE, SC,SB,SA,SD, TC, TMP) + AES_ROUND(TABLE, SD,SC,SB,SA, SD, TMP) + + movl TA, SA + movl TB, SB + movl TC, SC + + xorl (KEY),SA C add current session key to plaintext + xorl 4(KEY),SB + xorl 8(KEY),SC + xorl 12(KEY),SD + + add $16,KEY C point to next key + decl COUNT + jnz .Lround_loop + + C last round + AES_FINAL_ROUND(SA,SD,SC,SB, TABLE, TA, TMP) + AES_FINAL_ROUND(SB,SA,SD,SC, TABLE, TB, TMP) + AES_FINAL_ROUND(SC,SB,SA,SD, TABLE, TC, TMP) + AES_FINAL_ROUND(SD,SC,SB,SA, TABLE, SD, TMP) + + C Inverse S-box substitution + mov $3, COUNT +.Lsubst: + AES_SUBST_BYTE(TA,TB,TC,SD, TABLE, TMP) + + decl COUNT + jnz .Lsubst + + C Add last subkey, and store decrypted data + AES_STORE(TA,TB,TC,SD, KEY, DST) + + add $16, DST + decl BLOCK_COUNT + + jnz .Lblock_loop + + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx +.Lend: + ret +EPILOGUE(_nettle_aes_decrypt) diff --git a/x86_64/aes-encrypt-internal.asm b/x86_64/aes-encrypt-internal.asm new file mode 100644 index 0000000..c23feb6 --- /dev/null +++ b/x86_64/aes-encrypt-internal.asm @@ -0,0 +1,133 @@ +C nettle, low-level cryptographics library +C +C Copyright (C) 2001, 2002, 2005, 2008 Rafael R. Sevilla, Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +include_src() + +C Register usage: + +C AES state, use two of them +define(,<%eax>) +define(,<%ebx>) +define(,<%ecx>) +define(,<%edx>) + +define(,<%r10d>) +define(,<%r11d>) +define(,<%r12d>) + +define(, <%rdi>) +define(
, <%rsi>) +define(,<%edx>) C Length is only 32 bits +define(, <%rcx>) +define(, <%r8>) + +define(, <%r9>) +define(,<%r14>) +define(, <%r15d>) +define(, <%r13d>) + +C Must correspond to an old-style register, for movzb from %ah--%dh to +C work. +define(,<%rbp>) + + .file "aes-encrypt-internal.asm" + + C _aes_encrypt(struct aes_context *ctx, + C const struct aes_table *T, + C unsigned length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_encrypt) + test PARAM_LENGTH, PARAM_LENGTH + jz .Lend + + C save all registers that need to be saved + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + mov PARAM_DST, DST + movl PARAM_LENGTH, BLOCK_COUNT + shrl $4, BLOCK_COUNT +.Lblock_loop: + mov CTX,KEY + + AES_LOAD(SA, SB, SC, SD, SRC, KEY) + add $16, SRC C Increment src pointer + + C get number of rounds to do from ctx struct + movl AES_NROUNDS (CTX), COUNT + subl $1, COUNT + + add $16,KEY C point to next key + ALIGN(4) +.Lround_loop: + AES_ROUND(TABLE, SA,SB,SC,SD, TA, TMP) + AES_ROUND(TABLE, SB,SC,SD,SA, TB, TMP) + AES_ROUND(TABLE, SC,SD,SA,SB, TC, TMP) + AES_ROUND(TABLE, SD,SA,SB,SC, SD, TMP) + + movl TA, SA + movl TB, SB + movl TC, SC + + xorl (KEY),SA C add current session key to plaintext + xorl 4(KEY),SB + xorl 8(KEY),SC + xorl 12(KEY),SD + + add $16,KEY C point to next key + decl COUNT + jnz .Lround_loop + + C last round + AES_FINAL_ROUND(SA,SB,SC,SD, TABLE, TA, TMP) + AES_FINAL_ROUND(SB,SC,SD,SA, TABLE, TB, TMP) + AES_FINAL_ROUND(SC,SD,SA,SB, TABLE, TC, TMP) + AES_FINAL_ROUND(SD,SA,SB,SC, TABLE, SD, TMP) + + C S-box substitution + mov $3, COUNT +.Lsubst: + AES_SUBST_BYTE(TA,TB,TC,SD, TABLE, TMP) + + decl COUNT + jnz .Lsubst + + C Add last subkey, and store encrypted data + AES_STORE(TA,TB,TC,SD, KEY, DST) + + add $16, DST + decl BLOCK_COUNT + + jnz .Lblock_loop + + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx +.Lend: + ret +EPILOGUE(_nettle_aes_encrypt) diff --git a/x86_64/aes.m4 b/x86_64/aes.m4 new file mode 100644 index 0000000..8034f77 --- /dev/null +++ b/x86_64/aes.m4 @@ -0,0 +1,130 @@ +dnl LREG(reg) gives the 8-bit register corresponding to the given 32-bit register. +define(,)dnl + +define(,) + +define(,)dnl + +dnl AES_LOAD(a, b, c, d, src, key) +dnl Loads the next block of data from src, and add the subkey pointed +dnl to by key. +dnl Note that x86 allows unaligned accesses. +dnl Would it be preferable to interleave the loads and stores? +define(, < + movl ($5),$1 + movl 4($5),$2 + movl 8($5),$3 + movl 12($5),$4 + + xorl ($6),$1 + xorl 4($6),$2 + xorl 8($6),$3 + xorl 12($6),$4>)dnl + +dnl AES_STORE(a, b, c, d, key, dst) +dnl Adds the subkey to a, b, c, d, +dnl and stores the result in the area pointed to by dst. +dnl Note that x86 allows unaligned accesses. +dnl Would it be preferable to interleave the loads and stores? +define(, < + xorl ($5),$1 + xorl 4($5),$2 + xorl 8($5),$3 + xorl 12($5),$4 + + movl $1,($6) + movl $2,4($6) + movl $3,8($6) + movl $4,12($6)>)dnl + +dnl AES_ROUND(table,a,b,c,d,out,ptr) +dnl Computes one word of the AES round. Leaves result in $6. +define(, < + movzb LREG($2), $7 + movl AES_TABLE0 ($1, $7, 4),$6 + movzb HREG($3), XREG($7) + xorl AES_TABLE1 ($1, $7, 4),$6 + movl $4,XREG($7) + shr <$>16,$7 + and <$>0xff,$7 + xorl AES_TABLE2 ($1, $7, 4),$6 + movl $5,XREG($7) + shr <$>24,$7 + xorl AES_TABLE3 ($1, $7, 4),$6>)dnl + +dnl AES_FINAL_ROUND(a, b, c, d, table, out, tmp) +dnl Computes one word of the final round. Leaves result in $6. Also +dnl performs the first substitution step, on the least significant +dnl byte, and rotates 8 bits. +define(, < + movzb LREG($1),$7 + movzbl ($5, $7), $6 + movl $2,XREG($7) + andl <$>0x0000ff00,XREG($7) + orl XREG($7), $6 + movl $3,XREG($7) + andl <$>0x00ff0000,XREG($7) + orl XREG($7), $6 + movl $4,XREG($7) + andl <$>0xff000000,XREG($7) + orl XREG($7), $6 + roll <$>8, $6>)dnl + +dnl AES_SUBST_BYTE(A, B, C, D, table, tmp) +dnl Substitutes the least significant byte of +dnl each of eax, ebx, ecx and edx, and also rotates +dnl the words one byte to the left. +dnl Uses that AES_SBOX == 0 +define(, < + movzb LREG($1),$6 + movb ($5, $6),LREG($1) + roll <$>8,$1 + + movzb LREG($2),$6 + movb ($5, $6),LREG($2) + roll <$>8,$2 + + movzb LREG($3),$6 + movb ($5, $6),LREG($3) + roll <$>8,$3 + + movzb LREG($4),$6 + movb ($5, $6),LREG($4) + roll <$>8,$4>)dnl diff --git a/x86_64/machine.m4 b/x86_64/machine.m4 new file mode 100644 index 0000000..887bf3b --- /dev/null +++ b/x86_64/machine.m4 @@ -0,0 +1,3 @@ +C OFFSET(i) +C Expands to 4*i, or to the empty string if i is zero +define(, ) diff --git a/x86_64/sha1-compress.asm b/x86_64/sha1-compress.asm new file mode 100644 index 0000000..a912ce0 --- /dev/null +++ b/x86_64/sha1-compress.asm @@ -0,0 +1,254 @@ +C nettle, low-level cryptographics library +C +C Copyright (C) 2004, 2008 Niels Möller +C +C The nettle library is free software; you can redistribute it and/or modify +C it under the terms of the GNU Lesser General Public License as published by +C the Free Software Foundation; either version 2.1 of the License, or (at your +C option) any later version. +C +C The nettle library is distributed in the hope that it will be useful, but +C WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +C or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +C License for more details. +C +C You should have received a copy of the GNU Lesser General Public License +C along with the nettle library; see the file COPYING.LIB. If not, write to +C the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +C MA 02111-1307, USA. + +C Register usage. KVALUE and INPUT share a register. +define(,<%eax>)dnl +define(,<%r8d>)dnl +define(,<%ecx>)dnl +define(,<%edx>)dnl +define(,<%r9d>)dnl +define(,<%rsp>)dnl +define(,<%r10d>)dnl +define(,<%r11d>)dnl C Used by F3 +define(, <%esi>)dnl + +C Arguments +define(,<%rdi>)dnl +define(,<%rsi>)dnl + +C Constants +define(, <<$>0x5A827999>)dnl C Rounds 0-19 +define(, <<$>0x6ED9EBA1>)dnl C Rounds 20-39 +define(, <<$>0x8F1BBCDC>)dnl C Rounds 40-59 +define(, <<$>0xCA62C1D6>)dnl C Rounds 60-79 + +C Reads the input into register, byteswaps it, and stores it in the DATA array. +C SWAP(index, register) +define(, < + movl OFFSET($1)(INPUT), $2 + bswap $2 + movl $2, OFFSET($1) (DATA) +>)dnl + +C expand(i) is the expansion function +C +C W[i] = (W[i - 16] ^ W[i - 14] ^ W[i - 8] ^ W[i - 3]) <<< 1 +C +C where W[i] is stored in DATA[i mod 16]. +C +C Result is stored back in W[i], and also left in TMP, the only +C register that is used. +define(, < + movl OFFSET(eval($1 % 16)) (DATA), TMP + xorl OFFSET(eval(($1 + 2) % 16)) (DATA), TMP + xorl OFFSET(eval(($1 + 8) % 16)) (DATA), TMP + xorl OFFSET(eval(($1 + 13) % 16)) (DATA), TMP + roll <$>1, TMP + movl TMP, OFFSET(eval($1 % 16)) (DATA)>)dnl +define(, )dnl + +C The f functions, +C +C f1(x,y,z) = z ^ (x & (y ^ z)) +C f2(x,y,z) = x ^ y ^ z +C f3(x,y,z) = (x & y) | (z & (x | y)) +C f4 = f2 +C +C The macro Fk(x,y,z) computes = fk(x,y,z). +C Result is left in TMP. +define(, < + movl $3, TMP + xorl $2, TMP + andl $1, TMP + xorl $3, TMP>)dnl +define(, < + movl $1, TMP + xorl $2, TMP + xorl $3, TMP>)dnl +C Uses TMP2 +define(, < + movl $1, TMP2 + andl $2, TMP2 + movl $1, TMP + orl $2, TMP + andl $3, TMP + orl TMP2, TMP>)dnl + +C The form of one sha1 round is +C +C a' = e + a <<< 5 + f( b, c, d ) + k + w; +C b' = a; +C c' = b <<< 30; +C d' = c; +C e' = d; +C +C where <<< denotes rotation. We permute our variables, so that we +C instead get +C +C e += a <<< 5 + f( b, c, d ) + k + w; +C b <<<= 30 +C +C ROUND(a,b,c,d,e,f,w) +define(, < + addl KVALUE, $5 + addl ifelse($7,,TMP,$7), $5 + $6($2,$3,$4) + addl TMP, $5 + +C Using the TMP register could be avoided, by rotating $1 in place, +C adding, and then rotating back. + movl $1, TMP + roll <$>5, TMP + addl TMP, $5 + roll <$>30, $2>)dnl + + .file "sha1-compress.asm" + + C _nettle_sha1_compress(uint32_t *state, uint8_t *input) + + .text + ALIGN(4) +PROLOGUE(_nettle_sha1_compress) + C save all registers that need to be saved + + sub $68, %rsp C %rsp = W + + C Load and byteswap data + SWAP( 0, SA) SWAP( 1, SB) SWAP( 2, SC) SWAP( 3, SD) + SWAP( 4, SA) SWAP( 5, SB) SWAP( 6, SC) SWAP( 7, SD) + SWAP( 8, SA) SWAP( 9, SB) SWAP(10, SC) SWAP(11, SD) + SWAP(12, SA) SWAP(13, SB) SWAP(14, SC) SWAP(15, SD) + + C Load the state vector + movl (STATE), SA + movl 4(STATE), SB + movl 8(STATE), SC + movl 12(STATE), SD + movl 16(STATE), SE + + movl K1VALUE, KVALUE + ROUND(SA, SB, SC, SD, SE, , NOEXPAND( 0)) + ROUND(SE, SA, SB, SC, SD, , NOEXPAND( 1)) + ROUND(SD, SE, SA, SB, SC, , NOEXPAND( 2)) + ROUND(SC, SD, SE, SA, SB, , NOEXPAND( 3)) + ROUND(SB, SC, SD, SE, SA, , NOEXPAND( 4)) + + ROUND(SA, SB, SC, SD, SE, , NOEXPAND( 5)) + ROUND(SE, SA, SB, SC, SD, , NOEXPAND( 6)) + ROUND(SD, SE, SA, SB, SC, , NOEXPAND( 7)) + ROUND(SC, SD, SE, SA, SB, , NOEXPAND( 8)) + ROUND(SB, SC, SD, SE, SA, , NOEXPAND( 9)) + + ROUND(SA, SB, SC, SD, SE, , NOEXPAND(10)) + ROUND(SE, SA, SB, SC, SD, , NOEXPAND(11)) + ROUND(SD, SE, SA, SB, SC, , NOEXPAND(12)) + ROUND(SC, SD, SE, SA, SB, , NOEXPAND(13)) + ROUND(SB, SC, SD, SE, SA, , NOEXPAND(14)) + + ROUND(SA, SB, SC, SD, SE, , NOEXPAND(15)) + EXPAND(16) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(17) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(18) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(19) ROUND(SB, SC, SD, SE, SA, ) + + movl K2VALUE, KVALUE + EXPAND(20) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(21) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(22) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(23) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(24) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(25) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(26) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(27) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(28) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(29) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(30) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(31) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(32) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(33) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(34) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(35) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(36) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(37) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(38) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(39) ROUND(SB, SC, SD, SE, SA, ) + + movl K3VALUE, KVALUE + EXPAND(40) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(41) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(42) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(43) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(44) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(45) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(46) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(47) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(48) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(49) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(50) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(51) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(52) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(53) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(54) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(55) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(56) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(57) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(58) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(59) ROUND(SB, SC, SD, SE, SA, ) + + movl K4VALUE, KVALUE + EXPAND(60) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(61) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(62) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(63) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(64) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(65) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(66) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(67) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(68) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(69) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(70) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(71) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(72) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(73) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(74) ROUND(SB, SC, SD, SE, SA, ) + + EXPAND(75) ROUND(SA, SB, SC, SD, SE, ) + EXPAND(76) ROUND(SE, SA, SB, SC, SD, ) + EXPAND(77) ROUND(SD, SE, SA, SB, SC, ) + EXPAND(78) ROUND(SC, SD, SE, SA, SB, ) + EXPAND(79) ROUND(SB, SC, SD, SE, SA, ) + + C Update the state vector + addl SA, (STATE) + addl SB, 4(STATE) + addl SC, 8(STATE) + addl SD, 12(STATE) + addl SE, 16(STATE) + + add $68, %rsp + ret +EPILOGUE(_nettle_sha1_compress) diff --git a/yarrow.h b/yarrow.h new file mode 100644 index 0000000..22676c2 --- /dev/null +++ b/yarrow.h @@ -0,0 +1,137 @@ +/* yarrow.h + * + * The yarrow pseudo-randomness generator. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#ifndef NETTLE_YARROW_H_INCLUDED +#define NETTLE_YARROW_H_INCLUDED + +#include "aes.h" +#include "sha.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define yarrow256_init nettle_yarrow256_init +#define yarrow256_seed nettle_yarrow256_seed +#define yarrow256_update nettle_yarrow256_update +#define yarrow256_random nettle_yarrow256_random +#define yarrow256_is_seeded nettle_yarrow256_is_seeded +#define yarrow256_needed_sources nettle_yarrow256_needed_sources +#define yarrow256_fast_reseed nettle_yarrow256_fast_reseed +#define yarrow256_slow_reseed nettle_yarrow256_slow_reseed +#define yarrow_key_event_init nettle_yarrow_key_event_init +#define yarrow_key_event_estimate nettle_yarrow_key_event_estimate + +/* Obsolete alias for backwards compatibility. Will be deleted in some + later version. */ +#define yarrow256_force_reseed yarrow256_slow_reseed + +enum yarrow_pool_id { YARROW_FAST = 0, YARROW_SLOW = 1 }; + +struct yarrow_source +{ + /* Indexed by yarrow_pool_id */ + uint32_t estimate[2]; + + /* The pool next sample should go to. */ + enum yarrow_pool_id next; +}; + + +#define YARROW256_SEED_FILE_SIZE (2 * AES_BLOCK_SIZE) + +/* Yarrow-256, based on SHA-256 and AES-256 */ +struct yarrow256_ctx +{ + /* Indexed by yarrow_pool_id */ + struct sha256_ctx pools[2]; + + int seeded; + + /* The current key and counter block */ + struct aes_ctx key; + uint8_t counter[AES_BLOCK_SIZE]; + + /* The entropy sources */ + unsigned nsources; + struct yarrow_source *sources; +}; + +void +yarrow256_init(struct yarrow256_ctx *ctx, + unsigned nsources, + struct yarrow_source *sources); + +void +yarrow256_seed(struct yarrow256_ctx *ctx, + unsigned length, + const uint8_t *seed_file); + +/* Returns 1 on reseed */ +int +yarrow256_update(struct yarrow256_ctx *ctx, + unsigned source, unsigned entropy, + unsigned length, const uint8_t *data); + +void +yarrow256_random(struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst); + +int +yarrow256_is_seeded(struct yarrow256_ctx *ctx); + +unsigned +yarrow256_needed_sources(struct yarrow256_ctx *ctx); + +void +yarrow256_fast_reseed(struct yarrow256_ctx *ctx); + +void +yarrow256_slow_reseed(struct yarrow256_ctx *ctx); + + +/* Key event estimator */ +#define YARROW_KEY_EVENT_BUFFER 16 + +struct yarrow_key_event_ctx +{ + /* Counter for initial priming of the state */ + unsigned index; + unsigned chars[YARROW_KEY_EVENT_BUFFER]; + unsigned previous; +}; + +void +yarrow_key_event_init(struct yarrow_key_event_ctx *ctx); + +unsigned +yarrow_key_event_estimate(struct yarrow_key_event_ctx *ctx, + unsigned key, unsigned time); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_YARROW_H_INCLUDED */ diff --git a/yarrow256.c b/yarrow256.c new file mode 100644 index 0000000..7645a72 --- /dev/null +++ b/yarrow256.c @@ -0,0 +1,366 @@ +/* yarrow256.c + * + * The yarrow pseudo-randomness generator. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "yarrow.h" + +#include "macros.h" + +#ifndef YARROW_DEBUG +#define YARROW_DEBUG 0 +#endif + +#if YARROW_DEBUG +#include +#endif + +/* Parameters */ + +/* An upper limit on the entropy (in bits) in one octet of sample + * data. */ +#define YARROW_MULTIPLIER 4 + +/* Entropy threshold for reseeding from the fast pool */ +#define YARROW_FAST_THRESHOLD 100 + +/* Entropy threshold for reseeding from the fast pool */ +#define YARROW_SLOW_THRESHOLD 160 + +/* Number of sources that must exceed the threshold for slow reseed */ +#define YARROW_SLOW_K 2 + +/* The number of iterations when reseeding, P_t in the yarrow paper. + * Should be chosen so that reseeding takes on the order of 0.1-1 + * seconds. */ +#define YARROW_RESEED_ITERATIONS 1500 + +/* Entropy estimates sticks to this value, it is treated as infinity + * in calculations. It should fit comfortably in an uint32_t, to avoid + * overflows. */ +#define YARROW_MAX_ENTROPY 0x100000 + +/* Forward declarations */ +static void +yarrow_gate(struct yarrow256_ctx *ctx); + +void +yarrow256_init(struct yarrow256_ctx *ctx, + unsigned n, + struct yarrow_source *s) +{ + unsigned i; + + sha256_init(&ctx->pools[0]); + sha256_init(&ctx->pools[1]); + + ctx->seeded = 0; + + /* Not strictly necessary, but it makes it easier to see if the + * values are sane. */ + memset(ctx->counter, 0, sizeof(ctx->counter)); + + ctx->nsources = n; + ctx->sources = s; + + for (i = 0; isources[i].estimate[YARROW_FAST] = 0; + ctx->sources[i].estimate[YARROW_SLOW] = 0; + ctx->sources[i].next = YARROW_FAST; + } +} + +void +yarrow256_seed(struct yarrow256_ctx *ctx, + unsigned length, + const uint8_t *seed_file) +{ + assert(length > 0); + + sha256_update(&ctx->pools[YARROW_FAST], length, seed_file); + yarrow256_fast_reseed(ctx); +} + +/* FIXME: Generalize so that it generates a few more blocks at a + * time. */ +static void +yarrow_generate_block(struct yarrow256_ctx *ctx, + uint8_t *block) +{ + unsigned i; + + aes_encrypt(&ctx->key, sizeof(ctx->counter), block, ctx->counter); + + /* Increment counter, treating it as a big-endian number. This is + * machine independent, and follows appendix B of the NIST + * specification of cipher modes of operation. + * + * We could keep a representation of the counter as 4 32-bit values, + * and write entire words (in big-endian byteorder) into the counter + * block, whenever they change. */ + for (i = sizeof(ctx->counter); i--; ) + { + if (++ctx->counter[i]) + break; + } +} + +static void +yarrow_iterate(uint8_t *digest) +{ + uint8_t v0[SHA256_DIGEST_SIZE]; + unsigned i; + + memcpy(v0, digest, SHA256_DIGEST_SIZE); + + /* When hashed inside the loop, i should run from 1 to + * YARROW_RESEED_ITERATIONS */ + for (i = 0; ++i < YARROW_RESEED_ITERATIONS; ) + { + uint8_t count[4]; + struct sha256_ctx hash; + + sha256_init(&hash); + + /* Hash v_i | v_0 | i */ + WRITE_UINT32(count, i); + sha256_update(&hash, SHA256_DIGEST_SIZE, digest); + sha256_update(&hash, sizeof(v0), v0); + sha256_update(&hash, sizeof(count), count); + + sha256_digest(&hash, SHA256_DIGEST_SIZE, digest); + } +} + +/* NOTE: The SHA-256 digest size equals the AES key size, so we need + * no "size adaptor". */ + +void +yarrow256_fast_reseed(struct yarrow256_ctx *ctx) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + unsigned i; + +#if YARROW_DEBUG + fprintf(stderr, "yarrow256_fast_reseed\n"); +#endif + + /* We feed two block of output using the current key into the pool + * before emptying it. */ + if (ctx->seeded) + { + uint8_t blocks[AES_BLOCK_SIZE * 2]; + + yarrow_generate_block(ctx, blocks); + yarrow_generate_block(ctx, blocks + AES_BLOCK_SIZE); + sha256_update(&ctx->pools[YARROW_FAST], sizeof(blocks), blocks); + } + + sha256_digest(&ctx->pools[YARROW_FAST], sizeof(digest), digest); + + /* Iterate */ + yarrow_iterate(digest); + + aes_set_encrypt_key(&ctx->key, sizeof(digest), digest); + ctx->seeded = 1; + + /* Derive new counter value */ + memset(ctx->counter, 0, sizeof(ctx->counter)); + aes_encrypt(&ctx->key, sizeof(ctx->counter), ctx->counter, ctx->counter); + + /* Reset estimates. */ + for (i = 0; insources; i++) + ctx->sources[i].estimate[YARROW_FAST] = 0; +} + +void +yarrow256_slow_reseed(struct yarrow256_ctx *ctx) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + unsigned i; + +#if YARROW_DEBUG + fprintf(stderr, "yarrow256_slow_reseed\n"); +#endif + + /* Get digest of the slow pool*/ + sha256_digest(&ctx->pools[YARROW_SLOW], sizeof(digest), digest); + + /* Feed it into the fast pool */ + sha256_update(&ctx->pools[YARROW_FAST], sizeof(digest), digest); + + yarrow256_fast_reseed(ctx); + + /* Reset estimates. */ + for (i = 0; insources; i++) + ctx->sources[i].estimate[YARROW_SLOW] = 0; +} + +int +yarrow256_update(struct yarrow256_ctx *ctx, + unsigned source_index, unsigned entropy, + unsigned length, const uint8_t *data) +{ + enum yarrow_pool_id current; + struct yarrow_source *source; + + assert(source_index < ctx->nsources); + + if (!length) + /* Nothing happens */ + return 0; + + source = &ctx->sources[source_index]; + + if (!ctx->seeded) + /* While seeding, use the slow pool */ + current = YARROW_SLOW; + else + { + current = source->next; + source->next = !source->next; + } + + sha256_update(&ctx->pools[current], length, data); + + /* NOTE: We should be careful to avoid overflows in the estimates. */ + if (source->estimate[current] < YARROW_MAX_ENTROPY) + { + if (entropy > YARROW_MAX_ENTROPY) + entropy = YARROW_MAX_ENTROPY; + + if ( (length < (YARROW_MAX_ENTROPY / YARROW_MULTIPLIER)) + && (entropy > YARROW_MULTIPLIER * length) ) + entropy = YARROW_MULTIPLIER * length; + + entropy += source->estimate[current]; + if (entropy > YARROW_MAX_ENTROPY) + entropy = YARROW_MAX_ENTROPY; + + source->estimate[current] = entropy; + } + + /* Check for seed/reseed */ + switch(current) + { + case YARROW_FAST: +#if YARROW_DEBUG + fprintf(stderr, + "yarrow256_update: source_index = %d,\n" + " fast pool estimate = %d\n", + source_index, source->estimate[YARROW_FAST]); +#endif + if (source->estimate[YARROW_FAST] >= YARROW_FAST_THRESHOLD) + { + yarrow256_fast_reseed(ctx); + return 1; + } + else + return 0; + + case YARROW_SLOW: + { + if (!yarrow256_needed_sources(ctx)) + { + yarrow256_slow_reseed(ctx); + return 1; + } + else + return 0; + } + default: + abort(); + } +} + +static void +yarrow_gate(struct yarrow256_ctx *ctx) +{ + uint8_t key[AES_MAX_KEY_SIZE]; + unsigned i; + + for (i = 0; i < sizeof(key); i+= AES_BLOCK_SIZE) + yarrow_generate_block(ctx, key + i); + + aes_set_encrypt_key(&ctx->key, sizeof(key), key); +} + +void +yarrow256_random(struct yarrow256_ctx *ctx, unsigned length, uint8_t *dst) +{ + assert(ctx->seeded); + + while (length >= AES_BLOCK_SIZE) + { + yarrow_generate_block(ctx, dst); + dst += AES_BLOCK_SIZE; + length -= AES_BLOCK_SIZE; + } + if (length) + { + uint8_t buffer[AES_BLOCK_SIZE]; + + assert(length < AES_BLOCK_SIZE); + yarrow_generate_block(ctx, buffer); + memcpy(dst, buffer, length); + } + yarrow_gate(ctx); +} + +int +yarrow256_is_seeded(struct yarrow256_ctx *ctx) +{ + return ctx->seeded; +} + +unsigned +yarrow256_needed_sources(struct yarrow256_ctx *ctx) +{ + /* FIXME: This is somewhat inefficient. It would be better to + * either maintain the count, or do this loop only if the + * current source just crossed the threshold. */ + unsigned k, i; + + for (i = k = 0; i < ctx->nsources; i++) + if (ctx->sources[i].estimate[YARROW_SLOW] >= YARROW_SLOW_THRESHOLD) + k++; + +#if YARROW_DEBUG + fprintf(stderr, + "yarrow256_needed_sources: source_index = %d,\n" + " slow pool estimate = %d,\n" + " number of sources above threshold = %d\n", + source_index, source->estimate[YARROW_SLOW], k); +#endif + + return (k < YARROW_SLOW_K) ? (YARROW_SLOW_K - k) : 0; +} diff --git a/yarrow_key_event.c b/yarrow_key_event.c new file mode 100644 index 0000000..92360d9 --- /dev/null +++ b/yarrow_key_event.c @@ -0,0 +1,78 @@ +/* yarrow_key_event.c + * + * Exampel entropy estimator for key-like input events. */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001 Niels Möller + * + * The nettle 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 nettle 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 nettle 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "yarrow.h" + +void +yarrow_key_event_init(struct yarrow_key_event_ctx *ctx) +{ + unsigned i; + + ctx->index = 0; + ctx->previous = 0; + + for (i = 0; i < YARROW_KEY_EVENT_BUFFER; i++) + ctx->chars[i] = 0; +} + +unsigned +yarrow_key_event_estimate(struct yarrow_key_event_ctx *ctx, + unsigned key, unsigned time) +{ + unsigned entropy = 0; + unsigned i; + + /* Look at timing first. */ + if (ctx->previous && (time > ctx->previous) ) + { + if ( (time - ctx->previous) >= 256) + entropy++; + } + ctx->previous = time; + + if (!key) + return entropy; + + for (i = 0; i < YARROW_KEY_EVENT_BUFFER; i++) + if (key == ctx->chars[i]) + /* This is a recent character. Ignore it. */ + return entropy; + + /* Count one bit of entropy, unless this was one of the initial 16 + * characters. */ + if (ctx->chars[ctx->index]) + entropy++; + + /* Remember the character. */ + + ctx->chars[ctx->index] = key; + ctx->index = (ctx->index + 1) % YARROW_KEY_EVENT_BUFFER; + + return entropy; +} +