From 4090b66663dcb11ba1bd4d04d45bfcd762513d70 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 23:30:13 +0000 Subject: nettle-3.4.1 base --- 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/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..92200ab --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,21 @@ +# nettle -- Information about our contribution rules + +# Test suite: + + New functionality should be accompanied by a test case which verifies +its correctness, on successful use of the new functionality, as well as on +failure cases. The nettle test suite is run on "make check". + +# Continuous Integration (CI) + +We utilize a continuous integration systems, using gitlab-ci. + +This is run on a repository mirror at: +https://gitlab.com/gnutls/nettle + +# Sending patches + +Please do not utilize the gitlab web interfaces. They are not +being followed on. Please send your patches to nettle-bugs@lists.lysator.liu.se + + diff --git a/COPYING.LESSERv3 b/COPYING.LESSERv3 new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/COPYING.LESSERv3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU 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 as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/COPYINGv2 b/COPYINGv2 new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/COPYINGv2 @@ -0,0 +1,339 @@ + 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 Lesser 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 Lesser General +Public License instead of this License. diff --git a/COPYINGv3 b/COPYINGv3 new file mode 100644 index 0000000..2a00065 --- /dev/null +++ b/COPYINGv3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4c7338a --- /dev/null +++ b/ChangeLog @@ -0,0 +1,11081 @@ +2018-12-04 Niels Möller + + * Released nettle-3.4.1. + +2018-11-28 Niels Möller + + * configure.ac: Update GMP check. Check for the function + mpn_sec_div_r, available since GMP-6.0.0. + + * testsuite/rsa-encrypt-test.c (test_main): Fix allocation of + decrypted storage. Update test of rsa_decrypt, to allow clobbering + of all of the passed in message area. + + * pkcs1-decrypt.c (pkcs1_decrypt): Rewrite as a wrapper around + _pkcs1_sec_decrypt_variable. Improves side-channel silence of the + only caller, rsa_decrypt. + + * Makefile.in (DISTFILES): Add rsa-internal.h, needed for make + dist. Patch from Simo Sorce. + + * rsa-internal.h: Add include of rsa.h. + +2018-11-27 Niels Möller + + * rsa-sec-compute-root.c (sec_mul, sec_mod_mul, sec_powm): New + local helper functions, with their own itch functions. + (_rsa_sec_compute_root_itch, _rsa_sec_compute_root): Rewrote to + use helpers, for clarity. + +2018-11-26 Niels Möller + + * testsuite/rsa-compute-root-test.c (generate_keypair): Simplify + selection of psize and qsize, and fix so that qsize is used. + (test_main): Add outer loop, to test with more than one key. + Deallocate storage before exiting. + +2018-11-25 Niels Möller + + * testsuite/rsa-compute-root-test.c: Renamed, from ... + * testsuite/rsa-sec-compute-root-test.c: ... old name. + + * rsa.h (rsa_sec_compute_root_tr): Deleted declaration, moved to ... + * rsa-internal.h (_rsa_sec_compute_root_tr): ... new location. + * rsa-sign-tr.c (_rsa_sec_compute_root_tr): Renamed, from... + (rsa_sec_compute_root_tr): ... old name. Updated callers. + (cnd_mpn_zero): Use a volatile-declared mask variable. + + * testsuite/testutils.c (mpz_urandomb) [NETTLE_USE_MINI_GMP]: Fix + masking of most significant bits. + + * rsa-decrypt-tr.c (rsa_decrypt_tr): Use + NETTLE_OCTET_SIZE_TO_LIMB_SIZE. + + * testsuite/rsa-sec-decrypt-test.c (rsa_decrypt_for_test): Tweak + valgrind marking, and document potential leakage of lowest and + highest bits of p and q. + + * rsa-sec-compute-root.c (_rsa_sec_compute_root): Avoid calls to + mpz_sizeinbase, since that potentially leaks most significant bits + of private key parameters a and b. + + * testsuite/pkcs1-sec-decrypt-test.c (pkcs1_decrypt_for_test): Fix + valgrind marking of return value. + + Merged below changes from Simo Sorce, to make RSA private key + operations side-channel silent. + +2018-11-08 Simo Sorce + + * rsa-sign.c (rsa_compute_root) [!NETTLE_USE_MINI_GMP]: Use + _rsa_sec_compute_root. + + * testsuite/rsa-sec-compute-root-test.c: Add more tests for new + side-channel silent functions. + + * rsa-sign.c (rsa_private_key_prepare): Check that qn + cn >= pn, + since that is required for one of the GMP calls in + _rsa_sec_compute_root. + + * rsa-decrypt-tr.c: Switch to use side-channel silent functions. + + * pkcs1-sec-decrypt.c (_pkcs1_sec_decrypt_variable): New private + function. Variable size version for backwards compatibility. + + * testsuite/rsa-sec-decrypt-test.c: Adds more tests. + + * rsa-sec-decrypt.c (rsa_sec_decrypt): New function. + Fixed length side-channel silent version of rsa-decrypt. + * testsuite/rsa-encrypt-test.c: add tests for the new fucntion. + + * testsuite/pkcs1-sec-decrypt-test.c: Adds tests for + _pkcs1_sec_decrypt. + + * gmp-glue.c (mpn_get_base256): New function. + + * pkcs1-sec-decrypt.c (_pkcs1_sec_decrypt): New private function. + Fixed length side-channel silent version of pkcs1-decrypt. + + * cnd-memcpy.c (cnd_memcpy): New function. + * memops.h: Declare it. + * testsuite/cnd-memcpy-test.c: New test case. + + * rsa-sign-tr.c (rsa_sec_compute_root_tr): New function that uses + _rsa_sec_compute_root, as well as side-channel silent RSA + blinding. + (rsa_compute_root_tr) Rewritten as a wrapper around + rsa_sec_compute_root_tr. + (rsa_sec_blind, rsa_sec_unblind, sec_equal, rsa_sec_check_root) + (cnd_mpn_zero): New helper functions. + (rsa_sec_compute_root_tr) [NETTLE_USE_MINI_GMP]: Defined as a not + side-channel silent wrapper around rsa_compute_root_tr, and the + latter function left unchanged. + + * rsa-sec-compute-root.c (_rsa_sec_compute_root_itch) + (_rsa_sec_compute_root): New file, new private functions. + Side-channel silent version of rsa_compute_root. + * rsa-internal.h: New header file with declarations. + + * gmp-glue.h (NETTLE_OCTET_SIZE_TO_LIMB_SIZE): New macro. + +2018-11-24 Niels Möller + + * configure.ac: Bump package version to 3.4.1. + (LIBNETTLE_MINOR): Bump library version to 6.5. + (LIBHOGWEED_MINOR): Bump library version to 4.5. + +2018-06-17 Niels Möller + + Backported from master branch. + * aclocal.m4 (NETTLE_CHECK_IFUNC): Fix quoting. Patch contributed + by Dmitry Eremin-Solenikov. + * testsuite/symbols-test: Exclude ____chkstk_darwin symbols, + produced by Apple's Xcode 10 compiler. Patch contributed by + Dominyk Tiller. + +2018-02-18 Niels Möller + + Backported from master branch. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Moved pss-mgf1-test.c... + (TS_HOGWEED_SOURCES): ...to here. Fixes link failure in builds + without public-key support. + +2018-01-16 Niels Möller + + Backported from master branch. + * tools/pkcs1-conv.c (convert_file): Add missing break statements. + +2018-10-10 Niels Möller + + Backported from master branch. + * aes-set-encrypt-key.c: Add missing include of stdlib.h. + * des-compat.c: Likewise. + +2018-08-09 Niels Möller + + Backported from master branch. + * nettle-internal.c (des_set_key_wrapper, des3_set_key_wrapper) + (blowfish128_set_key_wrapper): Wrapper functions, to avoid cast + between incompatible function types (which gcc-8 warns about). + Wrappers are expected to compile to a single jmp instruction. + + * des-compat.c (des_compat_des3_encrypt) + (des_compat_des3_decrypt): Change length argument type to size_t. + +2017-11-19 Niels Möller + + * Released nettle-3.4. + +2017-11-12 Niels Möller + + * configure.ac: Update check of GMP_NUMB_BITS declaration in + assembly files. Was broken by rename of configure variable + GMP_NUMB_BITS --> NUMB_BITS. + +2017-11-11 Niels Möller + + * nettle.texinfo: Document nettle_get_hashes, nettle_get_ciphers + and nettle_get_aeads, and replace nettle_secp_256r1 by + nettle_get_secp_256r1. Update version numbers. Delete ancient + setting of ispell-skip-region-alist as an emacs file-local + variable. + +2017-11-08 Niels Möller + + * ecc-curve.h (nettle_secp_192r1, nettle_secp_224r1) + (nettle_secp_256r1, nettle_secp_384r1, nettle_secp_521r1): Delete + macro wrappers, partially reverting below 2017-04-09 change. They + didn't work at all for applications that only see a forward + declaration of struct ecc_curve. Instead, we will have to make an + ABI and API break and delete these symbols, when the size of + struct ecc_curve is increased. + +2017-11-05 Niels Möller + + * configure.ac Bump package version to 3.4. + (LIBNETTLE_MINOR): Bump library version to 6.4. + (LIBHOGWEED_MINOR): Bump library version to 4.4. + +2017-10-23 Niels Möller + + * examples/Makefile.in (check): Also set DYLD_LIBRARY_PATH in the + environment, to support Mac OSX shared libraries. + * testsuite/Makefile.in (LD_LIBRARY_PATH): Likewise. + +2017-10-23 Niels Möller + + Merge API fixes, starting at 2017-01-12. + +2017-04-09 Niels Möller + + * ecc-curve.h (nettle_get_secp_192r1, nettle_get_secp_224r1) + (nettle_get_secp_256r1, nettle_get_secp_384r1) + (nettle_get_secp_521r1): New functions, returning a pointer to + corresponding structure. + (nettle_secp_192r1, nettle_secp_224r1, nettle_secp_256r1) + (nettle_secp_384r1, nettle_secp_521r1): Redefined as macros, + calling the corresponding function. + + * nettle-meta.h (nettle_ciphers, nettle_aeads, nettle_armors): New + macros, analogous to below change to nettle_hashes. + + * nettle-meta-ciphers.c (nettle_get_ciphers): New function. + + * nettle-meta-aeads.c (nettle_get_aeads): New function. + + * nettle-meta-armors.c (nettle_get_armors): New function. + +2017-01-12 Niels Möller + + * tools/nettle-hash.c (find_algorithm): Deleted function. + (main): Replaced by call to nettle_lookup_hash. + + * testsuite/meta-hash-test.c (test_main): Use nettle_lookup_hash. + + * nettle-meta.h (nettle_hashes): New macro, expanding to a call to + nettle_get_hashes. Direct access to the array causes the array + size to leak into the ABI, since a plain un-relocatable executable + linking with libnettle.so gets copy relocations for any referenced + data items in the shared library. + + * nettle-meta-hashes.c (nettle_get_hashes): New function. + +2017-10-16 Niels Möller + + CFB support, contributed by Dmitry Eremin-Solenikov. + * cfb.c (cfb_encrypt, cfb_decrypt): New file, new functions. + * cfb.h: New header file. + (CFB_CTX, CFB_SET_IV, CFB_ENCRYPT, CFB_DECRYPT): New macros. + * Makefile.in (nettle_SOURCES): Add cfb.c. + (HEADERS): Add cfb.h. + * testsuite/cfb-test.c: New test case. + * testsuite/testutils.c (test_cipher_cfb): New function. + * nettle.texinfo (CFB): Documentation. + +2017-10-16 Niels Möller + + * aclocal.m4 (GMP_PROG_CC_FOR_BUILD): Add -g when compiling with + gcc. + +2017-09-27 Niels Möller + + Merged armor-signedness branch, starting 2017-08-27. + +2017-09-24 Niels Möller + + * tools/pkcs1-conv.c (base64_decode_in_place): New helper + function. + (decode_base64): Use it. + + * sexp-transport-format.c (base64_encode_in_place): New helper + function. + (sexp_transport_vformat): Use it. + + * testsuite/base64-test.c (test_fuzz_once): Update to use char + type where appropriate. + (test_main): Use helper functions base64_encode_in_place and + base64_decode_in_place (copied to this file). + + * testsuite/testutils.c (tstring_data): Use uint8_t for data + argument. + * testsuite/testutils.h (SDATA): Use US macro to cast data + argument. + +2017-08-27 Niels Möller + + * base64-encode.c (base64_encode_raw, base64_encode_group) + (base64_encode_single, base64_encode_update) + (base64_encode_final): Change type of destination to char *. + * base16-encode.c (base16_encode_single, base16_encode_update): + Likewise. + * base64-decode.c (base64_decode_single, base64_decode_update): + Change type of source argument to const char *. Update (almost) + all callers. + * base16-decode.c (base16_decode_single, base16_decode_update): + Likewise. + * nettle-types.h (nettle_armor_encode_update_func) + (nettle_armor_encode_final_func, nettle_armor_decode_update_func): + Corresponding updates to typedefs. + +2017-09-14 Niels Möller + + * hkdf.c: Delete unneeded includes. Use Nettle licensing notice. + * hkdf.h: Include only nettle-types.h, not nettle-meta.h. + + * ecc-mod.c (ecc_mod): Workaround to silence a false positive from + the clang static analyzer. + +2017-09-12 Niels Möller + + * testsuite/testutils.h (mpn_zero_p): Avoid redefining mpn_zero_p + when building with mini-gmp. Since the mini-gmp update, this + function is defined by mini-gmp, causing link errors if nettle is + configured with --enable-mini-gmp --disable-shared. Reported by + Tim Rühsen. + +2017-09-09 Daiki Ueno + + * testsuite/ecc-mul-g-test.c (test_main): Fixed mpn_cmp call. + * testsuite/ecc-mul-a-test.c (test_main): Likewise. + * eccdata.c (ecc_point_out): Write to given stream, instead of + stderr. + * eccdata.c (output_curve): In curve448, the bit size of the order + is slightly smaller than the one of p's. Adjust ecc_Bmodq_shifted + accordingly. + +2017-09-09 Niels Möller + + * mini-gmp.c: Updated mini-gmp from the gmp repository, latest + change from 2017-07-23. + * mini-gmp.h: Likewise. + +2017-09-06 Niels Möller + + * hkdf.c (hkdf_expand): Eliminate a (signed) ssize_t variable, use + break rather than return at loop termination. + +2017-09-06 Niels Möller + + HKDF implementation, contributed by Nikos Mavrogiannopoulos. + * hkdf.c (hkdf_extract, hkdf_expand): New file, new functions. + * hkdf.h: New file. + * Makefile.in (nettle_SOURCES): Add hkdf.c. + (HEADERS): Add hkdf.h. + * testsuite/hkdf-test.c: Tests for hkdf-sha256 and hkdf-sha1. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added hkdf-test.c. + * nettle.texinfo (Key derivation functions): Document HKDF. + +2017-09-04 Andreas Schneider + + * fat-arm.c: Add missing define for _GNU_SOURCE. + +2017-08-27 Niels Möller + + * configure.ac (GMP_NUMB_BITS): Set to dummy value "n/a" in + mini-gmp builds. + (NUMB_BITS): New substituted variable which always holds the + configured value. + * Makefile.in (GMP_NUMB_BITS): Renamed variable... + (NUMB_BITS): ...new name + * config.make.in: Update corresponding substitution. + +2017-08-26 Niels Möller + + * ecc-mod-inv.c (ecc_mod_inv): Add missing assert. Fixes a + "dead increment" warning from the clang static analyzer. + +2017-08-26 Niels Möller + + * examples/nettle-openssl.c (struct openssl_cipher_ctx): New + struct. Use everywhere, instead of typing EVP_CIPHER_CTX pointers + directly. + + * configure.ac: Update openssl-related tests. Checks for + cipher-specific headers are replaced by a check for openssl/evp.h, + and the check for the BF_ecb_encrypt function is replaced by a + check for EVP_CIPHER_CTX_new. + +2017-08-03 Daniel P. Berrange + + * examples/nettle-openssl.c: Rewritten to use openssl's EVP APIs. + The older cipher-specific functions always use openssl's generic + software implementation, while the EVP functions enables + platform-specific code, e.g., using the x86 AES-NI instructions. + (nettle_openssl_init): New function. + +2017-07-18 Niels Möller + + * ecc-add-eh.c (ecc_add_eh): Fix in-place operation by reordering + two multiplies. Previously, in-place operation resulted in an + invalid call to mpn_mul with overlapping operands. Reported by + Sergei Trofimovich. + +2017-06-09 Niels Möller + + * pss.c (pss_verify_mgf1): Check for m being too large, fixing an + assertion failure for certain invalid signatures. Based on a patch + contributed by Daiki Ueno. + + * testsuite/rsa-pss-sign-tr-test.c (test_main): Add test case + contributed by Daiki Ueno. Problem originally found by oss-fuzz, + see https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2132. + That problem report is currently embargoed, but will hopefully be + public in a month or two. + +2017-05-23 Niels Möller + + Rework the previous change, which had the unintended effect of + always regenerating .test-rules.make after ./configure is run. + * testsuite/Makefile.in (test-rules.stamp): New stamp file target, + depend on Makefile.in, and run $(MAKE) test-rules. + (.test-rules.make): Add a level of indirection, by depending on + test-rules.stamp. + +2017-05-20 Niels Möller + + * testsuite/Makefile.in (test-rules): Use $(srddir)/-prefix for + .test-rules.make target, and change dependency from Makefile.in to + Makefile. + +2017-05-17 Nikos Mavrogiannopoulos + + * testsuite/Makefile.in: Ensure .test-rules.make is regenerated + when Makefile.in is modified. + +2017-04-09 Niels Möller + + * testsuite/dlopen-test.c (main): Call dlclose, to fix memory leak + on success. + + * testsuite/pss-test.c: Delete magic to let valgrind to check if + pss_encode_mgf1 is side-channel silent with respect to the salt + and digest inputs. It turns out that the most significant bits of + the padded bignum, and hence its size, depends on these inputs. + Which results in a data-dependent branch in the normalization code + of at the end of gmp's mpz_import. + +2017-04-04 Niels Möller + + * pss.c (pss_verify_mgf1): Use const for input mpz_t argument. + (pss_encode_mgf1): Avoid unnecessary memset and xor operations. + + Merged RSA-PSS support, contributed by Daiki Ueno. + * pss-mgf1.h, pss.h: New header files. + * pss-mgf1.c (pss_mgf1): New file and function. + * pss.c (pss_encode_mgf1, pss_verify_mgf1): New file and + functions. + * rsa-verify.c (_rsa_verify_recover): New function. + * rsa-pss-sha256-sign-tr.c: (rsa_pss_sha256_sign_digest_tr): New + file and function. + * rsa-pss-sha256-verify.c (rsa_pss_sha256_verify_digest): New + file and function. + * rsa-pss-sha512-sign-tr.c (rsa_pss_sha384_sign_digest_tr) + (rsa_pss_sha512_sign_digest_tr): New file and functions. + * rsa-pss-sha512-verify.c (rsa_pss_sha384_verify_digest) + (rsa_pss_sha512_verify_digest): New file and functions. + * rsa.h: Prototypes for new functions. + * testsuite/rsa-pss-sign-tr-test.c: New test case. + * testsuite/pss-test.c: New test case. + * testsuite/pss-mgf1-test.c: New test case. + * Makefile.in, testsuite/Makefile.in: Added new files. + * nettle.texinfo: Documentation of rsa-pss functions. + +2017-03-20 Niels Möller + + * nettle-internal.h (NETTLE_MAX_HASH_CONTEXT_SIZE): New constant. + * testsuite/meta-hash-test.c (test_main): Add sanity check for + NETTLE_MAX_HASH_CONTEXT_SIZE. + + * tools/nettle-hash.c (list_algorithms): Also display the internal + context size. + +2017-01-03 Nikos Mavrogiannopoulos + + * ecdsa-verify.c (ecdsa_verify): Eliminated memory leak on error + path. + +2016-10-10 Niels Möller + + * write-be32.c (_nettle_write_be32): Use const for source argument. + * write-le32.c (_nettle_write_le32): Likewise. + * write-le64.c (_nettle_write_le64): Likewise. + * nettle-write.h: Update prototypes. + +2016-10-01 Niels Möller + + * Released nettle-3.3. + +2016-09-13 Niels Möller + + * nettle-meta-hashes.c (nettle_hashes): Added SHA3 hashes. + Reported missing by Thomas Walter. + * testsuite/meta-hash-test.c: Update test accordingly. + +2016-09-07 Niels Möller + + * nettle.texinfo (Elliptic curves): Split into sub-nodes. + (Miscellaneous functions): Document memeql_sec. + * NEWS: Mention memeql_sec. + +2016-09-06 Niels Möller + + * NEWS: Update for 3.3. + + * configure.ac: Bump package version to 3.3. + (LIBNETTLE_MINOR): Bump library version to 6.3. + (LIBHOGWEED_MINOR): Bump library version to 4.3. + +2016-09-05 Niels Möller + + * curve25519.h (NETTLE_CURVE25519_RFC7748): New preprocessor + constant. + * nettle.texinfo: Document it. + +2016-09-03 Niels Möller + + * config.make.in (.SUFFIXES): Delete no longer used .p$(OBJEXT). + + * sexp.h (TOKEN_CHAR): Delete macro and declaration of + sexp_token_chars. They belong in tools/misc.h, not here. + + * examples/ecc-benchmark.c (die): Deleted unused function. + + * testsuite/testutils.h (US): New macro, for unsigned string + literals. + (LDATA): Use the US macro, to eliminate pointer signedness + warnings. + + * testsuite/eddsa-verify-test.c (test_eddsa): Use LDATA. + * testsuite/pbkdf2-test.c (test_main): Likewise. + * testsuite/pkcs1-test.c (test_main): Likewise. + + * testsuite/md5-compat-test.c (test_main): Use US macro. + + * testsuite/sexp-test.c (test_main): Use const char * for assoc + keys. Overlooked in 2016-08-16 change. + + * testsuite/yarrow-test.c (test_main): Fix pointer + signednesss warnings. + * testsuite/sexp-format-test.c (test_main): Likewise. + * testsuite/rsa-encrypt-test.c (test_main): Likewise. + * tools/nettle-lfib-stream.c (main): Likewise. + * tools/output.c (sexp_put_string): Likewise. + + * testsuite/testutils.c (test_armor): Change ascii argument to + const char *. + * testsuite/base16-test.c (test_main): Use LDATA for the non-ascii + argument to test_armor. + * testsuite/base64-test.c (test_main): Likewise. + + * tools/nettle-pbkdf2.c (main): Fix some pointer signedness warning. + * tools/nettle-hash.c (hash_file): Likewise. + + * examples/rsa-decrypt.c (process_file): Use memeql_sec to check + the digest. + + * memeql-sec.c (memeql_sec): New public function, moved from... + * ccm.c (memeql_sec): ... previous location. + + * memops.h: New header file, generalizing memxor.h. + + * testsuite/memeql-test.c (test_main): New test case. + (memeql_sec_for_test): Wrapper to get valgrind to check for + side-channel silence. + +2016-08-29 Niels Möller + + * sexp-format.c (strlen_u8): New helper function. + (sexp_vformat): Use uint8_t * for strings instead of char *. + +2016-08-16 Niels Möller + + * examples/io.c (hash_file): Use uint8_t for buffer. + + * sexp.c (sexp_iterator_check_type, sexp_iterator_check_types) + (sexp_iterator_assoc): Use const char * for caller's expression + types. Updated all callers. + + * rsa2openpgp.c (rsa_keypair_to_openpgp): Added cast to const + uint8_t *. + + * pgp-encode.c (write_string): New helper function, replacing... + (WRITE): ... deleted macro. + + * examples/io.c (write_data): Renamed, and use const void * for + the input data. Updated all callers. + (write_string): ... old name. + (write_file): Use const void * for the input data. + +2016-08-05 Niels Möller + + * examples/hogweed-benchmark.c: Use uint8_t for curve25519 values. + (bench_rsa_init): Use unsigned char for sexp strings. + (bench_dsa_init): Likewise. + (hash_string): Delete length argument, calling strlen instead. + Cast string to const uint8_t *. Updated callers. + + * examples/io.c (read_file): Use size_t for sizes, and uint8_t for + the contents. + +2016-08-04 Niels Möller + + * dsa-sign.c (dsa_sign): Return failure if p is even, so that an + invalid key doesn't result in a crash inside mpz_powm_sec. + + * rsa-sign-tr.c (rsa_compute_root_tr): Return failure if any of p, + q or n is even, to avoid crashing inside mpz_powm_sec. Invalid + keys with even modulo are rejected by rsa_public_key_prepare and + rsa_private_key_prepare, but some applications, notably gnutls, + don't use them. + +2016-07-31 Niels Möller + + * rsa.c (_rsa_check_size): Check that n is odd. Otherwise, using + an invalid key may crash in mpz_powm_sec. Problem reported by + Hanno Böck. + +2016-07-13 Niels Möller + + * bignum.c (nettle_mpz_from_octets): Unconditionally use + mpz_import. + * gmp-glue.c (mpn_copyd, mpn_copyi, mpn_zero): Deleted + compatibility definitions for older versions of GMP. + * gmp-glue.h (mpn_sqr): Deleted compatibility definition. + * testsuite/testutils.c (mpz_combit): Deleted compatibility + definition. + +2016-07-12 Niels Möller + + * configure.ac: Check for mpz_powm_sec, and require GMP-5.0 or + later. + * bignum.h (mpz_powm_sec): Fall back to plain mpz_powm for + mini-gmp build. + * dsa-sign.c (dsa_sign): Use mpz_powm_sec. + * rsa-sign.c (rsa_compute_root): Likewise. + * rsa-sign-tr.c (rsa_blind, rsa_compute_root_tr): Likewise. + * rsa-blind.c (_rsa_blind): Likewise. + +2016-05-02 Niels Möller + + * nettle.texinfo: Update Curve25519 documentation. + + * testsuite/curve25519-dh-test.c: Test that inputs bits which must + be ignored really are ignored. + +2016-04-25 Niels Möller + + * curve25519-mul.c (curve25519_mul): Ignore top bit of the input x + coordinate, as required by RFC 7748. + +2016-03-30 Niels Möller + + From Nikos Mavrogiannopoulos. + * configure.ac: Change dll names to follow the libtool convention + with only major version number in the name. + +2016-03-15 Niels Möller + + * twofish.c (gf_multiply): Change return value to uint32_t, to + make shifting of the return value well defined, without any type + casts. Fixes an undefined shift in compute_s, reported by Nikos + Mavrogiannopoulos. + (h_byte): Deleted type casts. + + * blowfish.c (blowfish_encrypt, blowfish_decrypt): Use READ_UINT32 + macro. Fixes an undefined shift, reported by Nikos + Mavrogiannopoulos. + + From Nikos Mavrogiannopoulos. + * configure.ac (HOGWEED_EXTRA_SYMBOLS): Add "mp_*", when building + with mini-gmp. + * des.c (des_weak_p): Check that the hash value is in the proper + range before using it. Fixes an out-of-bounds read. + +2016-03-14 Niels Möller + + * getopt.c (_getopt_internal_r): Fix c99-ism, move declarations to + top of block. Reported by Henrik Grubbström. + +2016-02-16 Niels Möller + + * tools/input.c (sexp_get_string_length): Process advanced string + syntax only when in advanced mode. Fixes an assertion failure + reported by Hanno Böck, for input where advanced syntax is + improperly wrapped inside transport syntax. + + * tools/parse.c (sexp_parse): Fail with an error message for + unexpected ']' characters. Fixes crash reported by Hanno Böck. + Also handle SEXP_DISPLAY (internal error) explicitly, without a + default clause. + +2016-01-28 Niels Möller + + * Released nettle-3.2. + +2016-01-26 Niels Möller + + * tools/nettle-pbkdf2.c (main): Fix handling of unrecognized + options. Bug reported by Dongsheng Zhang. Display usage message + and exit non-zero. Also added "Usage: "-prefix to the message. + * tools/nettle-hash.c (usage): New function, extracted from main. + (main): Analogous fix for unrecognized options. + +2016-01-23 Niels Möller + + * nettle.texinfo: Set UPDATED-FOR to 3.2. + +2016-01-21 Niels Möller + + * .gitlab-ci.yml: New file. Configuration for gitlab's continuous + integration system. + +2016-01-20 Niels Möller + + * testsuite/dlopen-test.c (main): Mark arguments as UNUSED. + + * testsuite/Makefile.in (clean): Delete dlopen-test. + + * configure.ac: Bump package version, to nettle-3.2. + (LIBNETTLE_MINOR, LIBHOGWEED_MINOR): Bump minor versions, to + libnettle.so.6.2 and and libhogweed.so.4.2. + +2016-01-10 Niels Möller + + * base64-encode.c (encode_raw): Use const uint8_t * for the + alphabet argument. + + * nettle.texinfo (RSA): Document the rsa_pkcs1_verify and + rsa_pkcs1_sign functions, and the new rsa_*_tr functions. + +2015-12-18 Niels Möller + + * testsuite/testutils.h: Fix include order, system headers before + nettle headers. Always include version.h, needed by + version-test.c. It was included indirectly via bignum.h, but only + if configured with publickey support. + + * configure.ac (IF_DLOPEN_TEST): Fixed shell conditional. + + * testsuite/ecc-mod-test.c (test_main): Handle random seeding if + NETTLE_TEST_SEED is set in the environment. + +2015-12-15 Niels Möller + + * x86_64/ecc-384-modp.asm: Fixed carry propagation bug. Problem + reported by Hanno Böck. Simplified the folding to always use + non-negative carry, the old code attempted to add in a carry which + could be either positive or negative, but didn't get that case + right. + +2015-12-10 Niels Möller + + * ecc-256.c (ecc_256_modp): Fixed carry propagation bug. Problem + reported by Hanno Böck. + (ecc_256_modq): Fixed another carry propagation bug. + +2015-11-23 Niels Möller + + * nettle.texinfo: Document rsa_encrypt, rsa_decrypt and + rsa_decrypt_tr. Text contributed by Andy Lawrence. + +2015-11-15 Niels Möller + + * rsa.h (_rsa_blind, _rsa_unblind): Mark as deprecated. + +2015-09-17 Niels Möller + + * rsa-md5-sign-tr.c (rsa_md5_sign_tr, rsa_md5_sign_digest_tr): New + file, new functions. + * rsa-sha1-sign-tr.c (rsa_sha1_sign_tr, rsa_sha1_sign_digest_tr): + Likewise. + * rsa-sha256-sign-tr.c (rsa_sha256_sign_tr) + (rsa_sha256_sign_digest_tr): Likewise. + * rsa-sha512-sign-tr.c (rsa_sha512_sign_tr) + (rsa_sha512_sign_digest_tr): Likewise. + * rsa.h: Added corresponding prototypes. + * Makefile.in (hogweed_SOURCES): Added new files. + + * testsuite/testutils.c (SIGN): Extend macro to test new + functions, and the rsa_*_sign_digest functions. Updated callers. + +2015-09-14 Niels Möller + + * rsa-decrypt-tr.c (rsa_decrypt_tr): Use rsa_compute_root_tr. + Mainly for simplicity and consistency, I'm not aware of any CRT + fault attacks on RSA decryption. + + * testsuite/rsa-encrypt-test.c (test_main): Added test with + invalid private key. + + * rsa-sign-tr.c (rsa_compute_root_tr): New file and function. + * rsa.h: Declare it. + * rsa-pkcs1-sign-tr.c (rsa_pkcs1_sign_tr): Use rsa_compute_root_tr. + (rsa_verify_res): Deleted, replaced by rsa_compute_root_tr. + * testsuite/rsa-sign-tr-test.c (test_rsa_sign_tr): Check that + signature argument is unchanged on failure. + * Makefile.in (hogweed_SOURCES): Added rsa-sign-tr.c. + +2015-09-07 Niels Möller + + * testsuite/rsa-sign-tr-test.c: Drop include of nettle-internal.h. + (test_main): Fix incorrect use of sizeof, and use LDATA macro. + + From Nikos Mavrogiannopoulos. + * rsa-pkcs1-sign-tr.c (rsa_verify_res): New function. + (rsa_pkcs1_sign_tr): Check result of private key operation, to + protect against hardware or software errors leaking the private + key. + * testsuite/rsa-sign-tr-test.c: New testcase. + +2015-09-06 Niels Möller + + * nettle.texinfo: Updated SHA3 documentation. + +2015-09-02 Niels Möller + + * testsuite/dlopen-test.c: New test program, exposing the problem + with ifunc and RTLD_NOW. + + * testsuite/Makefile.in (TS_ALL): Conditionally add dlopen-test. + (SOURCES): Added dlopen-test.c. + (dlopen-test): New target, unlike other test programs, *not* + linked with -lnettle. + + * configure.ac: Check for dlfcn.h and the dlopen function. + (IF_DLOPEN_TEST): New substituted variable, true if dlopen is + available and we are building a shared library. + + * fat-setup.h: Disable use of ifunc, since it breaks dlopen with + RTLD_NOW. + +2015-08-25 Niels Möller + + * NEWS: Started on entries for Nettle-3.2. + + * sha3.h (NETTLE_SHA3_FIPS202): New preprocessor constant. + +2015-08-24 Niels Möller + + * testsuite/sha3.awk: Document origin of test vectors. + + From Nikos Mavrogiannopoulos. + * sha3.c (_sha3_pad): Update for NIST version. + * testsuite/sha3-224-test.c: Updated test vectors. + * testsuite/sha3-256-test.c: Likewise. + * testsuite/sha3-384-test.c: Likewise. + * testsuite/sha3-512-test.c: Likewise. + +2015-06-03 Niels Möller + + * arm/neon/chacha-core-internal.asm: New file. 55% speedup over C + version on Cortex-A9. + +2015-05-19 Niels Möller + + * configure.ac: ABI detection (n32 or n64) on Irix, and + appropriate default for libdir. Patch from Klaus Ziegler. + +2015-05-12 Niels Möller + + * version.c (nettle_version_major, nettle_version_minor): New + file. New functions, returning the value of the corresponding + preprocessor constant. + * Makefile.in (nettle_SOURCES): Added version.c. + * testsuite/version-test.c: New testcase. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added version-test.c. + +2015-04-29 Niels Möller + + * arm/v6/sha256-compress.asm: Fix syntax error in offset + addressing. Spotted by Jukka Ukkonen. + * arm/v6/aes-decrypt-internal.asm: Drop %-prefix on r12 register. + * arm/v6/aes-encrypt-internal.asm: Likewise. + +2015-04-24 Niels Möller + + * Released nettle-3.1.1. + + * configure.ac: Bump package version, to nettle-3.1.1. + (LIBNETTLE_MINOR, LIBHOGWEED_MINOR): Bump minor versions, to + libnettle.so.6.1 and and libhogweed.so.4.1. + +2015-04-22 Niels Möller + + * x86_64/gcm-hash8.asm: Use ".value" instead of ".short", since + the latter is not supported by the Sun/Oracle assembler. + +2015-04-13 Niels Möller + + * configure.ac: Fix shell quoting in test of GMP_NUMB_BITS asm + compatibility. Reported by Edward Sheldrake. + +2015-04-07 Niels Möller + + * Released nettle-3.1. + +2015-03-31 Niels Möller + + * x86_64/ecc-224-modp.asm: Require that GMP_NUMB_BITS == 64. + * x86_64/ecc-521-modp.asm: Likewise. Note that the other + ecc-*-modp.asm files happen to work fine on x86_64, with either 32 + or 64 bits. + + * asm.m4 (GMP_NUMB_BITS): New macro, expanding to nothing. + + * configure.ac: Move tests for compiler characteristics, + libraries, and GMP_NUMB_BITS, before assembler-related tests. + For files in $asm_hogweed_optional_list, check if they declare + a GMP_NUMB_BITS requirement, and skip files which are incompatible + with the configuration. Needed for --enable-mini-gmp om w64. + + * Makefile.in (clean-here): Unconditionally delete *.a (including + stub libraries like *.dll.a). + +2015-03-30 Niels Möller + + * version.h.in (GMP_NUMB_BITS) [NETTLE_USE_MINI_GMP]: Move + definition here (uses configure substitution). + * bignum.h (GMP_NUMB_BITS): ...old location. + + * nettle.texinfo: Updated version number. + (Installation): Document some more configure options. + + * testsuite/symbols-test: Look for NETTLE_USE_MINI_GMP in + version.h, not bignum.h. Allow leading underscore on mini-gmp + symbols. + +2015-03-26 Niels Möller + + * Makefile.in (PRE_CPPFLAGS): Drop -I$(srcdir), no longer needed. + (HEADERS): Added bignum.h. Removed version.h. + (INSTALL_HEADERS): Added version.h. + (DISTFILES): Removed bignum.h.in. + (bignum.h): Deleted make target. + (distclean-here): Don't delete bignum.h. + + * configure.ac: No longer generate bignum.h. + + * bignum.h: Renamed. Removed substitution of NETTLE_USE_MINI_GMP, + and include version.h instead. + * bignum.h.in: ... old name. + + * version.h.in (NETTLE_USE_MINI_GMP): Substitute here. + +2015-03-25 Niels Möller + + * configure.ac (MAJOR_VERSION, MINOR_VERSION): Tweak sed + expressions, to tolerate version suffixes. + + * Makefile.in (distdir): Include assembly files from the new + x86_64/aesni, x86_64/fat, and arm/fat directories. + + * ed25519-sha512-pubkey.c: Fix stack overwrite. The digest array + must have room for a complete sha512 digest. + +2015-03-19 Niels Möller + + * Makefile.in (OPT_HOGWEED_SOURCES): Deleted make variable. + (nettle_SOURCES, hogweed_SOURCES): Don't include optional sources + here. + (OPT_SOURCES): New variable. + (SOURCES): Include OPT_SOURCES. + (DISTFILES): Drop mini-gmp.c here, included via OPT_SOURCES. + (nettle_OBJS, hogweed_OBJS): Add the object files corresponding to + the optional source files included in the build. + + * ecc-curve.h (nettle_curve25519): Removed public declaration. + * ecc-internal.h (_nettle_curve25519): New location, new name. + Updated all users. + + * nettle.texinfo: Updated EdDSA documentation. + + * Makefile.in (DISTFILES): Added version.h.in, libnettle.map.in, + and libhogweed.map.in (latter two patch by Nikos). + (version.h): New make target. + (distclean-here): Added version.h, libnettle.map, and + libhogweed.map. + + From Nikos Mavrogiannopoulos. + * configure.ac (MAJOR_VERSION, MINOR_VERSION): New substituted + variables. + * version.h.in: New file, defining version numbers. + +2015-03-18 Niels Möller + + EdDSA interface change, use plain strings to represent keys. + * eddsa.h (_ED25519_LIMB_SIZE): Deleted constant. + (struct ed25519_private_key, ed25519_public_key): Deleted. + * eddsa-expand.c (_eddsa_expand_key): Don't compute the public + key. + (_eddsa_expand_key_itch): Deleted function. + * eddsa-pubkey.c (_eddsa_public_key, _eddsa_public_key_itch): New + file, new functions. + * ed25519-sha512-pubkey.c (ed25519_sha512_public_key): New file + and function. + * ed25519-sha512-verify.c (ed25519_sha512_set_public_key): Deleted + function. + (ed25519_sha512_verify): Use a string to represent the public key. + * ed25519-sha512-sign.c (ed25519_sha512_set_private_key): Deleted + function. + (ed25519_sha512_sign): Use strings for the input key pair. + * Makefile.in (hogweed_SOURCES): Added eddsa-pubkey.c and + ed25519-sha512-pubkey.c. + * testsuite/eddsa-sign-test.c (test_eddsa_sign): Adapt to + _eddsa_expand_key changes, and use _eddsa_public_key. + * testsuite/ed25519-test.c (test_one): Test + ed25519_sha512_public_key, and adapt to new ed25519 interface. + +2015-03-14 Niels Möller + + * ccm.c (memeql_sec): New function, more side-channel silent than + memcmp. + (ccm_decrypt_message): Use it. + +2015-03-12 Niels Möller + + * base64.h (struct base64_encode_ctx): Micro optimization of + struct layout, saving a few bytes. + (struct base64_decode_ctx): Likewise. + * base16.h (struct base16_decode_ctx): Likewise. + + * nettle.texinfo (ASCII encoding): Document base64url functions. + +2015-03-10 Niels Möller + + * nettle.texinfo: Update documentation of curve25519_mul. Say that + the output is undefined for points belonging to the twist rather + than the proper curve. + + * curve25519-mul.c (curve25519_mul): Changed return type to void. + * curve25519.h (curve25519_mul): Updated prototype. + * examples/hogweed-benchmark.c (bench_curve25519_mul): Drop check + of curve25519_mul return value. + * testsuite/curve25519-dh-test.c (test_a): Likewise. + +2015-02-26 Niels Möller + + * nettle.texinfo: Document curve25519 and eddsa. + +2015-02-10 Niels Möller + + * base64url-meta.c (nettle_base64url): New file. + * nettle-meta.h (nettle_base64url): Declare it. + * nettle-meta-armors.c (nettle_armors): Added nettle_base64url. + * testsuite/meta-armor-test.c: Updated testcase. + * testsuite/base64-test.c (test_main): Additional tests, using + nettle_base64url. + * Makefile.in (nettle_SOURCES): Added base64url-meta.c. + + Base-64 generalization to support RFC4648 URL safe alphabet, + contributed by Amos Jeffries. + * base64url-decode.c (base64url_decode_init): New file and + function. + * base64url-encode.c (base64url_encode_init): New file and + function. + * Makefile.in (nettle_SOURCES): Added base64url-encode.c and + base64url-decode.c. + * base64.h: Declare new functions. + * testsuite/base64-test.c (test_fuzz): Test base64url encoding and + decoding. + + * base64.h (struct base64_encode_ctx): Added pointer to alphabet. + (struct base64_decode_ctx): Added pointer to decoding table. + * base64-decode.c (base64_decode_init): Initialize table pointer. + Moved definition of table to local scope. + (base64_decode_single): Use the context's decoding table. + * base64-encode.c (ENCODE): Added alphabet argument. Updated all + uses. + (encode_raw): New static function, like base64_encode_raw + but with an alphabet argument. + (base64_encode_raw): Call encode_raw. + (base64_encode_init): Initialize alphabet pointer. + (base64_encode_single, base64_encode_update, base64_encode_final): + Use the context's alphabet. + +2015-02-09 Niels Möller + + * base64-encode.c (base64_encode): Deleted old #if:ed out + function. + + * testsuite/base64-test.c (test_fuzz_once, test_fuzz): Additional + tests, based on contribution by Amos Jeffries. + +2015-02-05 Niels Möller + + * configure.ac (LIBHOGWEED_MAJOR): Undo latest bump, 4 should be + enough (previous release, nettle-3.0, used 3). + +2015-01-30 Niels Möller + + Update chacha-poly1305 for draft-irtf-cfrg-chacha20-poly1305-08. + * chacha-poly1305.h (CHACHA_POLY1305_NONCE_SIZE): Increase to 12 + bytes, i.e., CHACHA_NONCE96_SIZE. + * chacha-poly1305.c (chacha_poly1305_set_nonce): Use + chacha_set_nonce96. + (poly1305_pad): New function. + (chacha_poly1305_encrypt): Use poly1305_pad. + (chacha_poly1305_digest): Call poly1305_pad, and format length + fields as a single poly1305 block. + + * chacha-set-nonce.c (chacha_set_nonce96): New function. + * chacha.h (CHACHA_NONCE96_SIZE): New constant. + * testsuite/chacha-test.c: Add test for chacha with 96-bit nonce. + +2015-01-27 Niels Möller + + * ecc.h: Deleted declarations of unused itch functions. Moved + declarations of internal functions to... + * ecc-internal.h: ...new location. Also added a leading under + score on the symbols. + (ecc_a_to_j, ecc_j_to_a, ecc_eh_to_a, ecc_dup_jj, ecc_add_jja) + (ecc_add_jjj, ecc_dup_eh, ecc_add_eh, ecc_add_ehh, ecc_mul_g) + (ecc_mul_a, ecc_mul_g_eh, ecc_mul_a_eh): Affected functions. + +2015-01-26 Niels Möller + + * ecc-add-eh.c (ecc_add_eh_itch): Deleted. + * ecc-add-ehh.c (ecc_add_ehh_itch): Deleted. + * ecc-add-jja.c (ecc_add_jja_itch): Deleted. + * ecc-add-jjj.c (ecc_add_jjj_itch): Deleted. + * ecc-dup-eh.c (ecc_dup_eh_itch): Deleted. + * ecc-dup-jj.c (ecc_dup_jj_itch): Deleted. + * ecc-eh-to-a.c (ecc_eh_to_a_itch): Deleted. + * ecc-j-to-a.c (ecc_j_to_a_itch): Deleted. + * ecc-mul-a-eh.c (ecc_mul_a_eh_itch): Deleted. + * ecc-mul-a.c (ecc_mul_a_itch): Deleted. + * ecc-mul-g-eh.c (ecc_mul_g_eh_itch): Deleted. + * ecc-mul-g.c (ecc_mul_g_itch): Deleted. + +2015-01-25 Niels Möller + + * arm/fat/sha1-compress-2.asm: New file. + * arm/fat/sha256-compress-2.asm: Likewise. + * fat-arm.c (fat_init): Setup for use of additional v6 assembly + functions. + + * sha1-compress.c: Prepare for fat build with C and assembly + implementations. + * sha256-compress.c: Likewise. + + * fat-setup.h (sha1_compress_func, sha256_compress_func): New typedefs. + + * configure.ac (asm_nettle_optional_list): Added + sha1-compress-2.asm and sha256-compress-2.asm, and corresponding + HAVE_NATIVE_*. + + From Martin Storsjö: + * arm: Add .arch directives for armv6. This allows building these + files as part of a fat build, even if the assembler by default + targets a lower architecture version. + +2015-01-23 Niels Möller + + * fat-setup.h (DEFINE_FAT_FUNC): Check value of function pointer, + before calling fat_init. Should be correct even without memory + barrier. + * fat-x86_64.c (fat_init): Deleted static variable initialized. + The checks of the relevant pointer in DEFINE_FAT_FUNC is more + robust. + * fat-arm.c (fat_init): Likewise. + +2015-01-21 Niels Möller + + * fat-arm.c (fat_init): Setup for use of neon assembly functions. + + * arm/fat/salsa20-core-internal-2.asm: New file. + * arm/fat/sha3-permute-2.asm: New file. + * arm/fat/sha512-compress-2.asm: New file. + * arm/fat/umac-nh-2.asm: New file. + * arm/fat/umac-nh-n-2.asm: New file. + + * salsa20-core-internal.c: Prepare for fat build with C and + assembly implementations. + * sha512-compress.c: Likewise. + * sha3-permute.c: Likewise. + * umac-nh.c: Likewise. + * umac-nh-n.c: Likewise. + + * configure.ac (asm_nettle_optional_list): Added more *-2.asm + files, and corresponding HAVE_NATIVE_* defines. Recognize PROLOGUE + macro in asm files, also when not at the start of the line. + +2015-01-20 Niels Möller + + * fat-arm.c (get_arm_features): Check NETTLE_FAT_OVERRIDE + environment variable. + + * fat-x86_64.c (get_x86_features): New function. Check + NETTLE_FAT_OVERRIDE environment variable. + (fat_init): Use it. + + * fat-setup.h (secure_getenv) [!HAVE_SECURE_GETENV]: Dummy + definition, returning NULL. + (ENV_OVERRIDE): New constant. + + * configure.ac: Check for secure_getenv function. + +2015-01-19 Niels Möller + + * configure.ac: Fat library setup for arm. + * fat-arm.c: New file. + * arm/fat/aes-encrypt-internal.asm: New files. + * arm/fat/aes-encrypt-internal-2.asm: New file. + * arm/fat/aes-decrypt-internal.asm: New file. + * arm/fat/aes-decrypt-internal-2.asm: New file. + + * Makefile.in (DISTFILES): Added fat-setup.h. + + * fat-setup.h: New file, declarations moved from... + * fat-x86_64.c: ... old location + +2015-01-17 Niels Möller + + * fat-x86_64.c (DECLARE_FAT_FUNC, DEFINE_FAT_FUNC) + (DECLARE_FAT_FUNC_VAR): New macros, to define needed resolver and + wrapper functions. + + * config.m4.in (SYMBOL_PREFIX): Define from from autoconf + ASM_SYMBOL_PREFIX. + (C_NAMS): move definition to... + * asm.m4 (C_NAME): Define here, also take fat_transform. + (fat_suffix): Replaced by... + (fat_transform): New macro, taking symbol name as argument. + Updated all uses of fat_suffix. + * fat-x86_64.c: Updated for internal "_nettle" prefix on + cpu-specific memxor functions. + + * fat-x86_64.c: Set up for sse2 vs non-sse2 memxor. Patch by Nikos + Mavrogiannopoulos. + * configure.ac (asm_nettle_optional_list): Added memxor-2.asm. + * x86_64/fat/memxor-2.asm: New file. + * x86_64/fat/memxor.asm: New file. + + * x86_64/memxor.asm: Use ifdef, not ifelse, for testing USE_SSE2. + +2015-01-16 Niels Möller + + * configure.ac (OPT_NETTLE_SOURCES): New substituted variable. + (asm_path): Fixed x86_64 fat setup. Include only x86_64 and + x86_64/fat in the asm_path. Put fat-x86_64.c in + OPT_NETTLE_SOURCES, with no symlinking. + + * fat-x86_64.c: Renamed,... + * x86_64/fat/fat.c: ... from old name. + +2015-01-13 Niels Möller + + * x86_64/fat/fat.c: For constructor hack, check + HAVE_GCC_ATTRIBUTE, not __GNUC__. Also support sun compilers, as + suggested by Nikos Mavrogiannopoulos, and attch the constructor + attribute directly to fat_init. + (fat_constructor): Deleted wrapper function. + + * x86_64/fat/fat.c: New file, initialization for x86_64 fat + library. + + * x86_64/fat/cpuid.asm (_nettle_cpuid): New file and function. + + * x86_64/fat/aes-encrypt-internal.asm: New file, including + x86_64/aes-encrypt-internal.asm, after setting fat_suffix to + _x86_64. + * x86_64/fat/aes-decrypt-internal.asm: New file, analogous setup. + * x86_64/fat/aes-encrypt-internal-2.asm: New file, including + x86_64/aesni/aes-encrypt-internal.asm, after setting fat_suffix to + _aesni. + * x86_64/fat/aes-decrypt-internal.asm-2: New file, analogous + setup. + + * configure.ac: New command line option --enable-fat. + (asm_nettle_optional_list): Added cpuid.asm, fat.c, + aes-encrypt-internal-2.asm, and aes-decrypt-internal-2.asm. + + * asm.m4 (fat_suffix): New suffix added to symbol names. + + * x86_64/aesni/aes-encrypt-internal.asm: Use explicit .byte + sequences for aes instructions, don't rely on assembler support. + * x86_64/aesni/aes-decrypt-internal.asm: Likewise. + + * aclocal.m4 (NETTLE_CHECK_IFUNC): New macro, checking for ifunc + and settting HAVE_LINK_IFUNC if working. + * configure.ac: Use it. + +2015-01-12 Niels Möller + + * asm.m4 (DECLARE_FUNC): New macro, extracted from PROLOGUE. + (PROLOGUE): Use it. + + * configure.ac (OPT_NETTLE_OBJS, OPT_HOGWEED_OBJS): Renamed + substituted variables, and list the object files rather than + source files. + (OPT_ASM_NETTLE_SOURCES, OPT_ASM_HOGWEED_SOURCES): ...Old names. + * Makefile.in (OPT_NETTLE_OBJS, OPT_HOGWEED_OBJS): Use new + variables. + +2015-01-11 Niels Möller + + * x86_64/aesni/aes-decrypt-internal.asm: New file. + * x86_64/aesni/aes-encrypt-internal.asm: New file. + * configure.ac: New configure flag --enable-x86-aesni. + + * aclocal.m4 (LSH_RPATH_INIT): Handle freebsd, in the same way as + gnu/linux, with -Wl,-rpath,. + + Merged memxor-reorg changes, starting at 2014-10-23. + +2015-01-10 Niels Möller + + * arm/memxor.asm (memxor3): Moved to new file. + * arm/memxor3.asm: New file. + +2014-11-24 Niels Möller + + * x86_64/memxor3.asm (memxor3): New file, code moved from old + memxor.asm. + * x86_64/memxor.asm (memxor): Rewritten, no longer jumps into + memxor3. + + * configure.ac (asm_replace_list): Added memxor.asm and + memxor3.asm. + +2014-10-23 Niels Möller + + * configure.ac (IF_ASM): New substituted variable. + * testsuite/Makefile.in (VALGRIND): Allow partial loads only when + build includes assembly files. + + * memxor-internal.h (READ_PARTIAL): New macro. + * memxor.c (memxor_different_alignment): Avoid out-of-bounds + reads, corresponding to valgrind's --partial-loads-ok. Use + READ_PARTIAL. + * memxor3.c: Analogous changes for unaligned operations. + + * configure.ac (asm_replace_list): Deleted memxor.asm, now + incompatible with the memxor/memxor3 split. + + * memxor3.c: New file, split off from memxor.c. + * memxor-internal.h: New file, declarations shared by memxor.c and + memxor3.c. + * memxor.c: memxor3 functions moved out from this file. + * Makefile.in (nettle_SOURCES): Added memxor3.c. + (DISTFILES): Added memxor-internal.h. + + * memxor.c (memxor_common_alignment, memxor_different_alignment) + (memxor): Change loop order, iterate from the end. + (memxor3_common_alignment): Unroll twice. + (word_t): On x86_64, unconditionally define as uint64_t, to get 64 + bits also in M$ windows. Replaced all uses of SIZEOF_LONG. + +2014-12-12 Niels Möller + + * cbc.h (CBC_ENCRYPT, CBC_DECRYPT): Make type-checking hack + stricter, warn if type of length argument is smaller than size_t. + * ctr.h (CTR_CRYPT): Likewise. + * eax.h (EAX_SET_KEY, EAX_SET_NONCE, EAX_UPDATE, EAX_ENCRYPT) + (EAX_DECRYPT, EAX_DIGEST): Likewise. + * gcm.h (GCM_SET_KEY, GCM_ENCRYPT, GCM_DECRYPT, GCM_DIGEST): + Likewise. + +2014-12-08 Niels Möller + + * aclocal.m4 (LD_VERSION_SCRIPT): Linker scripts no longer located + in the source tree. + + * configure.ac (LIBNETTLE_MAJOR): Bump major number, now 6. + (LIBHOGWEED_MAJOR): Bump major number, now 5. + + From Nikos Mavrogiannopoulos. Support for versioned symbols. + * aclocal.m4 (LD_VERSION_SCRIPT): New macro. Substitute + EXTRA_LINKER_FLAGS and EXTRA_HOGWEED_LINKER_FLAGS. + * configure.ac: Use LD_VERSION_SCRIPT. Generate libnettle.map + and libhogweed.map. + (HOGWEED_EXTRA_SYMBOLS): New substituted variable. + * libnettle.map.in: New file, libnettle.so linker script + * libhogweed.map.in: New file, libhogweed.so linker script. + * Makefile.in ($(LIBNETTLE_FORLINK)): Use EXTRA_LINKER_FLAGS. + ($(LIBHOGWEED_FORLINK)): Use EXTRA_HOGWEED_LINKER_FLAGS. + +2014-11-24 Niels Möller + + * gcm.h (GCM_SET_KEY): Rename macro argument KEY to avoid + collision with a struct tag. Spotted by Nikos Mavrogiannopoulos. + + * testsuite/eddsa-verify-test.c (test_eddsa): Fixed test case bug, + showing up as use of uninitialized data with valgrind. + +2014-10-23 Niels Möller + + * examples/nettle-benchmark.c (time_memxor): Allocate buffers as + arrays of unsigned long, for more reliable alignment. + +2014-10-22 Niels Möller + + * configure.ac: Check for getline function. + * testsuite/ed25519-test.c (getline) [!HAVE_GETLINE]: Fallback + definition. + + * Makefile.in (clean-here): Unconditionally delete .so and .dll + files. + (IMPLICIT_TARGETS): Deleted variable. + +2014-10-21 Niels Möller + + * testsuite/ed25519-test.c: New test case. Optionally reads the + file pointed to by $ED25519_SIGN_INPUT. + + * testsuite/testutils.c (tstring_hex): Rewrite, using Nettle's + base16 functions. + (decode_hex, decode_hex_length): Deleted functions. + +2014-10-20 Niels Möller + + * eddsa.h (ED25519_KEY_SIZE): New constant. + (ED25519_SIGNATURE_SIZE): New constant. + (struct ed25519_private_key): New struct. + (struct ed25519_public_key): New struct. + + * ed25519-sha512-sign.c (ed25519_sha512_set_private_key) + (ed25519_sha512_sign): New file and functions. + * ed25519-sha512-verify.c (ed25519_sha512_set_public_key) + (ed25519_sha512_verify): New file and functions. + * Makefile.in (hogweed_SOURCES): Added ed25519-sha512-sign.c and + ed25519-sha512-verify.c. + + +2014-10-18 Niels Möller + + * eddsa-verify.c (_eddsa_verify): Change argument order, putting A + before ctx. + * eddsa.h: Updated prototype. + * testsuite/eddsa-verify-test.c (test_eddsa): Updated + _eddsa_verify calls. + +2014-10-14 Niels Möller + + * eddsa-verify.c (equal_h): New function. + (_eddsa_verify): Use it for a proper point compare, replacing an + ecc_add_ehh. + + * testsuite/eddsa-verify-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + eddsa-verify-test.c. + + * eddsa-verify.c (_eddsa_verify, eddsa_verify_itch): New file, new + functions. + * eddsa.h: Declare new functions. + * Makefile.in (hogweed_SOURCES): Added eddsa-verify.c. + +2014-10-08 Niels Möller + + * testsuite/eddsa-sign-test.c (test_eddsa_sign): Use + _eddsa_expand_key, and check its public key output. + + * eddsa-expand.c (_eddsa_expand_key): New file, new function. + * eddsa.h (_eddsa_expand_key): Declare it. + * Makefile.in (hogweed_SOURCES): Added eddsa-expand.c. + + * eddsa-sign.c: Drop unneeded include of nettle-internal.h. + +2014-10-04 Niels Möller + + * testsuite/eddsa-sign-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + eddsa-sign-test.c. + + * eddsa-sign.c (_eddsa_sign, _eddsa_sign_itch): New file, new + functions. + * eddsa-hash.c (_eddsa_hash): New file and function. + * eddsa.h: Declare new functions. + * Makefile.in (hogweed_SOURCES): Added eddsa-hash.c and + eddsa-sign.c. + +2014-10-03 Niels Möller + + * testsuite/ecc-redc-test.c [NETTLE_USE_MINI_GMP]: Enable test. + (test_main): Replace gmp_fprintf calls. + * testsuite/ecc-mul-a-test.c: Likewise. + * testsuite/ecc-mul-g-test.c: Likewise. + + * testsuite/ecc-modinv-test.c [NETTLE_USE_MINI_GMP]: Enable test. + (ref_modinv): Use mpz_gcdext, instead of mpn_gcdext. + (test_modulo): Replace gmp_fprintf calls. + + * testsuite/ecc-mod-test.c [NETTLE_USE_MINI_GMP]: Enable test. + (ref_mod): Use mpz_mod and mpz_limbs_copy, instead of mpn_tdiv_qr. + (test_modulo): Replace gmp_fprintf calls by plain fprintf and + mpn_out_str. + + * testsuite/testutils.c (mpn_out_str): New function, needed to + replace uses of gmp_fprintf. + + * testsuite/ecc-sqrt-test.c (mpz_ui_kronecker) + [NETTLE_USE_MINI_GMP]: New fallback definition when building with + mini-gmp. + * testsuite/testutils.c (gmp_randinit_default) + [NETTLE_USE_MINI_GMP]: Likewise. + (mpz_urandomb): Likewise. + * testsuite/testutils.h (gmp_randstate_t) [NETTLE_USE_MINI_GMP]: + Fallback typedef, using knuth_lfib_ctx. + +2014-10-02 Niels Möller + + * testsuite/eddsa-compress-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + eddsa-compress-test.c. + + * eddsa-decompress.c (_eddsa_decompress): New file, new function. + * eddsa-compress.c (_eddsa_compress): New file, new function. + * eddsa.h: New file. + * Makefile.in (HEADERS): Added eddsa.h. + (hogweed_SOURCES): Added eddsa-compress.c and eddsa-decompress.c. + + * testsuite/ecc-sqrt-test.c: New test case. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecc-sqrt-test.c. + + * ecc-25519.c (PHIGH_BITS): Always define this constant. + (ecc_25519_zero_p): New function. + (ecc_25519_sqrt): Take a ratio u/v as input. Added scratch + argument. Made static. + * ecc-internal.h (ecc_mod_sqrt_func): New typedef. + (struct ecc_modulo): Added sqrt_itch and sqrt function pointer. + Updated all instances. + (ecc_25519_sqrt): Deleted declaration, function now static. + +2014-09-24 Niels Möller + + * curve25519.h [__cplusplus]: Fixed extern "C" block. + +2014-09-23 Niels Möller + + * ecc-hash.c (ecc_hash): Changed argument type from struct + ecc_curve to struct ecc_modulo. Updated callers. + * testsuite/ecdsa-sign-test.c (test_main): Updated curve25519 + signature s. Changed since the hash value is truncated a few bits + more, to match the size of q. + * testsuite/ecdsa-verify-test.c (test_main): Likewise. + + * testsuite/ecc-modinv-test.c (zero_p): New function, checking for + zero modulo p. + (test_modulo): Use zero_p. Switch to dynamic allocation. Updated + for larger modinv result area, and use invert_itch. + + * ecc-25519.c (ecc_mod_pow_2kp1): Renamed, and take a struct + ecc_modulo * as argument. + (ecc_modp_powm_2kp1): ... old name. + (ecc_mod_pow_252m3): New function, extracted from ecc_25519_sqrt. + (ecc_25519_inv): New modp invert function, about 5.5 times faster + then ecc_mod_inv. + (ecc_25519_sqrt): Use ecc_mod_pow_252m3. + (nettle_curve25519): Point to ecc_25519_inv. Updated p.invert_itch + and h_to_a_itch. + + * ecc-internal.h (struct ecc_modulo): New field invert_itch. + Updated all implementations. + (ECC_EH_TO_A_ITCH): Updated, and take invert itch as an argument. + * ecc-eh-to-a.c (ecc_eh_to_a_itch): Take invert scratch into account. + + * testsuite/testutils.c (test_ecc_mul_h): Use ecc->h_to_a_itch. + + * ecc-mod-inv.c (ecc_mod_inv): Interface change, make ap input + const, and require 2n limbs at rp. Preparing for powm-based + alternative implementations. Drop #if:ed out code and dp + temporary. Updated all callers, more complicated cases described + below. + * ecc-internal.h (typedef ecc_mod_inv_func): Added const to input + argument. + (ECC_MOD_INV_ITCH): Renamed, was ECC_MODINV_ITCH, and reduced to + 2*n. + * ecc-ecdsa-verify.c (ecc_ecdsa_verify): Overhauled allocation, + putting mod_inv scratch at the end. + +2014-09-22 Niels Möller + + * ecc-random.c (ecc_mod_random): Renamed, and take a const struct + ecc_modulo * as argument. Updated callers. + (ecc_modq_random): ... old name. + + * ecc-mod-arith.c: New file, replacing ecc-modp.c and ecc-modq.c. + All functions take a struct ecc_modulo as argument. + (ecc_mod_add, ecc_mod_sub, ecc_mod_mul_1, ecc_mod_addmul_1) + (ecc_mod_submul_1, ecc_mod_mul, ecc_mod_sqr): New functions, + replacing the corresponding ecc_modp_* functions. For convenience, + old names are defined as macros wrapping the new functions. + * ecc-modp.c: Deleted file. + * ecc-modq.c: Deleted file. + * Makefile.in (hogweed_SOURCES): Updated accordingly. + + * testsuite/ecc-redc-test.c (test_main): Relaxed tests for which + tests to run. + + * testsuite/ecc-modinv-test.c (test_modulo): New function, same + organization as in ecc-mod-test.c below. + + * testsuite/ecc-mod-test.c (test_modulo): New function, testing + one modulo. Replacing... + (test_curve): ... old function. + (test_main): Invoke test_modulo for p and q of each curve. + + * ecc-internal.h (ecc_mod_inv_func): New typedef. + (struct ecc_modulo): Added mp1h constant and invert function + pointer. Updated all callers. + * ecc-modp.c (ecc_modp_inv): Deleted wrapper function. + * ecc-modq.c (ecc_modq_inv): Deleted wrapper function. + + * ecc-mod-inv.c (ecc_mod_inv): Renamed file and function. Also + take a struct ecc_modulo * as argument. + * sec-modinv.c (sec_modinv): ... the old names. Deleted. + * Makefile.in (hogweed_SOURCES): Updated accordingly. + + * examples/ecc-benchmark.c (bench_modinv_powm, bench_curve): + Updated benchmarking of mpn_sec_powm. + + * ecc-internal.h (struct ecc_curve): Deleted redc function + pointer. Use only reduce pointer, which is redc or modp as + applicable. Updated all users. + (struct ecc_modulo): Moved mod and reduce function pointers to + this struct. + + * ecc-generic-modp.c (ecc_generic_modp): Deleted file and + function. We no longer need a wrapper around ecc_mod. + * ecc-generic-modq.c (ecc_generic_modq): Likewise deleted. + * Makefile.in (hogweed_SOURCES): Removed ecc-generic-modp.c and + ecc-generic-modq.c. + + * ecc-internal.h (typedef ecc_mod_func): Take a const struct + ecc_modulo * argument, not const struct ecc_curve *. Updated all + implementations and all callers. + + * ecc-mod.c (ecc_mod): Use struct ecc_modulo to specify the + modulo. Drop input size argument, always reduce from 2*size to + size. + + * ecc-internal.h (struct ecc_modulo): New struct, collecting + constants needed for modulo arithmetic. + (struct ecc_curve): Use struct ecc_modulo for p and q arithmetic. + Updated all ecc-related files. + +2014-09-17 Niels Möller + + * gmp-glue.c (mpn_get_base256_le): Fixed missing update of rn + counter, making the function clear some bytes beyond the end of + the output buffer. The bug triggered a make check failure on ARM. + + * testsuite/testutils.c (ecc_curves): Include curve25519 in list. + (test_ecc_mul_a): Include reference points for curve25519 (with + Edwards coordinates). Allow n == 0 and n == 1, comparing to zero + and the generator, respectively. + * testsuite/ecc-add-test.c (point_zero_p): Deleted function. + (test_main): Replace calls to point_zero_p by calls to + test_ecc_mul_h with n == 0. + * testsuite/ecc-dup-test.c: Likewise. + + * testsuite/ecc-modinv-test.c (mpn_zero_p): Moved function, to... + * testsuite/testutils.c (mpn_zero_p): New location. Also make + non-static. + + * testsuite/ecdsa-keygen-test.c (ecc_valid_p): Add special case + for curve25519. + + * testsuite/ecc-mul-a-test.c (test_main): Fix point negation to + support curve25519. + * testsuite/ecc-mul-g-test.c (test_main): Likewise. + + * ecc-a-to-eh.c (ecc_a_to_eh_itch, ecc_a_to_eh): Deleted file and + functions. + * ecc.h: Deleted corresponding declarations. + * ecc-internal.h (ECC_A_TO_EH_ITCH): Deleted macro. + * Makefile.in (hogweed_SOURCES): Removed ecc-a-to-eh.c. + + * testsuite/ecdh-test.c (test_main): Update curve25519 test to use + Edwards coordinates. + * testsuite/ecdsa-sign-test.c (test_main): Likewise. + * testsuite/ecdsa-verify-test.c (test_main): Likewise. + + * ecc-point.c (ecc_point_set): Use Edwards rather than Montgomery + curve. + + * ecc-mul-a-eh.c (ecc_mul_a_eh, table_init): Take an Edwards point + as input, not a Montgomery point. Hence, use ecc_a_to_j, not + ecc_a_to_eh. + + * ecc-eh-to-a.c (ecc_eh_to_a): Just convert to affine coordinates, + don't transform from Edwards to Montgomery form. Also reduces + scratch need slightly. + * ecc-internal.h (ECC_EH_TO_A_ITCH): Reduced. + + * ecdsa-keygen.c (ecdsa_generate_keypair): Use struct ecc_curve + function pointers. + + * testsuite/curve25519-dup-test.c: Deleted file. In the way for + conversion to Edwards coordinate convention, and in the end + the tests will be done by ecc-dup-test.c. + * testsuite/curve25519-add-test.c: Similarly deleted. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Removed + curve25519-dup-test.c and curve25519-add-test.c. + +2014-09-16 Niels Möller + + * testsuite/ecc-add-test.c: New generalized testcase, to replace + curve25519-add-test.c. + * testsuite/ecc-dup-test.c: New generalized testcase, to replace + curve25519-dup-test.c. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added ecc-add-test.c + and ecc-dup-test.c. + +2014-09-14 Niels Möller + + * testsuite/ecc-mul-a-test.c (test_main): Use struct ecc_curve + function pointers. + * testsuite/ecc-mul-g-test.c (test_main): Likewise. + +2014-09-09 Niels Möller + + * curve25519-mul.c (curve25519_mul): Switch to use Montgomery + ladder. About 20% faster than current Edwards curve operations. + Difference is expected to shrink when Edwards operations are + optimized to take advantage of the twist, but it seems unlikely to + get significantly faster than the Montgomery ladder. + + * gmp-glue.c (cnd_swap): Moved function here, made non-static. + Changed cnd type to mp_limb_t, for consistency with GMP + mpn_cnd_add_n. + * sec-modinv.c (cnd_swap): ... old location. + * gmp-glue.h (cnd_swap): Declare function. + +2014-09-06 Niels Möller + + * examples/hogweed-benchmark.c (bench_curve25519_mul_g) + (bench_curve25519_mul, bench_curve25519): New functions. + (main): Added benchmarking of curve25519 functions. + +2014-09-03 Niels Möller + + * Makefile.in: Revert 2013-02-06 Makefile changes: use a single + rule for transforming .asm to .o, and drop include of asm.d. + Possible now since we generate a single object file from each asm + file. This change also helps Solaris' make recognize .asm files. + * config.make.in (.SUFFIXES): Drop .s from list. + * configure.ac: Delete code to generate asm.d. + + * Makefile.in: Delete all uses of *.po files, use the same object + files for both shared and static libraries. + * configure.ac (dummy-dep-files): Don't create any .po.d files. + + * aclocal.m4 (LSH_CCPIC): Don't substitute CCPIC here, let + configure.ac do that if needed. + + * configure.ac (CCPIC_MAYBE, SHLIBCFLAGS): Deleted substituted + variables. Instead, use CCPIC directly when compiling all library + files. + (CCPIC): Set to empty, if --disable-pic is used. + + * config.make.in (SHLIBCFLAGS, CCPIC_MAYBE): Deleted. + (COMPILE, COMPILE_CXX): Drop CCPIC. New variable EXTRA_CFLAGS, + which can be set by individual Makefiles. + + * Makefile.in (EXTRA_CFLAGS): Set using CCPIC. + Also delete all uses of CCPIC_MAYBE and SHLIBCFLAGS. + +2014-09-02 Niels Möller + + * curve25519-eh-to-x.c (curve25519_eh_to_x): New file, new + function. The curve25519 transform currently done by ecc_eh_to_a, + but which should eventually be eliminted from that function. + * Makefile.in (hogweed_SOURCES): Added curve25519-eh-to-x.c. + * ecc-internal.h (curve25519_eh_to_x): Declare it. + + * curve25519-mul.c (curve25519_mul): Use it. + * curve25519-mul-g.c (curve25519_mul_g): Likewise. Also introduce + local variable ecc, and use ecc->mul_g_itch. + +2014-08-29 Niels Möller + + * testsuite/testutils.c (test_ecc_mul_j): Renamed, to ... + (test_ecc_mul_h): ... new name. Use ecc->h_to_a function pointer. + Updated callers. + + * examples/ecc-benchmark.c (bench_add_jjj): Renamed, to ... + (bench_add_hhh): ... new name. Use ecc->add_hhh function pointer. + (bench_add_ehh): Deleted. + (bench_curve): Use bench_add_hhh for all curves. Use ecc->mul_itch + for scratch size. + + Switch the curve25519 implementation to use the isomorphism to the + twisted Edwards curve which is used for Ed25519 signatures. + * eccdata.c (ecc_curve_init): Tweaked the transformation constant + for the isomorphism between curve25519 and the twisted Edwards + curve. + * ecc-add-ehh.c (ecc_add_ehh): Updated formulas for the twist curve. + * ecc-add-eh.c (ecc_add_eh): Likewise. + * ecc-dup-eh.c (ecc_dup_eh): Likewise. + +2014-08-28 Niels Möller + + * ecdsa-verify.c (ecdsa_verify): Drop include of ecc-internal.h, + use ecc_size function instead. + + * ecc-ecdsa-verify.c (ecc_ecdsa_verify): Use the struct ecc_curve + function pointers: mul, mul_g, add_hhh, h_to_a. + + * ecc-internal.h (ECC_ECDSA_VERIFY_ITCH): Deleted macro. Needed + scratch depends on curve type, not just size. + (ecc_add_func): New typedef. + (struct ecc_curve): New function pointer add_hhh, and constant + add_hhh_itch. Updated all instances. + + * ecdsa-verify.c (ecdsa_verify): Use the ecc_ecdsa_verify_itch + function, not the corresponding macro. + * ecc-ecdsa-verify.c (ecc_ecdsa_verify_itch): Take ecc->mul_itch + into account. Also reduce to 5*ecc->size + ecc->mul_itch. + + * testsuite/ecdsa-sign-test.c (test_main): Added test for the + obscure case of ecdsa using curve25519. + * testsuite/ecdsa-verify-test.c (test_main): Likewise (depends on + above changes). + + * ecc-ecdsa-sign.c (ecc_ecdsa_sign): Use mul_g and h_to_a function + pointers. Implies (obscure) support for curve25519. + + * ecc-25519.c (ecc_25519_modq): Access q via the ecc struct. + + * ecc-eh-to-a.c (ecc_eh_to_a): Analogous change as for ecc_j_to_a. + The modulo q case (op == 2) is hardcoded for curve25519. + + * ecc-j-to-a.c (ecc_j_to_a): For curves using redc, always convert + back from redc form. When producing x coordinate only, optionally + reduce it modulo q. Completely changes the meaning of the "flags" + argument, and renames it to "op". Update all users of this + function or ecc->h_to_a. + + * ecc-ecdsa-sign.c (ecc_ecdsa_sign): Use new ecc_j_to_a modulo q + feature. + * ecc-ecdsa-verify.c (ecc_ecdsa_verify): Likewise. + + * testsuite/symbols-test: Regexp fixes, to better filter out + get_pc_thunk functions. + + * ecc-generic-redc.c (ecc_generic_redc): Deleted file and + function. Split into... + * ecc-pp1-redc.c (ecc_pp1_redc): New file and function. + * ecc-pm1-redc.c (ecc_pm1_redc): New file and function. + * ecc-internal.h: Updated declarations. + * Makefile.in (hogweed_SOURCES): Replace ecc-generic-redc.c by + ecc-pp1-redc.c and ecc-pm1-redc.c. + * ecc-192.c: Use ecc_pp1_redc (benchmarking only). + * ecc-224.c: Use ecc_pm1_redc when applicable. + * ecc-256.c: Use ecc_pp1_redc when applicable. + * ecc-384.c: Use ecc_pp1_redc (benchmarking only). + * ecc-521.c: Use ecc_pp1_redc (benchmarking only). + * testsuite/ecc-redc-test.c (test_main): Replace use of + ecc_generic_redc by ecc_pp1_redc and ecc_pm1_redc. + + * eccdata.c (output_curve): Don't output ecc_redc_g. + * ecc-internal.h (struct ecc_curve): Deleted unused field redc_g. + Updated all instances. + +2014-08-27 Niels Möller + + * ecc-modq.c (ecc_modq_inv): Use q_bit_size. + + * ecc-internal.h (struct ecc_curve): New field q_bit_size. Updated + all instances. + + * configure.ac: Bumped package version number to 3.1. + (LIBHOGWEED_MAJOR): Bumped library version to 4.0. + + Merged curve25519 changes (starting at 2014-07-04). + * Makefile.in (clean-here): Added ecc-25519.h. + +2014-08-26 Niels Möller + + * examples/ecc-benchmark.c (bench_mul_g, bench_mul_a): Use struct + ecc_curve function pointers. + (bench_mul_g_eh, bench_mul_a_eh): Deleted. + (bench_curve): Make modq benchmark unconditional. Use bench_mul_g + and bench_mul_a also for curve25519. + + * testsuite/ecc-mod-test.c (test_curve): Make modq test + unconditional, partially reverting 2014-07-04 change. + + * ecc-25519.c (ecc_25519_modq): New function. + + * eccdata.c (output_curve): Precomputation for curve25519 mod q. + + * mini-gmp.c (mpz_abs_sub_bit): Do full normalization, needed in + case the most significant bit is cleared. + +2014-08-25 Niels Möller + + * testsuite/ecdh-test.c (set_point): Check return value of + ecc_point_set. + (test_main): Enable curve25519 test. + + * ecc-point-mul-g.c (ecc_point_mul_g): Use ecc->mul_g and + ecc->h_to_a function pointers. + * ecc-point-mul.c (ecc_point_mul): Use the ecc->mul and + ecc->h_to_a function pointers. + + * ecc-internal.h (ecc_mul_g_func, ecc_mul_func, ecc_h_to_a_func): + New typedefs. + (struct ecc_curve): New function pointers mul, mul_g, h_to_a, and + constans for their scratch requirements. Updated all instances. + + * ecc-point.c (ecc_point_set): Handle curve25519 as a special + case, when checking if the point is on the curve. + +2014-08-24 Niels Möller + + * testsuite/ecdh-test.c: Test ecc_point_mul and ecc_point_mul_g, + using test data generated by ecc-ref.gp. Tests for all curves + except curve25519, which doesn't yet work with the general + ecc_point interface. + + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added ecdh-test.c. + + * misc/ecc-ref.gp: Script to generate ECDH test data. + +2014-08-23 Niels Möller + + * ecc-a-to-j.c (ecc_a_to_j): Deleted INITIAL argument. + * ecc.h (ecc_a_to_j): Updated prototype. + * ecc-mul-a.c (ecc_mul_a, table_init): Updated calls to ecc_a_to_j. + + * ecc-mul-a.c (ecc_mul_a): Deleted INITIAL argument, all callers, + except the tests, pass 1. Updated all callers. + (table_init): Likewise deleted INITIAL. + * ecc.h (ecc_mul_a): Updated prototype. + * testsuite/ecc-mul-a-test.c (test_main): Deleted tests for + ecc_mul_a with INITIAL == 0. + + * ecc-internal.h (struct ecc_curve): Reordered struct, moved + function pointers before pointers to bignum constants. + + * sec-modinv.c (sec_modinv): Document that for a == 0 (mod m), we + should produce the "inverse" 0. + + * testsuite/ecc-modinv-test.c (test_main): Check that ecc_modp_inv + produces 0 if a == 0 or a == p. + +2014-08-22 Niels Möller + + * x86_64/ecc-25519-modp.asm: New file. Assembly implementation, + initial version yields 30% speedup of ecc_25519_modp. Early + folding eliminates one pass of carry propagation, and yields + almost 20% additional speedup. + + * ecc-25519.c [HAVE_NATIVE_ecc_25519_modp]: Use assembly version + if available. + + * configure.ac (asm_hogweed_optional_list): Added ecc-25519-modp.asm. + Also add HAVE_NATIVE_ecc_25519_modp to config.h.in. + +2014-08-19 Niels Möller + + * examples/ecc-benchmark.c (bench_curve): Support benchmarking of + curve25519, for now handled as a special case. + (curves): Added nettle_curve25519. + (bench_dup_eh, bench_add_eh, bench_add_ehh, bench_mul_g_eh): New + functions. + +2014-08-18 Niels Möller + + * testsuite/curve25519-dh-test.c (test_a): Use curve25519_mul. + (test_main): Use little-endian inputs for test_a. + (curve25519_sqrt, curve_25519): Deleted static helper functions, + no longer needed. + + * curve25519-mul.c (curve25519_mul): New file and function. + * curve25519.h (curve25519_mul): Declare it. + * Makefile.in (hogweed_SOURCES): Added curve25519-mul.c. + + * curve25519-mul-g.c (curve25519_mul_g): Renamed file and + function, updated callers. + * curve25519-base.c (curve25519_base): ... old names. + * Makefile.in (hogweed_SOURCES): Updated for rename. + + * eccdata.c (output_curve): Compute constants needed for + Shanks-Tonelli. + * ecc-25519.c (ecc_modp_powm_2kp1, ecc_25519_sqrt): New functions. + * ecc-internal.h (ecc_25519_sqrt): Declare it. + +2014-08-06 Niels Möller + + * testsuite/curve25519-dh-test.c (test_g): Use curve25519_base. + (test_main): Use little-endian inputs for test_g. + + * curve25519-base.c (curve25519_base): New file, new function. + Analogous to NaCl's crypto_scalarmult_base. + * curve25519.h: New file. + * Makefile.in (hogweed_SOURCES): Added curve25519-base.c. + (HEADERS): Added curve25519.h. + + * gmp-glue.c (mpn_set_base256_le, mpn_get_base256_le): New functions. + * gmp-glue.h: Declare them. + +2014-08-02 Niels Möller + + * testsuite/curve25519-dh-test.c (curve25519_sqrt): Fixed memory + leak, a mpz_clear call was missing. + + * ecc-internal.h (ECC_MUL_A_EH_WBITS): Set to 4, to enable + window-based scalar multiplication. + + * ecc-mul-a-eh.c (table_init) [ECC_MUL_A_EH_WBITS > 0]: Fixed + initialization of TABLE(1). + +2014-07-29 Niels Möller + + * ecc-internal.h (ECC_MUL_A_EH_WBITS): New constant. + (ECC_A_TO_EH_ITCH, ECC_MUL_A_EH_ITCH): New macros. + * ecc-a-to-eh.c (ecc_a_to_eh, ecc_a_to_eh_itch): New file, new + functions. + * ecc-mul-a-eh.c: New file. + (ecc_mul_a_eh): New function. The case [ECC_MUL_A_EH_WBITS > 0] + not yet working). + (ecc_mul_a_eh_itch): New function. + * ecc.h: Declare new functions. + * Makefile.in (hogweed_SOURCES): Added ecc-a-to-eh.c and + ecc-mul-a-eh.c. + + * testsuite/curve25519-dh-test.c (curve25519_sqrt): New function. + (curve_25519): Use ecc_mul_a_eh. + (test_a): New function. + (test_main): Test construction of shared secret, using scalar + multiplication with points other than the fix generator. + +2014-07-26 Niels Möller + + * ecc-add-ehh.c (ecc_add_ehh): Reduce scratch need. + * ecc-internal.h (ECC_ADD_EHH_ITCH): Reduced to 7*size. + +2014-07-23 Niels Möller + + * testsuite/curve25519-dh-test.c: New test case, based on + draft-josefsson-tls-curve25519-05 test vectors. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added curve25519-dh-test.c. + +2014-07-18 Niels Möller + + * ecc-mul-g-eh.c (ecc_mul_g_eh, ecc_mul_g_eh_itch): New file and + functions. Untested. + * ecc.h (ecc_mul_g_eh_itch): Declare new functions. + * ecc-internal.h (ECC_MUL_G_EH_ITCH): New macro. + * Makefile.in (hogweed_SOURCES): Added ecc-mul-g-eh.c. + +2014-07-17 Niels Möller + + * ecc-add-eh.c (ecc_add_eh): Reduce scratch need. + * ecc-internal.h (ECC_ADD_EH_ITCH): Reduced to 6*size. + + * testsuite/curve25519-dup-test.c (test_main): Free allocated + storage. + +2014-07-15 Niels Möller + + * ecc-add-eh.c (ecc_add_eh, ecc_add_eh_itch): New file, new + functions. + * ecc.h: Declare new functions. + * ecc-internal.h (ECC_ADD_EH_ITCH): New macro. + * Makefile.in (hogweed_SOURCES): Added ecc-add-eh.c. + * testsuite/curve25519-add-test.c (test_main): Test ecc_add_eh. + Additional test for g2+g2. Free allocated storage. + +2014-07-14 Niels Möller + + * testsuite/curve25519-add-test.c: New test case. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + curve25519-add-test.c. + + * ecc-add-ehh.c (ecc_add_ehh, ecc_add_ehh_itch): New file, new + functions. + * ecc.h (ecc_add_ehh, ecc_add_ehh_itch): Declare them. + * ecc-internal.h (ECC_ADD_EHH_ITCH): New macro. + * Makefile.in (hogweed_SOURCES): Added ecc-add-ehh.c. + + * ecc-25519.c (nettle_curve25519): Use ecc_d instead of ecc_b. + + * eccdata.c: For curve25519, output the Edwards curve constant, + ecc_d = (121665/121666) mod p. + + * testsuite/curve25519-dup-test.c (test_main): Add test for 4g. + Delete some left-over debug output. + +2014-07-11 Niels Möller + + * misc/ecc-formulas.tex: Some ECC notes. + + * testsuite/curve25519-dup-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + curve25519-dup-test.c. + + * testsuite/testutils.c (test_ecc_point): Made non-static. + * testsuite/testutils.h (struct ecc_ref_point): Moved here, from + testutils.h. + (test_ecc_point): Declare it. + + * ecc-dup-eh.c (ecc_dup_eh, ecc_dup_eh_itch): New file, new functions. + * ecc-eh-to-a.c (ecc_eh_to_a, ecc_eh_to_a_itch): New file, new + functions. + * ecc.h: Declare new functions. + * ecc-internal.h (ECC_EH_TO_A_ITCH, ECC_DUP_EH_ITCH): New macros. + * Makefile.in (hogweed_SOURCES): Added ecc-dup-eh.c and + ecc-eh-to-a.c. + + * ecc-internal.h (struct ecc_curve): New constant edwards_root. + * ecc-192.c (nettle_secp_192r1): Updated accordingly, additional + NULL pointer. + * ecc-224.c (nettle_secp_224r1): Likewise. + * ecc-256.c (nettle_secp_256r1): Likewise. + * ecc-384.c (nettle_secp_384r1): Likewise. + * ecc-521.c (nettle_secp_521r1): Likewise. + * ecc-25519.c (nettle_curve25519): Initialize new constant. + + * eccdata.c (ecc_curve_init): For curve 25519, use correct + constant for edwards coordinate transform, and output the constant + as ecc_edwards. + +2014-07-06 Niels Möller + + * eccdata.c: Use separate is_zero flag to represent the neutral + element. + (output_point, output_point_redc): Unified to a single function, + with a use_redc flag argument. Also support conversion to Edwards + form. + (ecc_curve_init_str): New argument for Edwards curve conversion + constant. + +2014-07-04 Niels Möller + + Started curve25519 branch. + * ecc-25519.c: New file. + (ecc_25519_modp): New function. + (nettle_curve25519): New curve. + + * ecc-curve.h (nettle_curve25519): Declare it. + + * Makefile.in (hogweed_SOURCES): Added ecc-25519.c. + (ecc-25519.h): New generated file. Add as explicit dependency for + ecc-25519.o. + + * testsuite/ecc-mod-test.c (test_curve): New function, extracted + from test_main. Tolerate NULL modq function pointer. + (test_main): Use test_curve, iterate over supported curves, and + also test curve_25519 for the new modp function. + +2014-08-23 Niels Möller + + * ecc-modp.c (ecc_modp_sub_1): Deleted unused function. + * ecc-internal.h: Deleted corresponding declaration. + + * examples/nettle-benchmark.c (time_cipher): Fixed memset calls, + amending the totally broken change from 2014-02-06. + +2014-07-02 Niels Möller + + * eccdata.c (ecc_dup): Use mpz_submul_ui, now available in + mini-gmp. + (ecc_type): New enum, for Weierstrass and Montgomery curves + (ecc_curve): New field type. + (ecc_dup): Support montgomery curves. + (ecc_add): Likewise. + (ecc_curve_init_str): New argument, for the curve type. + (ecc_curve_init): Pass curve type to all ecc_curve_init_str calls. + Recognize curve25519, for bit_size 255. + (output_modulo): Deleted assert, which isn't true for curve25519. + +2014-06-30 Niels Möller + + * camellia-absorb.c: Include , needed for correct use of + HAVE_NATIVE_64_BIT. Reported and debugged by Magnus Holmgren. + Fixes debian build failure on s390x. + +2014-06-26 Niels Möller + + From Martin Storsjö: + * configure.ac (IF_NOT_SHARED): New substituted variable. + * hogweed.pc.in: Use @LIBS@, instead of hardcoding -lgmp. When + shared libraries are disabled, move needed libraries from + Requires.private: to Requires: and from Libs.private: to Libs:. + + From Nikos Mavrogiannopoulos. + * examples/hogweed-benchmark.c (bench_alg): Tolerate alg->init + returning NULL. + (bench_openssl_ecdsa_init): Return NULL if + EC_KEY_new_by_curve_name fails, indicating the curve is not + supported. + +2014-06-25 Niels Möller + + Support for building with mini-gmp instead of the real GMP. Loosely + based on work by Nikos Mavrogiannopoulos. + * configure.ac: New command line option --enable-mini-gmp. Also + disable all libgmp-related checks when enabled. + (NETTLE_USE_MINI_GMP): New substituted variable. + (LIBHOGWEED_LIBS): Use $(LIBS) instead of -lgmp. + (IF_MINI_GMP): New Makefile conditional. + (GMP_NUMB_BITS): Alternative test for the mini-gmp case. + Substituted also in bignum.h. + (HAVE_MPZ_POWM_SEC): Drop this unused check. + + * bignum.h: Renamed, to... + * bignum.h.in: New name. + (NETTLE_USE_MINI_GMP): Substituted by configure. + (GMP_NUMB_BITS): Substituted by configure, for the mini-gmp case. + + * Makefile.in (OPT_HOGWEED_SOURCES): New variable, value + conditional on @IF_MINI_GMP@. + (hogweed_SOURCES): Add $(OPT_HOGWEED_SOURCES). + (PRE_CPPFLAGS): Add -I$(srcdir). + (HEADERS): Delete bignum.h. + (INSTALL_HEADERS): Add bignum.h. Also add mini-gmp.h, if mini-gmp + is enabled. + (DISTFILES): Added bignum.h.in. + (bignum.h): New target. + (distclean-here): Delete bignum.h. + + * examples/ecc-benchmark.c (modinv_gcd) [NETTLE_USE_MINI_GMP]: + Disable this benchmark. + (mpn_random) [NETTLE_USE_MINI_GMP]: Provide a simple implementation. + + * testsuite/ecc-mod-test.c [NETTLE_USE_MINI_GMP]: Skip test, it + depends on gmp_randstate_t. + * testsuite/ecc-modinv-test.c [NETTLE_USE_MINI_GMP]: Likewise. + * testsuite/ecc-mul-a-test.c [NETTLE_USE_MINI_GMP]: Likewise. + * testsuite/ecc-mul-g-test.c [NETTLE_USE_MINI_GMP]: Likewise. + * testsuite/ecc-redc-test.c [NETTLE_USE_MINI_GMP]: Likewise. + + Various preparations for mini-gmp support. + * testsuite/bignum-test.c: Use WITH_HOGWEED instead of HAVE_LIBGMP + for preprocessor conditionals. + * testsuite/testutils.h: Likewise. + * testsuite/sexp-format-test.c: Likewise. + + * testsuite/ecdsa-keygen-test.c (test_main): Use printf, + mpz_out_str and write_mpn instead of gmp_fprintf. + * testsuite/ecdsa-sign-test.c (test_ecdsa): Likewise. + * testsuite/ecdsa-verify-test.c (test_ecdsa): Likewise. + + * dsa.h: Include bignum.h instead of gmp.h. + * ecc-internal.h: Likewise. + * ecc.h: Likewise. + * gmp-glue.h: Likewise. + * pkcs1.h: Likewise. + * rsa.h: Likewise. + + * testsuite/testutils.c (die): Use plain vfprintf, not + gmp_vfprintf. + (write_mpn): New function. + (test_ecc_point): Use it, replacing gmp_fprintf. + * testsuite/testutils.h (write_mpn): Declare it. + + * der-iterator.c: Deleted HAVE_LIBGMP conditionals. + +2014-06-07 Niels Möller + + * Released nettle-3.0. + +2014-06-04 Niels Möller + + * NEWS: List des-compat.h as a candidate for removal in the next + release. + + * testsuite/des-compat-test.c (test_main): Fixed out of bounds + memory read, reported by Nikos Mavrogiannopoulos. + + * nettle-write.h: Include , fixing compilation on + freebsd. + + * aclocal.m4 (ac_stdint): Fixed "unsinged" typo, spotted by Andy + Goth. + +2014-06-01 Niels Möller + + * x86_64/gcm-hash8.asm: Pass correct argument count to W64_EXIT. + * x86_64/camellia-crypt-internal.asm: Pass correct argument count + to W64_ENTRY and W64_EXIT. + + * x86_64/machine.m4 [W64_ABI]: Fix for the case of 6 function + arguments. Also push %rdi unconditionally, and use aligned + accesses for save and restore %xmm registers (movdqa). + +2014-05-31 Niels Möller + + * configure.ac: Check for COFF type directives. + (ASM_COFF_STYLE): New substituted variable. + * config.m4.in: Set COFF_STYLE from configure. + * asm.m4 (PROLOGUE): Use COFF type directive, if enabled by + configure. Fixes problem with windows dll linking. + + * asm.m4: Deleted unused offsets for struct aes_ctx. + +2014-05-28 Niels Möller + + * testsuite/nettle-pbkdf2-test: Delete carriage return characters + from output. + + * configure.ac (LIBHOGWEED_LIBS): Be explicit and link + libhogweed.so with libnettle.so, not -lnettle. + (LIBHOGWEED_LINK): Drop -L. flag, no longer needed, and previously + not at the correct position in the link command line. + +2014-05-27 Niels Möller + + * examples/ecc-benchmark.c: If mpn_sec_powm is available, + benchmark it, for modinv. + (bench_modinv_powm): New function. + (bench_curve): Use it. + +2014-05-22 Niels Möller + + From Claudio Bley: + * Makefile.in ($(des_headers)): Use the EXEEXT_FOR_BUILD. + +2014-05-15 Niels Möller + + * NEWS: Updated with library version numbers. + + * configure.ac (dummy-dep-files): Use simpler and more portable + sed expression. Problem reported by Peter Eriksson. + (LIBHOGWEED_MAJOR): Bumped shared library version to 3.0. + (LIBHOGWEED_MINOR): Reset to zero. Also increased the package + version number to 3.0. + + * getopt.c: Don't use gettext. + +2014-05-14 Niels Möller + + * testsuite/nettle-pbkdf2-test: Avoid the bash construction + ${#foo}. + + * getopt.c: Copied from glibc tree, tag glibc-2.19. + * getopt.h: Likewise. + * getopt1.c: Likewise. + * getopt_int.h: New file, also copied from glibc. + * Makefile.in (DISTFILES): Added getopt_int.h. + +2014-05-09 Niels Möller + + * mini-gmp.c: Updated, use version from gmp-6.0.0. + * mini-gmp.h: Likewise. + + * testsuite/Makefile.in (all): Drop dependency on $(TARGETS), to + delay building of test programs until make check. + +2014-05-08 Niels Möller + + * nettle.texinfo (nettle_aead abstraction): Document nettle_aead. + + * Makefile.in (nettle_SOURCES): Added nettle-meta-aeads.c. + * nettle-meta.h (nettle_aeads): Declare array. + * nettle-meta-aeads.c (nettle_aeads): New file, new array. + * testsuite/meta-aead-test.c: New test case. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + meta-aead-test.c. + + * aclocal.m4 (GMP_PROG_CC_FOR_BUILD): If CC_FOR_BUILD is gcc, add + -O option. This makes eccdata twice as fast. + +2014-05-06 Niels Möller + + * nettle.texinfo: Document SHA3 and ChaCha-Poly1305 as + experimental. + +2014-05-05 Niels Möller + + * nettle.texinfo (POLY1305): Document poly1305-aes. + (Authenticated encryption): Move AEAD algorithms to their own + section. + (RSA, DSA, ECDSA): Change some subsections to subsubsections. + (ChaCha-Poly1305): Document ChaCha-Poly1305. + +2014-05-04 Niels Möller + + * nettle.texinfo (DSA): Document new DSA interface. + (Salsa20): Update salsa20 docs. + (ChaCha): Document ChaCha. + +2014-05-03 Niels Möller + + * configure.ac: Check for SIZEOF_SIZE_T. + * ccm.c (ccm_set_nonce): Skip code for 64-bit encoding when size_t + is only 32 bits. + + * nettle.texinfo (CCM): Document new ccm macros and constants. + Describe ccm restrictions. + + * ccm.h (CCM_DIGEST_SIZE): New constant. + +2014-04-30 Niels Möller + + * ccm.c (CCM_IV_MAX_SIZE, CCM_IV_MIN_SIZE): Deleted, replaced by + public constants CCM_MIN_NONCE_SIZE and CCM_MAX_NONCE_SIZE. + (ccm_build_iv): Updated for above rename. + (CCM_L_MAX_SIZE): Deleted, no longer used. + + * ccm.h (CCM_MIN_NONCE_SIZE, CCM_MAX_NONCE_SIZE): New constants. + (CCM_MAX_MSG_SIZE): New macro. + +2014-04-27 Niels Möller + + * nettle.texinfo (Cipher modes): Subsection on AEAD constructions. + (GCM): Update GCM documentation, including functions for + gcm_aes128, gcm_camellia128, ... + +2014-04-26 Niels Möller + + * nettle.texinfo: Update for introduction of nettle_cipher_func. + (GCM): Document GCM_DIGEST_SIZE. + (UMAC): Document new UMAC constants. + (Keyed hash functions): Make HMAC and UMAC their own info nodes. + (EAX): Document EAX. + + * umac.h (UMAC_MIN_NONCE_SIZE, UMAC_MAX_NONCE_SIZE): New + constants. + +2014-04-25 Niels Möller + + * All hash-related files: Renamed all _DATA_SIZE constants to + _BLOCK_SIZE, for consistency. Old names kept for backwards + compatibility. + + * nettle.texinfo (CCM): Documentation for CCM mode, contributed by + Owen Kirby. + + * testsuite/ccm-test.c (test_cipher_ccm): And tests. + + * ccm.c (ccm_decrypt_message): Change length argument, should now + be clear text (dst) length. + * ccm-aes128.c (ccm_aes128_decrypt_message): Likewise. + * ccm-aes192.c (ccm_aes192_decrypt_message): Likewise. + * ccm-aes256.c (ccm_aes256_decrypt_message): Likewise. + * ccm.h: Updated prototypes. + +2014-04-22 Niels Möller + + * nettle.texinfo (Recommended hash functions): Document additional + sha512 variants. + + * sha2.h (sha512_224_ctx, sha512_256_ctx): New aliases for the + sha512_ctx struct tag. + +2014-04-17 Niels Möller + + * examples/Makefile.in (SOURCES): Deleted next-prime.c (forgotten + in 2014-04-13 change). + +2014-04-16 Niels Möller + + * testsuite/ccm-test.c (test_cipher_ccm): Deleted check for NULL + authdata. + + * sha3-224.c (sha3_224_init): Pass pointer to context struct, not + pointer to first element, to memset. + * sha3-256.c (sha3_256_init): Likewise. + * sha3-384.c (sha3_384_init): Likewise. + * sha3-512.c (sha3_512_init): Likewise. + + * examples/eratosthenes.c (vector_alloc): Use sizeof(*vector) + instead of explicit type in malloc call. + (vector_init): Make constant explicitly unsigned long. + + * tools/input.c (sexp_get_quoted_char): Deleted useless for loop. + +2014-04-13 Niels Möller + + * rsa-compat.c: Deleted file. + * rsa-compat.h: Deleted file. + * Makefile.in (hogweed_SOURCES): Deleted rsa-compat.c. + (HEADERS): Deleted rsa-compat.h. + + * examples/next-prime.c: Deleted file. + * bignum-next-prime.c (nettle_next_prime): Deleted file and + function. + * prime-list.h: Deleted file. + * bignum.h (nettle_next_prime): Deleted prototype. + * Makefile.in (hogweed_SOURCES): Deleted bignum-next-prime.c. + (DISTFILES): Deleted prime-list.h. + * examples/Makefile.in (HOGWEED_TARGETS): Deleted next-prime, and + corresponding make target. + +2014-04-12 Niels Möller + + * nettle.texinfo (Copyright): Updated licensing info. + * README: Likewise. + + * Makefile.in (DISTFILES): Distribute new COPYING* files. + + * COPYING.LESSERv3: New file. + * COPYINGv3: New file. + * COPYING.LIB: Deleted. + * COPYINGv2: New name for GPL version 2 file. + * COPYING: Old name, deleted. + + * Update license headers for LGPL3+ and GPL2+ dual licensing. + +2014-04-11 Niels Möller + + * testsuite/testutils.c (test_aead): Use aead->digest_size. + + * configure.ac: Skip GMP tests if public key support is disabled. + + * eax.c (block16_xor): Fixed bug effecting 32-bit platforms. + + * Makefile.in (DISTFILES): Deleted memxor.c, already included via + nettle_SOURCES. + * tools/Makefile.in (SOURCES): Add nettle-pbkdf2.c. + +2014-04-10 Niels Möller + + From Nikos Mavrogiannopoulos: + * examples/hogweed-benchmark.c (bench_openssl_ecdsa_init): Support + for secp192r1 and secp256r1. + (alg_list): Add them. + +2014-04-09 Niels Möller + + * examples/nettle-benchmark.c (main): Benchmark sha512_224 and + sha512_256. + + * testsuite/sha512-224-test.c: New file. + * testsuite/sha512-256-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added new files. + + * nettle-meta.h (nettle_sha512_224, nettle_sha512_256): Declare. + * sha512-224-meta.c (nettle_sha512_224): New file, new nettle_hash. + * sha512-256-meta.c (nettle_sha512_256): New file, new nettle_hash. + + * sha2.h (SHA512_224_DIGEST_SIZE, SHA512_224_DATA_SIZE) + (SHA512_256_DIGEST_SIZE, SHA512_256_DATA_SIZE): New constants. + + * sha512.c (sha512_256_digest): Typo fix, call sha512_256_init. + + * testsuite/testutils.c (test_hash): Removed redundant init call. + Tests that digest implies init. + +2014-03-28 Niels Möller + + * testsuite/dsa-keygen-test.c (test_main): Explicitly use + dsa_compat_generate_keypair. + (test_main): Test dsa_generate_params and dsa_generate_keypair + with a large q; p_bits = 1024, q_bits = 768. + + * testsuite/testutils.h: Undo dsa-compat.h name mangling. + + * dsa-keygen.c (dsa_generate_keypair): New interface, generating + only a keypair, and no new parameters. + * dsa-compat-keygen.c (dsa_compat_generate_keypair): New file. + Moved old key generation function here. Use dsa_generate_keypair. + +2014-03-27 Niels Möller + + * dsa-compat.c (dsa_public_key_init, dsa_public_key_clear) + (dsa_private_key_init, dsa_private_key_clear): : Move deprecated + DSA functions to a separate file... + * dsa.c: ...from here. + * dsa-compat.h: New file, declaring deprecated DSA interface. + Include in corresponding C files. + * Makefile.in (hogweed_SOURCES): Add dsa-compat.c. + (HEADERS): Add dsa-compat.h. + + * dsa-gen-params.c (dsa_generate_params): New file and function, + extracted from DSA key generation. + * dsa-keygen.c (dsa_generate_keypair): Use dsa_generate_params. + +2014-03-26 Niels Möller + + * der2dsa.c (dsa_params_from_der_iterator): Converted to new DSA + interface. Allow q_size == 0, meaning any q < p is allowed. + Additional validity checks. + (dsa_public_key_from_der_iterator): Converted to new DSA + interface. Also check that the public value is in the correct + range. + (dsa_openssl_private_key_from_der_iterator): Converted + to new DSA interface. Additional validity checks. + (dsa_openssl_private_key_from_der): Converted to new DSA + interface. + * tools/pkcs1-conv.c (convert_dsa_private_key): Update to use + struct dsa_params, and adapt to the der decoding changes. + (convert_public_key): Likewise. + + * examples/hogweed-benchmark.c: Update dsa benchmarking to use new + DSA interface. + + * dsa.c (dsa_params_init, dsa_params_clear): New functions. + (dsa_public_key_init): Use dsa_params_init. + (dsa_public_key_clear): Use dsa_params_clear. + + * sexp2dsa.c (dsa_keypair_from_sexp_alist): Converted to new DSA + interface. Allow q_size == 0, meaning any q < p is allowed. + Additional validity checks. + (dsa_sha1_keypair_from_sexp, dsa_sha256_keypair_from_sexp): + Converted to new DSA interface. + + * dsa2sexp.c (dsa_keypair_to_sexp): Converted to new DSA + interface. + * tools/pkcs1-conv.c: Updated uses of dsa_keypair_to_sexp. + + * dsa.h (struct dsa_params): New struct. + + * dsa-sign.c (dsa_sign): Use struct dsa_params, with key as a + separate mpz_t. + * dsa-verify.c (dsa_verify): Likewise. + * dsa-sha1-verify.c (dsa_sha1_verify_digest, dsa_sha1_verify): Use + dsa_verify, cast the struct dsa_public_key * input to a struct + dsa_params * + * dsa-sha256-verify.c (dsa_sha256_verify_digest) + (dsa_sha256_verify): Likewise. + * dsa-sha1-sign.c (dsa_sha1_sign_digest, dsa_sha1_sign): Likewise + use dsa_sign, with a cast from struct dsa_public_key * to struct + dsa_params *. + * dsa-sha256-sign.c (dsa_sha256_sign_digest, dsa_sha256_sign): + Likewise. + + * testsuite/testutils.c (test_dsa_verify): Use struct dsa_params. + (test_dsa_key): Likewise. + * testsuite/dsa-test.c (test_main): Adapt to test_dsa_key and + test_dsa_verify changes. + * testsuite/dsa-keygen-test.c (test_main): Adapt to + test_dsa_key change. + + * testsuite/testutils.c (test_dsa_sign): #if out, currently + unused. + +2014-03-23 Niels Möller + + From Owen Kirby: + * ccm.c: New file. + * ccm.h: New file. + * ccm-aes128.c: New file. + * ccm-aes192.c: New file. + * ccm-aes256.c: New file. + * Makefile.in (nettle_SOURCES): Added ccm source files. + (HEADERS): Added ccm.h. + * testsuite/ccm-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added ccm-test.c. + +2014-03-20 Niels Möller + + From Joachim Strömbergson: + * sha512.c (K): Indentation fix. + (sha512_224_init, sha512_224_digest, sha512_256_init) + (sha512_256_digest): New functions. + * sha2.h: Add prototypes. + (sha512_224_update, sha512_256_update): New aliases for + sha512_update. + +2014-03-18 Niels Möller + + * examples/nettle-benchmark.c (main): Add benchmarking of arcfour, + salsa20 and chacha, via time_aead. + + * nettle-internal.c (nettle_arcfour128): Define, as a struct + nettle_aead (with NULL set_nonce, update, and digest methods). + * examples/nettle-openssl.c (nettle_openssl_arcfour128): Likewise. + * nettle-internal.h (nettle_arcfour128) + (nettle_openssl_arcfour128): Declare. + + * nettle-types.h (nettle_cipher_func): New typedef, similar to + nettle_crypt_func, but with a const context, intended for block + ciphers. + * nettle-meta.h (struct nettle_cipher): Use the nettle_cipher_func + type. + * Many other files affected: aes*-meta.c, camellia*-meta.c, + cast128-meta.c, serpent-meta.c, twofish-meta.c, cbc.[ch], + ctr.[ch], ctr.[ch], des-compat.c, eax.[ch], gcm*.[ch], + nettle-internal.*, testsuite/aes-test.c, + examples/nettle-benchmark.c, examples/nettle-openssl.c. + +2014-03-16 Niels Möller + + * chacha-set-key.c: Include string.h. + + * arcfour-meta.c: Deleted file. + * nettle-meta.h (nettle_arcfour128): Deleted declaration. + * nettle-meta-ciphers.c (nettle_ciphers): Deleted + nettle_arcfour128 from list. + * Makefile.in (nettle_SOURCES): Deleted arcfour-meta.c. + * examples/nettle-openssl.c (nettle_openssl_arcfour128): Deleted. + * testsuite/meta-cipher-test.c: Adjust test for removal of + nettle_arcfour128. + +2014-03-15 Niels Möller + + * examples/nettle-benchmark.c (struct bench_aead_info): New + struct. + (bench_aead_crypt, bench_aead_update, init_nonce, time_aead): New + functions, for benchmarking aead algorithms. + (time_gcm, time_eax): Deleted functions. + (main): Use time_aead to benchmark gcm, eax and chacha-poly1305. + + * salsa20.h (SALSA20_NONCE_SIZE): Renamed constant, old name + SALSA20_IV_SIZE kept as an alias. + (salsa20_set_nonce): Update prototype for the 2014-01-20 rename. + + * Makefile.in (.asm.s): Add dependencies. + (.s.o, .s.po): Empty any dependency .d file. + +2014-03-04 Niels Möller + + * testsuite/chacha-test.c (test_main): Additional test cases, for + 256-bit keys. + + * Makefile.in (nettle_SOURCES): Deleted chacha128-set-key.c and + chacha256-set-key.c. + + * chacha.h (CHACHA256_KEY_SIZE): Deleted. + (chacha_set_key): Updated prototype. + * chacha256-set-key.c (chacha256_set_key): Deleted file and + function, moved to... + * chacha-set-key.c (chacha_set_key): Do 256-bit keys only. Deleted + length argument. Updated all callers. + + * chacha128-set-key.c (chacha128_set_key): Deleted file and + function. Support for 128-bit chacha keys may be reintroduced + later, if really needed. + * chacha.h: Deleted chacha128-related declarations. + * chacha-set-key.c (chacha_set_key): Drop support for 128-bit + keys. + * testsuite/chacha-test.c (test_main): #if:ed out all tests with + 128-bit keys. + +2014-02-16 Niels Möller + + * gcm.h: Declarations for gcm-camellia256. + * gcm-camellia256.c: New file. + * gcm-camellia256-meta.c: New file. + * nettle-meta.h (nettle_gcm_camellia256): Declare. + * Makefile.in (nettle_SOURCES): Added gcm-camellia256.c and + gcm-camellia256-meta.c. + * testsuite/gcm-test.c (test_main): Test cases for + nettle_gcm_camellia256. + + * gcm.h: Include camellia.h. Declarations for gcm-camellia128. + * gcm-camellia128.c: New file. + * gcm-camellia128-meta.c: New file. + * nettle-meta.h (nettle_gcm_camellia128): Declare. + * Makefile.in (nettle_SOURCES): Added gcm-camellia128.c and + gcm-camellia128-meta.c. + * testsuite/gcm-test.c (test_main): Test cases for + nettle_gcm_camellia128. From Nikos Mavrogiannopoulos. + +2014-02-13 Niels Möller + + * Makefile.in (nettle_SOURCES): Added eax-aes128.c + eax-aes128-meta.c. + * examples/nettle-benchmark.c: Include eax.h. + * nettle-meta.h (nettle_eax_aes128): Declare, moved from + nettle-internal.h. + * eax.h: Declare eax_aes128_ctx and related functions. Moved from + nettle-internal.h + (EAX_IV_SIZE): New constant. + * eax-aes128-meta.c (nettle_eax_aes128): Moved definition to new + file. + * eax-aes128.c (eax_aes128_set_key, eax_aes128_set_nonce) + (eax_aes128_update, eax_aes128_encrypt, eax_aes128_decrypt) + (eax_aes128_digest): Moved functions to a new file. + * nettle-internal.c: ... from old location. + * nettle-internal.h: Moved eax declarations elsewhere. + + * tools/nettle-pbkdf2.c (main): Added missing deallocation. + +2014-02-12 Niels Möller + + * chacha-poly1305.h: New file. + * chacha-poly1305.c: New file. + * chacha-poly1305-meta.c (nettle_chacha_poly1305): New file, new + aead algorithm. + * nettle-meta.h (nettle_chacha_poly1305): Declare. + + * Makefile.in (nettle_SOURCES): Added chacha-poly1305.c and + chacha-poly1305-meta.c. + (HEADERS): Added chacha-poly1305.h. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + chacha-poly1305-test.c. + * testsuite/chacha-poly1305-test.c: New file. + + * nettle-meta.h (struct nettle_aead): New generalized version + if this struct. + (nettle_gcm_aes128, nettle_gcm_aes192, nettle_gcm_aes256) + (nettle_eax_aes128): Declare, moved from nettle-internal.h. + * nettle-internal.h (struct nettle_aead): Deleted struct, moved to + nettle-meta.h. Deleted declarations of unused instances. + (_NETTLE_AEAD): Deleted macro. + * nettle-internal.c (nettle_eax_aes128): Updated for new + nettle_aead struct. + (nettle_gcm_aes128, nettle_gcm_aes192, nettle_gcm_aes256): + Deleted, moved to new files. + * gcm-aes128-meta.c (nettle_gcm_aes128): Moved to new file, + updated for new nettle_aead struct. + * gcm-aes192-meta.c (nettle_gcm_aes192): Likewise. + * gcm-aes256-meta.c (nettle_gcm_aes256): Likewise. + * testsuite/testutils.c (test_aead): Take alternative set_nonce + function as argument, and use it when nonce size differs from + aead->nonce_length. + * testsuite/testutils.h (test_aead): Updated prototype. + * testsuite/gcm-test.c (nettle_gcm_unified_aes128): Updated for + new nettle_aead struct. + (test_main): Pass additional argument to test_aead. + * testsuite/eax-test.c (test_main): Pass additional NULL argument + to test_aead. + + * eax.h (EAX_DIGEST_SIZE): New constant. + * gcm.h (GCM_DIGEST_SIZE): Likewise. + +2014-02-10 Niels Möller + + * chacha-set-nonce.c (chacha_set_nonce): Renamed file and + function, updated callers and Makefile.in. + * chacha-set-iv.c (chacha_set_iv): ... from old names. + +2014-02-08 Niels Möller + + * testsuite/chacha-test.c (test_chacha): For 20 rounds, use + chacha_crypt, and test varying the message length. + (test_main): Add second key stream block, for all testcases with + 20 rounds. + + * chacha-crypt.c (chacha_crypt): Fixed block counter update. + +2014-02-07 Niels Möller + + * nettle.texinfo (ASCII encoding): Document that + base16_encode_update and base64_encode_update now uses dst_length + as an output only. + + * testsuite/base64-test.c (test_main): Updated + base64_decode_update test case. + + * sexp-transport.c (sexp_transport_iterator_first): For + base64_decode_update, omit initialization of coded_length. + * examples/base64dec.c (main): Likewise. + * examples/base16dec.c (main): Likewise, for base16_decode_update. + + * base64-decode.c (base64_decode_update): Use *dst_length for + output only. Don't require callers to pass a sane value. + * base16-decode.c (base16_decode_update): Likewise. + +2014-02-06 Niels Möller + + * NEWS: List _set_key incompatibilities. + + * nettle-meta.h (_NETTLE_CIPHER_SEP, _NETTLE_CIPHER_SEP_SET_KEY) + (_NETTLE_CIPHER_FIX, _NETTLE_CIPHER): Deleted unused macros. + + * nettle-internal.c (nettle_blowfish128): Deleted only use of + _NETTLE_CIPHER. + + * blowfish.c (blowfish128_set_key): New function. + * blowfish.h (BLOWFISH128_KEY_SIZE): New constant. + + * cast128-meta.c (nettle_cast128): Deleted only use of + _NETTLE_CIPHER_FIX. + + * examples/nettle-benchmark.c (time_cipher): Fixed memset calls. + +2014-01-30 Niels Möller + + * Makefile.in (nettle_SOURCES): Arrange in alphabetic order. + + * nettle.texinfo: Updated, document size_t for length arguments. + Document new AES and Camellia interfaces. + + * ecc-size.c (ecc_bit_size): New function. + * ecc.h (ecc_bit_size): Declare it. + +2014-01-29 Niels Möller + + * nettle-types.h (typedef nettle_set_key_func): Deleted length + argument. + + * arctwo.c (arctwo40_set_key, arctwo64_set_key) + (arctwo128_set_key, arctwo128_set_key_gutmann): New functions. + * arctwo.h: Declare them. + * arctwo-meta.c (ARCTWO): New macro. + (nettle_arctwo40, nettle_arctwo64, nettle_arctwo128) + (nettle_arctwo_gutmann128): Use new _set_key functions. + + * arcfour.h (ARCFOUR128_KEY_SIZE): New constant. + * arcfour.c (arcfour128_set_key): New function. + * arcfour-meta.c (nettle_arcfour128): Use arcfour128_set_key and + ARCFOUR128_KEY_SIZE. + + * cast128.c (cast5_set_key): Renamed, was cast128_set_key. + (cast128_set_key): New definition, with fixed key size. + * cast128.h (CAST128_MIN_KEY_SIZE, CAST128_MAX_KEY_SIZE): Renamed + constants, to... + (CAST5_MIN_KEY_SIZE, CAST5_MAX_KEY_SIZE): ... new names. + + * eax.h (EAX_SET_KEY): Deleted length argument. + + * aes128-meta.c: Deleted _set_key wrappers. + * aes192-meta.c: Likewise. + * aes256-meta.c: Likewise. + * camellia128-meta.c: Likewise. + * camellia192-meta.c: Likewise. + * camellia256-meta.c: Likewise. + + * gcm-aes128.c (gcm_aes128_set_key): Deleted length argument. + * gcm-aes192.c (gcm_aes192_set_key): Likewise. + * gcm-aes256.c (gcm_aes256_set_key): Likewise. + * gcm.h: Updated prototypes. + + * serpent-set-key.c (serpent128_set_key, serpent192_set_key) + (serpent256_set_key): New functions. + * serpent.h: Declare new functions. + (SERPENT128_KEY_SIZE, SERPENT192_KEY_SIZE) + (SERPENT256_KEY_SIZE): New constants. + * serpent-meta.c (SERPENT): New macro. + (nettle_serpent128, nettle_serpent192, nettle_serpent256): Use new + _set_key functions. + + * twofish-set-key.c (twofish128_set_key, twofish192_set_key) + (twofish256_set_key): New functions. + * twofish.h: Declare new functions. + (TWOFISH128_KEY_SIZE, TWOFISH192_KEY_SIZE) + (TWOFISH256_KEY_SIZE): New constants. + * twofish-meta.c (TWOFISH): New macro. + (nettle_twofish128, nettle_twofish192, nettle_twofish256): Use new + _set_key functions. + + * nettle-internal.h (struct nettle_aead): Use + nettle_hash_update_func for the set_iv function pointer. + + * nettle-internal.c (des_set_key_hack, des3_set_key_hack): Deleted + wrapper functions. + (chacha_set_key_hack): Deleted length argument. Use + chacha256_set_key. + (salsa20_set_key_hack): Deleted length argument. Use + salsa20_256_set_key. + (nettle_unified_aes128, nettle_unified_aes192) + (nettle_unified_aes256): Deleted, moved to test program. + (eax_aes128_set_key): Deleted length argument. Use EAX_SET_KEY. + + * examples/nettle-benchmark.c: Updated for _set_key changes. + * examples/nettle-openssl.c: Likewise. + * testsuite/testutils.c: Likewise. + * testsuite/gcm-test.c: Likewise. + + * testsuite/aes-test.c (UNIFIED_AES): New macro. Moved glue for + testing the old aes interface (struct aes_ctx) here. + + * testsuite/arcfour-test.c (test_arcfour): New function, for key + sizes != 128 bits. + (test_main): Use it. + + * testsuite/blowfish-test.c (test_blowfish): New function. + (test_main): Use it. Also deleted old #if:ed out code. + + * testsuite/cast128-test.c (test_cast5): New function. + (test_main): Use it, for 40-bit and 80-bit tests. + + * testsuite/serpent-test.c (test_serpent): New function. + (test_main): Use it. + +2014-01-27 Niels Möller + + * eax.h (struct eax_key, struct eax_ctx): Use union + nettle_block16, for alignment. + * eax.c: Updated everything to use nettle_block16. + (block16_xor): New function. + + * examples/nettle-benchmark.c (time_eax): New function. + (main): Use it. + + * x86_64/chacha-core-internal.asm: Use pshufhw + pshuflw for the + 16-bit rotate. + + * configure.ac (asm_replace_list): Added chacha-core-internal.asm. + * x86_64/chacha-core-internal.asm: New file. + + * examples/nettle-benchmark.c (main): Add benchmarking of chacha. + * nettle-internal.c (nettle_chacha): New const struct, for the + benchmark. + + Chacha implementation, based on contribution by Joachim + Strömbergson. + * chacha.h: New file. + * chacha256-set-key.c (chacha256_set_key): New file and function. + * chacha128-set-key.c (chacha128_set_key): New file and function. + * chacha-set-key.c (chacha_set_key): New file and function. + * chacha-set-iv.c (chacha_set_iv): New file and function. + * chacha-core-internal.c (_chacha_core): New file and function. + * chacha-crypt.c (chacha_crypt): New file and function. + * Makefile.in (nettle_SOURCES): Added chacha files. + (HEADERS): Added chacha.h. + * testsuite/chacha-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added chacha-test.c. + +2014-01-26 Niels Möller + + * nettle-internal.h (_NETTLE_AEAD_FIX): Renamed to... + (_NETTLE_AEAD): ... new name, and deleted old definition. Also use + _set_nonce instead of _set_iv. + * nettle-internal.c (nettle_gcm_aes128, nettle_gcm_aes192) + (nettle_gcm_aes256): Define in terms of new interface. + (nettle_eax_aes128): Updated for _NETTLE_AEAD changes. + + * testsuite/gcm-test.c (test_gcm_hash): Likewise use struct + gcm_aes128_ctx. + (test_main): Added a testcase using the old interface based on + struct gcm_aes_ctx. + + * examples/nettle-benchmark.c (time_gcm): Update to use new struct + gcm_aes128_ctx. Also use name "gcm-aes128" in output. + + * gcm.h: New interface for gcm_aes128, gcm_aes192, gcm_aes256, + using the new AES interface. + (GCM_CTX): Reorder fields, putting the cipher context + last. + + * Makefile.in (nettle_SOURCES): Added gcm-aes128.c, gcm-aes192.c, + and gcm-aes256.c. + + * gcm-aes128.c: New file. + * gcm-aes192.c: New file + * gcm-aes256.c: New file. + +2014-01-25 Niels Möller + + * gcm.h (GCM_SET_KEY): Deleted length argument. + * gcm-aes.c (gcm_aes_set_key): Use aes_set_encrypt_key and + gcm_set_key, can no longer use GCM_SET_KEY macro. + +2014-01-23 Niels Möller + + * testsuite/gcm-test.c (test_main): Use the correct + nettle_gcm_aes128/192/256 object. + +2014-01-21 Niels Möller + + Merged camellia-reorg changes (starting at 2013-10-07). + +2013-10-10 Niels Möller + + * Makefile.in (nettle_SOURCES): Updated list of camellia files. + + * testsuite/camellia-test.c (test_invert): Updated for new + camellia interface. + + * camellia.h: Reorganized camellia interface, with distinct + context structs and functions for camellia128 and camellia256. + + * camellia-meta.c: Deleted file. + * camellia256-meta.c: New file. + * camellia192-meta.c: New file. + * camellia128-meta.c: New file. + + * camellia-set-decrypt-key.c: Deleted file, code moved to: + * camellia128-set-decrypt-key.c: New file. + (camellia128_invert_key, camellia128_set_decrypt_key): New + functions. + * camellia256-set-decrypt-key.c: New file. + (camellia256_invert_key, camellia256_set_decrypt_key) + (camellia192_set_decrypt_key): New functions. + * camellia-invert-key.c (_camellia_invert_key): New file and + function. + + * camellia-set-encrypt-key.c: Deleted file, code moved to: + * camellia128-set-encrypt-key.c: New file. + (camellia128_set_encrypt_key): New function. + * camellia256-set-encrypt-key.c: New file. + (_camellia256_set_encrypt_key, camellia256_set_encrypt_key) + (camellia192_set_encrypt_key): New functions. + * camellia-absorb.c (_camellia_absorb): New file and function. + * camellia-internal.h: Moved key schedule macros here. + + * camellia-crypt.c: Deleted file, code moved to: + * camellia128-crypt.c (camellia128_crypt): New file and function. + * camellia256-crypt.c (camellia256_crypt): New file and function. + +2013-10-07 Niels Möller + + * configure.ac: Delete check for ALIGNOF_UINT64_T, no longer + needed. + * config.m4.in: Likewise delete ALIGNOF_UINT64_T. + + * camellia-crypt.c (camellia_crypt): Updated call to + _camellia_crypt. + * camellia-internal.h (_camellia_crypt): Updated prototype. + * camellia-crypt-internal.c (_camellia_crypt): Take separate + arguments for rounds and subkey array. + * x86_64/camellia-crypt-internal.asm: Likewise. Also corrected + .file pseudo-ops. + * x86/camellia-crypt-internal.asm: Likewise. + +2014-01-20 Niels Möller + + * poly1305-internal.c (poly1305_digest): Use union nettle_block16 + for s argument. + * poly1305-aes.c (poly1305_aes_digest): Update for poly1305_digest + change. + + Merged poly1305 changes (starting at 2013-11-08). + * x86_64/poly1305-internal.asm: Update to new interface. + poly1305_digest much simplified. + + * poly1305.h (struct poly1305_ctx): Moved block and index + fields... + (struct poly1305_aes_ctx): ... to here. + * asm.m4: Delete also from the assembly definition of struct + poly1305_ctx. + + * poly1305-internal.c (poly1305_digest): Don't do final padding + here, leave that to caller. Add digest to the provided nonce s, + and deleted length and dst arguments. Also reset h0-h4 to zero + when done. + (_poly1305_block): Renamed, from... + (poly1305_block): ...old name. + + * poly1305-aes.c (poly1305_aes_update): New function. + (poly1305_aes_digest): Update for poly1305_digest changes, do + final padding here. + + * poly1305.c (poly1305_update): Deleted file and function. Moved + to poly1305-aes.c. + * Makefile.in (nettle_SOURCES): Deleted poly1305.c. + +2014-01-17 Niels Möller + + * poly1305-internal.c (poly1305_block): Additional argument with + the high bit. + (poly1305_block_internal): Deleted function, code moved into the + poly1305_block. + (poly1305_digest): Simplified padding code, call poly1305_block + with high bit 0. + * poly1305.h (poly1305_block): Update prototype. + * poly1305.c (poly1305_update): Call poly1305_block with high bit 1. + * x86_64/poly1305-internal.asm (poly1305_block): Handle new + argument. + + * poly1305.h (struct poly1305_ctx): Moved nonce field from here... + (struct poly1305_aes_ctx): ... to here. + * poly1305-aes.c (poly1305_aes_set_nonce, poly1305_aes_digest): + Updated for above. + * poly1305.c (poly1305_set_nonce): Deleted function. + * asm.m4: Delete nonce also from the assembly definition of struct + poly1305_ctx. + +2014-01-16 Niels Möller + + * poly1305-aes.c: Include poly1305.h. Rewrite functions without + using the POLY1305_* macros. + + * Makefile.in (HEADERS): Deleted poly1305-aes.h. + + * poly1305.h (POLY1305_CTX, POLY1305_SET_KEY, POLY1305_SET_NONCE) + (POLY1305_DIGEST): Deleted macros. Only implemented variant is + poly1305-aes. + (POLY1305_DIGEST_SIZE, POLY1305_BLOCK_SIZE, POLY1305_KEY_SIZE): + New constants. + (POLY1305_AES_KEY_SIZE, POLY1305_AES_DIGEST_SIZE): Moved here, + from poly1305-aes.h. + (struct poly1305_aes_ctx): Likewise. + (poly1305_aes_set_key, poly1305_aes_set_nonce) + (poly1305_aes_update, poly1305_aes_digest): Likewise. + * poly1305-aes.h: Deleted file, declarations moved to poly1305.h. + Update all users. + + * poly1305-internal.c (s2, s3, s4): Fixed macros. + + * poly1305-aes.h (struct poly1305_aes_ctx): Replace struct aes_ctx + by struct aes128_ctx. + * poly1305-aes.c (poly1305_aes_set_key, poly1305_aes_digest): + Update to use aes128_* functions. + * poly1305.h (POLY1305_SET_KEY): Drop key size argument when + calling set_key. + +2013-12-19 Niels Möller + + * poly1305-aes.h (poly1305_aes_update): Define as an alias for + poly1305_update, using preprocessor and a type cast. + + * poly1305-aes.c (poly1305_aes_update): Deleted function. + + * poly1305.h (poly1305_update): Declare. + (_POLY1305_BLOCK, POLY1305_UPDATE): Deleted macros. + + * poly1305.c (poly1305_update): New function. + +2013-11-21 Niels Möller + + * x86_64/poly1305-internal.asm: New file. Almost a factor of two + speedup. + + * configure.ac (asm_replace_list): Added poly1305-internal.asm. + + * asm.m4: Define struct offsets for 64-bit poly1305_ctx. + + * poly1305.h (POLY1305_DIGEST): Pass the encrypted nonce as an + additional argument to poly1305_digest. + (struct poly1305_ctx): Introduce unions, to support either 26-bit + or 64-bit implementation. + + * poly1305-internal.c (poly1305_digest): Added s argument. + + * poly1305.c (poly1305_set_s): Deleted function. + +2013-11-12 Niels Möller + + * poly1305-internal.c: New file, for poly1305 functions depending + on the internal mod (2^130 - 5) representation. + (poly1305_block_internal): New helper function. + (poly1305_block, poly1305_digest): Use it. + +2013-11-08 Nikos Mavrogiannopoulos + + * poly1305.h: New file. + * poly1305.c: New file. + * poly1305-aes.h: New file. + * poly1305-aes.c: New file. + * Makefile.in (nettle_SOURCES): Added poly1305-aes.c and poly1305.c. + (HEADERS): Added poly1305-aes.h and poly1305.h. + + * testsuite/poly1305-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added poly1305-test.c. + + * examples/nettle-benchmark.c (time_poly1305_aes): New function. + (main): Benchmark poly1305. + +2014-01-20 Niels Möller + + * Makefile.in (nettle_SOURCES): Added salsa20-set-nonce.c, + salsa20-128-set-key.c, and salsa20-256-set-key.c. + + * salsa20.h: Declare new functions. + (SALSA20_128_KEY_SIZE, SALSA20_256_KEY_SIZE): New constants. + (salsa20_set_iv): Define as an alias for salsa20_set_nonce. + + * salsa20-set-key.c (salsa20_set_key): Use salsa20_128_set_key and + salsa20_256_set_key. + (salsa20_set_iv): Renamed and moved... + * salsa20-set-nonce.c (salsa20_set_nonce): ... new file, new name. + + * salsa20-256-set-key.c (salsa20_256_set_key): New file and + function. + * salsa20-128-set-key.c (salsa20_128_set_key): New file and + function. + +2014-01-13 Niels Möller + + * nettle-types.h (union nettle_block16): New type, replacing union + gcm_block. + * gcm.h (union gcm_block): Deleted. Replaced by nettle_block16. + * gcm.c: Replaced all use of gcm_block by nettle_block16. + +2014-01-04 Niels Möller + + * config.guess: Updated to 2014-01-01 version, from + git://git.sv.gnu.org/config.git. + * config.sub: Likewise. + + * testsuite/memxor-test.c [HAVE_VALGRIND_MEMCHECK_H] (test_mark): + New function. + (test_memxor, test_memxor3): Use test_mark to tell valgrind the + start and end of src and destination areas. + + * configure.ac: Check for valgrind/memcheck.h. + + * testsuite/Makefile.in (VALGRIND): Added --partial-loads-ok=yes, + needed for the way unaligned data is handled in, e.g., memxor. + +2014-01-03 Niels Möller + + * shadata.c (main): Zero-pad output values to 8 hex digits. + * sha256.c (K): Updated table. + +2013-12-17 Niels Möller + + * configure.ac (ASM_RODATA): New substituted variable. Needed for + portability to darwin. + * config.m4.in: Define RODATA, using configure variable ASM_RODATA + * x86_64/gcm-hash8.asm: Use RODATA macro. + + * bignum-random-prime.c (_nettle_generate_pocklington_prime): Use + stronger variants of Pocklington's theorem, to allow p0 of size + down to bits/3. + +2013-12-15 Niels Möller + + * nettle-internal.h (NETTLE_MAX_BIGNUM_BITS) + (NETTLE_MAX_BIGNUM_SIZE): Deleted arbitrary limits. + +2013-12-15 Nikos Mavrogiannopoulos + + Introduced TMP_GMP_ALLOC macro for temporary allocations of + potentially large data, e.g, sized as an RSA key. + * gmp-glue.h (TMP_GMP_DECL, TMP_GMP_ALLOC, TMP_GMP_FREE): New + macros. + * gmp-glue.c (gmp_alloc, gmp_free): New functions. + * bignum-next-prime.c (nettle_next_prime): Use TMP_GMP_ALLOC. + * bignum-random.c (nettle_mpz_random_size): Likewise. + * pkcs1-decrypt.c (pkcs1_decrypt): Likewise. + * pkcs1-encrypt.c (pkcs1_encrypt): Likewise. + * pkcs1-rsa-digest.c (pkcs1_rsa_digest_encode): Likewise. + * pkcs1-rsa-sha512.c (pkcs1_rsa_sha512_encode) + (pkcs1_rsa_sha512_encode_digest): Likewise. + * 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-md5.c (pkcs1_rsa_md5_encode) + (pkcs1_rsa_md5_encode_digest): Likewise. + +2013-12-14 Niels Möller + + * x86_64/gcm-hash8.asm: Use .short rather than .hword, for + compatibility with apple's assembler. + +2013-12-03 Niels Möller + + * x86_64/sha1-compress.asm: Reorganized, to get closer to the x86 + version. No difference in running time. + + * configure.ac (dummy-dep-files): Don't overwrite any existing + dependency files. + + * x86_64/md5-compress.asm: New file, similar to the x86 version. + 35% speedup on AMD, 15% speedup on Intel. + +2013-11-25 Niels Möller + + * testsuite/dsa-test.c (test_main): Additional tests from NIST + test vectors. + + * testsuite/testutils.c (test_dsa_sign, test_dsa_verify): New + functions, supporting arbitrary digest size. + + * testsuite/testutils.h (ASSERT): Improved failure message. + + * dsa-verify.c (dsa_verify): Renamed, from _dsa_verify. + * dsa-sign.c (dsa_sign): Renamed, from _dsa_sign. + +2013-11-24 Niels Möller + + * testsuite/dsa-keygen-test.c (test_main): Test generating a + key with 224-bit q. + + * dsa-verify.c (_dsa_verify): Use _dsa_hash. + + * dsa-sign.c (_dsa_sign): Use _dsa_hash. Fix memory leak in + error case, spotted by Nikos. + + * dsa-keygen.c (dsa_generate_keypair): Allow q_bits == 224. + + * dsa-hash.c (_dsa_hash): New file and function. Allows digest + sizes not matching the bitsize of q. + * dsa.h (_dsa_hash): Declare it. + * Makefile.in (hogweed_SOURCES): Added dsa-hash.c. + +2013-11-23 Niels Möller + + * configure.ac: Check also for openssl/ecdsa.h. + +2013-10-05 Niels Möller + + * Makefile.in (nettle_SOURCES): Added eax.c. + (HEADERS): Added eax.h. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added eax-test.c. + + * testsuite/eax-test.c: New file. + + * nettle-internal.c (nettle_eax_aes128): New aead algorithm. + (eax_aes128_set_key, eax_aes128_set_nonce, eax_aes128_update) + (eax_aes128_encrypt, eax_aes128_decrypt, eax_aes128_digest): New + functions. + + * eax.c: New file. + * eax.h: New file. + + * aes.h: Fixed typo in name mangling for new aes functions. + +2013-09-28 Niels Möller + + * Merge aes-reorg branch. Changes below, + dated 2013-05-17 - 2013-08-13. + +2013-08-13 Niels Möller + + * yarrow.h (struct yarrow256_ctx): Use aes256_ctx, not aes_ctx. + * yarrow256.c: Adapted to use new aes256 interface. + +2013-08-07 Niels Möller + + * umac.h (_UMAC_STATE): Use struct aes128_ctx, not aes_ctx. + * umac-set-key.c (umac_kdf, _umac_set_key): Use aes128 interface. + * umac32.c (umac32_digest): Likewise. + * umac64.c (umac64_digest): Likewise. + * umac96.c (umac96_digest): Likewise. + * umac128.c (umac128_digest): Likewise. + +2013-06-25 Niels Möller + + * aes-meta.c: Deleted file. + + Analogous changes for new aes192 and aes256 interface. + + * aes.h (struct aes128_ctx): New aes128 declarations. + * aes-decrypt.c (aes128_decrypt): New function. + * aes-encrypt.c (aes128_encrypt): New function. + * aes128-meta.c: New file. + * aes128-set-encrypt-key.c (aes128_set_encrypt_key): New file and + function. + * aes128-set-decrypt-key.c (aes128_set_decrypt_key) + (aes128_invert_key): New file and functions. + * Makefile.in (nettle_SOURCES): Added aes128-set-encrypt-key.c, + aes128-set-decrypt-key.c and aes128-meta.c. + + * nettle-internal.c (nettle_unified_aes128): For testing the old + AES interface. + * testsuite/aes-test.c (test_cipher2): New function. + (test_main): Test both nettle_aes128 and nettle_unified_aes128. + +2013-05-22 Niels Möller + + * Makefile.in (nettle_SOURCES): Added aes-invert-internal.c and + aes-set-key-internal.c. + + * aes.h (AES128_KEY_SIZE, _AES128_ROUNDS): New constants. + Similarly also for aes192 and aes256. + + * aes-internal.h: Declare new functions. + + * aes-set-key-internal.c (_aes_set_key): New file and funxtion + extracted from aes_set_encrypt_key. + * aes-set-encrypt-key.c (aes_set_encrypt_key): Use _aes_set_key. + + * aes-invert-internal.c (_aes_invert): New file and function, + extracted from aes_invert_key. + * aes-set-decrypt-key.c (aes_invert_key): Use _aes_invert. + + * arm/v6/aes-encrypt-internal.asm: Adapted to new interface. + Unfortunately, 4% slowdown on Cortex-A9, for unknown reason. + * arm/v6/aes-decrypt-internal.asm: Likewise. + * arm/aes-encrypt-internal.asm: Adapted to new interface. + * arm/aes-decrypt-internal.asm: Likewise. + +2013-05-21 Niels Möller + + * sparc32/aes-encrypt-internal.asm: Adapted to new interface. + * sparc32/aes-decrypt-internal.asm: Likewise. + * sparc64/aes-encrypt-internal.asm: Likewise. + * sparc64/aes-decrypt-internal.asm: Likewise. + + * x86/aes-encrypt-internal.asm: Adapted to new interface. + * x86/aes-decrypt-internal.asm: Likewise. + +2013-05-20 Niels Möller + + * x86_64/aes-encrypt-internal.asm: Adapted to new interface. + * x86_64/aes-decrypt-internal.asm: Likewise. + +2013-05-17 Niels Möller + + * aes.h (struct aes_ctx): Renamed nrounds to rounds, and moved + first in the structure. + * aes-set-encrypt-key.c (aes_set_encrypt_key): Updated for renaming. + * aes-set-decrypt-key.c (aes_invert_key): Likewise. + + * aes-encrypt-internal.c (_nettle_aes_encrypt): Take rounds and + subkeys as separate arguments, not a struct aes_ctx *. Updated + callers. + * aes-decrypt-internal.c (_nettle_aes_decrypt): Likewise. + * aes-internal.h: Updated prototypes. + + * Start of aes-reorg changes. + +2013-09-28 Niels Möller + + * md4.h (struct md4_ctx): Use single uint64_t variable for block + count. + * md4.c: Use new block count variable. + * md5.c, md5.h (struct md5_ctx): Likewise. + * ripemd160.c, ripemd160.h (struct ripemd160_ctx): Likewise. + * sha1.c, sha1.h (struct sha1_ctx): Likewise. + * sha256.c, sha2.h (struct sha256_ctx): Likewise. + + * testsuite/testutils.c (test_hash_large): Added simple progress + indicator. + + * macros.h (MD_PAD): Use size argument, don't depend on + sizeof of the count field(s). + +2013-09-22 Niels Möller + + * x86_64/gcm-hash8.asm: New file. + * x86_64/gcm-gf-mul-8.asm: Deleted. + + * configure.ac (asm_nettle_optional_list): Look for gcm-hash8.asm, + not gcm-gf-mul-8.asm. + * gcm.c [HAVE_NATIVE_gcm_hash8]: Make use of (optional) assembly + implementation. + +2013-09-21 Niels Möller + + * Makefile.in (des.po): Add same dependencies as for des.o. + Reported by Vincent Torri. + +2013-09-20 Niels Möller + + * testsuite/gcm-test.c: Added tests with associated data of + varying size. + + * testsuite/testutils.c (tstring_alloc): Add NUL-termination. + +2013-09-18 Niels Möller + + * Makefile.in: New stampfiles, libnettle.stamp and + libhogweed.stamp, updated when both static and shared libraries + are rebuilt. Used as link dependencies in subdirectories. + * examples/Makefile.in: Make executable targets depend on + ../libnettle.stamp and libhogweed.stamp, not directly on the + static library files. + * testsuite/Makefile.in: Likewise. + * tools/Makefile.in: Likewise. + +2013-09-09 Niels Möller + + * gcm.c [HAVE_NATIVE_gcm_gf_mul_8]: Make use of (optional) + assembly implementation. + + * configure.ac: Support optional assembly files for both nettle + and hogweed. Replaced OPT_ASM_SOURCES with OPT_ASM_NETTLE_SOURCES, + OPT_ASM_HOGWEED_SOURCES, and asm_optional_list with + asm_nettle_optional_list and asm_hogweed_optional_list. + (asm_nettle_optional_list): Added gcm-gf-mul-8.asm. + +2013-06-25 Niels Möller + + * testsuite/gcm-test.c: Deleted redundant include of aes.h. + + * testsuite/testutils.c (test_aead): Allow digest size smaller + than the block size. + + * tools/nettle-pbkdf2.c: New command line tool. + * tools/Makefile.in (TARGETS): Added nettle-pbkdf2. + (nettle-pbkdf2$(EXEEXT)): New target. + * testsuite/nettle-pbkdf2-test: New test case. + * testsuite/Makefile.in (TS_SH): Added nettle-pbkdf2-test. + + * tools/nettle-hash.c (digest_file): Use stack allocation for the + small hex output buffer. + + * examples/io.c (MIN): Deleted unused macro. + +2013-05-21 Niels Möller + + From nettle-2.7-fixes branch: + * Makefile.in (distdir): Distribute files in arm/v6 subdirectory. + +2013-05-20 Niels Möller + + * arm/v6/sha1-compress.asm: Moved into v6 directory, since it uses + the v6 instruction uadd8, sel and rev. + * arm/v6/sha256-compress.asm: Likewise. + + * nettle-types.h: Include , for size_t. + +2013-05-17 Niels Möller + + * macros.h (ROTL32, ROTL64): Avoid undefined behaviour for zero + rotation count. Unfortunately makes CAST128 a bit slower with + gcc-4.6.3. + + * ecc-j-to-a.c (ecc_j_to_a): Fixed ecc_modp_mul call, to avoid + invalid overlap of arguments to mpn_mul_n. Problem tracked down by + Magnus Holmgren. + +2013-05-16 Niels Möller + + * arm/aes-encrypt-internal.asm: New file, for pre-v6 processors. + * arm/aes-decrypt-internal.asm: New file, likewise. + + * arm/aes.m4 (AES_FINAL_ROUND_V5): Variant without using uxtb. + (AES_FINAL_ROUND_V6): New name, updated callers. + (AES_FINAL_ROUND): ... old name. Also eliminated one uxtb + instruction. + (AES_ENCRYPT_ROUND, AES_DECRYPT): Moved macros to the + files using them. + + * arm/v6/aes-encrypt-internal.asm: Use ALIGN macro. Use 16-byte + alignment for loops. + * arm/v6/aes-decrypt-internal.asm: Likewise. Also added a nop + which mysteriously improves benchmark performance on Cortex-A9. + +2013-05-15 Niels Möller + + * configure.ac (asm_path): Handle armv6 and armv7 differently from + older ARMs. Add the arm/v6 directory to asm_path when appropriate. + + * arm/v6/aes-encrypt-internal.asm: Moved into v6 directory. Uses + the uxtb instruction which is not available for older ARMs. + * arm/v6/aes-decrypt-internal.asm: Likewise. + +2013-05-03 Niels Möller + + * cast128.c: Adapt to new struct cast128_ctx. + (cast128_set_key): Rewrite, eliminating lots of conditions and + some false warnings. + + * cast128.h (struct cast128_ctx): Separate the small 5-bit + rotation subkeys and the larger 32-bit masking subkeys. + +2013-05-02 Niels Möller + + * testsuite/testutils.c (mpz_combit): Renamed. Define only if not + provided GMP. Updated all uses. + (mpz_togglebit): ... old name. + + * sexp-format.c (sexp_vformat): Use type mpz_srcptr rather + than the old MP_INT *. + +2013-04-26 Niels Möller + + * Many files: Use size_t rather than unsigned for data sizes. + * x86_64/aes-encrypt-internal.asm: Accept 64-bit length. + * x86_64/aes-decrypt-internal.asm: Likewise. + +2013-04-25 Niels Möller + + * configure.ac: Changed version number, to 2.8. + (LIBNETTLE_MAJOR): Bumped major number, following + nettle_memxor ABI break. + (LIBNETTLE_MINOR): Reset to zero. + + * examples/hogweed-benchmark.c: Add benchmarking of OpenSSL's RSA + functions. + (all functions): Deleted unneeded casts. + +2013-04-24 Niels Möller + + * nettle.texinfo (Miscellaneous functions): Updated memxor + prototype. Document memxor3. + + * salsa20-crypt.c (salsa20_crypt): Deleted cast of memxor + argument, no longer needed. + * salsa20r12-crypt.c (salsa20r12_crypt): Likewise. + * sha3.c (sha3_absorb): Likewise. + + * memxor.h: Updated prototypes. Drop include of nettle-types.h. + + * memxor.c: Include nettle-types.h, for uintptr_t. Replace all + internal uses of uint8_t by plain char. + (memxor): Use void * rather than uint8_t * for + arguments. + (memxor3): Likewise. + + * x86_64/memxor.asm: Added nettle_ prefix to symbols. + * arm/memxor.asm: Likewise. + + * testsuite/symbols-test: Don't allow memxor functions without + nettle prefix, + + * memxor.h (memxor3): Added name mangling to add "nettle_" prefix + to memxor and memxor3 symbols. + + * Makefile.in (nettle_OBJS): Deleted $(LIBOBJS), and also deleted + LIBOBJS substitution. + (nettle_SOURCES): Added memxor.c, to include it in the library + unconditionally. + + * configure.ac: Deleted AC_REPLACE_FUNCS for memxor. + + * Released nettle-2.7. + +2013-04-23 Niels Möller + + From Martin Storsjö: + * x86_64/sha256-compress.asm: Add forgotten W64_EXIT. + * x86_64/sha512-compress.asm: Likewise. + * x86_64/salsa20-crypt.asm (Lpartial): Don't return via W64_EXIT + within this subfunction. + * x86_64/machine.m4 (W64_ENTRY): Use movdqu instead of movdqa for + saving xmm registers, since the stack is not guaranteed to be + 16-byte aligned on win64. Take pushed xmm registers into account + when reading the fifth parameter from the stack. + + * Makefile.in: Consistently use EXEEXT_FOR_BUILD. + +2013-04-21 Niels Möller + + * Makefile.in (DISTFILES): Added mini-gmp.c and mini-gmp.h. + (distdir): Use find, for identifying assembly files to copy. + +2013-04-18 Niels Möller + + * configure.ac: Recognize cpu type "arm*", not just "armv7*'. + + * arm/aes-encrypt-internal.asm: Updated include of aes.m4. + * arm/aes-decrypt-internal.asm: Likewise. + + * Makefile.in (distdir): Updated for ARM reorganization. + + * configure.ac (asm_path): Generalized, can now be a list of + directories. On ARM, check for neon instructions, and add arm/neon + if appropriate. New command line options + --enable-arm-neon/--disable-arm-neon, for overriding the default. + + arm/neon: New subdirectory, for assembly files making use of neon + instructions. + + arm: Renamed directory, from... + armv7: ...old name. + + * aclocal.m4 (NETTLE_CHECK_ARM_NEON): New macro. + + * nettle.texinfo (Keyed hash functions): Document UMAC. + + * umac.h (UMAC32_DIGEST_SIZE, UMAC64_DIGEST_SIZE) + (UMAC96_DIGEST_SIZE, UMAC128_DIGEST_SIZE): New constants. + (UMAC_DATA_SIZE): New name, for consistency with hash functions. + Updated all uses. + (UMAC_BLOCK_SIZE): ... old name. + +2013-04-17 Niels Möller + + * examples/nettle-benchmark.c (main): Benchmark salsa20r12. + + * nettle-internal.c (nettle_salsa20r12): Cipher struct for + benchmarking only. + * nettle-internal.h (nettle_salsa20): Declare it. + + * Makefile.in (eccdata): Depend on mini-gmp files. Drop -lgmp. + + * eccdata.c: Use mini-gmp, to avoid gmp dependency and associated + configure tests for the *build* system. Replaced mpz_submul_ui by + mpz_mul_ui + mpz_sub, and gmp_printf and gmp_fprintf by calls to + mpz_out_str. + + * mini-gmp.h, mini-gmp.c: New files, copied from gmp-5.1.1. + +2013-04-16 Niels Möller + + * umac-set-key.c (BE_SWAP32_N): Fixed dummy definition used for + big-endian systems. + + * Makefile.in (TARGETS): Deleted eccdata, it should be build only + when public key support is enabled. + (clean-here): Exlicitly list it here. + + * asm.m4 (m4_log2): New macro, similar to the one in gmp. + (ALIGN): Changed to take alignment in bytes. Updated all callers, + currently used only in x86 and x86_64 files. + + * umac.h (umac32_ctx, umac64_ctx, umac96_ctx, umac128_ctx): Make + block count an uint64_t. Reorder some elements to put short values + together. + * umac-l2.c (_umac_l2, _umac_l2_final): Make count argument an uint64_t. + (_umac_l2): Deleted redundant memcpy. + (_umac_l2, _umac_l2_final): Store input buffer at end of the + poly64/poly128 state. Deleted l1_out from corresponding context + structs, and updated all callers. + + * configure.ac: Changed version number to 2.7. + (LIBNETTLE_MINOR): Bumped library version, to 4.6. + (LIBHOGWEED_MINOR): And to 2.4. + + * Makefile.in (distdir): Include files from armv7 subdirectory. + + * x86_64/umac-nh-n.asm: New file, 3.5 time speedup. + + * umac32.c (umac32_digest): Fix nonce caching. + * umac64.c (umac64_digest): Likewise. + + * testsuite/umac-test.c (test_incr): New function. + (test_main): Test nonce increment. + + * misc/umac/umac.py: UMAC reference implementation. + * misc/umac/rijndael.py: AES implementation used by umac.py. + * misc/umac/mkvectors: Script to generate UMAC test vectors. + * misc/umac/vectors.out: Generated test vectors. + + * umac32.c (umac32_digest): Fix nonce increment, use INCREMENT + macro. + * umac64.c (umac64_digest): Likewise. + * umac96.c (umac96_digest): Likewise. + * umac128.c (umac128_digest): Likewise. + + * macros.h (INCREMENT): Allow size == 1. + +2013-04-15 Niels Möller + + * x86_64/umac-nh.asm: New file. 4.4 time speedup. + + * armv7/umac-nh-n.asm: New file. 2.0-2.3 time speedup. + + * testsuite/umac-test.c (test_align): Fixed memory leak. + +2013-04-12 Niels Möller + + * armv7/umac-nh.asm: New file. 2.4 time speedup. + + * armv7/machine.m4 (D0REG, D1REG): New macros. + + * configure.ac (asm_replace_list): Added umac-nh.asm and + umac-nh-n.asm. + + * testsuite/umac-test.c: Test different alignments for the + message. + +2013-04-11 Niels Möller + + * umac-nh-n.c (_umac_nh_n): Rewrote as a single pass over the + message data. + + * examples/nettle-benchmark.c (time_umac): New function. + (main): Call it. + + * umac-set-key.c (_umac_set_key): Drop byteswapping of l3_key2, it + can be xored directly to the pad in native byteorder. + * umac-l3.c (_umac_l3): Drop key_2 argument, let caller do that + xor. Updated all callers. + * umac32.c (umac32_digest): Adapt to l3 changes. + * umac64.c (umac64_digest): Likewise. + * umac96.c (umac96_digest): Likewise. + * umac128.c (umac128_digest): Likewise. + + Initial implementation of umac. + * umac.h: New file. + * umac-nh.c: New file. + * umac-nh-n.c: New file. + * umac-poly64.c: New file. + * umac-poly128.c: New file. + * umac-l2.c: New file. + * umac-l3.c: New file. + * Makefile.in (nettle_SOURCES): Added umac source files. + (HEADERS): Added umac.h. + * testsuite/umac-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added umac-test.c. + + * ecc-mul-a.c (ecc_mul_a): Avoid using mp_bitcnt_t, for + compatibility with older GMP versions. + * ecc-mul-g.c (ecc_mul_g): Likewise. + * eccdata.c (ecc_mul_binary): Likewise. + * sec-modinv.c (sec_modinv): Likewise. + + * x86_64/sha3-permute.asm: Go via memory for moves between general + registers and xmm registers. + +2013-04-06 Niels Möller + + From Edgar E. Iglesias: + * sha3.c (_sha3_update): Fix condition for when the block buffer + is full. + +2013-04-04 Niels Möller + + * ecc-point.c (ecc_point_get): Allow NULL x or y, ignore + corresponding coordinate. + + * nettle.texinfo (Elliptic curves): Document high-level ECDSA + support. + + From Martin Storsjö. Fallback functions for older GMP releases. + * gmp-glue.c (mpn_copyd, mpn_copyi, mpn_zero): New functions. + * gmp-glue.h: Declare them. + (mpn_sqr): Fallback macro. + + * gmp-glue.h (cnd_add_n, cnd_sub_n): Moved here, define in terms + of mpn_cnd_add_n and mpn_sub_n if available, otherwise in terms of + mpn_addmul_1 and mpn_submul_1. This seems to be an improvement for + subtraction, but more questionable for addition. + + * ecc-internal.h: Include gmp-glue.h. Deleted corresponding + include in all files using ecc-internal.h. + (cnd_add_n, cnd_sub_n): Moved from here. + +2013-04-03 Niels Möller + + * ecc-point-mul-g.c (ecc_point_mul_g): New file and function. + * ecc-point-mul.c (ecc_point_mul): New file and function. + * ecc.h: Updated declarations and name mangling. + * Makefile.in (hogweed_SOURCES): Added ecc-point-mul.c and + ecc-point-mul-g.c. + + * testsuite/salsa20-test.c (test_main): Tests for salsa20r12, + contributed by Nikos Mavrogiannopoulos. + +2013-03-26 Niels Möller + + * armv7/salsa20-core-internal.asm: New file. 45% speedup. + +2013-03-25 Niels Möller + + From Martin Storsjö: + * examples/timing.c: New file, extracted from nettle-benchmark.c. + * examples/timing.h: New file. + * examples/Makefile.in (SOURCES): Added timing.c. + (DISTFILES): Added timing.h. + (BENCH_OBJS, ECC_BENCH_OBJS, HOGWEED_BENCH_OBJS): Added timing.o. + * examples/nettle-benchmark.c: Use timing.h. + * examples/hogweed-benchmark.c: Likewise. + * examples/ecc-benchmark.c: Likewise. + + From Nikos Mavrogiannopoulos: + * salsa20r12-crypt.c (salsa20r12_crypt): New file and function. + * salsa20.h (salsa20r12_crypt): Declare. + * Makefile.in (nettle_SOURCES): Added salsa20r12-crypt.c. + + From Martin Storsjö: + * examples/hogweed-benchmark.c: Include local headers. + * testsuite/ecdsa-keygen-test.c: Likewise. + * x86_64/sha3-permute.asm: Workaround for Apple's assembler; write + movq instructions as movd. + + * Makefile.in (hogweed_PURE_OBJS): Don't include OPT_ASM_SOURCES + twice. + +2013-03-15 Niels Möller + + * armv7/sha3-permute.asm: New file. 4.5 time speedup. + + * armv7/machine.m4 (QREG): New macro. + +2013-03-14 Niels Möller + + * configure.ac (asm_replace_list): Added sha3-permute.asm, + revering 2012-12-30 change. 34% speedup on intel i5, from 2190 + cycles for the C implementation down to 1630. + + * armv7/sha512-compress.asm: Optimized. Keep expanded data in + registers, exploit parallelism. Another 70% speedup. + + * testsuite/sha512-test.c (test_main): Additional test vectors, + including some longer than 128 bytes. + +2013-03-13 Niels Möller + + * armv7/sha512-compress.asm: New file, using neon instructions. + 2.3 time speedup. + + * configure.ac (asm_replace_list): Added sha512-compress.asm. + * x86_64/machine.m4 (OFFSET64): New macro. + * x86_64/sha512-compress.asm: New file, 20% speedup. + + * sha512-compress.c (ROUND): Eliminated a temporary, analogous to + sha256 change below. + + * x86_64/sha256-compress.asm: New file, 16% speedup (benchmarked + on intel i5). + +2013-03-11 Niels Möller + + * armv7/sha256-compress.asm: New file, 25% speedup. + + * configure.ac (asm_replace_list): Added sha256-compress.asm. + + * sha256-compress.c (ROUND): Eliminated a temporary. + + * armv7/sha1-compress.asm: New file, 9% speedup. + + * testsuite/testutils.c (test_hash): Test different alignments for + the hash input. + +2013-03-08 Niels Möller + + * armv7/aes-decrypt-internal.asm: New file, 15% speedup. + * armv7/aes-encrypt-internal.asm: New file, 25% speedup. + * armv7/aes.m4: New file. + +2013-03-07 Niels Möller + + * gmp-glue.c (mpz_limbs_cmp): Don't use PTR and SIZ macros. + + * Makefile.in (aesdata, desdata, twofishdata, shadata, gcmdata) + (eccdata): Arrange for compiling these programs for running on the + build system, also when cross compiling everything else. + + * config.make.in (CC_FOR_BUILD, EXEEXT_FOR_BUILD): New variables. + + * configure.ac: Use GMP_PROG_CC_FOR_BUILD and + GMP_PROG_EXEEXT_FOR_BUILD. + + * aclocal.m4 (GMP_PROG_CC_FOR_BUILD, GMP_PROG_CC_FOR_BUILD_WORKS) + (GMP_PROG_EXEEXT_FOR_BUILD): New macros, based on GMP's. + + * aesdata.c: Deleted includes of config.h and nettle-types.h. Use + unsigned char and unsigned long instead of stdint.h types. + + * desdata.c: Deleted includes of config.h and desCode.h. + (main): Return 1 on invalid argument. Don't use ROR macro. Use + unsigned long instead of uint32_t, and make it work if unsigned + long is larger than 32 bits. + + * gcmdata.c: Deleted include of config.h and use UNUSED macro. + * shadata.c: Likewise. + + * twofishdata.c: Deleted include of nettle-types.h. Use unsigned + char instead of stdint.h types. + + * x86_64/ecc-521-modp.asm: New file. 2.4 time speedup. + +2013-03-06 Niels Möller + + * x86_64/ecc-384-modp.asm: New file, 3 time speedup. + * x86_64/ecc-256-redc.asm: New file, 2.5 time speedup. + * x86_64/ecc-224-modp.asm: New file, 5 time speedup over C + version. + +2013-03-05 Niels Möller + + * configure.ac (asm_optional_list): Added ecc-521-modp.asm. + * ecc-521.c: Check HAVE_NATIVE_ecc_521_modp, and use native + version if available. + * armv7/ecc-521-modp.asm: New file, 2 time speedup over C version. + +2013-03-04 Niels Möller + + * configure.ac (asm_optional_list): Added ecc-384-modp.asm. Deleted + bogus reference to $asm_search_list. + * ecc-384.c: Check HAVE_NATIVE_ecc_384_modp, and use native + version if available. + * armv7/ecc-384-modp.asm: New file, 3 time speedup over C version. + +2013-03-03 Niels Möller + + * ecc-256.c: Fixed definition of USE_REDC. + +2013-03-01 Niels Möller + + * ecc-256.c: Check HAVE_NATIVE_ecc_256_redc, and use native + version if available. + * armv7/ecc-256-redc.asm: New file, 4 time speedup over C version. + + * testsuite/ecc-redc-test.c: Increased test count. + + * ecc-224.c: Check HAVE_NATIVE_ecc_224_modp, and use native + version if available. + * armv7/ecc-224-modp.asm: New file, 4.5 time speedup over C + version. + + * configure.ac (asm_optional_list): Added ecc-224-modp.asm. + (OPT_ASM_SOURCES): Fixed assignment. + +2013-02-28 Niels Möller + + * x86_64/ecc-192-modp.asm: Reorganized to reduce number of + additions. Use setc instruction. + + * examples/Makefile.in: Let $(HOGWEED_TARGETS) depend on + ../libhogweed.a. + + * armv7/ecc-192-modp.asm: New file. 2.5 time speedup over C + version. + +2013-02-27 Niels Möller + + * ecc-192.c: Check HAVE_NATIVE_ecc_192_modp, and use native + version if available. + (ecc_192_modp): Fixed carry handling bug in 32-bit version. + + * x86_64/ecc-192-modp.asm: New file. 3.8 times speedup over C + version. + + * configure.ac (OPT_ASM_SOURCES): New substituted variable. + (asm_replace_list, asm_optional_list): New variables. For files in + asm_optional_list, also add them to OPT_ASM_SOURCES and define + appropriate HAVE_NATIVE_* symbols found. + + * Makefile.in (OPT_ASM_SOURCES): New variable. Used for setting + hogweed_OBJS and hogweed_PURE_OBJS. + + * testsuite/ecc-mod-test.c: Increased test count. + + * ecc-384.c (ecc_384_modp): Fixed typo which broke carry handling + in the 64-bit version. + + * examples/ecc-benchmark.c (bench_add_jjj): Typo fix, benchmark + the right function. + + * gmp-glue.h: Check if GMP provides mpz_limbs_read (expected in + next release). + * gmp-glue.c: Use GMP's mpz_limbs_read and friends if available. + Renamed all functions for consistency with GMP. Updated all + callers. + +2013-02-20 Niels Möller + + * examples/Makefile.in (HOGWEED_TARGETS): Added + hogweed-benchmark$(EXEEXT). + (SOURCES): Added hogweed-benchmark.c. + (hogweed-benchmark$(EXEEXT)): New target. + + * examples/hogweed-benchmark.c: New file. + + * ecdsa-keygen.c (ecdsa_generate_keypair): New file and function. + * Makefile.in (hogweed_SOURCES): Added ecdsa-keygen.c. + * testsuite/ecdsa-keygen-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecdsa-keygen-test.c. + + * nettle-internal.h (TMP_ALLOC): Added missing parentheses. + +2013-02-18 Niels Möller + + * testsuite/ecdsa-verify-test.c: New testcase. + * testsuite/ecdsa-sign-test.c: New testcase. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecdsa-sign-test.c and ecdsa-verify-test.c. + * testsuite/testutils.h: Include ecdsa.h. + (SHEX): Deleted const cast. + + * ecc-point.c: New file, struct ecc_point abstraction. + * ecc-scalar.c: New file, struct ecc_scalar abstraction. + * ecc-random.c (ecc_modq_random, ecc_scalar_random): New file, new + functions. + * ecc-hash.c (ecc_hash): New file and function. + * ecc-ecdsa-sign.c: New file, low-level signing interface. + * ecc-ecdsa-verify.c: New file, low-level ecdsa verify. + * ecdsa-sign.c: (ecdsa_sign): New file and function. + * ecdsa-verify.c (ecdsa_verify): New file and function. + * ecdsa.h: New header file. + * ecc.h: Declare ecc_point and ecc_scalar functions. + * ecc-internal.h: Added declarations. + * Makefile.in (hogweed_SOURCES): Added new source files. + (HEADERS): Added ecdsa.h. + + * gmp-glue.c (_mpz_set_mpn): New convenience function. + (_mpn_set_base256): New function. + (_gmp_alloc_limbs): New function. + (_gmp_free_limbs): New function. + * gmp-glue.h: Corresponding declarations. Include nettle-stdinh.h. + + * examples/Makefile.in (HOGWEED_TARGETS): Renamed, was + RSA_TARGETS. Added ecc-benchmark$(EXEEXT). + (SOURCES): Added ecc-benchmark.c. + (ecc-benchmark$(EXEEXT)): New target. + + * examples/ecc-benchmark.c: New file, benchmarking ecc primitives. + +2013-02-15 Niels Möller + + Integrate ecc_mul_a. + * ecc-a-to-j.c: New file. + * ecc-add-jjj.c: New file. + * ecc-mul-a.c: New file. + * Makefile.in (hogweed_SOURCES): Added new files. + * testsuite/ecc-mul-a-test.c: New file. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecc-mul-a-test.c. + + * testsuite/testutils.c: Removed redundant includes. + (die): New function. + + Integrate ecc_mul_g. + * ecc.h: New file. + * ecc-j-to-a.c: New file. + * ecc-size.c: New file. + * ecc-add-jja.c: New file. + * ecc-dup-jj.c: New file. + * ecc-mul-g.c: New file. + * sec-tabselect.c: New file. + * Makefile.in (hogweed_SOURCES): Added new files. + (HEADERS): Added ecc.h + * testsuite/ecc-mul-g-test.c: New file. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added + ecc-mul-g-test.c. + * testsuite/testutils.c (xalloc_limbs): New function. + (test_mpn): New function. + (test_ecc_point): New function. + (test_ecc_mul_a): New function. + (test_ecc_mul_j): New function. + * testsuite/testutils.h: Corresponding declarations. + + Integrate ECC internals. + * ecc-curve.h: New file. + * ecc-internal.h: New file. + * cnd-copy.c: New file. + * ecc-192.c: New file. + * ecc-224.c: New file. + * ecc-256.c: New file. + * ecc-384.c: New file. + * ecc-521.c: New file. + * ecc-generic-modp.c: New file. + * ecc-generic-modq.c: New file. + * ecc-generic-redc.c: New file. + * ecc-mod.c: New file. + * ecc-modp.c: New file. + * ecc-modq.c: New file. + * sec-add-1.c: New file. + * sec-modinv.c: New file. + * sec-sub-1.c: New file. + * Makefile.in (hogweed_SOURCES): Added new files. + (HEADERS): Added ecc-curve.h. + (DISTFILES): Added ecc-internal.h. + * testsuite/ecc-mod-test.c: New file. + * testsuite/ecc-modinv-test.c: New file. + * testsuite/ecc-redc-test.c: New file. + * testsuite/testutils.c (ecc_curves): New constant array. + * testsuite/testutils.h: Include ecc-related headers. Declare + ecc_curves array. + * testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added ecc-mod-test.c + ecc-modinv-test.c ecc-redc-test.c. + + * gmp-glue.c: New file, mpn <-> mpz conversions. + * gmp-glue.h: New file. + * Makefile.in: Added to hogweed_SOURCES and DISTFILES, respectively. + + * eccdata.c: New program, for generating ECC-related tables. + * Makefile.in (ecc-192.h, ecc-224.h, ecc-256.h, ecc-384.h) + (ecc-512.h): New generated files. + +2013-02-19 Niels Möller + + * armv7/memxor.asm (memxor): Software pipelining for the aligned + case. Runs at 6 cycles (0.5 cycles per byte). Delayed push of + registers until we know how many registers we need. + (memxor3): Use 3-way unrolling also for aligned memxor3. + Runs at 8 cycles (0.67 cycles per byte) + +2013-02-14 Niels Möller + + * configure.ac: Find GMP's GMP_NUMB_BITS. Substitute in Makefile. + * config.make.in (GMP_NUMB_BITS): New variable. + + * examples/rsa-keygen.c (uint_arg): New function. + (main): New options -s and -e, to specify key size and public + exponent. Increased default key size to 2048. + +2013-02-12 Niels Möller + + * armv7/memxor.asm (memxor): Optimized aligned case, using 3-way + unrolling. + +2013-02-06 Niels Möller + + * armv7/memxor.asm (memxor, memxor3): Optimized aligned case, now + runs at 0.75 cycles/byte. + + * armv7/README: New file. + * armv7/machine.m4: New (empty) file. + * armv7/memxor.asm: Initial assembly implementation. + + * config.m4.in: Substitute ASM_TYPE_PROGBITS as TYPE_PROGBITS. + + * config.make.in: Added .s to the suffix list. + + * Makefile.in (.asm.s): Use a separate make target for .asm + preprocessing. Include asm.d, which the corresponding + dependencies. + + * configure.ac (asm_file_list): Collect assembly files into this + variable. + (asm.d): Make config.status write dependencies for .s files into + asm.d. + (ASM_ALIGN_LOG): Set to "no" when appropriate. + (ASM_TYPE_FUNCTION): Default to "@function". + (ASM_TYPE_PROGBITS): New substituted variable, set in the same way + as ASM_TYPE_FUNCTION. + (ASM_MARK_NOEXEC_STACK): Use TYPE_PROGBITS. + (asm_path): Set up asm_path for armv7. + + * asm.m4: Use changecom to disable m4 quoting. Use divert to + suppress output. + +2013-02-05 Niels Möller + + * testsuite/rsa-keygen-test.c (test_main): Updated expected + signatures, after the nettle_mpz_random change below. + * testsuite/dsa-test.c (test_main): Likewise. Also fixed the + dsa256 test to actually use the expected signature. + +2013-01-31 Niels Möller + + * bignum-random.c (nettle_mpz_random): Increased number of extra + bits to 64, following FIPS 186-3. + +2013-01-16 Niels Möller + + * Released nettle-2.6. + +2013-01-12 Niels Möller + + * configure.ac: Use AC_LANG_SOURCE. + +2013-01-02 Niels Möller + + * configure.ac (LIBNETTLE_MINOR): Bumped library version, to 4.5. + (LIBHOGWEED_MINOR): And to 2.3. + + * examples/Makefile.in: Explicit rules for building objects in + parent directory. + * tools/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2013-01-01 Niels Möller + + * nettle.texinfo (Recommended hash functions): Document additional + sha3 functions. + + * examples/nettle-benchmark.c (main): Benchmark additional sha3 + functions. + +2012-12-30 Niels Möller + + * sha3-224.c, sha3-224-meta.c: New files. + * sha3-384.c, sha3-384-meta.c: New files. + * sha3-512.c, sha3-512-meta.c: New files. + * sha3.h: Prototypes for sha3 with sizes 224, 384 and 512. + * nettle-meta.h: Declare nettle_sha3_224, nettle_sha3_384 and + nettle_sha3_512. + * Makefile.in (nettle_SOURCES): Added new sha3 files. + + * testsuite/sha3-224-test.c: New file. + * testsuite/sha3-384-test.c: New file. + * testsuite/sha3-512-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added new sha3 test files. + + * configure.ac: Disabled use of sha3-permute.asm. + +2012-12-20 Niels Möller + + From Tim Rühsen: + * testsuite/des-compat-test.c (pt): Use proper prototype, use + const. + * testsuite/testutils.c (test_dsa_key): Deleted spurious + semicolon. + +2012-12-15 Niels Möller + + Based on a patch from Alon Bar-Lev: + * Makefile.in (LIBTARGETS, SHLIBTARGET): Define as empty if static + or shared libraries, respectively, are disabled. + (TARGETS): Deleted @IF_SHARED@ conditional, now in the definition + of SHLIBTARGET. + + From Alon Bar-Lev: + * configure.ac: Check for ar program. New option --disable-static. + * config.make.in (AR): Use configured value. + +2012-12-13 Niels Möller + + * x86_64/sha3-permute.asm: Rewrote, to keep all state in + registers. 2400 cycles on x86_64, only slightly faster than the + current C code. + +2012-12-09 Niels Möller + + * sha3-permute.c (sha3_permute): Rewrote to do permutation in + place. 80% speedup on x86_64, 2500 cycles. + +2012-12-04 Niels Möller + + * ctr.c (ctr_crypt): Fix bug reported by Tim Kosse. Don't + increment the counter when length is zero (was broken for the + in-place case). + + * testsuite/ctr-test.c (test_main): Added test with zero-length + data. + * testsuite/testutils.c (test_cipher_ctr): Check the ctr value + after encrypt and decrypt. + +2012-12-03 Niels Möller + + * sha3-permute.c (sha3_permute): Optimized, to reduce number of + passes over the data. 20% speedup on x86_64, 4700 cycles. + + * configure.ac: Added sha3-permute.asm. + + * x86_64/sha3-permute.asm: New file. 30% speedup over current C + code, 4300 cycles. + + * nettle.texinfo (Hash functions): Split into several sections, + separating recommended hash functions and legacy hash functions. + Document sha3-256. + +2012-12-02 Niels Möller + + Split sha.h into new files sha1.h and sha2.h. Replaced all + internal usage of sha.h in all files. + * sha.h: Kept for compatibility, just includes both new files. + * sha1.h: New file. + * sha2.h: New file. + * Makefile.in (HEADERS): Added sha1.h and sha2.h. + +2012-11-28 Niels Möller + + From Fredrik Thulin: + * testsuite/pbkdf2-test.c (test_main): Add PBKDF2-HMAC-SHA512 test + cases. + +2012-11-15 Niels Möller + + * sha3-permute.c (sha3_permute): Use ULL suffix on round + constants. Avoid passing shift count 0 to ROTL64. + + * sha3.c (sha3_absorb): Fixed big-endian code. Need macros.h. + + * macros.h (LE_READ_UINT64): New macro. + +2012-11-13 Niels Möller + + * sha3-permute.c (sha3_permute): Micro optimizations. Partial + unrolling. Use lookup table for the permutation. On an x86_64, + execution time reduced from appr. 13000 cycles to appr. 6000. + + * examples/nettle-benchmark.c (TIME_CYCLES): New macro. + (bench_sha1_compress, bench_salsa20_core): Use it. + (bench_sha3_permute): New function. + (main): Call bench_sha3_permute. + +2012-11-12 Niels Möller + + * examples/nettle-benchmark.c (main): Benchmark sha3_256. + + * sha3-permute.c: New file. Permutation function for sha3, aka + Keccak. + * sha3.h: New header file. + * sha3.c: New file, absorption and padding for sha3. + * sha3-256.c: New file. + * sha3-256-meta.c: New file. + * nettle-meta.h (nettle_sha3_256): Declare. + * Makefile.in (nettle_SOURCES): Added sha3 files. + (HEADERS): Added sha3.h. + * testsuite/sha3.awk: New file. Script to extract test vectors. + * testsuite/sha3-256-test.c: New file. + * testsuite/sha3-permute-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + sha3-permute-test.c and sha3-256-test.c. + (DISTFILES): Added sha3.awk. + * testsuite/.test-rules.make: Added sha3 targets. + + * macros.h (LE_WRITE_UINT64): New macro. + * write-le64.c (_nettle_write_le64): New file and function. + * nettle-write.h (_nettle_write_le64): Declare. Also deleted + declaration of non-existent _nettle_write_be64. + * Makefile.in (nettle_SOURCES): Added write-le64.c. + + * macros.h (ROTL64): New macro, moved from... + * sha512-compress.c (ROTL64): ... old location, deleted. + + * serpent-internal.h [HAVE_NATIVE_64_BIT] (DROTL32): Renamed from... + (ROTL64): ... old name. + (DRSHIFT32): Renamed from ... + (RSHIFT64): ... old name. + * serpent-encrypt.c (LINEAR_TRANSFORMATION64): Updated for above + renames. + * serpent-decrypt.c (LINEAR_TRANSFORMATION64_INVERSE): Likewise. + +2012-11-11 Niels Möller + + From Nikos Mavrogiannopoulos: + * nettle.texinfo (Hash functions): Added documentation for + gosthash94. + * examples/nettle-benchmark.c (main): Benchmark gosthash94. + +2012-11-10 Niels Möller + + * nettle.texinfo (nettle_hashes, nettle_ciphers): Use deftypevr, + not deftypevrx. Spotted by Nikos Mavrogiannopoulos. + +2012-11-08 Niels Möller + + Gost hash function, ported from Aleksey Kravchenko's rhash library + by Nikos Mavrogiannopoulos. + * gosthash94.c: New file. + * gosthash94.h: New file. + * gosthash94-meta.c: New file. + * nettle-meta.h (nettle_gosthash94): Declare. + * Makefile.in (nettle_SOURCES): Added gosthash94.c and + gosthash94-meta.c. + (HEADERS): Added gosthash94.h. + * testsuite/gosthash94-test.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + gosthash94-test.c. + +2012-10-29 Niels Möller + + From Martin Storsjö: + * configure.ac (dummy-dep-files): Avoid non-posix \|-operator in + sed regexp. + +2012-10-29 Niels Möller + + * x86_64/salsa20-core-internal.asm: New file. + * configure.ac: Added salsa20-core-internal.asm. + * examples/nettle-benchmark.c (bench_salsa20_core): New function. + +2012-10-27 Niels Möller + + * testsuite/Makefile.in (TS_SOURCES, CXX_SOURCES): Include sources + unconditionally. + (TS_CXX): Moved @IF_CXX@ conditional here. + (DISTFILES): Use $(SOURCES), which now includes all C source + files. testutils.c was lost in a the 2012-09-20 change. + + * x86_64/salsa20-crypt.asm: Include x86_64/salsa20.m4. + Make all exits go via .Lend and W64_EXIT. + + * x86_64/salsa20.m4: New file, extracted from + x86_64/salsa20-crypt.asm. + +2012-10-26 Niels Möller + + * configure.ac (LIBNETTLE_LINK, LIBHOGWEED_LIBS): Add $(CFLAGS) on + the link command line. Reported by Dennis Clarke. + +2012-10-03 Niels Möller + + From: Nikos Mavrogiannopoulos: + * testsuite/testutils.c (test_hash): On failure, print the + expected and returned hash values. + +2012-09-23 Niels Möller + + * Makefile.in (nettle_SOURCES): Added salsa20-core-internal.c. + + * salsa20-core-internal.c (_salsa20_core): New file and function, + extracted from salsa20_crypt. + * salsa20.h (_salsa20_core): Declare it. + * salsa20-crypt.c (salsa20_crypt): Use _salsa20_core. + +2012-09-21 Niels Möller + + * pbkdf2.c (pbkdf2): assert that iterations > 0. Reorganized + loops. + + * nettle.texinfo (Cipher functions): Stress that the salsa20 hash + function is not suitable as a general hash function. + +2012-09-20 Simon Josefsson + + * pbkdf2-hmac-sha1.c, pbkdf2-hmac-sha256.c: New files. + * pbkdf2.h (pbkdf2_hmac_sha1, pbkdf2_hmac_sha256): New prototypes. + * Makefile.in (nettle_SOURCES): Add pbkdf2-hmac-sha1.c and + pbkdf2-hmac-sha256.c. + * nettle.texinfo (Key derivation functions): Improve. + * testsuite/pbkdf2-test.c (test_main): Test new functions. + +2012-09-20 Niels Möller + + * pbkdf2.c (pbkdf2): Reordered arguments, for consistency. + * pbkdf2.h (PBKDF2): Analogous reordering. + * testsuite/pbkdf2-test.c: Adapted to new argument order. Also use + LDATA for the salt. + * nettle.texinfo (Key derivation functions): Updated documented + pbkdf2 prototype. + + * testsuite/Makefile.in (VALGRIND): New variable, to make valgrind + checking easier. + + * configure.ac: New substitution IF_CXX, replacing CXX_TESTS. + (dummy-dep-files): Handle .cxx files. + + * testsuite/Makefile.in: Use IF_CXX. Include dependency file for + cxx-test.o. + +2012-09-19 Niels Möller + + From Tim Rühsen: + * examples/rsa-encrypt.c (main): Added missing mpz_clear. + * examples/rsa-keygen.c (main): Added missing deallocation. + + * testsuite/meta-hash-test.c (test_main): Validate + NETTLE_MAX_HASH_DIGEST_SIZE. + + * pbkdf2.h (PBKDF2): New macro. + * testsuite/pbkdf2-test.c: Use it. + +2012-09-12 Simon Josefsson + + * NEWS: Mention addition of PBKDF2. + * pbkdf2.c (pbkdf2): New file and function. + * pbkdf2.h: Declare it. + * Makefile.in (nettle_SOURCES): Add pbkdf2.c. + (HEADERS): Add pbkdf2.h. + * nettle.texinfo (Key derivation functions): New section. + * testsuite/pbkdf2-test.c: New test case. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Add pbkdf2-test.c. + * testsuite/.test-rules.make (pbkdf2-test): New target. + +2012-09-16 Niels Möller + + * testsuite/: Overhaul of testsuite, affecting almost all files. + + Use struct tstring for allocated strings, and deallocate before + exit. + + Changed most test functions to take struct tstring as arguments. + + Made all test_main return on success. + + * testsuite/testutils.h (struct tstring): New struct type. + (H2, HL, MEMEQH, SUCCESS): Deleted macros. + (SHEX, SDATA): New macros. + (H): Redefined to track storage. + + * testsuite/testutils.c (tstring_alloc): New function. + (tstring_clear): New function. + (tstring_data): New function. + (tstring_hex): New function. + (tstring_print_hex): New function. + (decode_hex_length): Made static. + (decode_hex): Made static. No return value, abort on error. + (main): Expect test_main to return, and call tstring_clear before + exit. + (test_dsa_key): Added missing mpz_clear. + (test_mac): Deleted unused function. + + * testsuite/rsa2sexp-test.c (test_main): Added missing + nettle_buffer_clear. + + * testsuite/yarrow-test.c (open_file): Don't leak filename. + (test_main): fclose input file properly. + + * testsuite/sexp-format-test.c (test_main): Added missing calls to + nettle_buffer_clear and mpz_clear. + + * testsuite/serpent-test.c (tstring_hex_reverse): New function, + replacing... + (decode_hex_reverse): ... deleted function. + (RHEX): New macro, replacing... + (RH, RHL): ... deleted macros. + + * testsuite/rsa2sexp-test.c (test_main): Added missing + nettle_buffer_clear. + + * testsuite/random-prime-test.c (test_main): Added missing + mpz_clear. + + * realloc.c (nettle_realloc): Only call libc realloc if length > + 0, otherwise call free. Fixes a small memory leak. + (nettle_xrealloc): Likewise. + + * run-tests (test_program): Don't quote $EMULATOR; allow it to + expand to program and arguments (e.g., valgrind). + + * tools/pkcs1-conv.c (convert_public_key): Added missing calls to + dsa_public_key_clear and rsa_public_key_clear. + (main): Added missing nettle_buffer_clear. + +2012-09-10 Niels Möller + + * examples/eratosthenes.c (main): Explicitly deallocate storage + before exit. + + * examples/io.c (read_file): Explicitly treat an empty file as an + error. Rearrange loop, check for short fread return value. + + * desdata.c: Don't declare printf, include instead. Also + deleted casts of printf return value. + + From Tim Rühsen: + * examples/nettle-benchmark.c (die): Use PRINTF_STYLE attribute. + * pgp-encode.c (pgp_put_rsa_sha1_signature): Deleted unused variable. + * rsa2openpgp.c (rsa_keypair_to_openpgp): Likewise. + * examples/base16enc.c (main): Deleted useless allocations. + +2012-09-07 Niels Möller + + * examples/nettle-benchmark.c (die): Add NORETURN attribute. Patch + from Tim Rühsen. + * tools/misc.h (die, werror): Use PRINTF_STYLE and NORETURN macros + for attributes. Patch from Tim Rühsen. + + * examples/io.h (werror): Use PRINTF_STYLE macro. + +2012-08-22 Niels Möller + + From Sam Thursfield : + * configure.ac: Make documentation optional, to avoid requiring + TeX. New option --disable-documentation, and Makefile substitution + IF_DOCUMENTATION. + * Makefile.in: Use IF_DOCUMENTATION. + +2012-07-12 Niels Möller + + * asm.m4 (ALIGN): Use << operator rather than **, with m4 eval. + The latter is not supported by BSD m4. + +2012-07-07 Niels Möller + + Copyright headers: Updated FSF address. Patch from David Woodhouse. + + * examples/Makefile.in (BENCH_LIBS): Added -lm, needed for the + ldexp function. Reported by Anthony G. Basile. + + * configure.ac: Changed version number to 2.6. + + * Released nettle-2.5. + +2012-07-05 Niels Möller + + * x86_64/salsa20-crypt.asm (salsa20_crypt): Write the 64-bit movq + instructions as "movd", since that makes the osx assembler + happier. Assembles to the same machine code on gnu/linux. + +2012-07-03 Niels Möller + + * aclocal.m4 (LSH_FUNC_ALLOCA): In the config.h boilerplate, + include malloc.h if it exists, also when compiling with gcc. + Needed for cross-compiling with --host=i586-mingw32msvc. + + * examples/base16dec.c: Don't #include files using , + we don't want to pick up installed versions. On windows, include + , needed for _setmode. + * examples/base16enc.c: Likewise. + * examples/base64dec.c: Likewise. + * examples/base64enc.c: Likewise + + * nettle.texinfo (Cipher functions): Document Salsa20. + +2012-06-25 Niels Möller + + * pkcs1.c (_pkcs1_signature_prefix): Renamed function, adding a + leading underscore. Updated all callers. + + * bignum-next-prime.c (nettle_next_prime): Consistently use the + type nettle_random_func * (rather then just nettle_random_func) + when passing the function pointer as argument. Similar change for + nettle_progress_func. Should have been done for the 2.0 release, + but a few arguments were overlooked. + * bignum-random-prime.c (_nettle_generate_pocklington_prime) + (nettle_random_prime): Likewise. + * bignum-random.c (nettle_mpz_random_size, nettle_mpz_random): + Likewise. + * dsa-keygen.c (dsa_generate_keypair): Likewise. + * dsa-sha1-sign.c (dsa_sha1_sign_digest, dsa_sha1_sign): Likewise. + * dsa-sha256-sign.c (dsa_sha256_sign_digest, dsa_sha256_sign): + Likewise. + * dsa-sign.c (_dsa_sign): Likewise. + * pkcs1-encrypt.c (pkcs1_encrypt): Likewise. + * rsa-blind.c (_rsa_blind): Likewise. + * rsa-decrypt-tr.c (rsa_decrypt_tr): Likewise. + * rsa-encrypt.c (rsa_encrypt): Likewise. + * rsa-keygen.c (rsa_generate_keypair): Likewise. + * rsa-pkcs1-sign-tr.c (rsa_pkcs1_sign_tr): Likewise. + + * cbc.c (cbc_encrypt, cbc_decrypt): Similarly, use the type + nettle_crypt_func * rather than just nettle_crypt_func. + * ctr.c (ctr_crypt): Likewise. + * gcm.c (gcm_set_key): Likewise. + + * testsuite/des-compat-test.c (test_main): Disable declarations of + disabled functions and variables, to avoid warnings. No verbose + output unless verbose flag is set. + +2012-06-09 Niels Möller + + * examples/Makefile.in (SOURCES): Added base16dec.c, forgotten + earlier. + + General pkcs1 signatures, with a "DigestInfo" input. Suggested by + Nikos Mavrogiannopoulos. + * Makefile.in (hogweed_SOURCES): Added pkcs1-rsa-digest.c, + rsa-pkcs1-sign.c, rsa-pkcs1-sign-tr.c, and rsa-pkcs1-verify.c. + + * pkcs1-rsa-digest.c (pkcs1_rsa_digest_encode): New file and + function. + * pkcs1.h: Declare it. + + * rsa-pkcs1-verify.c (rsa_pkcs1_verify): New file and function. + * rsa-pkcs1-sign.c (rsa_pkcs1_sign): New file and function. + * rsa-pkcs1-sign-tr.c (rsa_pkcs1_sign_tr): New file and function, + contributed by Nikos Mavrogiannopoulos. + * rsa.h: Declare new functions. + + * rsa.h (_rsa_blind, _rsa_unblind): Declare functions. + * rsa-blind.c (_rsa_blind, _rsa_unblind): Functions moved to a + separate file, renamed and made non-static. Moved from... + * rsa-decrypt-tr.c: ... here. + +2012-06-03 Niels Möller + + * testsuite/pkcs1-test.c (test_main): Include leading zero in + expected result. + + * pkcs1.c (pkcs1_signature_prefix): Return pointer to where the + digest should be written. Let the size input be the key size in + octets, rather then key size - 1. + * pkcs1-rsa-*.c: Updated for above. + * rsa-*-sign.c, rsa-*-verify.c: Pass key->size, not key->size - 1. + +2012-05-18 Niels Möller + + * pkcs1-encrypt.c (pkcs1_encrypt): New file and function. + * rsa-encrypt.c (rsa_encrypt): Use pkcs1_encrypt. + +2012-05-09 Niels Möller + + * rsa-decrypt-tr.c (rsa_decrypt_tr): Added missing mpz_clear, + spotted by Nikos Mavrogiannopoulos. + +2012-05-07 Niels Möller + + * nettle-types.h (_STDINT_HAVE_INT_FAST32_T): Define here, to + force nettle-stdint.h to not try to define the int_fast*_t types. + Avoids compilation problems with gnutls on SunOS-5.8, where the + definitions here collide with gnulib's. + +2012-04-23 Niels Möller + + * nettle-internal.h (NETTLE_MAX_BIGNUM_SIZE): New constant. Based + on NETTLE_MAX_BIGNUM_BITS, rounded upwards. Replaced all uses of + NETTLE_MAX_BIGNUM_BITS. + +2012-04-19 Niels Möller + + * list-obj-sizes.awk: Use decimal rather than hexadecimal output. + (hex2int): Use local variables. + +2012-04-18 Niels Möller + + * x86_64/salsa20-crypt.asm: New file. + +2012-04-17 Niels Möller + + * testsuite/salsa20-test.c (test_salsa20_stream): Check that + salsa20_crypt doesn't write beyond the given destination area. + (test_salsa20): Likewise. + + * salsa20-crypt.c: Renamed file, from... + * salsa20.c: ... old name. + + * x86_64/machine.m4 (WREG): New macro. + + * salsa20.c (salsa20_hash): Deleted function, inlined into + salsa20_crypt. + (salsa20_set_key, salsa20_set_iv): Moved, to... + * salsa20-set-key.c: ...new file. + +2012-04-15 Niels Möller + + * testsuite/salsa20-test.c (test_salsa20_stream): New function. + (test_main): Tests for encrypting more than one block at a time. + +2012-04-14 Niels Möller + + * examples/io.c (write_file): Use write_string. + + * examples/Makefile.in (base64enc): New targets. Also + added missing io.o dependency to several other targets. + (base64dec, base16enc, base16dec): Likewise. + + * examples/base64enc.c: New file, based on example code + contributed by Jeronimo Pellegrini. + * examples/base64dec.c: Likewise. + * examples/base16enc.c: Likewise. + * examples/base16dec.c: Likewise. + + * examples/rsa-encrypt.c (process_file): Reorganized fread loop. + (usage): New function. + (main): Implemented --help option. + + * examples/rsa-decrypt.c (process_file): Improved error message + for too short input file. + + * aes-set-decrypt-key.c (gf2_log, gf2_exp): Deleted tables. + (mult, inv_mix_column): Deleted functions. + (mtable): New table. + (MIX_COLUMN): New macro. + (aes_invert_key): Use MIX_COLUMN and mtable. + + * aesdata.c (compute_mtable): New table, for the inv mix column + operation in aes_invert_key. + +2012-04-13 Niels Möller + + * aes-set-encrypt-key.c (aes_set_encrypt_key): Use LE_READ_UINT32. + Tabulate the needed "round constants". + (xtime): Deleted function. + + * aes-internal.h (SUBBYTE): Cast to uint32_t. Use B0, ..., B3 + macros. + +2012-04-09 Niels Möller + + Timing resistant RSA decryption, based on RSA blinding code + contributed by Nikos Mavrogiannopoulos. + * rsa-decrypt-tr.c (rsa_decrypt_tr): New function. + (rsa_blind): Helper function. + (rsa_unblind): Helper function. + * rsa.h: Declare rsa_decrypt_tr. Some cleanups, no longer include + nettle-meta.h, more consistent declarations of function pointer + arguments. + * testsuite/rsa-encrypt-test.c (test_main): Test rsa_decrypt_tr. + Check for writes past the end of the message area. + + * Makefile.in (hogweed_SOURCES): Added pkcs1-decrypt.c. + * rsa-decrypt.c (rsa_decrypt): Use pkcs1_decrypt. + * pkcs1-decrypt.c (pkcs1_decrypt): New file and function, + extracted from rsa_decrypt. + +2012-04-01 Niels Möller + + * salsa20.c (LE_SWAP32): Typo fix for big-endian case. + (QROUND): New macro. + (salsa20_hash): Use it. + +2012-03-31 Niels Möller + + * salsa20.c: (salsa20_set_iv): Deleted size argument, only one + size allowed. + (U8TO32_LITTLE): Deleted macro. Use LE_READ_UINT32 instead, which + avoids unaligned reads. + (salsa20_set_key): Rearranged slightly, to avoid unnecessary + byte-to-word conversions. + + (LE_SWAP32): Renamed macro from... + (U32TO32_LITTLE): ... old name. + (U32TO8_LITTLE): Deleted macro. + (salsa20_wordtobyte): Renamed function to... + (salsa20_hash): ... new name. Changed output argument from byte + array to word array. Use memxor3, which brings a considerable + performance gain. + + * nettle-internal.c (salsa20_set_key_hack): Updated salsa20_set_iv + call. + * testsuite/salsa20-test.c (test_salsa20): Deleted iv_length + argument, updated all calls. + + * salsa20.h (SALSA20_BLOCK_SIZE): New constant. + (_SALSA20_INPUT_LENGTH): New constant. + * salsa20.c: Use these constants. + + * salsa20.c (ROTL32): Deleted macro, use the one from macros.h + instead, with reversed order of arguments. + (ROTATE, XOR, PLUS, PLUSONE): Deleted macros, use ROTL32 and + builtin operators directly. + + Unification of rotation macros. + * macros.h (ROTL32): New macro, to replace (almost) all other + rotation macros. + + * aes-set-encrypt-key.c: Include macros.h. + (aes_set_encrypt_key): Use ROTL32. + * aes-internal.h (ROTBYTE, ROTRBYTE): Deleted macros. + + * camellia-internal.h (ROL32): Deleted macro. + (ROTL128): Renamed for consistency, from... + (ROL128): ... old name. + * camellia-crypt-internal.c: Updated for renamed rotation macros. + * camellia-set-encrypt-key.c: Likewise. + * cast128.c (ROL): Deleted macro. + (F1, F2, F3): Updated to use ROTL32 (reversed order of arguments). + Also added proper do { ... } while (0) wrappers. + + * ripemd160-compress.c (ROL32): Deleted macro. + (R): Updated to use ROTL32 (reversed order of arguments). + + * serpent-internal.h (ROL32): Deleted macro. + (ROTL64): Renamed (from ROL64) and reorderd arguments, for + consistency. + (RSHIFT64): Reordered arguments, for consistency. + * serpent-decrypt.c: Updated for renamed rotation macros, with + reversed argument order. + * serpent-encrypt.c: Likewise. + * serpent-set-key.c: Likewise. + + * sha1-compress.c (ROTL): Deleted macro, use ROTL32 instead. + + * sha256-compress.c (ROTR): Deleted macro. Replaced by ROTL32, + with complemented shift count. + (SHR): Deleted macro, use plain shift operator instead. + + * sha512-compress.c (ROTR): Deleted macro, replaced by... + (ROTL64): ...new macro, with complemented shift count + (SHR): Deleted macro, use plain shift operator instead. + (S0, S1, s0, s1): Updated accordingly. + +2012-03-30 Niels Möller + + * nettle-internal.c (nettle_salsa20): Cipher struct for + benchmarking only. Sets a fix zero IV, and ignores block size. + * nettle-internal.h (nettle_salsa20): Declare it. + + * examples/nettle-benchmark.c (block_cipher_p): New function. + (time_cipher): Use block_cipher_p. + (main): Include salsa20 in benchmark. + + * Makefile.in (soname link): Fixed logic. + (nettle_SOURCES): Removed nettle-internal.c, so that it's not + part of the library... + (internal_SOURCES): ...and put it here. + * testsuite/Makefile.in (TEST_OBJS): Added ../nettle-internal.o. + * examples/Makefile.in (BENCH_OBJS): New variable, to simplify the + nettle-benchmark rule. Also link with ../nettle-internal.o. + +2012-03-29 Niels Möller + + Implementation of Salsa20, contributed by Simon Josefsson. + * salsa20.h: New file. + * salsa20.c: New file. + * Makefile.in (nettle_SOURCES): Added salsa20.c + (HEADERS): Added salsa20.h. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added salsa20-test.c. + * testsuite/salsa20-test.c: New test case. + + * Makefile.in (soname links): Adding missing space before ]. + +2012-03-23 Niels Möller + + * arcfour.h (arcfour_stream): Deleted obsolete prototype. + +2012-03-05 Niels Möller + + * configure.ac (enable_shared): Build shared libraries by default. + +2012-03-04 Niels Möller + + * configure.ac (LIBNETTLE_MINOR): Bumped library version, to 4.4. + (LIBHOGWEED_MINOR): And to 2.2. + +2012-02-27 Niels Möller + + * list-obj-sizes.awk: Recognize elf64 objects. + + * Makefile.in (.texinfo.dvi): Pass -b option to texi2dvi. + + * Makefile.in (TARGETS): Added twofishdata. + (SOURCES): Added twofishdata.c. + (twofishdata): New rule. + + * twofish.c (q0, q1): Made const, and reformatted to match the + twofishdata program. + + * twofishdata.c: Resurrected old file. Used to be called + generate_q.c, when the twofish code was contributed back in 1999. + + * nettle.texinfo: Documentation for base16 and base64 encoding. + Text contributed by Jeronimo Pellegrini + , back in April 2006. + +2012-02-18 Niels Möller + + * run-tests, getopt.c, getopt1.c, getopt.h: These files were moved + to the top-level in the conversion to an independent git + repository. They used to be symlinks to lsh files, from the + subdirectories which use them. + + * Makefile.in: Build and distribute getopt files. Distribute + run-tests script. + * examples/Makefile.in: Adapt to getopt files and the run-tests + script now located in the parent directory. + * testsuite/Makefile.in: Likewise. + * tools/Makefile.in: Likewise. + + * index.html: Converted to xhtml (from lsh repository, change + dated 2012-02-03). Updated git instructions. + + * nettle.texinfo: Updated charset declaration. + * misc/plan.html: Likewise. + +2012-01-17 Niels Möller + + * testsuite/Makefile.in (DISTFILES): Added setup-env. + + * examples/rsa-decrypt.c (main): Use _setmode rather than setmode, + suggested by Eli Zaretskii. Affects windows builds only. + * examples/rsa-encrypt.c: Likewise. + + * Makefile.in ($(LIBNETTLE_FORLINK)): Always create a .lib symlink + to the library file. Use LN_S. + ($(LIBHOGWEED_FORLINK)): Likewise. + + (install-shared-nettle): Use LN_S. + (install-shared-hogweed): Likewise. + + * configure.ac: Use AC_PROG_LN_S. + * config.make.in (LN_S): New substitution. + + * testsuite/setup-env: New file. Wine workaround. Can't get + ../.lib into wine's dll search path, so create additional + symlinks. + * testsuite/teardown-env: ...and delete them here. Also delete + file testtmp. + * examples/setup-env: Similar links setup here. + * examples/teardown-env: ... and deleted. + +2012-01-07 Niels Möller + + * examples/Makefile.in (check): Add ../.lib to PATH, like in + testsuite/Makefile. Needed for w*ndows. Reported by Eli Zaretskii. + +2011-11-25 Niels Möller + + From Martin Storsjö: + * x86_64/machine.m4 (W64_ENTRY, W64_EXIT): New macros for + supporting W64 ABI. + * x86_64: Updated all assembly files to use them. + + * configure.ac (W64_ABI): New variable, set when compiling for + W64 ABI (64-bit M$ windows). + * config.m4.in (W64_ABI): Define, from configure substitution. + +2011-11-24 Niels Möller + + From Martin Storsjö: + * examples/Makefile.in (check): Pass $(EMULATOR) and $(EXEEXT) in + the environment of run-tests. + * examples/rsa-encrypt-test: Use $EXEEXT and $EMULATOR. + * examples/rsa-sign-test: Likewise. + * examples/rsa-verify-test: Likewise. + * examples/setup-env: Likewise. + + * testsuite/Makefile.in (check): Pass $(EXEEXT) in the environment of + run-tests. + * testsuite/pkcs1-conv-test: Use $EXEEXT and $EMULATOR. Ignore \r + in rsa-sign output. + + * examples/rsa-decrypt.c (main) [WIN32]: Set stdout/stdin to + binary mode. + * examples/rsa-encrypt.c (main): Likewise. + +2011-11-24 Niels Möller + + * configure.ac (HAVE_NATIVE_64_BIT): Workaround to get it set to 1 + on w64. + + * serpent-internal.h (ROL64): Use (uint64_t) 1 rather than 1L, for + M$ w64. + (RSHIFT64): Likewise. Also added a missing parenthesis. + +2011-11-24 Niels Möller + + From Martin Storsjö: + * testsuite/symbols-test: Use $NM, falling back to nm if undefined. + * testsuite/Makefile.in (check): Pass $(NM) in the environment of + run-tests. + * config.make.in (NM): Set NM. + + * testsuite/sexp-conv-test: Use $EMULATOR when running test + programs. Also ignore \r for output in the non-canonical output + formats. + * testsuite/Makefile.in (check): Pass $(EMULATOR) in the + environment of run-tests. + * configure.ac (EMULATOR): New substituted variable. Set to wine + or wine64 when cross compiling for windows, otherwise empty. + * config.make.in (EMULATOR): Set from autoconf value. + +2011-11-20 Niels Möller + + * x86/camellia-crypt-internal.asm: Take ALIGNOF_UINT64_T into + account when getting the offset for the subkeys. Differs between + w32 and other systems. w32 problem identified by Martin Storsjö. + + * config.m4.in: Define ALIGNOF_UINT64_T (from configure). + + * configure.ac: Check alignment of uint64_t, and also use AC_SUBST + for use in config.m4.in. + +2011-11-19 Niels Möller + + Cygwin/mingw32 improvements contributed by Martin Storsjö: + * Makefile.in (IMPLICIT_TARGETS): New variable for DLL link + libraries. + (clean-here): Delete the DLL import libraries. + + * configure.ac: Setup installation of DLL files in $bindir. + (IF_DLL, LIBNETTLE_FILE_SRC, LIBHOGWEED_FILE_SRC): New + substitutions. + + * config.make.in (LIBNETTLE_FILE_SRC): Substitute new autoconf + variable. + (LIBHOGWEED_FILE_SRC): Likewise. + + * Makefile.in (install-dll-nettle, uninstall-dll-nettle): New + target for installing the DLL file in $bindir. + (install-shared-nettle): Conditionally + depend on install-dll-nettle. Use LIBNETTLE_FILE_SRC. + (uninstall-shared-nettle): Conditionally depend on + install-dll-nettle. + (various hogweed targets): Analogous changes. + + * configure.ac: Unify shared lib setup for cygwin and mingw. + +2011-10-31 Niels Möller + + * configure.ac (LIBHOGWEED_LIBS): Typo fix for the darwin case. + Spotted by Martin Storsjö. + +2011-10-25 Niels Möller + + * configure.ac (LIBHOGWEED_LIBS): cygwin fix, added + libnettle.dll.a. Reported by Volker Zell. + +2011-10-18 Niels Möller + + * configure.ac: Improved setup för darwin shared libraries. + Patch contributed by Ryan Schmidt. + +2011-10-03 Niels Möller + + * x86_64/memxor.asm: Implemented sse2-loop. Configured at compile + time, and currently disabled. + + * testsuite/testutils.h (ASSERT): Write message to stderr. + + * testsuite/memxor-test.c: Use 16-byte alignment for "fully + aligned" operands. + +2011-09-03 Niels Möller + + * x86/camellia-crypt-internal.asm: Use "l"-suffix on instructions + more consistently. Reportedly, freebsd and netbsd systems with + clang are more picky about this. + + * configure.ac: Changed version number to 2.5. + + * Released nettle-2.4. + + * configure.ac (LIBNETTLE_MINOR): Bumped library version, to 4.3. + + * gcm-aes.c: Include config.h. + * tools/nettle-lfib-stream.c: Likewise. + + * ripemd160-compress.c: Added missing include of config.h. Needed + for correct operation on big-endian systems. + +2011-09-02 Niels Möller + + * configure.ac: Changed version number to 2.4. + + * Released nettle-2.3. + +2011-08-30 Niels Möller + + * testsuite/hmac-test.c: Added tests for hmac-ripemd160. + + * hmac.h: Declare hmac-ripemd160 related functions. + + * Makefile.in (nettle_SOURCES): Added hmac-ripemd160.c. + +2011-08-30 Niels Möller + + * nettle.texinfo (Hash functions): Document ripemd-160. + + * hmac-ripemd160.c: New file. + + * hmac.h: Declare hmac-ripemd160 functions. + +2011-08-29 Niels Möller + + * sha256.c (sha256_update): Updated MD_UPDATE call for new + conventions. + (sha256_write_digest): Use MD_PAD rather than MD_FINAL, and insert + the length manually. + * sha512.c: Analogous changes. + + * sha1.c (COMPRESS): New macro. + (sha1_update): Updated MD_UPDATE call for new conventions. + (sha1_digest): Use MD_PAD rather than MD_FINAL, and insert the + length manually. + + * ripemd160.c (ripemd160_init): Use memcpy for initializing the + state vector. + (COMPRESS): New macro. + (ripemd160_update): Use MD_UPDATE. + (ripemd160_digest): Inline ripemd160_final processing. Use MD_PAD + and _nettle_write_le32. + (ripemd160_final): Deleted function. + + * ripemd160.h (struct ripemd160_ctx): Use a 64-bit block count. + Renamed digest to state. + + * md5.c (md5_init): Use memcpy for initializing the state vector. + (COMPRESS): New macro, wrapping _nettle_md5_compress. + (md5_update): Use MD_UPDATE. + (md5_digest): Inline md5_final processing. Use MD_PAD and + _nettle_write_le32. + (md5_final): Deleted. + + * md5.h (struct md5_ctx): Renamed some fields, for consistency. + + * md4.h (struct md4_ctx): Renamed some fields, for consistency. + + * md4.c (md4_init): Use memcpy for initializing the state vector. + (md4_update): Use MD_UPDATE. + (md4_digest): Inline md4_final processing, using MD_PAD. Use + _nettle_write_le32. + (md4_block): Renamed, to... + (md4_compress): ... new name. Take ctx pinter as argument. + (md4_final): Deleted function. + + * md2.c (md2_update): Use MD_UPDATE. + + * macros.h (MD_UPDATE): Added incr argument. Invoke compression + function with ctx pointer as argument, rather than ctx->state. + (MD_FINAL): Just pad, don't store length field. Renamed to MD_PAD. + (MD_PAD): Analogous change of compression invocations. + + * sha512.c: (COMPRESS): New macro wrapping _nettle_sha512_compress. + (sha512_update): Use MD_UPDATE. + (sha512_final): Deleted function. + (sha512_write_digest): Use MD_FINAL. + + * sha256.c (COMPRESS): New macro wrapping _nettle_sha256_compress. + (SHA256_INCR): Deleted macro. + (sha256_update): Use MD_UPDATE. + (sha256_final): Deleted function. + (sha256_write_digest): New function, replacing sha256_final, and + using MD_FINAL. + (sha256_digest): Use sha256_write_digest. + (sha224_digest): Likewise. + + * tools/nettle-hash.c (list_algorithms): Fixed typo in header. + + * sha1.c (SHA1_DATA_LENGTH): Deleted unused macro. + (sha1_init): Use memcpy to initialize the state vector. + (SHA1_INCR): Deleted macro. + (sha1_update): Use MD_UPDATE macro, to reduce code duplication. + (sha1_digest): Use MD_FINAL macro. + (sha1_final): Deleted function. + + * sha.h (struct sha1_ctx): Renamed attribute digest to state. + + * macros.h (MD_UPDATE): New macro. + (MD_FINAL): New macro. + +2011-08-28 Niels Möller + + * ripemd160.c (ripemd160_final): Use LE_WRITE_UINT32. Deleted byte + swapping at the end, leaving it to ripemd160_digest. + (ripemd160_digest): Use _nettle_write_le32. + + * Makefile.in (nettle_SOURCES): Added write-le32.c. + + * md5.c (md5_digest): Use _nettle_write_le32. + + * write-le32.c (_nettle_write_le32): New file and function. + + * ripemd160-compress.c (ROL32): Renamed macro (was "rol"). Deleted + x86 version using inline assembly; at least gcc-4.4.5 recognizes + shift-and-or expressions which are in fact rotations. + (_nettle_ripemd160_compress): Use LE_READ_UINT32. + + * configure.ac (LIBNETTLE_MINOR): Bumped library version, to 4.2. + + * testsuite/meta-hash-test.c: Updated for the addition of + ripemd-160. + + * testsuite/.test-rules.make: Added rule for ripemd160-test. + + * examples/nettle-benchmark.c (main): Benchmark ripemd-160. + +2011-08-28 Niels Möller + + RIPEMD-160 hash function. Ported from libgcrypt by Andres Mejia. + * testsuite/ripemd160-test.c: New file. + * ripemd160.h: New file. + * nettle-meta.h: Declare nettle_ripemd160. + * ripemd160.c: New file, ported from libgcrypt. + * ripemd160-compress.c: Likewise. + * ripemd160-meta.c: New file. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + ripemd160-test.c. + * nettle-meta-hashes.c (nettle_hashes): Added nettle_ripemd160. + * Makefile.in (nettle_SOURCES): Added ripemd160.c, + ripemd160-compress.c, and ripemd160-meta.c. + (HEADERS): Added ripemd160.h. + +2011-08-10 Niels Möller + + * nettle.texinfo: Fixed mis-placed const in various prototypes. + Spotted by Tatsuhiro Tsujikawa. + +2011-07-24 Niels Möller + + * Makefile.in (PKGCONFIG_FILES, pkgconfigdir): New variables. + (DISTFILES): Added nettle.pc.in and hogweed.pc.in. + (nettle.pc, hogweed.pc): New targets (invoking config.status). + (install-pkgconfig, uninstall-pkgconfig): New targets. + (install-here): Depend on install-pkgconfig. + (uninstall-here): Depend on uninstall-pkgconfig. + (distclean-here): Delete nettle.pc and hogweed.pc. + +2011-07-20 Niels Möller + + * configure.ac: Generate nettle.pc and hogweed.pc. + + * nettle.pc.in, hogweed.pc.in: New files. + +2011-07-17 Niels Möller + + * nettle-internal.h: Added missing extern declarations. + +2011-07-11 Niels Möller + + * configure.ac: Changed version number to 2.3. + + * Released nettle-2.2. + + * Makefile.in (DISTFILES): Distribute COPYING.LIB, not COPYING, + +2011-07-07 Niels Möller + + * tools/misc.h (werror): Removed incorrect noreturn attribute from + declaration. + + * examples/io.c (read_file): Bug fix, in dependence of initial + size on max_size. + +2011-07-01 Niels Möller + + * cbc.c (CBC_BUFFER_LIMIT): Reduced to 512 bytes. + (cbc_decrypt): For in-place operation, use overlapping memxor3 and + eliminate a memcpy. + + * ctr.c (ctr_crypt): Reorganized to call the encryption function + with several blocks at a time. Handle the case of a single block + specially. + + * x86_64/memxor.asm: Added ALIGN for shifting loop. Deleted + obsolete ifelse. + +2011-06-30 Niels Möller + + * configure.ac: Link in serpent-decrypt.asm, if found. + + * x86_64/serpent-decrypt.asm: Added an SSE2 loop, doing four + blocks at a time in parallel. + + * x86_64/serpent-encrypt.asm: Include serpent.m4. Deleted a + redundant label. + + * x86_64/serpent.m4: New file, with serpent-related macros. + +2011-06-29 Niels Möller + + * x86_64/serpent-decrypt.asm: Wrote main (32-bit) loop. + (SBOX0I, SBOX1I, SBOX7I): Fixed bugs. + + * nettle.texinfo (Copyright): Updated for license change to + LGPLv2+. Updated copyright info on serpent. + + * NEWS: Updated information for nettle-2.2. + + * x86_64/serpent-decrypt.asm: New file. + + * x86_64/serpent-encrypt.asm: Fixed .file pseudo op. + + * testsuite/testutils.c (test_cipher_ctr): Display more info on + failure. + + * examples/nettle-benchmark.c (bench_ctr): New function. + (time_cipher): Also benchmark CTR mode. + + * configure.ac (LIBNETTLE_MINOR): Updated library version number + to 4.1. + (LIBHOGWEED_MINOR): And to 2.1. + +2011-06-22 Niels Möller + + * configure.ac: Use pwd -P when examining lib directories. + Link in serpent-encrypt.asm, if found. + +2011-06-21 Niels Möller + + * serpent-decrypt.c (SBOX3_INVERSE): Eliminated temporaries. + (SBOX4_INVERSE): Likewise. + (SBOX5_INVERSE): Likewise. + (SBOX6_INVERSE): Likewise. + (SBOX7_INVERSE): Likewise. + (All SBOX_INVERSE-macros): Deleted type argument, and updated users. + +2011-06-20 Niels Möller + + * serpent-decrypt.c: Renamed arguments in sbox macros. + (SBOX0_INVERSE): Eliminated temporaries. + (SBOX1_INVERSE): Likewise. + (SBOX2_INVERSE): Likewise. + + * x86_64/serpent-encrypt.asm: Added an SSE2 loop, doing four + blocks at a time in parallel. + + * testsuite/serpent-test.c (test_main): Added some more multiple + block tests. + +2011-06-15 Niels Möller + + * configure.ac (libdir): On 64-bit Linux, we used to assume that + libraries are installed according to the FHS. Since at least + Fedora and Gentoo follow the FHS convention, while at least Debian + doesn't, we have to try to figure out which convention is used. + +2011-06-14 Niels Möller + + * x86_64/serpent-encrypt.asm: Slight simplification of loop logic. + + * x86_64/serpent-encrypt.asm: New file. + +2011-06-12 Niels Möller + + * testsuite/serpent-test.c (test_main): Added tests with multiple + blocks at a time. + + * serpent-encrypt.c (SBOX6): Renamed arguments. Eliminated + temporaries. + (SBOX7): Likewise. + (All SBOX-macros): Deleted type argument, and updated users. + + * configure.ac: Display summary at the end of configure.. + (asm_path): Set only if enable_assember is yes. + +2011-06-10 Niels Möller + + * serpent-encrypt.c (SBOX5): Renamed arguments. Eliminated + temporaries. + +2011-06-09 Niels Möller + + * serpent-encrypt.c (SBOX4): Renamed arguments. Eliminated + temporaries. + + * configure.ac (LIBNETTLE_LINK, LIBHOGWEED_LINK): Cygwin fix, from + Vincent Torri. + +2011-06-08 Niels Möller + + * examples/eratosthenes.c (find_first_one): Fixed c99-style + declaration. Reported by Sebastian Reitenbach. + (find_first_one): Declare the lookup table as static const, and + use unsigned char rather than unsigned.. + +2011-06-07 Niels Möller + + * serpent-encrypt.c (SBOX0): Renamed arguments. Eliminated + temporaries. + (SBOX1): Likewise. + (SBOX2): Likewise. + (SBOX3): Likewise. + +2011-06-06 Niels Möller + + * Makefile.in (DISTFILES): Added serpent-internal.h. + (nettle_SOURCES): Replaced serpent.c by serpent-set-key.c, + serpent-encrypt.c, and serpent-decrypt.c. + + * serpent.c: Replaced by several new files. + * serpent-set-key.c: New file. + * serpent-encrypt.c: New file. + * serpent-decrypt.c: New file. + * serpent-internal.h: New file. + + * serpent.c [HAVE_NATIVE_64_BIT]: Process two blocks at a time in + parallel. Measured speedup of 10%--25% (higher for encryption) on + x86_64. + +2011-06-01 Niels Möller + + * serpent.c (ROUNDS): Deleted macro. + (serpent_block_t): Deleted array typedef. + (KEYXOR): New macro, replacing BLOCK_XOR. + (BLOCK_COPY, SBOX, SBOX_INVERSE): Deleted macros. + (LINEAR_TRANSFORMATION): Use four separate arguments. + (LINEAR_TRANSFORMATION_INVERSE): Likewise. + (ROUND): Take separate arguments for all input and output words. + (ROUND_INVERSE): Likewise. + (ROUND_LAST, ROUND_FIRST_INVERSE): Deleted macros. + (serpent_set_key): Moved loop termination test. + (serpent_encrypt): Rewrote with unrolling of just eight rounds, + and without serpent_block_t. + (serpent_decrypt): Likewise. + + * serpent.c: Added do { ... } while (0) around block macros. + (serpent_key_t): Deleted array typedef. + (ROL32, ROR32): Renamed macros, were rol and ror. + (KS_RECURRENCE, KS): New macros. + (serpent_key_pad): Renamed, from... + (serpent_key_prepare): ...old name. + (serpent_subkeys_generate): Deleted function. + (serpent_set_key): Rewrote the generation of subkeys. Reduced both + temporary storage and code size (less unrolling) + +2011-05-31 Niels Möller + + * testsuite/serpent-test.c (test_main): Enabled test with short, + 40-bit, key. + + * serpent.c (byte_swap_32): Deleted macro. + (serpent_key_prepare): Use LE_READ_UINT32. Don't require aligned + input, and support arbitrary key sizes. + +2011-05-30 Simon Josefsson + + * serpent.c: Rewrite, based on libgcrypt code. License changed + from GPL to LGPL. + * serpent_sboxes.h: Removed. + * Makefile.in: Drop serpent_sboxes.h. + +2011-05-31 Niels Möller + + * testsuite/serpent-test.c (test_main): Added some tests for + padding of keys of length which is not a multiple of four bytes. + +2011-05-30 Simon Josefsson + + * testsuite/serpent-test.c (test_main): Add test vectors from + libgcrypt. + +2011-05-21 Niels Möller + + * dsa-keygen.c (dsa_generate_keypair): Avoid double init of mpz + variable. Spotted by Nikos Mavrogiannopoulos. + +2011-05-06 Niels Möller + + * configure.ac: Fix link flags for shared libraries on Solaris, + which needs -h to set the soname. Patch contributed by Dagobert + Michelsen. + +2011-05-06 Niels Möller + + * configure.ac: New configure option --enable-gcov. + + * arcfour.h (arcfour_stream): Deleted obsolete define. + +2011-04-27 Niels Möller + + * tools/nettle-hash.c (find_algorithm): Require exact match. + +2011-04-15 Niels Möller + + Reverted broken byte-order change from 2001-06-17: + * serpent.c (serpent_set_key): Use correct byteorder. + (serpent_encrypt): Likewise. + (serpent_decrypt): Likewise. + + * testsuite/serpent-test.c (decode_hex_reverse): New function. + (RH, RHL): New macros. + (test_main): Byte reverse inputs and outputs for the testvectors + taken from the serpent submission package. Enable test vectors + from http://www.cs.technion.ac.il/~biham/Reports/Serpent/. + +2011-03-23 Niels Möller + + * tools/sexp-conv.c (xalloc): Deleted function, now it's in misc.c + instead. + + * configure.ac: Use LSH_FUNC_STRERROR. + + * tools/Makefile.in (TARGETS): Added nettle-hash, and related + build rules. + (SOURCES): Added nettle-hash.c. + + * tools/misc.c (xalloc): New function. + + * tools/pkcs1-conv.c (main): Made the OPT_* constants local, and + fixed numerical values to start with non-ASCII 0x300. + + * tools/nettle-hash.c: New file. + +2011-03-23 Niels Möller + + Contributed by Daniel Kahn Gillmor: + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added + meta-hash-test.c, meta-cipher-test.c, and meta-armor-test.c. + + * testsuite/meta-hash-test.c: New file. + * testsuite/meta-cipher-test.c: New file. + * testsuite/meta-armor-test.c: New file. + + * nettle.texinfo: Document nettle_hashes and nettle_ciphers. + + * nettle-meta.h: Declare algorithm lists nettle_ciphers, + nettle_hashes, nettle_armors. + + * Makefile.in (nettle_SOURCES): Added nettle-meta-hashes.c, + nettle-meta-ciphers.c, and nettle-meta-armors.c. + + * nettle-meta-armors.c: New file. + * nettle-meta-ciphers.c: New file. + * nettle-meta-hashes.c: New file. + +2011-02-18 Niels Möller + + * arcfour.c (arcfour_stream): Deleted function. It's not very + useful, and neither documented nor tested. + +2011-02-16 Niels Möller + + * cbc.h (CBC_ENCRYPT): Avoid using NULL; we don't ensure that it + is defined. + (CBC_DECRYPT): Likewise. + + * gcm-aes.c (gcm_aes_set_iv): Use GCM_SET_IV. + (gcm_aes_set_key): Deleted cast. + (gcm_aes_encrypt): Likewise. + (gcm_aes_decrypt): Likewise. + (gcm_aes_digest): Likewise. + (gcm_aes_update): One less argument to GCM_UPDATE. + + * gcm.h (GCM_SET_KEY): Added cast to nettle_crypt_func *. Help + compiler type checking despite this cast. + (GCM_ENCRYPT): Likewise. + (GCM_DECRYPT): Likewise. + (GCM_DIGEST): Likewise. + (GCM_SET_IV): New macro, for completeness. + (GCM_UPDATE): Deleted unused argument encrypt. + +2011-02-14 Niels Möller + + * nettle.texinfo: Split node on cipher modes, and started on + the GCM documentation. + + * testsuite/gcm-test.c (test_gcm_aes): Deleted function, replaced + by test_aead. + (test_main): Use test_aead. + + * testsuite/testutils.c (test_aead): New function, replacing + test_gcm_aes and before that test_cipher_gcm. + + * nettle-internal.c (nettle_gcm_aes128): New const struct. + (nettle_gcm_aes192): Likewise. + (nettle_gcm_aes256): Likewise. + + * nettle-internal.h (struct nettle_aead): Tentative interface for + authenticated encryption with associated data. + + * examples/nettle-benchmark.c (time_gcm): Renamed. Updated for + gcm_aes_auth to gcm_aes_update renaming. Benchmark both encryption + and hashing. + (time_gmac): ...old name. + + * nettle-internal.c (des_set_key_hack): Don't touch the bits + parity, since thay are now ignored. + (des3_set_key_hack): Likewise. + + * cast128-meta.c (nettle_cast128): Don't pass keysize. + * nettle-meta.h (_NETTLE_CIPHER_FIX): Deleted keysize parameter + derived from the appropriate constant instead. + + * testsuite/gcm-test.c (test_gcm_aes): Updated for gcm_aes_auth to + gcm_aes_update renaming. + +2011-02-13 Niels Möller + + * gcm.h (GCM_UPDATE): Renamed, from... + (GCM_AUTH): ...old name. + + * gcm-aes.c (gcm_aes_update): Renamed, from... + (gcm_aes_auth): ...old name. + + * gcm.c (gcm_update): Renamed, and fixed an assert. From... + (gcm_auth): ...old name. + + * gcm.h (GCM_TABLE_BITS): Increase table size to 8 bits, + corresponding to 4 KByte of key-dependent tables. + +2011-02-10 Niels Möller + + * x86_64/memxor.asm: New file. Improves performance by 22% for the + unaligned01 case and 35% for the unaligned12 case, benchmarked on + Intel SU1400. + + * examples/nettle-benchmark.c (cgt_works_p): New function. + (cgt_time_start): Likewise. + (cgt_time_end): Likewise. + (clock_time_start): Likewise. + (clock_time_end): Likewise. + (time_function): Read clock via function pointers time_start and + time_end, so we can select method at runtime. + (xalloc): Use die function. + (main): Choose timing function. If available, try clock_gettime, + and fall back to clock if it doesn't exist. + + * examples/nettle-benchmark.c (die): New function. + (TIME_END, TIME_START): Check return value from clock_gettime. + + * gcm.h (union gcm_block): Use correct length for w array. + + * testsuite/gcm-test.c (test_main): Added the rest of the + testcases from the spec. + +2011-02-09 Niels Möller + + * testsuite/gcm-test.c (test_main): Enabled testcases 5 and 6, + with different IV lengths. + + * gcm-aes.c (gcm_aes_set_iv): Updated for gcm_set_iv change. + + * gcm.c (gcm_hash_sizes): New function. + (gcm_set_iv): Added support for IVs of arbitrary size. Needed + another argument, for the hash subkey. + (gcm_digest): Use gcm_hash_sizes. + + * examples/nettle-benchmark.c (time_gmac): Use gcm_aes interface. + + * testsuite/gcm-test.c (test_gcm_aes): New function, replacing + test_cipher_gcm and using the new gcm_aes interface. + (test_main): Updated to use test_gcm_aes. + * testsuite/testutils.c (test_cipher_gcm): Deleted function. + + * Makefile.in (nettle_SOURCES): Added gcm-aes.c. + + * gcm.c (gcm_set_key): Replaced context argument by a struct + gcm_key *. + (gcm_hash): Replaced context argument by a struct gcm_key * and a + pointer to the hashing state block. + (gcm_auth): Added struct gcm_key * argument. + (gcm_encrypt): Likewise. + (gcm_decrypt): Likewise. + (gcm_digest): Likewise. + + * gcm-aes.c: New file. + (gcm_aes_set_key): New function. + (gcm_aes_set_iv): Likewise. + (gcm_aes_auth): Likewise. + (gcm_aes_encrypt): Likewise. + (gcm_aes_decrypt): Likewise. + (gcm_aes_digest): Likewise. + + * gcm.h (struct gcm_key): Moved the key-dependent and + message-independent state to its own struct. + (struct gcm_ctx): ... and removed it here. + (GCM_CTX): New macro. + (GCM_SET_KEY): Likewise. + (GCM_AUTH): Likewise. + (GCM_ENCRYPT): Likewise. + (GCM_DECRYPT): Likewise. + (GCM_DIGEST): Likewise. + (struct gcm_aes_ctx): New struct. + +2011-02-08 Niels Möller + + * gcm.h (struct gcm_ctx): The hash key is now always an array, + named h, with array size depending on GCM_TABLE_BITS. + * gcm.c (gcm_gf_shift): Added a separate result argument. + (gcm_gf_mul): Compile bitwise version only when GCM_TABLE_BITS == + 0. Simplified interface with just two arguments pointing to + complete blocks. + (gcm_gf_shift_4, gcm_gf_shift_8): Renamed table-based functions, from... + (gcm_gf_shift_chunk): ... old name. + (gcm_gf_mul): Renamed both table-based versions and made the + argument types compatible with the bitwise gcm_gf_mul. + (gcm_gf_mul_chunk): ... the old name. + (gcm_set_key): Initialize the table using adds and shifts only. + When GCM_TABLE_BITS > 0, this eliminates the only use of the + bitwise multiplication. + (gcm_hash): Simplified, now that we have the same interface for + gcm_gf_mul, regardless of table size. + + * gcm.c (GHASH_POLYNOMIAL): Use unsigned long for this constant. + (gcm_gf_shift_chunk): Fixed bugs for the big endian 64-bit case, + e.g., sparc64. For both 4-bit and 8-bit tables. + + * gcm.c: Use the new union gcm_block for all gf operations. + + * gcm.h (union gcm_block): New union, used to enforce alignment. + +2011-02-07 Niels Möller + + * gcm.c (gcm_gf_shift_chunk) : Bug fix for little-endian 8-bit + tables. + + * gcm.c (gcm_gf_mul_chunk): Special case first and last iteration. + (gcm_gf_add): New function, a special case of memxor. Use it for + all memxor calls with word-aligned 16 byte blocks. Improves + performance to 152 cycles/byte with no tables, 28 cycles per byte + with 4-bit tables and 10.5 cycles per byte with 8-bit tables. + + Introduced 8-bit tables. If enabled, gives gmac performance of 19 + cycles per byte (still on intel x86_64). + * gcm.c (gcm_gf_shift_chunk): New implementation for 8-bit tables. + (gcm_gf_mul_chunk): Likewise. + (gcm_set_key): Generate 8-bit tables. + + * Makefile.in (SOURCES): Added gcmdata.c. + + * gcm.h (GCM_TABLE_BITS): Set to 4. + +2011-02-06 Niels Möller + + * Makefile.in (TARGETS): Added gcmdata. + (gcmdata): New rule. + + Introduced 4-bit tables. Gives gmac performance of 45 cycles per + byte (still on intel x86_64). + * gcm.c (gcm_gf_shift): Renamed. Tweaked little-endian masks. + (gcm_rightshift): ... old name. + (gcm_gf_mul): New argument for the output. Added length argument + for one of the inputs (implicitly padding with zeros). + (shift_table): New table (in 4-bit and 8-bit versions), generated + by gcmdata. + (gcm_gf_shift_chunk): New function shifting 4 bits at + a time. + (gcm_gf_mul_chunk): New function processing 4 bits at a time. + (gcm_set_key): Generation of 4-bit key table. + (gcm_hash): Use tables, when available. + + * gcmdata.c (main): New file. + + * gcm.c (gcm_rightshift): Moved the reduction of the shifted out + bit here. + (gcm_gf_mul): Updated for gcm_rightshift change. Improves gmac + performance to 181 cycles/byte. + + * gcm.c (gcm_gf_mul): Rewrote. Still uses the bitwise algorithm from the + specification, but with separate byte and bit loops. Improves gmac + performance a bit further, to 227 cycles/byte. + + * gcm.c (gcm_rightshift): Complete rewrite, to use word rather + than byte operations. Improves gmac performance from 830 cycles / + byte to (still poor) 268 cycles per byte on intel x86_64. + +2011-02-05 Niels Möller + + * examples/nettle-benchmark.c (time_gmac): New function. + (main): Call time_gmac. + + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added gcm-test.c. + + * testsuite/testutils.c (test_cipher_gcm): New function, + contributed by Nikos Mavrogiannopoulos. + + * testsuite/gcm-test.c: New file, contributed by Nikos + Mavrogiannopoulos. + + * Makefile.in (nettle_SOURCES): Added gcm.c. + (HEADERS): Added gcm.h. + + * gcm.c: New file, contributed by Nikos Mavrogiannopoulos. + * gcm.h: New file, contributed by Nikos Mavrogiannopoulos. + + * macros.h (INCREMENT): New macro, moved from ctr.c. Deleted third + argument. + * ctr.c: Use INCREMENT macro from macros.h, deleted local version. + +2011-01-07 Niels Möller + + * testsuite/Makefile.in (check): Add ../.lib to PATH, since that's + where w*ndows looks for dlls. + + * testsuite/testutils.c (test_cipher_stream): More debug output on + failure. + +2010-12-14 Niels Möller + + * nettle-types.h: Deleted some unnecessary parenthesis from + function typedefs. + (nettle_realloc_func): Moved typedef here... + * realloc.h: ...from here. + + * buffer.c (nettle_buffer_init_realloc): Use an explicit pointer + for realloc argument. + +2010-12-07 Niels Möller + + * nettle.texinfo (Copyright): Updated info on blowfish. + +2010-11-26 Niels Möller + + Reapplied optimizations (150% speedup on x86_32) and other fixes, + relicensing them as LGPL. + * blowfish.c (do_encrypt): Renamed, to... + (encrypt): ...new name. + (F): Added context argument. Shift input explicitly, instead of + reading individual bytes via memory. + (R): Added context argument. + (encrypt): Deleted a bunch of local variables. Using the context + pointer for everything should consume less registers. + (decrypt): Likewise. + (initial_ctx): Arrange constants into a struct, to simplify key + setup. + (blowfish_set_key): Some simplification. + +2010-11-26 Simon Josefsson + + * blowfish.c: New version ported from libgcrypt. License changed + from GPL to LGPL. + +2010-11-25 Niels Möller + + * Makefile.in (install-shared-nettle): Use INSTALL_DATA, which + clears the execute permission bits. + (install-shared-hogweed): Likewise. + +2010-11-16 Niels Möller + + * configure.ac: Updated gmp url. + +2010-11-01 Niels Möller + + * tools/misc.c (werror): Don't call exit (copy&paste-error). + +2010-10-26 Niels Möller + + * examples/rsa-encrypt.c (main): No extra message for bad options. + + * examples/rsa-keygen.c (main): Added long options. Deleted -?, + and fixed handling of bad options. + + * examples/next-prime.c (main): Deleted -?, and fixed handling of + bad options. + * examples/random-prime.c (main): Likewise. + +2010-10-22 Niels Möller + + * examples/nettle-benchmark.c (main): Added long options. Deleted -?, + and fixed handling of bad options. + + * examples/eratosthenes.c (main): Added long options. Deleted -?, + and fixed handling of bad options. Renamed -s to -q (long option + --quiet). + + * tools/pkcs1-conv.c (main): Deleted short alias -? for --help, + and fixed handling of bad options. + * tools/sexp-conv.c (parse_options): Likewise. + +2010-10-06 Niels Möller + + * memxor.c (memxor3): Optimized. + (memxor3_common_alignment): New function. + (memxor3_different_alignment_b): New function. + (memxor3_different_alignment_ab): New function. + (memxor3_different_alignment_all): New function. + + * examples/nettle-benchmark.c (time_function): Reorganized, to + reduce overhead. + (time_memxor): Also benchmark memxor3. + + * x86_64/memxor.asm: New file. + + * examples/nettle-benchmark.c (overhead): New global variable. + (time_function): Compensate for call overhead. + (bench_nothing, time_overhead): New functions. + (time_memxor): Tweaked src size, making it an integral number of + words. + (main): Call time_overhead. + +2010-10-01 Niels Möller + + * x86_64/camellia-crypt-internal.asm (ROUND): Reordered sbox + lookups. + + * testsuite/memxor-test.c: Also test memxor3. + +2010-09-30 Niels Möller + + * configure.ac: Link in memxor.asm, if found. + + * testsuite/testutils.c (test_cipher_cbc): Print more info when + failing. + + * testsuite/memxor-test.c (test_xor): Added verbose printout. + + * examples/nettle-benchmark.c (time_memxor): Count size of + unsigned long as "block size" for memxor. + +2010-09-24 Niels Möller + + * testsuite/.test-rules.make: Added rule for memxor-test. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Added memxor-test.c + * testsuite/memxor-test.c: New file. + + * memxor.c (memxor_common_alignment): New function. + (memxor_different_alignment): New function. + (memxor): Optimized to do word-operations rather than byte + operations. + + * configure.ac (HAVE_NATIVE_64_BIT): New config.h define. + + Partial revert of 2010-09-20 changes. + * camellia-set-encrypt-key.c (camellia_set_encrypt_key): + Reintroduce CAMELLIA_F_HALF_INV, for 32-bit machines. + * camellia-crypt-internal.c (CAMELLIA_ROUNDSM): Two variants, + differing in where addition of the key is done. + * x86/camellia-crypt-internal.asm: Moved addition of key. + +2010-09-22 Niels Möller + + * examples/nettle-benchmark.c (BENCH_INTERVAL): Changed unit to + seconds. + (time_function): Use clock_gettime with CLOCK_PROCESS_CPUTIME_ID, + if available. This gives better accuracy, at least on recent + linux. + (BENCH_INTERVAL): Reduced to 0.1 s. + (struct bench_memxor_info): New struct. + (bench_memxor): New function. + (time_memxor): New function. + (main): Use time_memxor. Added optional argument used to limit the + algorithms being benchmarked. + (GET_CYCLE_COUNTER): Define also for x86_64. + (time_memxor): Improved display. + + * examples/Makefile.in (nettle-benchmark): Link using + $(BENCH_LIBS) rather than $(LIBS). + + * configure.ac: Check for clock_gettime, and add -lrt to + BENCH_LIBS if needed. + +2010-09-20 Niels Möller + + * configure.ac: Less quoting when invoking $CC, to allow CC="gcc + -m32". + + * x86/camellia-crypt-internal.asm (ROUND): Adapted to new key + convention, moving key xor to the end. + + * camellia-set-encrypt-key.c (CAMELLIA_F_HALF_INV): Deleted macro. + (camellia_set_encrypt_key): Deleted the CAMELLIA_F_HALF_INV + operations intended for moving the key xor into the middle of the + round. + + * camellia-crypt-internal.c (CAMELLIA_ROUNDSM): Moved addition of + key to the end, to use a 64-bit xor operation. + + * x86_64/camellia-crypt-internal.asm: New file. + + * x86_64/machine.m4 (LREG, HREG, XREG): New macros. + +2010-09-17 Niels Möller + + * configure.ac: Support shared libraries (dlls) with mingw32. + Contributed by David Hoyt. + +2010-07-25 Niels Möller + + * configure.ac: Changed version number to nettle-2.2. + + * 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: Likewise. + * rsa_sha1.c: Likewise. + + * 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 exit 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..a74881a --- /dev/null +++ b/Makefile.in @@ -0,0 +1,651 @@ +# Nettle Makefile + +@SET_MAKE@ + +srcdir = @srcdir@ +VPATH = @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@ + +OPT_NETTLE_OBJS = @OPT_NETTLE_OBJS@ +OPT_HOGWEED_OBJS = @OPT_HOGWEED_OBJS@ + +OPT_NETTLE_SOURCES = @OPT_NETTLE_SOURCES@ + +SUBDIRS = tools testsuite examples + +include config.make + +PRE_CPPFLAGS = -I. +EXTRA_CFLAGS = $(CCPIC) + +# FIXME: Add configuration of LIBEXT? +LIBTARGETS = @IF_STATIC@ libnettle.a @IF_HOGWEED@ libhogweed.a +SHLIBTARGETS = @IF_SHARED@ $(LIBNETTLE_FORLINK) @IF_HOGWEED@ $(LIBHOGWEED_FORLINK) + +getopt_SOURCES = getopt.c getopt1.c +getopt_TARGETS = $(getopt_SOURCES:.c=.$(OBJEXT)) + +internal_SOURCES = nettle-internal.c +internal_TARGETS = $(internal_SOURCES:.c=.$(OBJEXT)) + +TARGETS = aesdata$(EXEEXT_FOR_BUILD) desdata$(EXEEXT_FOR_BUILD) \ + twofishdata$(EXEEXT_FOR_BUILD) shadata$(EXEEXT_FOR_BUILD) \ + gcmdata$(EXEEXT_FOR_BUILD) \ + $(getopt_TARGETS) $(internal_TARGETS) \ + $(LIBTARGETS) $(SHLIBTARGETS) + +DOCTARGETS = @IF_DOCUMENTATION@ nettle.info nettle.html nettle.pdf + +PKGCONFIG_FILES = nettle.pc @IF_HOGWEED@ hogweed.pc +pkgconfigdir = $(libdir)/pkgconfig + +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-invert-internal.c aes-set-key-internal.c \ + aes-set-encrypt-key.c aes-set-decrypt-key.c \ + aes128-set-encrypt-key.c aes128-set-decrypt-key.c \ + aes128-meta.c \ + aes192-set-encrypt-key.c aes192-set-decrypt-key.c \ + aes192-meta.c \ + aes256-set-encrypt-key.c aes256-set-decrypt-key.c \ + aes256-meta.c \ + arcfour.c arcfour-crypt.c \ + arctwo.c arctwo-meta.c blowfish.c \ + base16-encode.c base16-decode.c base16-meta.c \ + base64-encode.c base64-decode.c base64-meta.c \ + base64url-encode.c base64url-decode.c base64url-meta.c \ + buffer.c buffer-init.c \ + camellia-crypt-internal.c camellia-table.c \ + camellia-absorb.c camellia-invert-key.c \ + camellia128-set-encrypt-key.c camellia128-crypt.c \ + camellia128-set-decrypt-key.c \ + camellia128-meta.c \ + camellia192-meta.c \ + camellia256-set-encrypt-key.c camellia256-crypt.c \ + camellia256-set-decrypt-key.c \ + camellia256-meta.c \ + cast128.c cast128-meta.c cbc.c \ + ccm.c ccm-aes128.c ccm-aes192.c ccm-aes256.c cfb.c \ + cnd-memcpy.c \ + chacha-crypt.c chacha-core-internal.c \ + chacha-poly1305.c chacha-poly1305-meta.c \ + chacha-set-key.c chacha-set-nonce.c \ + ctr.c des.c des3.c des-compat.c \ + eax.c eax-aes128.c eax-aes128-meta.c \ + gcm.c gcm-aes.c \ + gcm-aes128.c gcm-aes128-meta.c \ + gcm-aes192.c gcm-aes192-meta.c \ + gcm-aes256.c gcm-aes256-meta.c \ + gcm-camellia128.c gcm-camellia128-meta.c \ + gcm-camellia256.c gcm-camellia256-meta.c \ + gosthash94.c gosthash94-meta.c \ + hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \ + hmac-sha224.c hmac-sha256.c hmac-sha384.c hmac-sha512.c \ + knuth-lfib.c hkdf.c \ + md2.c md2-meta.c md4.c md4-meta.c \ + md5.c md5-compress.c md5-compat.c md5-meta.c \ + memeql-sec.c memxor.c memxor3.c \ + nettle-lookup-hash.c \ + nettle-meta-aeads.c nettle-meta-armors.c \ + nettle-meta-ciphers.c nettle-meta-hashes.c \ + pbkdf2.c pbkdf2-hmac-sha1.c pbkdf2-hmac-sha256.c \ + poly1305-aes.c poly1305-internal.c \ + realloc.c \ + ripemd160.c ripemd160-compress.c ripemd160-meta.c \ + salsa20-core-internal.c \ + salsa20-crypt.c salsa20r12-crypt.c salsa20-set-key.c \ + salsa20-set-nonce.c \ + salsa20-128-set-key.c salsa20-256-set-key.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 \ + sha512-224-meta.c sha512-256-meta.c \ + sha3.c sha3-permute.c \ + sha3-224.c sha3-224-meta.c sha3-256.c sha3-256-meta.c \ + sha3-384.c sha3-384-meta.c sha3-512.c sha3-512-meta.c\ + serpent-set-key.c serpent-encrypt.c serpent-decrypt.c \ + serpent-meta.c \ + twofish.c twofish-meta.c \ + umac-nh.c umac-nh-n.c umac-l2.c umac-l3.c \ + umac-poly64.c umac-poly128.c umac-set-key.c \ + umac32.c umac64.c umac96.c umac128.c \ + version.c \ + write-be32.c write-le32.c write-le64.c \ + yarrow256.c yarrow_key_event.c + +hogweed_SOURCES = sexp.c sexp-format.c \ + sexp-transport.c sexp-transport-format.c \ + bignum.c bignum-random.c bignum-random-prime.c \ + sexp2bignum.c \ + pkcs1.c pkcs1-encrypt.c pkcs1-decrypt.c \ + pkcs1-sec-decrypt.c \ + pkcs1-rsa-digest.c pkcs1-rsa-md5.c pkcs1-rsa-sha1.c \ + pkcs1-rsa-sha256.c pkcs1-rsa-sha512.c \ + pss.c pss-mgf1.c \ + rsa.c rsa-sign.c rsa-sign-tr.c rsa-verify.c \ + rsa-sec-compute-root.c \ + rsa-pkcs1-sign.c rsa-pkcs1-sign-tr.c rsa-pkcs1-verify.c \ + rsa-md5-sign.c rsa-md5-sign-tr.c rsa-md5-verify.c \ + rsa-sha1-sign.c rsa-sha1-sign-tr.c rsa-sha1-verify.c \ + rsa-sha256-sign.c rsa-sha256-sign-tr.c rsa-sha256-verify.c \ + rsa-sha512-sign.c rsa-sha512-sign-tr.c rsa-sha512-verify.c \ + rsa-pss-sha256-sign-tr.c rsa-pss-sha256-verify.c \ + rsa-pss-sha512-sign-tr.c rsa-pss-sha512-verify.c \ + rsa-encrypt.c rsa-decrypt.c \ + rsa-sec-decrypt.c rsa-decrypt-tr.c \ + rsa-keygen.c rsa-blind.c \ + rsa2sexp.c sexp2rsa.c \ + dsa.c dsa-compat.c dsa-compat-keygen.c dsa-gen-params.c \ + dsa-sign.c dsa-verify.c dsa-keygen.c dsa-hash.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 \ + sec-add-1.c sec-sub-1.c sec-tabselect.c \ + gmp-glue.c cnd-copy.c \ + ecc-mod.c ecc-mod-inv.c \ + ecc-mod-arith.c ecc-pp1-redc.c ecc-pm1-redc.c \ + ecc-192.c ecc-224.c ecc-256.c ecc-384.c ecc-521.c \ + ecc-25519.c \ + ecc-size.c ecc-j-to-a.c ecc-a-to-j.c \ + ecc-dup-jj.c ecc-add-jja.c ecc-add-jjj.c \ + ecc-eh-to-a.c \ + ecc-dup-eh.c ecc-add-eh.c ecc-add-ehh.c \ + ecc-mul-g-eh.c ecc-mul-a-eh.c \ + ecc-mul-g.c ecc-mul-a.c ecc-hash.c ecc-random.c \ + ecc-point.c ecc-scalar.c ecc-point-mul.c ecc-point-mul-g.c \ + ecc-ecdsa-sign.c ecdsa-sign.c \ + ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c \ + curve25519-mul-g.c curve25519-mul.c curve25519-eh-to-x.c \ + eddsa-compress.c eddsa-decompress.c eddsa-expand.c \ + eddsa-hash.c eddsa-pubkey.c eddsa-sign.c eddsa-verify.c \ + ed25519-sha512-pubkey.c \ + ed25519-sha512-sign.c ed25519-sha512-verify.c + +OPT_SOURCES = fat-x86_64.c fat-arm.c mini-gmp.c + +HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \ + base16.h base64.h bignum.h buffer.h camellia.h cast128.h \ + cbc.h ccm.h cfb.h chacha.h chacha-poly1305.h ctr.h \ + curve25519.h des.h des-compat.h dsa.h dsa-compat.h eax.h \ + ecc-curve.h ecc.h ecdsa.h eddsa.h \ + gcm.h gosthash94.h hmac.h \ + knuth-lfib.h hkdf.h \ + macros.h \ + md2.h md4.h \ + md5.h md5-compat.h \ + memops.h memxor.h \ + nettle-meta.h nettle-types.h \ + pbkdf2.h \ + pgp.h pkcs1.h pss.h pss-mgf1.h realloc.h ripemd160.h rsa.h \ + salsa20.h sexp.h \ + serpent.h sha.h sha1.h sha2.h sha3.h twofish.h \ + umac.h yarrow.h poly1305.h + +INSTALL_HEADERS = $(HEADERS) nettle-stdint.h version.h @IF_MINI_GMP@ mini-gmp.h + +SOURCES = $(nettle_SOURCES) $(hogweed_SOURCES) \ + $(getopt_SOURCES) $(internal_SOURCES) \ + $(OPT_SOURCES) \ + aesdata.c desdata.c twofishdata.c shadata.c gcmdata.c eccdata.c + +# NOTE: This list must include all source files, with no duplicates, +# independently of which source files are included in the build. +DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \ + .bootstrap run-tests \ + aclocal.m4 configure.ac \ + configure stamp-h.in version.h.in \ + libnettle.map.in libhogweed.map.in \ + config.guess config.sub install-sh texinfo.tex \ + config.h.in config.m4.in config.make.in Makefile.in \ + README CONTRIBUTING.md AUTHORS COPYING.LESSERv3 COPYINGv2 COPYINGv3 \ + INSTALL NEWS TODO ChangeLog \ + nettle.pc.in hogweed.pc.in \ + $(des_headers) descore.README \ + aes-internal.h camellia-internal.h serpent-internal.h \ + cast128_sboxes.h desinfo.h desCode.h \ + memxor-internal.h nettle-internal.h nettle-write.h \ + rsa-internal.h \ + gmp-glue.h ecc-internal.h fat-setup.h \ + mini-gmp.h asm.m4 \ + nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c + +# Rules building static libraries +nettle_OBJS = $(nettle_SOURCES:.c=.$(OBJEXT)) \ + $(OPT_NETTLE_SOURCES:.c=.$(OBJEXT)) $(OPT_NETTLE_OBJS) + +hogweed_OBJS = $(hogweed_SOURCES:.c=.$(OBJEXT)) \ + $(OPT_HOGWEED_OBJS) @IF_MINI_GMP@ mini-gmp.$(OBJEXT) + +libnettle.a: $(nettle_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(nettle_OBJS) + $(RANLIB) $@ + echo nettle > libnettle.stamp + +libhogweed.a: $(hogweed_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(hogweed_OBJS) + $(RANLIB) $@ + echo hogweed > libhogweed.stamp + +.c.$(OBJEXT): + $(COMPILE) -c $< \ + && $(DEP_PROCESS) + +# Rules building shared libraries. +$(LIBNETTLE_FORLINK): $(nettle_OBJS) + $(LIBNETTLE_LINK) $(nettle_OBJS) @EXTRA_LINKER_FLAGS@ -o $@ $(LIBNETTLE_LIBS) + -mkdir .lib 2>/dev/null + (cd .lib \ + && rm -f $(LIBNETTLE_FORLINK) \ + && $(LN_S) ../$(LIBNETTLE_FORLINK) $(LIBNETTLE_FORLINK) \ + && [ -z "$(LIBNETTLE_SONAME)" ] \ + || { rm -f $(LIBNETTLE_SONAME) \ + && $(LN_S) $(LIBNETTLE_FORLINK) $(LIBNETTLE_SONAME) ; } ) + echo nettle > libnettle.stamp + +$(LIBHOGWEED_FORLINK): $(hogweed_OBJS) $(LIBNETTLE_FORLINK) + $(LIBHOGWEED_LINK) $(hogweed_OBJS) @EXTRA_HOGWEED_LINKER_FLAGS@ -o $@ $(LIBHOGWEED_LIBS) + -mkdir .lib 2>/dev/null + (cd .lib \ + && rm -f $(LIBHOGWEED_FORLINK) \ + && $(LN_S) ../$(LIBHOGWEED_FORLINK) $(LIBHOGWEED_FORLINK) \ + && [ -z "$(LIBHOGWEED_SONAME)" ] \ + || { rm -f $(LIBHOGWEED_SONAME) \ + && $(LN_S) $(LIBHOGWEED_FORLINK) $(LIBHOGWEED_SONAME) ; } ) + echo hogweed > libhogweed.stamp + +# For Solaris and BSD make, we have to use an explicit rule for each +# executable. Avoid object file targets to make it easy to run the +# right compiler. +aesdata$(EXEEXT_FOR_BUILD): aesdata.c + $(CC_FOR_BUILD) `test -f aesdata.c || echo '$(srcdir)/'`aesdata.c \ + -o aesdata$(EXEEXT_FOR_BUILD) + +desdata$(EXEEXT_FOR_BUILD): desdata.c + $(CC_FOR_BUILD) `test -f desdata.c || echo '$(srcdir)/'`desdata.c \ + -o desdata$(EXEEXT_FOR_BUILD) + +twofishdata$(EXEEXT_FOR_BUILD): twofishdata.c + $(CC_FOR_BUILD) `test -f twofishdata.c || echo '$(srcdir)/'`twofishdata.c \ + -o twofishdata$(EXEEXT_FOR_BUILD) + +shadata$(EXEEXT_FOR_BUILD): shadata.c + $(CC_FOR_BUILD) `test -f shadata.c || echo '$(srcdir)/'`shadata.c -lm \ + -o shadata$(EXEEXT_FOR_BUILD) + +gcmdata$(EXEEXT_FOR_BUILD): gcmdata.c + $(CC_FOR_BUILD) `test -f gcmdata.c || echo '$(srcdir)/'`gcmdata.c \ + -o gcmdata$(EXEEXT_FOR_BUILD) + +eccdata$(EXEEXT_FOR_BUILD): eccdata.c mini-gmp.c mini-gmp.h + $(CC_FOR_BUILD) `test -f eccdata.c || echo '$(srcdir)/'`eccdata.c \ + -o eccdata$(EXEEXT_FOR_BUILD) + +# 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_FOR_BUILD) + f="$(srcdir)/`basename $@`"; \ + ./desdata$(EXEEXT_FOR_BUILD) $(@F) > $${f}T; \ + test -s $${f}T && mv -f $${f}T $$f + +des.$(OBJEXT): des.c des.h $(des_headers) + +# Generate ECC files. +# Some possible choices for 192: +# k = 15, c = 4, 64 entries, ~3 KB +# k = 20, c = 6, 128 entries, ~6 KB +# k = 10, c = 6, 256 entries, ~12 KB +# k = 7, c = 6, 320 entries, ~15 KB +# k = 9, c = 7, 512 entries, ~24 KB +ecc-192.h: eccdata.stamp + ./eccdata$(EXEEXT_FOR_BUILD) 192 7 6 $(NUMB_BITS) > $@T && mv $@T $@ +# Some possible choices for 224: +# k = 18, c = 4, 64 entries, ~4 KB +# k = 24, c = 6, 128 entries, ~8 KB +# k = 12, c = 6, 256 entries, ~16 KB +# k = 8, c = 6, 320 entries, ~20 KB +# k = 10, c = 7, 512 entries, ~32 KB +ecc-224.h: eccdata.stamp + ./eccdata$(EXEEXT_FOR_BUILD) 224 12 6 $(NUMB_BITS) > $@T && mv $@T $@ +# Some possible choices for 256: +# k = 20, c = 4, 64 entries, ~4 KB +# k = 27, c = 6, 128 entries, ~8 KB +# k = 14, c = 6, 256 entries, ~16 KB +# k = 9, c = 6, 320 entries, ~20 KB +# k = 12, c = 7, 512 entries, ~32 KB +ecc-256.h: eccdata.stamp + ./eccdata$(EXEEXT_FOR_BUILD) 256 14 6 $(NUMB_BITS) > $@T && mv $@T $@ +# Some possible choices for 384: +# k = 31, c = 4, 64 entries, ~6 KB +# k = 41, c = 6, 128 entries, ~12 KB +# k = 20, c = 6, 256 entries, ~24 KB +# k = 14, c = 6, 320 entries, ~30 KB +# k = 18, c = 7, 512 entries, ~48 KB +ecc-384.h: eccdata.stamp + ./eccdata$(EXEEXT_FOR_BUILD) 384 41 6 $(NUMB_BITS) > $@T && mv $@T $@ +# Some possible choices for 521: +# k = 42, c = 4, 64 entries, ~9 KB +# k = 56, c = 6, 128 entries, ~18 KB +# k = 28, c = 6, 256 entries, ~35 KB +# k = 19, c = 6, 320 entries, ~44 KB +# k = 24, c = 7, 512 entries, ~70 KB +ecc-521.h: eccdata.stamp + ./eccdata$(EXEEXT_FOR_BUILD) 521 56 6 $(NUMB_BITS) > $@T && mv $@T $@ + +ecc-25519.h: eccdata.stamp + ./eccdata$(EXEEXT_FOR_BUILD) 255 14 6 $(NUMB_BITS) > $@T && mv $@T $@ + +eccdata.stamp: eccdata.c + $(MAKE) eccdata$(EXEEXT_FOR_BUILD) + echo stamp > eccdata.stamp + +ecc-192.$(OBJEXT): ecc-192.h +ecc-224.$(OBJEXT): ecc-224.h +ecc-256.$(OBJEXT): ecc-256.h +ecc-384.$(OBJEXT): ecc-384.h +ecc-521.$(OBJEXT): ecc-521.h +ecc-25519.$(OBJEXT): ecc-25519.h + +.asm.$(OBJEXT): $(srcdir)/asm.m4 machine.m4 config.m4 + $(M4) $(srcdir)/asm.m4 machine.m4 config.m4 $< >$*.s + $(COMPILE) -c $*.s + @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 -b `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 $@ + +nettle.pc: nettle.pc.in config.status + ./config.status $@ + +hogweed.pc: hogweed.pc.in config.status + ./config.status $@ + +version.h: version.h.in config.status + ./config.status $@ + +# Installation +install-doc: @IF_DOCUMENTATION@ install-info +install-here: install-doc install-headers install-static install-pkgconfig \ + @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-dll-nettle: + $(MKDIR_P) $(DESTDIR)$(bindir) + $(INSTALL_DATA) $(LIBNETTLE_FORLINK) $(DESTDIR)$(bindir)/$(LIBNETTLE_FORLINK) + +install-shared-nettle: $(LIBNETTLE_FORLINK) @IF_DLL@ install-dll-nettle + $(MKDIR_P) $(DESTDIR)$(libdir) + $(INSTALL_DATA) $(LIBNETTLE_FILE_SRC) $(DESTDIR)$(libdir)/$(LIBNETTLE_FILE) + [ -z "$(LIBNETTLE_SONAME)" ] \ + || (cd $(DESTDIR)$(libdir) \ + && rm -f $(LIBNETTLE_SONAME) $(LIBNETTLE_FORLINK) \ + && $(LN_S) $(LIBNETTLE_FILE) $(LIBNETTLE_SONAME) \ + && $(LN_S) $(LIBNETTLE_FILE) $(LIBNETTLE_FORLINK)) + +install-dll-hogweed: + $(MKDIR_P) $(DESTDIR)$(bindir) + $(INSTALL_DATA) $(LIBHOGWEED_FORLINK) $(DESTDIR)$(bindir)/$(LIBHOGWEED_FORLINK) + +install-shared-hogweed: $(LIBHOGWEED_FORLINK) @IF_DLL@ install-dll-hogweed + $(MKDIR_P) $(DESTDIR)$(libdir) + $(INSTALL_DATA) $(LIBHOGWEED_FILE_SRC) $(DESTDIR)$(libdir)/$(LIBHOGWEED_FILE) + [ -z "$(LIBHOGWEED_SONAME)" ] \ + || (cd $(DESTDIR)$(libdir) \ + && rm -f $(LIBHOGWEED_SONAME) $(LIBHOGWEED_FORLINK) \ + && $(LN_S) $(LIBHOGWEED_FILE) $(LIBHOGWEED_SONAME) \ + && $(LN_S) $(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 + +install-pkgconfig: $(PKGCONFIG_FILES) + $(MKDIR_P) $(DESTDIR)$(pkgconfigdir) + for f in $(PKGCONFIG_FILES) ; do \ + $(INSTALL_DATA) "$$f" $(DESTDIR)$(pkgconfigdir) ; \ + done + +# Uninstall +uninstall-here: uninstall-info uninstall-headers uninstall-static \ + uninstall-pkgconfig @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-dll-nettle: + rm -f $(DESTDIR)$(bindir)/$(LIBNETTLE_FORLINK) + +uninstall-shared-nettle: @IF_DLL@ uninstall-dll-nettle + rm -f $(DESTDIR)$(libdir)/$(LIBNETTLE_FILE) + [ -z "$(LIBNETTLE_SONAME)" ] \ + || rm -f $(LIBNETTLE_SONAME) $(LIBNETTLE_FORLINK) + +uninstall-dll-hogweed: + rm -f $(DESTDIR)$(bindir)/$(LIBHOGWEED_FORLINK) + +uninstall-shared-hogweed: @IF_DLL@ uninstall-dll-hogweed + rm -f $(DESTDIR)$(libdir)/$(LIBHOGWEED_FILE) + [ -z "$(LIBHOGWEED_SONAME)" ] \ + || rm -f $(LIBHOGWEED_SONAME) $(LIBHOGWEED_FORLINK) + +uninstall-pkgconfig: + for f in $(PKGCONFIG_FILES) ; do \ + rm -f $(DESTDIR)$(pkgconfigdir)/$$f ; \ + done + +# 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 x86_64/aesni x86_64/fat \ + arm arm/neon arm/v6 arm/fat ; do \ + mkdir "$(distdir)/$$d" ; \ + find "$(srcdir)/$$d" -maxdepth 1 '(' -name '*.asm' -o -name '*.m4' ')' \ + -exec cp '{}' "$(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) *.s *.so *.dll *.a \ + ecc-192.h ecc-224.h ecc-256.h ecc-384.h ecc-521.h ecc-25519.h \ + eccdata$(EXEEXT_FOR_BUILD) eccdata.stamp + -rm -rf .lib libnettle.stamp libhogweed.stamp + +distclean-here: clean-here + -rm -f config.h stamp-h config.log config.status machine.m4 \ + config.make config.m4 Makefile nettle-stdint.h version.h \ + nettle.pc hogweed.pc libnettle.map libhogweed.map \ + *.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) +@DEP_INCLUDE@ $(DEP_FILES) diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..cadd0f0 --- /dev/null +++ b/NEWS @@ -0,0 +1,1292 @@ +NEWS for the Nettle 3.4.1 release + + This release fixes a few bugs, and makes the RSA private key + operations side channel silent. The RSA improvements are + contributed by Simo Sorce and Red Hat, and include one new + public function, rsa_sec_decrypt, see below. + + All functions using RSA private keys are now side-channel + silent, meaning that they try hard to avoid any branches or + memory accesses depending on secret data. This applies both to + the bignum calculations, which now use GMP's mpn_sec_* family + of functions, and the processing of PKCS#1 padding needed for + RSA decryption. + + Nettle's ECC functions were already side-channel silent, while + the DSA functions still aren't. There's also one caveat + regarding the improved RSA functions: due to small table + lookups in relevant mpn_sec_* functions in GMP-6.1.2, the + lowest and highest few bits of the secret factors p and q may + still leak. I'm not aware of any attacks on RSA where knowing + a few bits of the factors makes a significant difference. This + leak will likely be plugged in later GMP versions. + + Changes in behavior: + + * The functions rsa_decrypt and rsa_decrypt_tr may now clobber + all of the provided message buffer, independent of the + actual message length. They are side-channel silent, in that + branches and memory accesses don't depend on the validity or + length of the message. Side-channel leakage from the + caller's use of length and return value may still provide an + oracle useable for a Bleichenbacher-style chosen ciphertext + attack. Which is why the new function rsa_sec_decrypt is + recommended. + + New features: + + * A new function rsa_sec_decrypt. It differs from + rsa_decrypt_tr in that the length of the decrypted message + is given a priori, and PKCS#1 padding indicating a different + length is treated as an error. For applications that may be + subject to chosen ciphertext attacks, it is recommended to + initialize the message area with random data, call this + function, and ignore the return value. This applies in + particular to RSA-based key exchange in the TLS protocol. + + Bug fixes: + + * Fix bug in pkcs1-conv, missing break statements in the + parsing of PEM input files. + + * Fix link error on the pss-mgf1-test test, affecting builds + without public key support. + + Performance regression: + + * All RSA private key operations employing RSA blinding, i.e., + rsa_decrypt_tr, rsa_*_sign_tr, the new rsa_sec_decrypt, and + rsa_compute_root_tr, are significantly slower. This is + because (i) RSA blinding now use side-channel silent + operations, (ii) blinding includes a modular inversion, and + (iii) side-channel silent modular inversion, implemented as + mpn_sec_invert, is very expensive. A 60% slowdown for + 2048-bit RSA keys have been measured. + + Miscellaneous: + + * Building the public key support of nettle now requires GMP + version 6.0 or later (unless --enable-mini-gmp is used). + + The shared library names are libnettle.so.6.5 and + libhogweed.so.4.5, with sonames still libnettle.so.6 and + libhogweed.so.4. It is intended to be fully binary compatible + with nettle-3.1. + +NEWS for the Nettle 3.4 release + + This release fixes bugs and adds a few new features. It also + addresses an ABI compatibility issue affecting Nettle-3.1 and + later, see below. + + Bug fixes: + + * Fixed an improper use of GMP mpn_mul, breaking curve2559 and + eddsa on certain platforms. Reported by Sergei Trofimovich. + + * Fixed memory leak when handling invalid signatures in + ecdsa_verify. Fix contributed by Nikos Mavrogiannopoulos. + + * Fix compilation error with --enable-fat om ARM. Fix + contributed by Andreas Schneider. + + * Reorganized the way certain data items are made available. + + Short version: Nettle header files now define the symbols + nettle_hashes, nettle_ciphers, and nettle_aeads, as + preprocessor macros invoking a corresponding accessor + function. For backwards ABI compatibility, the symbols are + still present in the compiled libraries, and with the same + sizes as in nettle-3.3. + + New features: + + * Support for RSA-PSS signatures, contributed by Daiki Ueno. + + * Support for the HKDF key derivation function, defined by RFC + 5869. Contributed by Nikos Mavrogiannopoulos. + + * Support for the Cipher Feedback Mode (CFB), contributed by + Dmitry Eremin-Solenikov. + + * New accessor functions: nettle_get_hashes, + nettle_get_ciphers, nettle_get_aeads, nettle_get_secp_192r1, + nettle_get_secp_224r1, nettle_get_secp_256r1, + nettle_get_secp_384r1, nettle_get_secp_521r1. + + For source-level compatibility with future versions, + applications are encouraged to migrate to using these + functions instead of referring to the corresponding data + items directly. + + Miscellaneous: + + * The base16 and base64 functions now use the type char * for + ascii data, rather than uint8_t *. This eliminates the last + pointer-signedness warnings when building Nettle. This is a + minor API change, and applications may need to be adjusted, + but the ABI is unaffected on all platforms I'm aware of. + + * The contents of the header file nettle/version.h is now + architecture independent, except in --enable-mini-gmp + configurations. + + ABI issue: + + Since the breakage was a bit subtle, let me document it + here. The nettle and hogweed libraries export a couple of + data symbols, and for some of these, the size was never + intended to be part of the ABI. E.g., + + extern const struct nettle_hash * const nettle_hashes[]; + + which is an NULL-terminated array. + + It turns out the sizes nevertheless may leak into the ABI, and + that increasing the sizes can break old executables linked + with a newer version of the library. + + When linking a classic non-PIE executable with a shared + library, we get ELF relocations of type R_X86_64_COPY for + references to data items. These mean that the linker allocates + space for the data item in the data segment of executable, at + a fixed address determined at link-time, and with size + extracted from the version of the .so-file seen when linking. + + At load time, the run time linker then copies the contents of + the symbol from the .so file to that location, and uses the + copy instead of the version loaded with the .so-file. And if + the data item in the .so file used at load time is larger than + the data item seen at link time, it is silently truncated in + the process. + + So when SHA3 hashes were was added to the nettle_hashes array + in the nettle-3.3 release, this way of linking produces a + truncated array at load time, no longer NULL-terminated. + + We will get similar problems for planned extensions of the + internal struct ecc_curve, and exported data items like + + extern const struct ecc_curve nettle_secp_256r1; + + where the ecc_curve struct is only forward declared in the + public headers. To prepare, applications should migrate to + using the new function nettle_get_secp_256r1, and similarly + for the other curves. + + In some future version, the plan is to add a leading + underscore to the name of the actual data items. E.g., + nettle_hashes --> _nettle_hashes, breaking the ABI, while + keeping the nettle_get_hashes function and the nettle_hashes + macro as the supported ways to access it. We will also + rename nettle_secp_256r1 --> _nettle_secp_256r1, breaking + both ABI and API. + + Note that data items like nettle_sha256 are *not* affected, + since the size and layout of this struct is considered part + of the ABI, and R_X86_64_COPY-relocations then work fine. + + The shared library names are libnettle.so.6.4 and + libhogweed.so.4.4, with sonames still libnettle.so.6 and + libhogweed.so.4. It is intended to be fully binary compatible + with nettle-3.1. + +NEWS for the Nettle 3.3 release + + This release fixes a couple of bugs, and improves resistance + to side-channel attacks on RSA and DSA private key operations. + + Changes in behavior: + + * Invalid private RSA keys, with an even modulo, are now + rejected by rsa_private_key_prepare. (Earlier versions + allowed such keys, even if results of using them were bogus). + + Nettle applications are required to call + rsa_private_key_prepare and check the return value, before + using any other RSA private key functions; failing to do so + may result in crashes for invalid private keys. As a + workaround for versions of Gnutls which don't use + rsa_private_key_prepare, additional checks for even moduli + are added to the rsa_*_tr functions which are used by all + recent versions of Gnutls. + + * Ignore bit 255 of the x coordinate of the input point to + curve25519_mul, as required by RFC 7748. To differentiate at + compile time, curve25519.h defines the constant + NETTLE_CURVE25519_RFC7748. + + Security: + + * RSA and DSA now use side-channel silent modular + exponentiation, to defend against attacks on the private key + from evil processes sharing the same processor cache. This + attack scenario is of particular relevance when running an + HTTPS server on a virtual machine, where you don't know who + you share the cache hardware with. + + (Private key operations on elliptic curves were already + side-channel silent). + + Bug fixes: + + * Fix sexp-conv crashes on invalid input. Reported by Hanno + Böck. + + * Fix out-of-bounds read in des_weak_p. Fixed by Nikos + Mavrogiannopoulos. + + * Fix a couple of formally undefined shift operations, + reported by Nikos Mavrogiannopoulos. + + * Fix compilation with c89. Reported by Henrik Grubbström. + + New features: + + * New function memeql_sec, for side-channel silent comparison + of two memory areas. + + Miscellaneous: + + * Building the public key support of nettle now requires GMP + version 5.0 or later (unless --enable-mini-gmp is used). + + * Filenames of windows DLL libraries now include major number + only. So the dll names change at the same time as the + corresponding soname on ELF platforms. Fixed by Nikos + Mavrogiannopoulos. + + * Eliminate most pointer-signedness warnings. In the process, + the strings representing expression type for sexp_interator + functions were changed from const uint8_t * to const char *. + These functions are undocumented, and it doesn't change the + ABI on any platform I'm aware of. + + The shared library names are libnettle.so.6.3 and + libhogweed.so.4.3, with sonames still libnettle.so.6 and + libhogweed.so.4. It is intended to be fully binary compatible + with nettle-3.1. + +NEWS for the Nettle 3.2 release + + Bug fixes: + + * The SHA3 implementation is updated according to the FIPS 202 + standard. It is not interoperable with earlier versions of + Nettle. Thanks to Nikos Mavrogiannopoulos. To easily + differentiate at compile time, sha3.h defines the constant + NETTLE_SHA3_FIPS202. + + * Fix corner-case carry propagation bugs affecting elliptic + curve operations on the curves secp_256r1 and secp_384r1 on + certain platforms, including x86_64. Reported by Hanno Böck. + + New features: + + * New functions for RSA private key operations, identified by + the "_tr" suffix, with better resistance to side channel + attacks and to hardware or software failures which could + break the CRT optimization. See the Nettle manual for + details. Initial patch by Nikos Mavrogiannopoulos. + + * New functions nettle_version_major, nettle_version_minor, as + a run-time variant of the compile-time constants + NETTLE_VERSION_MAJOR and NETTLE_VERSION_MINOR. + + Optimizations: + + * New ARM Neon implementation of the chacha stream cipher. + + Miscellaneous: + + * ABI detection on mips, with improved default libdir + location. Contributed by Klaus Ziegler. + + * Fixes for ARM assembly syntax, to work better with the clang + assembler. Thanks to Jukka Ukkonen. + + * Disabled use of ifunc relocations for fat builds, to fix + problems most easily triggered by using dlopen RTLD_NOW. + + The shared library names are libnettle.so.6.2 and + libhogweed.so.4.2, with sonames still libnettle.so.6 and + libhogweed.so.4. It is intended to be fully binary compatible + with nettle-3.1. + +NEWS for the Nettle 3.1.1 release + + This release fixes a couple of non-critical bugs. + + Bug fixes: + + * By accident, nettle-3.1 disabled the assembly code for the + secp_224r1 and secp_521r1 elliptic curves on all x86_64 + configurations, making signature operations on those curves + 10%-30% slower. This code is now re-enabled. + + * The x86_64 assembly implementation of gcm hashing has been + fixed to work with the Sun/Oracle assembler. + + The shared library names are libnettle.so.6.1 and + libhogweed.so.4.1, with sonames still libnettle.so.6 and + libhogweed.so.4. It is intended to be fully binary compatible + with nettle-3.1. + +NEWS for the Nettle 3.1 release + + This release adds a couple of new features. + + The library is mostly source-level compatible with nettle-3.0. + It is however not binary compatible, due to the introduction + of versioned symbols, and extensions to the base64 context + structs. The shared library names are libnettle.so.6.0 and + libhogweed.so.4.0, with sonames libnettle.so.6 and + libhogweed.so.4. + + Bug fixes: + + * Fixed a missing include of , which made the + camellia implementation fail on all 64-bit non-x86 + platforms. + + * Eliminate out-of-bounds reads in the C implementation of + memxor (related to valgrind's --partial-loads-ok flag). + + Interface changes: + + * Declarations of many internal functions are moved from ecc.h + to ecc-internal.h. The functions are undocumented, and + luckily they're apparently also unused by applications, so I + don't expect any problems from this change. + + New features: + + * Support for curve25519 and for EdDSA25519 signatures. + + * Support for "fat builds" on x86_64 and arm, where the + implementation of certain functions is selected at run-time + depending on available cpu features. Configure with + --enable-fat to try this out. If it turns out to work well + enough, it will likely be enabled by default in later + releases. + + * Support for building the hogweed library (public key + support) using "mini-gmp", a small but slower implementation + of a subset of the GMP interfaces. Note that builds using + mini-gmp are *not* binary compatible with regular builds, + and more likely to leak side-channel information. + + One intended use-case is for small embedded applications + which need to verify digital signatures. + + * The shared libraries are now built with versioned symbols. + Should reduce problems in case a program links explicitly to + nettle and/or hogweed, and to gnutls, and the program and + gnutls expect different versions. + + * Support for "URL-safe" base64 encoding and decoding, as + specified in RFC 4648. Contributed by Amos Jeffries. + + Optimizations: + + * New x86_64 implementation of AES, using the "aesni" + instructions. Autodetected in fat builds. In non-fat builds, + it has to be enabled explicitly with --enable-x86-aesni. + + Build system: + + * Use the same object files for both static and shared + libraries. This eliminates the *.po object files which were + confusing to some tools (as well as humans). Like before, + PIC code is used by default; to build a non-pic static + library, configure with --disable-pic --disable-shared. + + Miscellaneous: + + * Made type-checking hack in CBC_ENCRYPT and similar macros + stricter, to generate warnings if they are used with + functions which have a length argument smaller than size_t. + +NEWS for the Nettle 3.0 release + + This is a major release, including several interface changes, + and new features, some of which are a bit experimental. + Feedback is highly appreciated. + + It is *not* binary (ABI) compatible with earlier versions. It + is mostly source-level (API) compatible, with a couple of + incompatibilities noted below. The shared library names are + libnettle.so.5.0 and libhogweed.so.3.0, with sonames + libnettle.so.5 and libhogweed.so.3. + + There may be some problems in the new interfaces and new + features which really need incompatible fixes. It is likely + that there will be an update in the form of a 3.1 release in + the not too distant future, with small but incompatible + changes, and if that happens, bugfix-only releases 3.0.x are + unlikely. Users and applications which desire better API and + ABI stability are advised to stay with nettle-2.7.x (latest + version is now 2.7.1) until the dust settles. + + Interface changes: + + * For the many _set_key functions, it is now consider the + normal case to have a fixed key size, with no key_size + arguments. _set_key functions with a length parameter are + provided only for algorithms with a truly variable keysize, + and where it makes sense for backwards compatibility. + + INCOMPATIBLE CHANGE: cast128_set_key no longer accepts a key + size argument. The old function is available under a new + name, cast5_set_key. + + INCOMPATIBLE CHANGE: The function typedef + nettle_set_key_func no longer accepts a key size argument. + In particular, this affects users of struct nettle_cipher. + + * The nettle_cipher abstraction (in nettle-meta.h) is + restricted to block ciphers only. The encrypt and decrypt + functions now take a const argument for the context. + + INCOMPATIBLE CHANGE: nettle_arcfour, i.e., the nettle_cipher + abstraction for the arcfour stream cipher, is deleted. + + INCOMPATIBLE CHANGE: New type, nettle_cipher_func, for the + encrypt and decrypt fields of struct nettle_cipher. + + * New DSA interface, with a separate struct dsa_param to + represent the underlying group, and generalized dsa_sign and + dsa_verify functions which don't care about the hash + function used. Limited backwards compatibility provided in + dsa-compat.h. + + INCOMPATIBLE CHANGE: Declarations of the old interface, + e.g., struct dsa_public_key, dsa_sha1_sign, etc, is moved to + dsa-compat.h. + + INCOMPATIBLE CHANGE: The various key conversion functions, + e.g., dsa_keypair_to_sexp, all use the new DSA interface, with + no backwards compatible functions. + + INCOMPATIBLE CHANGE: dsa_generate_keypair also uses the new + interface. dsa-compat.h declares a function + dsa_compat_generate_keypair, implementing the old + interface, and #defines dsa_generate_keypair to refer to + this backwards compatible function. + + * New AES and Camellia interfaces. There are now separate + context structs for each key size, e.g., aes128_ctx and + camellia256_ctx, and corresponding new functions. The old + interface, with struct aes_ctx and struct camellia_ctx, is + kept for backwards compatibility, but might be removed in + later versions. + + * The type of most length arguments is changed from unsigned + to size_t. The memxor functions have their pointer arguments + changed from uint8_t * to void *, for consistency with + related libc functions. + + * For hash functions, the constants *_DATA_SIZE have been + renamed to *_BLOCK_SIZE. Old names kept for backwards + compatibility. + + Removed features: + + * The nettle_next_prime function has been deleted. + Applications should use GMP's mpz_nextprime instead. + + * Deleted the RSAREF compatibility, including the header file + rsa-compat.h and everything declared therein. + + * Also under consideration for removal is des-compat.h and + everything declared therein. This implements a subset of the + old libdes/ssleay/openssl interface for DES and triple-DES, + and it is poorly tested. If anyone uses this interface, + please speak up! Otherwise, it will likely be removed in the + next release. + + Bug fixes: + + * Building with ./configure --disable-static now works. + + * Use GMP's allocation functions for temporary storage related + to bignums, to avoid potentially large stack allocations. + + * Fixes for shared libraries on M$ Windows. + + New features: + + * Support for Poly1305-AES MAC. + + * Support for the ChaCha stream cipher and EXPERIMENTAL + support for the ChaCha-Poly1305 AEAD mode. Specifications + are still in flux, and future releases may do incompatible + changes to track standardization. Currently uses 256-bit key + and 64-bit nonce. + + * Support for EAX mode. + + * Support for CCM mode. Contributed by Owen Kirby. + + * Additional variants of SHA512 with output size of 224 and + 256 bits. Contributed by Joachim Strömbergson. + + * New interface, struct nettle_aead, for mechanisms providing + authenticated encryption with associated data (AEAD). + + * DSA: Support a wider range for the size of q and a wider + range for the digest size. + + Optimizations: + + * New x86_64 assembly for GCM and MD5. Modest speedups on the + order of 10%-20%. + + Miscellaneous: + + * SHA3 is now documented as EXPERIMENTAL. Nettle currently + implements SHA3 as specified at the time Keccak won the SHA3 + competition. However, the final standard specified by NIST + is likely to be incompatible, in which case future releases + may do incompatible changes to track standardization. + + * The portability fix for the rotation macros, mentioned in + NEWS for 2.7.1, actually didn't make it into that release. + It is included now. + + * cast128_set_key rewritten for clarity, also eliminating a + couple of compiler warnings. + + * New command line tool nettle-pbkdf2. + +NEWS for the 2.7.1 release + + This is a bugfix release. + + Bug fixes: + + * Fixed a bug in the new ECC code. The ecc_j_to_a function + called GMP:s mpn_mul_n (via ecc_modp_mul) with overlapping + input and output arguments, which is not supported. + + * The assembly files for SHA1, SHA256 and AES depend on ARMv6 + instructions, breaking nettle-2.7 for pre-v6 ARM processors. + The configure script now enables those assembly files only + when building for ARMv6 or later. + + * Use a more portable C expression for rotations. The + previous version used the following "standard" expression + for 32-bit rotation: + + (x << n) | (x >> (32 - n)) + + But this gives undefined behavior (according to the C + specification) for n = 0. The rotate expression is replaced + by the more portable: + + (x << n) | (x >> ((-n)&31)) + + This change affects only CAST128, which uses non-constant + rotation counts. Unfortunately, the new expression is poorly + optimized by released versions of gcc, making CAST128 a bit + slower. This is being fixed by the gcc hackers, see + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57157. + + The following problems have been reported, but are *not* fixed + in this release: + + * ARM assembly files use instruction syntax which is not + supported by all assemblers. Workaround: Use a current + version of GNU as, or configure with --disable-assembler. + + * Configuring with --disable-static doesn't work on windows. + + The libraries are intended to be binary compatible with + nettle-2.2 and later. The shared library names are + libnettle.so.4.7 and libhogweed.so.2.5, with sonames still + libnettle.so.4 and libhogweed.so.2. + +NEWS for the 2.7 release + + This release includes an implementation of elliptic curve + cryptography (ECC) and optimizations for the ARM architecture. + This work was done at the offices of South Pole AB, and + generously funded by the .SE Internet Fund. + + Bug fixes: + + * Fixed a bug in the buffer handling for incremental SHA3 + hashing, with a possible buffer overflow. Patch by Edgar + E. Iglesias. + + New features: + + * Support for ECDSA signatures. Elliptic curve operations over + the following curves: secp192r1, secp224r1, secp256r1, + secp384r1 and secp521r1, including x86_64 and ARM assembly + for the most important primitives. + + * Support for UMAC, including x86_64 and ARM assembly. + + * Support for 12-round salsa20, "salsa20r12", as specified by + eSTREAM. Contributed by Nikos Mavrogiannopoulos. + + Optimizations: + + * ARM assembly code for several additional algorithms, + including AES, Salsa20, and the SHA family of hash + functions. + + * x86_64 assembly for SHA256, SHA512, and SHA3. (SHA3 assembly + was included in the 2.6 release, but disabled due to poor + performance on some AMD processors. Hopefully, that + performance problem is fixed now). + + The ARM code was tested and benchmarked on Cortex-A9. Some of + the functions use "neon" instructions. The configure script + decides if neon instructions can be used, and the command line + options --enable-arm-neon and --disable-arm-neon can be used + to override its choice. Feedback appreciated. + + The libraries are intended to be binary compatible with + nettle-2.2 and later. The shared library names are + libnettle.so.4.6 and libhogweed.so.2.4, with sonames still + libnettle.so.4 and libhogweed.so.2. + +NEWS for the 2.6 release + + Bug fixes: + + * Fixed a bug in ctr_crypt. For zero length (which should be a + NOP), it sometimes incremented the counter. Reported by Tim + Kosse. + + * Fixed a small memory leak in nettle_realloc and + nettle_xrealloc. + + New features: + + * Support for PKCS #5 PBKDF2, to generate a key from a + password or passphrase. Contributed by Simon Josefsson. + Specification in RFC 2898 and test vectors in RFC 6070. + + * Support for SHA3. + + * Support for the GOST R 34.11-94 hash algorithm. Ported from + librhash by Nikos Mavrogiannopoulos. Written by Aleksey + Kravchenko. More information in RFC4357. Test vectors taken + from the GOST hash wikipedia page. + + Miscellaneous: + + * The include file has been split into + and . For now, sha.h is kept + for backwards compatibility and it simply includes both + files, but applications are encouraged to use the new names. + The new SHA3 functions are declared in . + + * Testsuite can be run under valgrind, using + + make check EMULATOR='$(VALGRIND)' + + For this to work, test programs and other executables now + deallocate storage. + + * New configure options --disable-documentation and + --disable-static. Contributed by Sam Thursfield and Alon + Bar-Lev, respectively. + + * The section on hash functions in the manual is split into + separate nodes for recommended hash functions and legacy + hash functions. + + * Various smaller improvements, most of them portability + fixes. Credits go to David Woodhouse, Tim Rühsen, Martin + Storsjö, Nikos Mavrogiannopoulos, Fredrik Thulin and Dennis + Clarke. + + Finally, a note on the naming of the various "SHA" hash + functions. Naming is a bit inconsistent; we have, e.g., + + SHA1: sha1_digest + SHA2: sha256_digest (not sha2_256_digest) + SHA3: sha3_256_digest + + Renaming the SHA2 functions to make Nettle's naming more + consistent has been considered, but the current naming follows + common usage. Most documents (including the specification for + SHA2) refer to 256-bit SHA2 as "SHA-256" or "SHA256" rather + than "SHA2-256". + + The libraries are intended to be binary compatible with + nettle-2.2 and later. The shared library names are + libnettle.so.4.5 and libhogweed.so.2.3, with sonames still + libnettle.so.4 and libhogweed.so.2 + +NEWS for the 2.5 release + + This release includes important portability fixes for Windows + and MacOS. There are also a few new features. + + First a *warning*: Some internal functions have been removed + from the library. Since the functions in question are internal + and not documented, this is not considered a change of ABI or + API. Programs explicitly using any of these functions will + break. + + * The function pkcs1_signature_prefix has been renamed to + _pkcs1_signature_prefix, and with slightly different + behavior. + + * The file nettle-internal.c is no longer included in the + library (the features defined there are used by the + benchmark and test programs, and were never intended for + public use). + + New features: + + * Support for the salsa20 stream cipher, including x86_64 + assembler. Originally contributed by Simon Josefsson, based + on the reference implementation, then further optimized. + + * Tentative interface for timing-resistant RSA functions, + contributed by Nikos Mavrogiannopoulos. + + * A more general interface for PKCS#1 signatures, taking the + input in the form of a "DigestInfo". Suggested by Nikos + Mavrogiannopoulos. + + Configuration: + + * Building of shared libraries (./configure --enable-shared) + is now enabled by default. + + * Various portability fixes for MacOS and M$ Windows. A lot of + this work done by Martin Storsjö. + + * In particular, Nettle now hopefully works on 64-bit Windows + builds, "W64", including the x86_64 assembly code. + + Miscellaneous: + + * Documentation and example programs for the base16 and base64 + functions. Was contributed by Jeronimo Pellegrini back in + 2006, but unfortunately forgotten until now. + + * Use an additional table to avoid GF2^8 multiplications in + aes_invert_key (mainly used by aes_set_decrypt_key). Also + tabulate round constants in aes_set_encrypt_key. + + * The nettle repository has been migrated from cvs to git, + with a public repository at + http://git.lysator.liu.se/nettle. To make it independent of + the LSH repository, a few files have been moved around. + While at it, files have also been converted from latin-1 to + utf-8. + + The libraries are intended to be binary compatible with + nettle-2.2 and later. The shared library names are + libnettle.so.4.4 and libhogweed.so.2.2, with sonames still + libnettle.so.4 and libhogweed.so.2 + +NEWS for the 2.4 release + + This is a bugfix release only. It turned out ripemd160 in the + 2.3 release was broken on all big-endian systems, due to a + missing include of config.h. nettle-2.4 fixes this. + + The library is intended to be binary compatible with + nettle-2.2 and nettle-2.3. The shared library names are + libnettle.so.4.3 and libhogweed.so.2.1, with sonames still + libnettle.so.4 and libhogweed.so.2. + +NEWS for the 2.3 release + + * Support for the ripemd-160 hash function. + + * Generates and installs nettle.pc and hogweed.pc files, for + use with pkg-config. Feedback appreciated. For projects + using autoconf, the traditional non-pkg-config ways of + detecting libraries, and setting LIBS and LDFLAGS, is still + recommended. + + * Fixed a bug which made the testsuite fail in the GCM test on + certain platforms. Should not affect any documented features + of the library. + + * Reorganization of the code for the various Merkle-Damgård + hash functions. Some fields in the context structs for md4, + md5 and sha1 have been renamed, for consistency. + Applications should not peek inside these structs, and the + ABI is unchanged. + + * In the manual, fixed mis-placed const in certain function + prototypes. + + The library is intended to be binary compatible with + nettle-2.2. The shared library names are libnettle.so.4.2 and + libhogweed.so.2.1, with sonames still libnettle.so.4 and + libhogweed.so.2. + +NEWS for the 2.2 release + + Licensing change: + + * Relicensed as LGPL v2.1 or later (user's option). + + * Replaced blowfish and serpent implementation. New code is + based on the LGPLed code in libgcrypt. + + New features: + + * Support for Galois/Counter Mode (GCM). + + * New interface for enumerating (most) available algorithms, + contributed by Daniel Kahn Gillmor. + + * New tool nettle-hash. Can generate hash digests using any + supported hash function, with output compatible with md5sum + and friends from GNU coreutils. Checking (like md5sum -c) + not yet implemented. + + Bug fixes: + + * The old serpent code had a byte order bug (introduced by + yours truly about ten years ago). New serpent implementation + does not interoperate with earlier versions of nettle. + + * Fixed ABI-dependent libdir default for Linux-based systems + which do not follow the Linux File Hierarchy Standard, e.g., + Debian GNU/Linux. + + Optimizations: + + * x86_64 implemention of serpent. + + * x86_64 implemention of camellia. + + * Optimized memxor using word rather than byte operations. + Both generic C and x86_64 assembler. + + * Eliminated a memcpy for in-place CBC decrypt. + + Miscellaneous: + + * In command line tools, no longer support -? for requesting + help, since using it without shell quoting is a dangerous + habit. Use long option --help instead. + + The shared library names are libnettle.so.4.1 and + libhogweed.so.2.1, with sonames libnettle.so.4 and + libhogweed.so.2. + +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..8355739 --- /dev/null +++ b/README @@ -0,0 +1,49 @@ +What is GNU 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. + +GNU Nettle is free software; you can redistribute it and/or modify it +under the terms contained in the files COPYING* (see the manual for +information on how these licenses apply). + +If you have downloaded a Nettle release, build it with the usual +./configure && make && make check && make install (see the INSTALL +file for further instructions). + +You can also get Nettle from git, see +http://www.lysator.liu.se/~nisse/nettle/ for current instructions. In +particular, you need to run the ./.bootstrap script after checkout and +before running ./configure. + +Read the manual. Mail me if you have any questions or suggestions. + +You may want to subscribe to the nettle-bugs mailing list. See +. + +See CONTRIBUTING.md for information on contibuting patches. + + +Happy hacking, +/Niels Möller diff --git a/TODO b/TODO new file mode 100644 index 0000000..20b05a5 --- /dev/null +++ b/TODO @@ -0,0 +1,17 @@ +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. + +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..772f68e --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1307 @@ +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)]) + +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*|freebsd*) 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 +# else +/* Needed for alloca on windows, also with gcc */ +# if HAVE_MALLOC_H +# include +# endif +# 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 GMP_PROG_CC_FOR_BUILD +dnl --------------------- +dnl Establish CC_FOR_BUILD, a C compiler for the build system. +dnl +dnl If CC_FOR_BUILD is set then it's expected to work, likewise the old +dnl style HOST_CC, otherwise some likely candidates are tried, the same as +dnl configfsf.guess. + +AC_DEFUN([GMP_PROG_CC_FOR_BUILD], +[AC_REQUIRE([AC_PROG_CC]) +if test -n "$CC_FOR_BUILD"; then + GMP_PROG_CC_FOR_BUILD_WORKS($CC_FOR_BUILD,, + [AC_MSG_ERROR([Specified CC_FOR_BUILD doesn't seem to work])]) +elif test -n "$HOST_CC"; then + GMP_PROG_CC_FOR_BUILD_WORKS($HOST_CC, + [CC_FOR_BUILD=$HOST_CC], + [AC_MSG_ERROR([Specified HOST_CC doesn't seem to work])]) +else + if test $cross_compiling = no ; then + CC_FOR_BUILD="$CC" + else + for i in gcc cc c89 c99; do + GMP_PROG_CC_FOR_BUILD_WORKS($i, + [CC_FOR_BUILD=$i + break]) + done + if test -z "$CC_FOR_BUILD"; then + AC_MSG_ERROR([Cannot find a build system compiler]) + fi + fi + if test "$CC_FOR_BUILD" = gcc ; then + CC_FOR_BUILD="$CC_FOR_BUILD -O -g" + fi +fi + +AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) +AC_SUBST(CC_FOR_BUILD) +]) + + +dnl GMP_PROG_CC_FOR_BUILD_WORKS(cc/cflags[,[action-if-good][,action-if-bad]]) +dnl ------------------------------------------------------------------------- +dnl See if the given cc/cflags works on the build system. +dnl +dnl It seems easiest to just use the default compiler output, rather than +dnl figuring out the .exe or whatever at this stage. + +AC_DEFUN([GMP_PROG_CC_FOR_BUILD_WORKS], +[AC_MSG_CHECKING([build system compiler $1]) +# remove anything that might look like compiler output to our "||" expression +rm -f conftest* a.out b.out a.exe a_out.exe +cat >conftest.c <&AC_FD_CC 2>&1; then + cc_for_build_works=yes + fi +fi +rm -f conftest* a.out b.out a.exe a_out.exe +AC_MSG_RESULT($cc_for_build_works) +if test "$cc_for_build_works" = yes; then + ifelse([$2],,:,[$2]) +else + ifelse([$3],,:,[$3]) +fi +]) + +dnl GMP_PROG_EXEEXT_FOR_BUILD +dnl ------------------------- +dnl Determine EXEEXT_FOR_BUILD, the build system executable suffix. +dnl +dnl The idea is to find what "-o conftest$foo" will make it possible to run +dnl the program with ./conftest. On Unix-like systems this is of course +dnl nothing, for DOS it's ".exe", or for a strange RISC OS foreign file +dnl system cross compile it can be ",ff8" apparently. Not sure if the +dnl latter actually applies to a build-system executable, maybe it doesn't, +dnl but it won't hurt to try. + +AC_DEFUN([GMP_PROG_EXEEXT_FOR_BUILD], +[AC_REQUIRE([GMP_PROG_CC_FOR_BUILD]) +AC_CACHE_CHECK([for build system executable suffix], + gmp_cv_prog_exeext_for_build, +[if test $cross_compiling = no ; then + gmp_cv_prog_exeext_for_build="$EXEEXT" +else + cat >conftest.c <&AC_FD_CC; then + gmp_cv_prog_exeext_for_build=$i + break + fi + fi + done + rm -f conftest* + if test "${gmp_cv_prog_exeext_for_build+set}" != set; then + AC_MSG_ERROR([Cannot determine executable suffix]) + fi +fi +]) +AC_SUBST(EXEEXT_FOR_BUILD,$gmp_cv_prog_exeext_for_build) +]) + +dnl NETTLE_CHECK_ARM_NEON +dnl --------------------- +dnl Check if ARM Neon instructions should be used. +dnl Obeys enable_arm_neon, which should be set earlier. +AC_DEFUN([NETTLE_CHECK_ARM_NEON], +[if test "$enable_arm_neon" = auto ; then + if test "$cross_compiling" = yes ; then + dnl Check if compiler/assembler accepts it, + dnl without an explicit .fpu neon directive. + AC_CACHE_CHECK([if assembler accepts Neon instructions], + nettle_cv_asm_arm_neon, + [GMP_TRY_ASSEMBLE([ +.text +foo: + vmlal.u32 q1, d0, d1 +], + [nettle_cv_asm_arm_neon=yes], + [nettle_cv_asm_arm_neon=no])]) + enable_arm_neon="$nettle_cv_asm_arm_neon" + else + AC_MSG_CHECKING([if /proc/cpuinfo claims neon support]) + if grep '^Features.*:.* neon' /proc/cpuinfo >/dev/null ; then + enable_arm_neon=yes + else + enable_arm_neon=no + fi + AC_MSG_RESULT($enable_arm_neon) + fi +fi +]) + +dnl NETTLE_CHECK_IFUNC +dnl ------------------ +dnl Check if __attribute__ ((ifunc(...))) works +AC_DEFUN([NETTLE_CHECK_IFUNC], +[AC_REQUIRE([AC_PROG_CC]) +AC_CACHE_CHECK([for ifunc support], + nettle_cv_link_ifunc, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([ +static int +foo_imp(int x) +{ + return 1; +} + +typedef void void_func (void); + +static void_func * +foo_resolv(void) +{ + return (void_func *) foo_imp; +} + +int foo (int x) __attribute__ ((ifunc("foo_resolv"))); +],[ + return foo(0); + +])], +[nettle_cv_link_ifunc=yes], +[nettle_cv_link_ifunc=no])]) +AH_TEMPLATE([HAVE_LINK_IFUNC], [Define if compiler and linker supports __attribute__ ifunc]) +if test "x$nettle_cv_link_ifunc" = xyes ; then + AC_DEFINE(HAVE_LINK_IFUNC) +fi +]) + +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 @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 unsigned 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" +]) +]) + +# ld-version-script.m4 serial 3 +dnl Copyright (C) 2008-2014 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Simon Josefsson + +# FIXME: The test below returns a false positive for mingw +# cross-compiles, 'local:' statements does not reduce number of +# exported symbols in a DLL. Use --disable-ld-version-script to work +# around the problem. + +# gl_LD_VERSION_SCRIPT +# -------------------- +# Check if LD supports linker scripts, and define automake conditional +# HAVE_LD_VERSION_SCRIPT if so. +AC_DEFUN([LD_VERSION_SCRIPT], +[ + AC_ARG_ENABLE([ld-version-script], + AS_HELP_STRING([--enable-ld-version-script], + [enable linker version script (default is enabled when possible)]), + [have_ld_version_script=$enableval], []) + if test -z "$have_ld_version_script"; then + AC_MSG_CHECKING([if LD -Wl,--version-script works]) + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" + cat > conftest.map < conftest.map < + +#include "aes-internal.h" +#include "macros.h" + +void +_nettle_aes_decrypt(unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t 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 i; + + /* Get clear text, using little-endian byte order. + * Also XOR with the first subkey. */ + + w0 = LE_READ_UINT32(src) ^ keys[0]; + w1 = LE_READ_UINT32(src + 4) ^ keys[1]; + w2 = LE_READ_UINT32(src + 8) ^ keys[2]; + w3 = LE_READ_UINT32(src + 12) ^ keys[3]; + + for (i = 1; i < rounds; i++) + { + t0 = AES_ROUND(T, w0, w3, w2, w1, keys[4*i]); + t1 = AES_ROUND(T, w1, w0, w3, w2, keys[4*i + 1]); + t2 = AES_ROUND(T, w2, w1, w0, w3, keys[4*i + 2]); + t3 = AES_ROUND(T, w3, w2, w1, w0, keys[4*i + 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, keys[4*i]); + t1 = AES_FINAL_ROUND(T, w1, w0, w3, w2, keys[4*i + 1]); + t2 = AES_FINAL_ROUND(T, w2, w1, w0, w3, keys[4*i + 2]); + t3 = AES_FINAL_ROUND(T, w3, w2, w1, w0, keys[4*i + 3]); + + LE_WRITE_UINT32(dst, t0); + LE_WRITE_UINT32(dst + 4, t1); + LE_WRITE_UINT32(dst + 8, t2); + LE_WRITE_UINT32(dst + 12, t3); + } +} diff --git a/aes-decrypt.c b/aes-decrypt.c new file mode 100644 index 0000000..a0897f5 --- /dev/null +++ b/aes-decrypt.c @@ -0,0 +1,385 @@ +/* aes-decrypt.c + + Decryption function for aes/rijndael block cipher. + + Copyright (C) 2002, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_decrypt(ctx->rounds, ctx->keys, &_aes_decrypt_table, + length, dst, src); +} + +void +aes128_decrypt(const struct aes128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_decrypt(_AES128_ROUNDS, ctx->keys, &_aes_decrypt_table, + length, dst, src); +} + +void +aes192_decrypt(const struct aes192_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_decrypt(_AES192_ROUNDS, ctx->keys, &_aes_decrypt_table, + length, dst, src); +} + +void +aes256_decrypt(const struct aes256_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_decrypt(_AES256_ROUNDS, ctx->keys, &_aes_decrypt_table, + length, dst, src); +} diff --git a/aes-encrypt-internal.c b/aes-encrypt-internal.c new file mode 100644 index 0000000..9f61386 --- /dev/null +++ b/aes-encrypt-internal.c @@ -0,0 +1,113 @@ +/* aes-encrypt-internal.c + + Encryption function for the aes/rijndael block cipher. + + Copyright (C) 2002, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" +#include "macros.h" + +void +_nettle_aes_encrypt(unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t 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 i; + + /* Get clear text, using little-endian byte order. + * Also XOR with the first subkey. */ + + w0 = LE_READ_UINT32(src) ^ keys[0]; + w1 = LE_READ_UINT32(src + 4) ^ keys[1]; + w2 = LE_READ_UINT32(src + 8) ^ keys[2]; + w3 = LE_READ_UINT32(src + 12) ^ keys[3]; + + for (i = 1; i < rounds; i++) + { + t0 = AES_ROUND(T, w0, w1, w2, w3, keys[4*i]); + t1 = AES_ROUND(T, w1, w2, w3, w0, keys[4*i + 1]); + t2 = AES_ROUND(T, w2, w3, w0, w1, keys[4*i + 2]); + t3 = AES_ROUND(T, w3, w0, w1, w2, keys[4*i + 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, keys[4*i]); + t1 = AES_FINAL_ROUND(T, w1, w2, w3, w0, keys[4*i + 1]); + t2 = AES_FINAL_ROUND(T, w2, w3, w0, w1, keys[4*i + 2]); + t3 = AES_FINAL_ROUND(T, w3, w0, w1, w2, keys[4*i + 3]); + + LE_WRITE_UINT32(dst, t0); + LE_WRITE_UINT32(dst + 4, t1); + LE_WRITE_UINT32(dst + 8, t2); + 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..200de7c --- /dev/null +++ b/aes-encrypt-table.c @@ -0,0 +1,354 @@ +/* aes-encrypt-table.c + + Encryption table for the aes/rijndael block cipher. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..f962924 --- /dev/null +++ b/aes-encrypt.c @@ -0,0 +1,83 @@ +/* aes-encrypt.c + + Encryption function for the aes/rijndael block cipher. + + Copyright (C) 2002, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_encrypt(ctx->rounds, ctx->keys, &_aes_encrypt_table, + length, dst, src); +} + +void +aes128_encrypt(const struct aes128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_encrypt(_AES128_ROUNDS, ctx->keys, &_aes_encrypt_table, + length, dst, src); +} + +void +aes192_encrypt(const struct aes192_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_encrypt(_AES192_ROUNDS, ctx->keys, &_aes_encrypt_table, + length, dst, src); +} + +void +aes256_encrypt(const struct aes256_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % AES_BLOCK_SIZE) ); + _aes_encrypt(_AES256_ROUNDS, ctx->keys, &_aes_encrypt_table, + length, dst, src); +} diff --git a/aes-internal.h b/aes-internal.h new file mode 100644 index 0000000..7001d12 --- /dev/null +++ b/aes-internal.h @@ -0,0 +1,111 @@ +/* aes-internal.h + + The aes/rijndael block cipher. + + Copyright (C) 2001, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_AES_INTERNAL_H_INCLUDED +#define NETTLE_AES_INTERNAL_H_INCLUDED + +#include "aes.h" + +/* Name mangling */ +#define _aes_set_key _nettle_aes_set_key +#define _aes_invert _nettle_aes_invert +#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_set_key(unsigned nr, unsigned nk, + uint32_t *subkeys, const uint8_t *key); + +void +_aes_invert(unsigned rounds, uint32_t *dst, const uint32_t *src); + +void +_aes_encrypt(unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src); + +void +_aes_decrypt(unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src); + +/* Macros */ +/* 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 SUBBYTE(x, box) ((uint32_t)(box)[B0(x)] \ + | ((uint32_t)(box)[B1(x)] << 8) \ + | ((uint32_t)(box)[B2(x)] << 16) \ + | ((uint32_t)(box)[B3(x)] << 24)) + +#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-invert-internal.c b/aes-invert-internal.c new file mode 100644 index 0000000..ddcddba --- /dev/null +++ b/aes-invert-internal.c @@ -0,0 +1,164 @@ +/* aes-invert-internal.c + + Inverse key setup for the aes/rijndael block cipher. + + Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Originally written by Rafael R. Sevilla */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aes-internal.h" + +#include "macros.h" + +/* NOTE: We don't include rotated versions of the table. */ +static const uint32_t mtable[0x100] = +{ + 0x00000000,0x0b0d090e,0x161a121c,0x1d171b12, + 0x2c342438,0x27392d36,0x3a2e3624,0x31233f2a, + 0x58684870,0x5365417e,0x4e725a6c,0x457f5362, + 0x745c6c48,0x7f516546,0x62467e54,0x694b775a, + 0xb0d090e0,0xbbdd99ee,0xa6ca82fc,0xadc78bf2, + 0x9ce4b4d8,0x97e9bdd6,0x8afea6c4,0x81f3afca, + 0xe8b8d890,0xe3b5d19e,0xfea2ca8c,0xf5afc382, + 0xc48cfca8,0xcf81f5a6,0xd296eeb4,0xd99be7ba, + 0x7bbb3bdb,0x70b632d5,0x6da129c7,0x66ac20c9, + 0x578f1fe3,0x5c8216ed,0x41950dff,0x4a9804f1, + 0x23d373ab,0x28de7aa5,0x35c961b7,0x3ec468b9, + 0x0fe75793,0x04ea5e9d,0x19fd458f,0x12f04c81, + 0xcb6bab3b,0xc066a235,0xdd71b927,0xd67cb029, + 0xe75f8f03,0xec52860d,0xf1459d1f,0xfa489411, + 0x9303e34b,0x980eea45,0x8519f157,0x8e14f859, + 0xbf37c773,0xb43ace7d,0xa92dd56f,0xa220dc61, + 0xf66d76ad,0xfd607fa3,0xe07764b1,0xeb7a6dbf, + 0xda595295,0xd1545b9b,0xcc434089,0xc74e4987, + 0xae053edd,0xa50837d3,0xb81f2cc1,0xb31225cf, + 0x82311ae5,0x893c13eb,0x942b08f9,0x9f2601f7, + 0x46bde64d,0x4db0ef43,0x50a7f451,0x5baafd5f, + 0x6a89c275,0x6184cb7b,0x7c93d069,0x779ed967, + 0x1ed5ae3d,0x15d8a733,0x08cfbc21,0x03c2b52f, + 0x32e18a05,0x39ec830b,0x24fb9819,0x2ff69117, + 0x8dd64d76,0x86db4478,0x9bcc5f6a,0x90c15664, + 0xa1e2694e,0xaaef6040,0xb7f87b52,0xbcf5725c, + 0xd5be0506,0xdeb30c08,0xc3a4171a,0xc8a91e14, + 0xf98a213e,0xf2872830,0xef903322,0xe49d3a2c, + 0x3d06dd96,0x360bd498,0x2b1ccf8a,0x2011c684, + 0x1132f9ae,0x1a3ff0a0,0x0728ebb2,0x0c25e2bc, + 0x656e95e6,0x6e639ce8,0x737487fa,0x78798ef4, + 0x495ab1de,0x4257b8d0,0x5f40a3c2,0x544daacc, + 0xf7daec41,0xfcd7e54f,0xe1c0fe5d,0xeacdf753, + 0xdbeec879,0xd0e3c177,0xcdf4da65,0xc6f9d36b, + 0xafb2a431,0xa4bfad3f,0xb9a8b62d,0xb2a5bf23, + 0x83868009,0x888b8907,0x959c9215,0x9e919b1b, + 0x470a7ca1,0x4c0775af,0x51106ebd,0x5a1d67b3, + 0x6b3e5899,0x60335197,0x7d244a85,0x7629438b, + 0x1f6234d1,0x146f3ddf,0x097826cd,0x02752fc3, + 0x335610e9,0x385b19e7,0x254c02f5,0x2e410bfb, + 0x8c61d79a,0x876cde94,0x9a7bc586,0x9176cc88, + 0xa055f3a2,0xab58faac,0xb64fe1be,0xbd42e8b0, + 0xd4099fea,0xdf0496e4,0xc2138df6,0xc91e84f8, + 0xf83dbbd2,0xf330b2dc,0xee27a9ce,0xe52aa0c0, + 0x3cb1477a,0x37bc4e74,0x2aab5566,0x21a65c68, + 0x10856342,0x1b886a4c,0x069f715e,0x0d927850, + 0x64d90f0a,0x6fd40604,0x72c31d16,0x79ce1418, + 0x48ed2b32,0x43e0223c,0x5ef7392e,0x55fa3020, + 0x01b79aec,0x0aba93e2,0x17ad88f0,0x1ca081fe, + 0x2d83bed4,0x268eb7da,0x3b99acc8,0x3094a5c6, + 0x59dfd29c,0x52d2db92,0x4fc5c080,0x44c8c98e, + 0x75ebf6a4,0x7ee6ffaa,0x63f1e4b8,0x68fcedb6, + 0xb1670a0c,0xba6a0302,0xa77d1810,0xac70111e, + 0x9d532e34,0x965e273a,0x8b493c28,0x80443526, + 0xe90f427c,0xe2024b72,0xff155060,0xf418596e, + 0xc53b6644,0xce366f4a,0xd3217458,0xd82c7d56, + 0x7a0ca137,0x7101a839,0x6c16b32b,0x671bba25, + 0x5638850f,0x5d358c01,0x40229713,0x4b2f9e1d, + 0x2264e947,0x2969e049,0x347efb5b,0x3f73f255, + 0x0e50cd7f,0x055dc471,0x184adf63,0x1347d66d, + 0xcadc31d7,0xc1d138d9,0xdcc623cb,0xd7cb2ac5, + 0xe6e815ef,0xede51ce1,0xf0f207f3,0xfbff0efd, + 0x92b479a7,0x99b970a9,0x84ae6bbb,0x8fa362b5, + 0xbe805d9f,0xb58d5491,0xa89a4f83,0xa397468d, +}; + +#define MIX_COLUMN(T, key) do { \ + uint32_t _k, _nk, _t; \ + _k = (key); \ + _nk = T[_k & 0xff]; \ + _k >>= 8; \ + _t = T[_k & 0xff]; \ + _nk ^= ROTL32(8, _t); \ + _k >>= 8; \ + _t = T[_k & 0xff]; \ + _nk ^= ROTL32(16, _t); \ + _k >>= 8; \ + _t = T[_k & 0xff]; \ + _nk ^= ROTL32(24, _t); \ + (key) = _nk; \ + } while(0) + + +#define SWAP(a, b) \ +do { uint32_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0) + +void +_aes_invert(unsigned rounds, uint32_t *dst, const uint32_t *src) +{ + unsigned i; + + /* 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 = rounds * 4; + i < j; + i += 4, j -= 4) + for (k = 0; k<4; k++) + SWAP(dst[i+k], dst[j+k]); + } + else + { + unsigned k; + + for (i = 0; i <= rounds * 4; i += 4) + for (k = 0; k < 4; k++) + dst[i+k] = src[rounds * 4 - i + k]; + } + + /* Transform all subkeys but the first and last. */ + for (i = 4; i < 4 * rounds; i++) + MIX_COLUMN (mtable, dst[i]); +} diff --git a/aes-set-decrypt-key.c b/aes-set-decrypt-key.c new file mode 100644 index 0000000..ffbb189 --- /dev/null +++ b/aes-set-decrypt-key.c @@ -0,0 +1,58 @@ +/* aes-set-decrypt-key.c + + Inverse key setup for the aes/rijndael block cipher. + + Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aes-internal.h" + +void +aes_invert_key(struct aes_ctx *dst, + const struct aes_ctx *src) +{ + _aes_invert (src->rounds, dst->keys, src->keys); + dst->rounds = src->rounds; +} + +void +aes_set_decrypt_key(struct aes_ctx *ctx, + size_t 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..8de474d --- /dev/null +++ b/aes-set-encrypt-key.c @@ -0,0 +1,67 @@ +/* aes-set-encrypt-key.c + + Key setup for the aes/rijndael block cipher. + + Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "aes-internal.h" + +void +aes_set_encrypt_key(struct aes_ctx *ctx, + size_t keysize, const uint8_t *key) +{ + unsigned nk, nr; + + assert(keysize >= AES_MIN_KEY_SIZE); + assert(keysize <= AES_MAX_KEY_SIZE); + + /* Truncate keysizes to the valid key sizes provided by Rijndael */ + if (keysize == AES256_KEY_SIZE) { + nk = 8; + nr = _AES256_ROUNDS; + } else if (keysize >= AES192_KEY_SIZE) { + nk = 6; + nr = _AES192_ROUNDS; + } else { /* must be 16 or more */ + nk = 4; + nr = _AES128_ROUNDS; + } + + ctx->rounds = nr; + _aes_set_key (nr, nk, ctx->keys, key); +} diff --git a/aes-set-key-internal.c b/aes-set-key-internal.c new file mode 100644 index 0000000..88728d8 --- /dev/null +++ b/aes-set-key-internal.c @@ -0,0 +1,73 @@ +/* aes-set-key-internal.c + + Key setup for the aes/rijndael block cipher. + + Copyright (C) 2000, 2001, 2002 Rafael R. Sevilla, Niels Möller + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Originally written by Rafael R. Sevilla */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aes-internal.h" +#include +#include "macros.h" + +void +_aes_set_key(unsigned nr, unsigned nk, + uint32_t *subkeys, const uint8_t *key) +{ + static const uint8_t rcon[10] = { + 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36, + }; + const uint8_t *rp; + unsigned lastkey, i; + uint32_t t; + + assert(nk != 0); + lastkey = (AES_BLOCK_SIZE/4) * (nr + 1); + + for (i=0, rp = rcon; i 6 && (i%nk) == 4) + t = SUBBYTE(t, aes_sbox); + + subkeys[i] = subkeys[i-nk] ^ t; + } +} diff --git a/aes.h b/aes.h new file mode 100644 index 0000000..5a0545c --- /dev/null +++ b/aes.h @@ -0,0 +1,177 @@ +/* aes.h + + The aes/rijndael block cipher. + + Copyright (C) 2001, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 aes128_set_encrypt_key nettle_aes128_set_encrypt_key +#define aes128_set_decrypt_key nettle_aes128_set_decrypt_key +#define aes128_invert_key nettle_aes128_invert_key +#define aes128_encrypt nettle_aes128_encrypt +#define aes128_decrypt nettle_aes128_decrypt +#define aes192_set_encrypt_key nettle_aes192_set_encrypt_key +#define aes192_set_decrypt_key nettle_aes192_set_decrypt_key +#define aes192_invert_key nettle_aes192_invert_key +#define aes192_encrypt nettle_aes192_encrypt +#define aes192_decrypt nettle_aes192_decrypt +#define aes256_set_encrypt_key nettle_aes256_set_encrypt_key +#define aes256_set_decrypt_key nettle_aes256_set_decrypt_key +#define aes256_invert_key nettle_aes256_invert_key +#define aes256_encrypt nettle_aes256_encrypt +#define aes256_decrypt nettle_aes256_decrypt + +#define AES_BLOCK_SIZE 16 + +#define AES128_KEY_SIZE 16 +#define AES192_KEY_SIZE 24 +#define AES256_KEY_SIZE 32 +#define _AES128_ROUNDS 10 +#define _AES192_ROUNDS 12 +#define _AES256_ROUNDS 14 + +/* 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 AES128_KEY_SIZE +#define AES_MAX_KEY_SIZE AES256_KEY_SIZE + +/* Older nettle-2.7 interface */ + +#define AES_KEY_SIZE 32 + +struct aes_ctx +{ + unsigned rounds; /* number of rounds to use for our key size */ + uint32_t keys[4*(_AES256_ROUNDS + 1)]; /* maximum size of key schedule */ +}; + +void +aes_set_encrypt_key(struct aes_ctx *ctx, + size_t length, const uint8_t *key); + +void +aes_set_decrypt_key(struct aes_ctx *ctx, + size_t 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, + size_t length, uint8_t *dst, + const uint8_t *src); +void +aes_decrypt(const struct aes_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +struct aes128_ctx +{ + uint32_t keys[4 * (_AES128_ROUNDS + 1)]; +}; + +void +aes128_set_encrypt_key(struct aes128_ctx *ctx, const uint8_t *key); +void +aes128_set_decrypt_key(struct aes128_ctx *ctx, const uint8_t *key); +void +aes128_invert_key(struct aes128_ctx *dst, + const struct aes128_ctx *src); +void +aes128_encrypt(const struct aes128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); +void +aes128_decrypt(const struct aes128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +struct aes192_ctx +{ + uint32_t keys[4 * (_AES192_ROUNDS + 1)]; +}; + +void +aes192_set_encrypt_key(struct aes192_ctx *ctx, const uint8_t *key); +void +aes192_set_decrypt_key(struct aes192_ctx *ctx, const uint8_t *key); +void +aes192_invert_key(struct aes192_ctx *dst, + const struct aes192_ctx *src); +void +aes192_encrypt(const struct aes192_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); +void +aes192_decrypt(const struct aes192_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +struct aes256_ctx +{ + uint32_t keys[4 * (_AES256_ROUNDS + 1)]; +}; + +void +aes256_set_encrypt_key(struct aes256_ctx *ctx, const uint8_t *key); +void +aes256_set_decrypt_key(struct aes256_ctx *ctx, const uint8_t *key); +void +aes256_invert_key(struct aes256_ctx *dst, + const struct aes256_ctx *src); +void +aes256_encrypt(const struct aes256_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); +void +aes256_decrypt(const struct aes256_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_AES_H_INCLUDED */ diff --git a/aes128-meta.c b/aes128-meta.c new file mode 100644 index 0000000..772fbd6 --- /dev/null +++ b/aes128-meta.c @@ -0,0 +1,49 @@ +/* aes128-meta.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "aes.h" + +const struct nettle_cipher nettle_aes128 = + { "aes128", sizeof(struct aes128_ctx), + AES_BLOCK_SIZE, AES128_KEY_SIZE, + (nettle_set_key_func *) aes128_set_encrypt_key, + (nettle_set_key_func *) aes128_set_decrypt_key, + (nettle_cipher_func *) aes128_encrypt, + (nettle_cipher_func *) aes128_decrypt + }; diff --git a/aes128-set-decrypt-key.c b/aes128-set-decrypt-key.c new file mode 100644 index 0000000..db0b259 --- /dev/null +++ b/aes128-set-decrypt-key.c @@ -0,0 +1,54 @@ +/* aes128-set-decrypt-key.c + + Key setup for the aes/rijndael block cipher. + + Copyright (C) 2013, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" +#include "macros.h" + +void +aes128_invert_key (struct aes128_ctx *dst, const struct aes128_ctx *src) +{ + _aes_invert (_AES128_ROUNDS, dst->keys, src->keys); +} + +void +aes128_set_decrypt_key(struct aes128_ctx *ctx, const uint8_t *key) +{ + aes128_set_encrypt_key (ctx, key); + aes128_invert_key (ctx, ctx); +} diff --git a/aes128-set-encrypt-key.c b/aes128-set-encrypt-key.c new file mode 100644 index 0000000..870f263 --- /dev/null +++ b/aes128-set-encrypt-key.c @@ -0,0 +1,44 @@ +/* aes128-set-encrypt-key.c + + Copyright (C) 2013, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" + +void +aes128_set_encrypt_key(struct aes128_ctx *ctx, const uint8_t *key) +{ + _aes_set_key (_AES128_ROUNDS, AES128_KEY_SIZE / 4, ctx->keys, key); +} diff --git a/aes192-meta.c b/aes192-meta.c new file mode 100644 index 0000000..8a5a6df --- /dev/null +++ b/aes192-meta.c @@ -0,0 +1,49 @@ +/* aes192-meta.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "aes.h" + +const struct nettle_cipher nettle_aes192 = + { "aes192", sizeof(struct aes192_ctx), + AES_BLOCK_SIZE, AES192_KEY_SIZE, + (nettle_set_key_func *) aes192_set_encrypt_key, + (nettle_set_key_func *) aes192_set_decrypt_key, + (nettle_cipher_func *) aes192_encrypt, + (nettle_cipher_func *) aes192_decrypt + }; diff --git a/aes192-set-decrypt-key.c b/aes192-set-decrypt-key.c new file mode 100644 index 0000000..8ce5ead --- /dev/null +++ b/aes192-set-decrypt-key.c @@ -0,0 +1,52 @@ +/* aes192-set-decrypt-key.c + + Copyright (C) 2013, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" +#include "macros.h" + +void +aes192_invert_key (struct aes192_ctx *dst, const struct aes192_ctx *src) +{ + _aes_invert (_AES192_ROUNDS, dst->keys, src->keys); +} + +void +aes192_set_decrypt_key(struct aes192_ctx *ctx, const uint8_t *key) +{ + aes192_set_encrypt_key (ctx, key); + aes192_invert_key (ctx, ctx); +} diff --git a/aes192-set-encrypt-key.c b/aes192-set-encrypt-key.c new file mode 100644 index 0000000..8faa6c8 --- /dev/null +++ b/aes192-set-encrypt-key.c @@ -0,0 +1,44 @@ +/* aes192-set-encrypt-key.c + + Copyright (C) 2013, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" + +void +aes192_set_encrypt_key(struct aes192_ctx *ctx, const uint8_t *key) +{ + _aes_set_key (_AES192_ROUNDS, AES192_KEY_SIZE / 4, ctx->keys, key); +} diff --git a/aes256-meta.c b/aes256-meta.c new file mode 100644 index 0000000..b482f11 --- /dev/null +++ b/aes256-meta.c @@ -0,0 +1,49 @@ +/* aes256-meta.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "aes.h" + +const struct nettle_cipher nettle_aes256 = + { "aes256", sizeof(struct aes256_ctx), + AES_BLOCK_SIZE, AES256_KEY_SIZE, + (nettle_set_key_func *) aes256_set_encrypt_key, + (nettle_set_key_func *) aes256_set_decrypt_key, + (nettle_cipher_func *) aes256_encrypt, + (nettle_cipher_func *) aes256_decrypt + }; diff --git a/aes256-set-decrypt-key.c b/aes256-set-decrypt-key.c new file mode 100644 index 0000000..452794c --- /dev/null +++ b/aes256-set-decrypt-key.c @@ -0,0 +1,52 @@ +/* aes256-set-decrypt-key.c + + Copyright (C) 2013, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" +#include "macros.h" + +void +aes256_invert_key (struct aes256_ctx *dst, const struct aes256_ctx *src) +{ + _aes_invert (_AES256_ROUNDS, dst->keys, src->keys); +} + +void +aes256_set_decrypt_key(struct aes256_ctx *ctx, const uint8_t *key) +{ + aes256_set_encrypt_key (ctx, key); + aes256_invert_key (ctx, ctx); +} diff --git a/aes256-set-encrypt-key.c b/aes256-set-encrypt-key.c new file mode 100644 index 0000000..bbfb57e --- /dev/null +++ b/aes256-set-encrypt-key.c @@ -0,0 +1,44 @@ +/* aes256-set-encrypt-key.c + + Copyright (C) 2013, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes-internal.h" + +void +aes256_set_encrypt_key(struct aes256_ctx *ctx, const uint8_t *key) +{ + _aes_set_key (_AES256_ROUNDS, AES256_KEY_SIZE / 4, ctx->keys, key); +} diff --git a/aesdata.c b/aesdata.c new file mode 100644 index 0000000..9202d0f --- /dev/null +++ b/aesdata.c @@ -0,0 +1,315 @@ +#include +#include +#include +#include + +#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%08lx" +#define WORD_COLUMNS 4 + +unsigned char sbox[0x100]; +unsigned char isbox[0x100]; + +unsigned char gf2_log[0x100]; +unsigned char gf2_exp[0x100]; + +unsigned long dtable[4][0x100]; +unsigned long itable[4][0x100]; +unsigned long mtable[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; + unsigned long 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; + unsigned long 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; + } +} + +/* Used for key inversion, inverse mix column. No sbox. */ +static void +compute_mtable(void) +{ + unsigned i; + for (i = 0; i<0x100; i++) + { + unsigned j; + unsigned long t = ( (mult(i, 0xb) << 24) + | (mult(i, 0xd) << 16) + | (mult(i, 0x9) << 8) + | (mult(i, 0xe) )); + + for (j = 0; j<4; j++, t = (t << 8) | (t >> 24)) + mtable[j][i] = t; + } +} + +static void +display_byte_table(const char *name, unsigned char *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, + size_t 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.c b/arcfour.c new file mode 100644 index 0000000..87f4959 --- /dev/null +++ b/arcfour.c @@ -0,0 +1,71 @@ +/* arcfour.c + + The arcfour/rc4 stream cipher. + + Copyright (C) 2001, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + size_t 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 +arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key) +{ + arcfour_set_key (ctx, ARCFOUR128_KEY_SIZE, key); +} diff --git a/arcfour.h b/arcfour.h new file mode 100644 index 0000000..804b9e4 --- /dev/null +++ b/arcfour.h @@ -0,0 +1,79 @@ +/* arcfour.h + + The arcfour/rc4 stream cipher. + + Copyright (C) 2001, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_ARCFOUR_H_INCLUDED +#define NETTLE_ARCFOUR_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define arcfour128_set_key nettle_arcfour128_set_key +#define arcfour_set_key nettle_arcfour_set_key +#define arcfour_crypt nettle_arcfour_crypt + +/* 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 +#define ARCFOUR128_KEY_SIZE 16 + +struct arcfour_ctx +{ + uint8_t S[256]; + uint8_t i; + uint8_t j; +}; + +void +arcfour_set_key(struct arcfour_ctx *ctx, + size_t length, const uint8_t *key); + +void +arcfour128_set_key(struct arcfour_ctx *ctx, const uint8_t *key); + +void +arcfour_crypt(struct arcfour_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ARCFOUR_H_INCLUDED */ + diff --git a/arctwo-meta.c b/arctwo-meta.c new file mode 100644 index 0000000..0c1e70f --- /dev/null +++ b/arctwo-meta.c @@ -0,0 +1,65 @@ +/* arctwo-meta.c + + Copyright (C) 2004 Simon Josefsson + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "arctwo.h" + +#define ARCTWO(bits) { \ + "arctwo" #bits, sizeof (struct arctwo_ctx), \ + ARCTWO_BLOCK_SIZE, bits/8, \ + (nettle_set_key_func *) arctwo ## bits ## _set_key, \ + (nettle_set_key_func *) arctwo ## bits ## _set_key, \ + (nettle_cipher_func *) arctwo_encrypt, \ + (nettle_cipher_func *) arctwo_decrypt, \ +} +const struct nettle_cipher nettle_arctwo40 += ARCTWO(40); +const struct nettle_cipher nettle_arctwo64 += ARCTWO(64); +const struct nettle_cipher nettle_arctwo128 += ARCTWO(128); + +/* Gutmann variant. */ +const struct nettle_cipher nettle_arctwo_gutmann128 = + { + "arctwo_gutmann128", sizeof (struct arctwo_ctx), + ARCTWO_BLOCK_SIZE, 16, + (nettle_set_key_func *) arctwo128_set_key_gutmann, + (nettle_set_key_func *) arctwo128_set_key_gutmann, + (nettle_cipher_func *) arctwo_encrypt, + (nettle_cipher_func *) arctwo_decrypt, + }; diff --git a/arctwo.c b/arctwo.c new file mode 100644 index 0000000..340f562 --- /dev/null +++ b/arctwo.c @@ -0,0 +1,261 @@ +/* arctwo.c + + The cipher described in rfc2268; aka Ron's Cipher 2. + + Copyright (C) 2004 Simon Josefsson + Copyright (C) 2003 Nikos Mavroyanopoulos + Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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, + size_t 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, + size_t 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, + size_t length, const uint8_t *key, unsigned ekb) +{ + size_t 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, size_t length, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, length, key, 8 * length); +} + +void +arctwo_set_key_gutmann (struct arctwo_ctx *ctx, + size_t length, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, length, key, 0); +} + +void +arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, 5, key, 40); +} +void +arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, 8, key, 64); +} + +void +arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, 16, key, 128); +} +void +arctwo128_set_key_gutmann (struct arctwo_ctx *ctx, + const uint8_t *key) +{ + arctwo_set_key_ekb (ctx, 16, key, 1024); +} diff --git a/arctwo.h b/arctwo.h new file mode 100644 index 0000000..1a9b8b3 --- /dev/null +++ b/arctwo.h @@ -0,0 +1,103 @@ +/* arctwo.h + + The arctwo/rfc2268 block cipher. + + Copyright (C) 2004 Simon Josefsson + Copyright (C) 2002, 2004, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_set_key_gutmann nettle_arctwo_set_key_gutmann +#define arctwo40_set_key nettle_arctwo40_set_key +#define arctwo64_set_key nettle_arctwo64_set_key +#define arctwo128_set_key nettle_arctwo128_set_key +#define arctwo128_set_key_gutmann nettle_arctwo128_set_key_gutmann +#define arctwo_encrypt nettle_arctwo_encrypt +#define arctwo_decrypt nettle_arctwo_decrypt + +#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, + size_t 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, size_t length, const uint8_t *key); +void +arctwo40_set_key (struct arctwo_ctx *ctx, const uint8_t *key); +void +arctwo64_set_key (struct arctwo_ctx *ctx, const uint8_t *key); +void +arctwo128_set_key (struct arctwo_ctx *ctx, const uint8_t *key); + +/* Equvivalent to arctwo_set_key_ekb, with ekb = 1024 */ +void +arctwo_set_key_gutmann (struct arctwo_ctx *ctx, + size_t length, const uint8_t *key); +void +arctwo128_set_key_gutmann (struct arctwo_ctx *ctx, + const uint8_t *key); + +void +arctwo_encrypt (struct arctwo_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); +void +arctwo_decrypt (struct arctwo_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ARCTWO_H_INCLUDED */ diff --git a/arm/aes-decrypt-internal.asm b/arm/aes-decrypt-internal.asm new file mode 100644 index 0000000..3da333c --- /dev/null +++ b/arm/aes-decrypt-internal.asm @@ -0,0 +1,191 @@ +C arm/aes-decrypt-internal.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +include_src() + +define(, ) +define(, ) +define(, ) +define(, ) +C On stack: DST, SRC + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) C Overlaps inputs, except TABLE +define(, ) +define(, ) +define(, ) +define(, ) C lr + +define(, <[sp]>) +define(, <[sp, #+4]>) +define(, <[sp, #+8]>) +C 8 saved registers +define(, <[sp, #+44]>) +define(, <[sp, #+48]>) + + +define(, < + and T0, MASK, $1, lsl #2 + ldr $5, [TABLE, T0] + and T0, MASK, $2, lsl #2 + ldr $6, [TABLE, T0] + and T0, MASK, $3, lsl #2 + ldr $7, [TABLE, T0] + and T0, MASK, $4, lsl #2 + ldr $8, [TABLE, T0] + + and T0, MASK, $4, ror #6 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0] + eor $5, $5, T0 + and T0, MASK, $1, ror #6 + ldr T0, [TABLE, T0] + eor $6, $6, T0 + and T0, MASK, $2, ror #6 + ldr T0, [TABLE, T0] + eor $7, $7, T0 + and T0, MASK, $3, ror #6 + ldr T0, [TABLE, T0] + eor $8, $8, T0 + + and T0, MASK, $3, ror #14 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0] + eor $5, $5, T0 + and T0, MASK, $4, ror #14 + ldr T0, [TABLE, T0] + eor $6, $6, T0 + and T0, MASK, $1, ror #14 + ldr T0, [TABLE, T0] + eor $7, $7, T0 + and T0, MASK, $2, ror #14 + ldr T0, [TABLE, T0] + eor $8, $8, T0 + + and T0, MASK, $2, ror #22 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0] + eor $5, $5, T0 + and T0, MASK, $3, ror #22 + ldr T0, [TABLE, T0] + eor $6, $6, T0 + and T0, MASK, $4, ror #22 + ldr T0, [TABLE, T0] + eor $7, $7, T0 + and T0, MASK, $1, ror #22 + ldr T0, [TABLE, T0] + + ldm $9!, {$1,$2,$3,$4} + eor $8, $8, T0 + sub TABLE, TABLE, #3072 + eor $5, $5, $1 + eor $6, $6, $2 + eor $7, $7, $3 + eor $8, $8, $4 +>) + + .file "aes-decrypt-internal.asm" + + C _aes_decrypt(unsigned rounds, const uint32_t *keys, + C const struct aes_table *T, + C size_t length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_decrypt) + teq PARAM_LENGTH, #0 + beq .Lend + + push {r0,r1,r3, r4,r5,r6,r7,r8,r10,r11,lr} + mov MASK, #0x3fc + ALIGN(16) +.Lblock_loop: + ldr X0, FRAME_SRC C Use X0 as SRC pointer + ldm sp, {COUNT, KEY} + + AES_LOAD(X0,KEY,W0) + AES_LOAD(X0,KEY,W1) + AES_LOAD(X0,KEY,W2) + AES_LOAD(X0,KEY,W3) + + str X0, FRAME_SRC + + add TABLE, TABLE, #AES_TABLE0 + + b .Lentry + ALIGN(16) +.Lround_loop: + C Transform X -> W + AES_DECRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY) + +.Lentry: + subs COUNT, COUNT,#2 + C Transform W -> X + AES_DECRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY) + + bne .Lround_loop + + lsr COUNT, MASK, #2 C Put the needed mask in the unused COUNT register + sub TABLE, TABLE, #AES_TABLE0 + C Final round + AES_FINAL_ROUND_V5(X0, X3, X2, X1, KEY, W0, COUNT) + AES_FINAL_ROUND_V5(X1, X0, X3, X2, KEY, W1, COUNT) + AES_FINAL_ROUND_V5(X2, X1, X0, X3, KEY, W2, COUNT) + AES_FINAL_ROUND_V5(X3, X2, X1, X0, KEY, W3, COUNT) + + ldr X0, FRAME_DST + ldr X1, FRAME_LENGTH + + AES_STORE(X0,W0) + AES_STORE(X0,W1) + AES_STORE(X0,W2) + AES_STORE(X0,W3) + + subs X1, X1, #16 + str X0, FRAME_DST + str X1, FRAME_LENGTH + + bhi .Lblock_loop + + add sp, sp, #12 C Drop saved r0, r1, r3 + pop {r4,r5,r6,r7,r8,r10,r11,pc} + +.Lend: + bx lr +EPILOGUE(_nettle_aes_decrypt) diff --git a/arm/aes-encrypt-internal.asm b/arm/aes-encrypt-internal.asm new file mode 100644 index 0000000..e8b3df6 --- /dev/null +++ b/arm/aes-encrypt-internal.asm @@ -0,0 +1,200 @@ +C arm/aes-encrypt-internal.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +include_src() + +C Benchmarked at at 725, 815, 990 cycles/block on cortex A9, +C for 128, 192 and 256 bit key sizes. + +C Possible improvements: More efficient load and store with +C aligned accesses. Better scheduling. + +define(, ) +define(, ) +define(
, ) +define(, ) +C On stack: DST, SRC + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) C Overlaps inputs, except TABLE +define(, ) +define(, ) +define(, ) +define(, ) C lr + +define(, <[sp]>) +define(, <[sp, #+4]>) +define(, <[sp, #+8]>) +C 8 saved registers +define(, <[sp, #+44]>) +define(, <[sp, #+48]>) + + +C AES_ENCRYPT_ROUND(x0,x1,x2,x3,w0,w1,w2,w3,key) +C MASK should hold the constant 0x3fc. +define(, < + + and T0, MASK, $1, lsl #2 + ldr $5, [TABLE, T0] + and T0, MASK, $2, lsl #2 + ldr $6, [TABLE, T0] + and T0, MASK, $3, lsl #2 + ldr $7, [TABLE, T0] + and T0, MASK, $4, lsl #2 + ldr $8, [TABLE, T0] + + and T0, MASK, $2, ror #6 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0] + eor $5, $5, T0 + and T0, MASK, $3, ror #6 + ldr T0, [TABLE, T0] + eor $6, $6, T0 + and T0, MASK, $4, ror #6 + ldr T0, [TABLE, T0] + eor $7, $7, T0 + and T0, MASK, $1, ror #6 + ldr T0, [TABLE, T0] + eor $8, $8, T0 + + and T0, MASK, $3, ror #14 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0] + eor $5, $5, T0 + and T0, MASK, $4, ror #14 + ldr T0, [TABLE, T0] + eor $6, $6, T0 + and T0, MASK, $1, ror #14 + ldr T0, [TABLE, T0] + eor $7, $7, T0 + and T0, MASK, $2, ror #14 + ldr T0, [TABLE, T0] + eor $8, $8, T0 + + and T0, MASK, $4, ror #22 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0] + eor $5, $5, T0 + and T0, MASK, $1, ror #22 + ldr T0, [TABLE, T0] + eor $6, $6, T0 + and T0, MASK, $2, ror #22 + ldr T0, [TABLE, T0] + eor $7, $7, T0 + and T0, MASK, $3, ror #22 + ldr T0, [TABLE, T0] + + ldm $9!, {$1,$2,$3,$4} + eor $8, $8, T0 + sub TABLE, TABLE, #3072 + eor $5, $5, $1 + eor $6, $6, $2 + eor $7, $7, $3 + eor $8, $8, $4 +>) + + .file "aes-encrypt-internal.asm" + + C _aes_encrypt(unsigned rounds, const uint32_t *keys, + C const struct aes_table *T, + C size_t length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_encrypt) + teq PARAM_LENGTH, #0 + beq .Lend + + push {r0,r1,r3, r4,r5,r6,r7,r8,r10,r11,lr} + mov MASK, #0x3fc + ALIGN(16) +.Lblock_loop: + ldr X0, FRAME_SRC C Use X0 as SRC pointer + ldm sp, {COUNT, KEY} + + AES_LOAD(X0,KEY,W0) + AES_LOAD(X0,KEY,W1) + AES_LOAD(X0,KEY,W2) + AES_LOAD(X0,KEY,W3) + + str X0, FRAME_SRC + + add TABLE, TABLE, #AES_TABLE0 + + b .Lentry + ALIGN(16) +.Lround_loop: + C Transform X -> W + AES_ENCRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY) + +.Lentry: + subs COUNT, COUNT,#2 + C Transform W -> X + AES_ENCRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY) + + bne .Lround_loop + + lsr COUNT, MASK, #2 C Put the needed mask in the unused COUNT register + sub TABLE, TABLE, #AES_TABLE0 + C Final round + AES_FINAL_ROUND_V5(X0, X1, X2, X3, KEY, W0, COUNT) + AES_FINAL_ROUND_V5(X1, X2, X3, X0, KEY, W1, COUNT) + AES_FINAL_ROUND_V5(X2, X3, X0, X1, KEY, W2, COUNT) + AES_FINAL_ROUND_V5(X3, X0, X1, X2, KEY, W3, COUNT) + + ldr X0, FRAME_DST + ldr X1, FRAME_LENGTH + + AES_STORE(X0,W0) + AES_STORE(X0,W1) + AES_STORE(X0,W2) + AES_STORE(X0,W3) + + subs X1, X1, #16 + str X0, FRAME_DST + str X1, FRAME_LENGTH + + bhi .Lblock_loop + + add sp, sp, #12 C Drop saved r0, r1, r3 + pop {r4,r5,r6,r7,r8,r10,r11,pc} + +.Lend: + bx lr +EPILOGUE(_nettle_aes_encrypt) diff --git a/arm/aes.m4 b/arm/aes.m4 new file mode 100644 index 0000000..91f340a --- /dev/null +++ b/arm/aes.m4 @@ -0,0 +1,58 @@ +C Loads one word, and adds it to the subkey. Uses T0 +C AES_LOAD(SRC, KEY, REG) +define(, < + ldrb $3, [$1], #+1 + ldrb T0, [$1], #+1 + orr $3, T0, lsl #8 + ldrb T0, [$1], #+1 + orr $3, T0, lsl #16 + ldrb T0, [$1], #+1 + orr $3, T0, lsl #24 + ldr T0, [$2], #+4 + eor $3, T0 +>) +C Stores one word. Destroys input. +C AES_STORE(DST, X) +define(, < + strb $2, [$1], #+1 + ror $2, $2, #8 + strb $2, [$1], #+1 + ror $2, $2, #8 + strb $2, [$1], #+1 + ror $2, $2, #8 + strb $2, [$1], #+1 +>) + +C AES_FINAL_ROUND_V6(a,b,c,d,key,res) +define(, < + uxtb T0, $1 + ldrb $6, [TABLE, T0] + uxtb T0, $2, ror #8 + ldrb T0, [TABLE, T0] + eor $6, $6, T0, lsl #8 + uxtb T0, $3, ror #16 + ldrb T0, [TABLE, T0] + eor $6, $6, T0, lsl #16 + ldrb T0, [TABLE, $4, lsr #24] + eor $6, $6, T0, lsl #24 + ldr T0, [$5], #+4 + eor $6, $6, T0 +>) + +C AES_FINAL_ROUND_V5(a,b,c,d,key,res,mask) +C Avoids the uxtb instruction, introduced in ARMv6. +C The mask argument should hold the constant 0xff +define(, < + and T0, $7, $1 + ldrb $6, [TABLE, T0] + and T0, $7, $2, ror #8 + ldrb T0, [TABLE, T0] + eor $6, $6, T0, lsl #8 + and T0, $7, $3, ror #16 + ldrb T0, [TABLE, T0] + eor $6, $6, T0, lsl #16 + ldrb T0, [TABLE, $4, lsr #24] + eor $6, $6, T0, lsl #24 + ldr T0, [$5], #+4 + eor $6, T0 +>) diff --git a/arm/ecc-192-modp.asm b/arm/ecc-192-modp.asm new file mode 100644 index 0000000..b6074a2 --- /dev/null +++ b/arm/ecc-192-modp.asm @@ -0,0 +1,106 @@ +C arm/ecc-192-modp.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "ecc-192-modp.asm" + .arm + +define(, ) C Overlaps unused modulo argument +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) C Overlaps T0 and T1 +define(

, ) +define(, ) +define(, ) + + C ecc_192_modp (const struct ecc_modulo *m, mp_limb_t *rp) + .text + .align 2 + +PROLOGUE(nettle_ecc_192_modp) + push {r4,r5,r6,r7,r8,r10} + C Reduce two words at a time + add HP, RP, #48 + add RP, RP, #8 + ldmdb HP!, {H0,H1} + ldm RP, {T2,T3,T4,T5,T6,T7} + mov C4, #0 + adds T4, T4, H0 + adcs T5, T5, H1 + adcs T6, T6, H0 + adcs T7, T7, H1 + C Need to add carry to T2 and T4, do T4 later. + adc C4, C4, #0 + + ldmdb HP!, {H0,H1} + mov C2, #0 + adcs T2, T2, H0 + adcs T3, T3, H1 + adcs T4, T4, H0 + adcs T5, T5, H1 + C Need to add carry to T0 and T2, do T2 later + adc C2, C2, #0 + + ldmdb RP!, {T0, T1} + adcs T0, T0, T6 + adcs T1, T1, T7 + adcs T2, T2, T6 + adcs T3, T3, T7 + adc C4, C4, #0 + + adds T2, T2, C2 + adcs T3, T3, #0 + adcs T4, T4, C4 + adcs T5, T5, #0 + mov C2, #0 + adc C2, C2, #0 + + C Add in final carry + adcs T0, T0, #0 + adcs T1, T1, #0 + adcs T2, T2, C2 + adcs T3, T3, #0 + adcs T4, T4, #0 + adc T5, T5, #0 + + stm RP, {T0,T1,T2,T3,T4,T5} + + pop {r4,r5,r6,r7,r8,r10} + bx lr +EPILOGUE(nettle_ecc_192_modp) diff --git a/arm/ecc-224-modp.asm b/arm/ecc-224-modp.asm new file mode 100644 index 0000000..15cc0c1 --- /dev/null +++ b/arm/ecc-224-modp.asm @@ -0,0 +1,124 @@ +C arm/ecc-224-modp.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "ecc-224-modp.asm" + .arm + +define(, ) +define(, ) C Overlaps unused modulo argument + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + C ecc_224_modp (const struct ecc_modulo *m, mp_limb_t *rp) + .text + .align 2 + +PROLOGUE(nettle_ecc_224_modp) + push {r4,r5,r6,r7,r8,r10,r11,lr} + + add L2, RP, #28 + ldm L2, {T0,T1,T2,T3,T4,T5,T6} + mov H, #0 + + adds T0, T0, T4 + adcs T1, T1, T5 + adcs T2, T2, T6 + adc H, H, #0 + + C This switch from adcs to sbcs takes carry into account with + C correct sign, but it always subtracts 1 too much. We arrange + C to also add B^7 + 1 below, so the effect is adding p. This + C addition of p also ensures that the result never is + C negative. + + sbcs N3, T3, T0 + sbcs T4, T4, T1 + sbcs T5, T5, T2 + sbcs T6, T6, H + mov H, #1 C This is the B^7 + sbc H, #0 + subs T6, T6, T3 + sbc H, #0 + + C Now subtract from low half + ldm RP!, {L0,L1,L2} + + C Clear carry, with the sbcs, this is the 1. + adds RP, #0 + + sbcs T0, L0, T0 + sbcs T1, L1, T1 + sbcs T2, L2, T2 + ldm RP!, {T3,L0,L1,L2} + sbcs T3, T3, N3 + sbcs T4, L0, T4 + sbcs T5, L1, T5 + sbcs T6, L2, T6 + rsc H, H, #0 + + C Now -2 <= H <= 0 is the borrow, so subtract (B^3 - 1) |H| + C Use (B^3 - 1) H = if -1 <=H <= 0, and + C (B^3 - 1) H = <1,B-1, B-1, B-2> if H = -2 + subs T0, T0, H + asr L1, H, #1 + sbcs T1, T1, L1 + eor H, H, L1 + sbcs T2, T2, L1 + sbcs T3, T3, H + sbcs T4, T4, #0 + sbcs T5, T5, #0 + sbcs T6, T6, #0 + sbcs H, H, H + + C Final borrow, subtract (B^3 - 1) |H| + subs T0, T0, H + sbcs T1, T1, H + sbcs T2, T2, H + sbcs T3, T3, #0 + sbcs T4, T4, #0 + sbcs T5, T5, #0 + sbcs T6, T6, #0 + + stmdb RP, {T0,T1,T2,T3,T4,T5,T6} + + pop {r4,r5,r6,r7,r8,r10,r11,pc} +EPILOGUE(nettle_ecc_224_modp) diff --git a/arm/ecc-256-redc.asm b/arm/ecc-256-redc.asm new file mode 100644 index 0000000..0c5e846 --- /dev/null +++ b/arm/ecc-256-redc.asm @@ -0,0 +1,173 @@ +C arm/ecc-256-redc.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "ecc-256-redc.asm" + .arm + +define(, ) + +define(, ) C Overlaps unused modulo argument +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + C ecc_256_redc (const struct ecc_modulo *m, mp_limb_t *rp) + .text + .align 2 + +PROLOGUE(nettle_ecc_256_redc) + push {r4,r5,r6,r7,r8,r10,r11,lr} + + ldm RP!, {T0,T1,T2,T3,T4,T5,T6,T7} + + C Set to the high 4 limbs of (B^2-B+1) + C T2 T1 + C T2 T1 T0 + C - T2 T1 T0 + C ------------- + C F3 F2 F1 F0 + + + adds F1, T0, T2 + adcs F2, T1, #0 + adc F3, T2, #0 + + subs F0, T1, T0 + sbcs F1, F1, T1 C Could also be rsc ? + sbcs F2, F2, T2 + sbc F3, F3, #0 + + C Add: + C T10 T9 T8 T7 T6 T5 T4 T3 + C + F3 F2 F1 F0 T0 T2 T1 T0 + C -------------------------- + C T7 T6 T5 T4 T3 T2 T1 T0 + + adds T3, T3, T0 + adcs T1, T4, T1 + adcs T2, T5, T2 + adcs T6, T6, T0 + mov T0, T3 C FIXME: Be more clever? + mov T3, T6 + adcs T4, T7, F0 + + ldm RP!, {T5,T6,T7} + adcs T5, T5, F1 + adcs T6, T6, F2 + adcs T7, T7, F3 + + C New F3, F2, F1, F0, also adding in carry + adcs F1, T0, T2 + adcs F2, T1, #0 + adc F3, T2, #0 + + subs F0, T1, T0 + sbcs F1, F1, T1 C Could also be rsc ? + sbcs F2, F2, T2 + sbc F3, F3, #0 + + C Start adding + adds T3, T3, T0 + adcs T1, T4, T1 + adcs T2, T5, T2 + adcs T6, T6, T0 + mov T0, T3 C FIXME: Be more clever? + mov T3, T6 + adcs T4, T7, F0 + + ldm RP!, {T5,T6,T7} + adcs T5, T5, F1 + adcs T6, T6, F2 + adcs T7, T7, F3 + + C Final iteration, eliminate only T0, T1 + C Set to the high 3 limbs of (B^2-B+1) + + C T1 T0 T1 + C - T1 T0 + C ------------- + C F2 F1 F0 + + C First add in carry + adcs F1, T0, #0 + adcs F2, T1, #0 + subs F0, T1, T0 + sbcs F1, F1, T1 + sbc F2, F2, #0 + + C Add: + C T9 T8 T7 T6 T5 T4 T3 T2 + C + F2 F1 F0 T0 0 T1 T0 0 + C -------------------------- + C F2 F1 T7 T6 T5 T4 T3 T2 + + adds T3, T3, T0 + adcs T4, T4, T1 + adcs T5, T5, #0 + adcs T6, T6, T0 + adcs T7, T7, F0 + ldm RP!, {T0, T1} + mov F3, #0 + adcs F1, F1, T0 + adcs F2, F2, T1 + + C Sum is < B^8 + p, so it's enough to fold carry once, + C If carry, add in + C B^7 - B^6 - B^3 + 1 = <0, B-2, B-1, B-1, B-1, 0, 0, 1> + + C Mask from carry flag, leaving carry intact + adc F3, F3, #0 + rsb F3, F3, #0 + + adcs T0, T2, #0 + adcs T1, T3, #0 + adcs T2, T4, #0 + adcs T3, T5, F3 + adcs T4, T6, F3 + adcs T5, T7, F3 + and F3, F3, #-2 + adcs T6, F1, F3 + adcs T7, F2, #0 + + sub RP, RP, #64 + stm RP, {T0,T1,T2,T3,T4,T5,T6,T7} + + pop {r4,r5,r6,r7,r8,r10,r11,pc} +EPILOGUE(nettle_ecc_256_redc) diff --git a/arm/ecc-384-modp.asm b/arm/ecc-384-modp.asm new file mode 100644 index 0000000..1d36319 --- /dev/null +++ b/arm/ecc-384-modp.asm @@ -0,0 +1,270 @@ +C arm/ecc-384-modp.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "ecc-384-modp.asm" + .arm + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + C ecc_384_modp (const struct ecc_modulo *m, mp_limb_t *rp) + .text + .align 2 + +PROLOGUE(nettle_ecc_384_modp) + push {r4,r5,r6,r7,r8,r10,lr} + + add RP, RP, #80 + ldm RP, {T0, T1, T2, T3} C 20-23 + + C First get top 4 limbs, which need folding twice, as + C + C T3 T2 T1 T0 + C T3 T2 T1 + C -T3 + C ---------------- + C F4 F3 F2 F1 F0 + C + C Start with + C + C T3 T1 T0 + C T1 + C -T3 + C ----------- + C F2 F1 F0 Always fits + + adds F0, T0, T1 + adcs F1, T1, #0 + adcs F2, T3, #0 + subs F0, F0, T3 + sbcs F1, F1, #0 + sbcs F2, F2, #0 + + C T3 T2 T2 0 + C F2 F1 F0 + C ---------------- + C F4 F3 F2 F1 F0 + + mov F4, #0 + adds F1, F1, T2 + adcs F2, F2, T2 + adcs F3, T3, #0 + adcs F4, F4, #0 + + C Add in to high part + sub RP, RP, #32 + ldm RP, {T0, T1, T2, T3} C 12-15 + mov H, #0 + adds F0, T0, F0 + adcs F1, T1, F1 + adcs F2, T2, F2 + adcs F3, T3, F3 + adcs F4, F4, #0 C Do F4 later + + C Add to low part, keeping carry (positive or negative) in H + sub RP, RP, #48 + ldm RP, {T0, T1, T2, T3} C 0-3 + mov H, #0 + adds T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + adcs T3, T3, F3 + adc H, H, #0 + subs T1, T1, F0 + sbcs T2, T2, F1 + sbcs T3, T3, F2 + sbc H, H, #0 + adds T3, T3, F0 + adc H, H, #0 + + stm RP!, {T0,T1,T2,T3} C 0-3 + mov N, #2 +.Loop: + ldm RP, {T0,T1,T2,T3} C 4-7 + + C First, propagate carry + adds T0, T0, H + asr H, #31 C Sign extend + adcs T1, T1, H + adcs T2, T2, H + adcs T3, T3, H + adc H, H, #0 + + C +B^4 term + adds T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + adcs T3, T3, F3 + adc H, H, #0 + + C +B^3 terms + ldr F0, [RP, #+48] C 16 + adds T0, T0, F1 + adcs T1, T1, F2 + adcs T2, T2, F3 + adcs T3, T3, F0 + adc H, H, #0 + + C -B + ldr F1, [RP, #+52] C 17-18 + ldr F2, [RP, #+56] + subs T0, T0, F3 + sbcs T1, T1, F0 + sbcs T2, T2, F1 + sbcs T3, T3, F2 + sbcs H, H, #0 + + C +1 + ldr F3, [RP, #+60] C 19 + adds T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + adcs T3, T3, F3 + adc H, H, #0 + subs N, N, #1 + stm RP!, {T0,T1,T2,T3} + bne .Loop + + C Fold high limbs, we need to add in + C + C F4 F4 0 -F4 F4 H H 0 -H H + C + C We always have F4 >= 0, but we can have H < 0. + C Sign extension gets tricky when F4 = 0 and H < 0. + sub RP, RP, #48 + + ldm RP, {T0,T1,T2,T3} C 0-3 + + C H H 0 -H H + C ---------------- + C S H F3 F2 F1 F0 + C + C Define S = H >> 31 (asr), we then have + C + C F0 = H + C F1 = S - H + C F2 = - [H > 0] + C F3 = H - [H > 0] + C H = H + S + C + C And we get underflow in S - H iff H > 0 + + C H = 0 H > 0 H = -1 + mov F0, H C 0 H -1 + asr H, #31 + subs F1, H, F0 C 0,C=1 -H,C=0 0,C=1 + sbc F2, F2, F2 C 0 -1 0 + sbc F3, F0, #0 C 0 H-1 -1 + + adds T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + adcs T3, T3, F3 + adc H, H, F0 C 0+cy H+cy -2+cy + + stm RP!, {T0,T1,T2,T3} C 0-3 + ldm RP, {T0,T1,T2,T3} C 4-7 + + C F4 0 -F4 + C --------- + C F3 F2 F1 + + rsbs F1, F4, #0 + sbc F2, F2, F2 + sbc F3, F4, #0 + + C Sign extend H + adds F0, F4, H + asr H, H, #31 + adcs F1, F1, H + adcs F2, F2, H + adcs F3, F3, H + adcs F4, F4, H + adc H, H, #0 + + adds T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + adcs T3, T3, F3 + + stm RP!, {T0,T1,T2,T3} C 4-7 + ldm RP, {T0,T1,T2,T3} C 8-11 + + adcs T0, T0, F4 + adcs T1, T1, H + adcs T2, T2, H + adcs T3, T3, H + adc H, H, #0 + + stm RP, {T0,T1,T2,T3} C 8-11 + + C Final (unlikely) carry + sub RP, RP, #32 + ldm RP, {T0,T1,T2,T3} C 0-3 + C Fold H into F0-F4 + mov F0, H + asr H, #31 + subs F1, H, F0 + sbc F2, F2, F2 + sbc F3, F0, #0 + add F4, F0, H + + adds T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + adcs T3, T3, F3 + + stm RP!, {T0,T1,T2,T3} C 0-3 + ldm RP, {T0,T1,T2,T3} C 4-7 + adcs T0, T0, F4 + adcs T1, T1, H + adcs T2, T2, H + adcs T3, T3, H + stm RP!, {T0,T1,T2,T3} C 4-7 + ldm RP, {T0,T1,T2,T3} C 8-11 + adcs T0, T0, H + adcs T1, T1, H + adcs T2, T2, H + adcs T3, T3, H + stm RP!, {T0,T1,T2,T3} C 8-11 + pop {r4,r5,r6,r7,r8,r10,pc} +EPILOGUE(nettle_ecc_384_modp) diff --git a/arm/ecc-521-modp.asm b/arm/ecc-521-modp.asm new file mode 100644 index 0000000..3fba239 --- /dev/null +++ b/arm/ecc-521-modp.asm @@ -0,0 +1,127 @@ +C arm/ecc-521-modp.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "ecc-521-modp.asm" + .arm + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + C ecc_521_modp (const struct ecc_modulo *m, mp_limb_t *rp) + .text +.Lc511: + .int 511 + + .align 2 + +PROLOGUE(nettle_ecc_521_modp) + push {r4,r5,r6,r7,r8,lr} + + C Use that B^17 = 2^23 (mod p) + ldr F3, [RP, #+68] C 17 + add HP, RP, #72 C 18 + ldr T0, [RP] C 0 + adds T0, T0, F3, lsl #23 + str T0, [RP], #+4 + mov N, #5 + + C 5 iterations, reading limbs 18-20, 21-23, 24-26, 27-29, 30-32 + C and adding to limbs 1-3, 4-6, 7-9, 19-12, 13-15 +.Loop: + ldm RP, {T0,T1,T2} C 1+3*k -- 3+3*k + lsr F0, F3, #9 + ldm HP!, {F1,F2,F3} C 18+3*k -- 20+3*k + orr F0, F0, F1, lsl #23 + lsr F1, F1, #9 + orr F1, F1, F2, lsl #23 + lsr F2, F2, #9 + orr F2, F2, F3, lsl #23 + adcs T0, T0, F0 + adcs T1, T1, F1 + adcs T2, T2, F2 + sub N, N, #1 + stm RP!,{T0,T1,T2} + teq N, #0 + bne .Loop + + ldr F0, [RP], #-64 C 16 + ldr F1, [HP] C 33 + ldr T0, .Lc511 + + C Handling of high limbs + C F0 = rp[16] + carry in + F3 >> 9 + adcs F0, F0, F3, lsr #9 + C Copy low 9 bits to H, then shift right including carry + and H, F0, T0 + mov F0, F0, rrx + lsr F0, F0, #8 + C Add in F1 = rp[33], with weight 2^1056 = 2^14 + adds F0, F0, F1, lsl #14 + lsr F1, F1, #18 + adc F1, F1, #0 + + ldm RP, {T0, T1} C 0-1 + adds T0, T0, F0 + adcs T1, T1, F1 + stm RP!, {T0, T1} + + ldm RP, {T0,T1,T2,F0,F1,F2,F3} C 2-8 + adcs T0, T0, #0 + adcs T1, T1, #0 + adcs T2, T2, #0 + adcs F0, F0, #0 + adcs F1, F1, #0 + adcs F2, F2, #0 + adcs F3, F3, #0 + stm RP!, {T0,T1,T2,F0,F1,F2,F3} C 2-8 + ldm RP, {T0,T1,T2,F0,F1,F2,F3} C 9-15 + adcs T0, T0, #0 + adcs T1, T1, #0 + adcs T2, T2, #0 + adcs F0, F0, #0 + adcs F1, F1, #0 + adcs F2, F2, #0 + adcs F3, F3, #0 + adcs H, H, #0 + stm RP, {T0,T1,T2,F0,F1,F2,F3,H} C 9-16 + + pop {r4,r5,r6,r7,r8,pc} +EPILOGUE(nettle_ecc_521_modp) diff --git a/arm/fat/aes-decrypt-internal-2.asm b/arm/fat/aes-decrypt-internal-2.asm new file mode 100644 index 0000000..2110f31 --- /dev/null +++ b/arm/fat/aes-decrypt-internal-2.asm @@ -0,0 +1,35 @@ +C arm/fat/aes-decrypt-internal-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +define(, <$1_armv6>) +include_src() diff --git a/arm/fat/aes-decrypt-internal.asm b/arm/fat/aes-decrypt-internal.asm new file mode 100644 index 0000000..8d76388 --- /dev/null +++ b/arm/fat/aes-decrypt-internal.asm @@ -0,0 +1,35 @@ +C arm/fat/aes-decrypt-internal.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +define(, <$1_arm>) +include_src() diff --git a/arm/fat/aes-encrypt-internal-2.asm b/arm/fat/aes-encrypt-internal-2.asm new file mode 100644 index 0000000..490a52b --- /dev/null +++ b/arm/fat/aes-encrypt-internal-2.asm @@ -0,0 +1,35 @@ +C arm/fat/aes-encrypt-internal-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +define(, <$1_armv6>) +include_src() diff --git a/arm/fat/aes-encrypt-internal.asm b/arm/fat/aes-encrypt-internal.asm new file mode 100644 index 0000000..e695a28 --- /dev/null +++ b/arm/fat/aes-encrypt-internal.asm @@ -0,0 +1,35 @@ +C arm/fat/aes-encrypt-internal.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +define(, <$1_arm>) +include_src() diff --git a/arm/fat/salsa20-core-internal-2.asm b/arm/fat/salsa20-core-internal-2.asm new file mode 100644 index 0000000..64d9030 --- /dev/null +++ b/arm/fat/salsa20-core-internal-2.asm @@ -0,0 +1,37 @@ +C arm/fat/salsa20-core-internal-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_salsa20_core) picked up by configure + +define(, <$1_neon>) +include_src() diff --git a/arm/fat/sha1-compress-2.asm b/arm/fat/sha1-compress-2.asm new file mode 100644 index 0000000..c326bef --- /dev/null +++ b/arm/fat/sha1-compress-2.asm @@ -0,0 +1,37 @@ +C arm/fat/sha1-compress-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_sha1_compress) picked up by configure + +define(, <$1_armv6>) +include_src() diff --git a/arm/fat/sha256-compress-2.asm b/arm/fat/sha256-compress-2.asm new file mode 100644 index 0000000..e1babb3 --- /dev/null +++ b/arm/fat/sha256-compress-2.asm @@ -0,0 +1,37 @@ +C arm/fat/sha256-compress-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_sha256_compress) picked up by configure + +define(, <$1_armv6>) +include_src() diff --git a/arm/fat/sha3-permute-2.asm b/arm/fat/sha3-permute-2.asm new file mode 100644 index 0000000..b423a76 --- /dev/null +++ b/arm/fat/sha3-permute-2.asm @@ -0,0 +1,37 @@ +C arm/fat/sha3-permute-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_sha3_permute) picked up by configure + +define(, <_$1_neon>) +include_src() diff --git a/arm/fat/sha512-compress-2.asm b/arm/fat/sha512-compress-2.asm new file mode 100644 index 0000000..428604e --- /dev/null +++ b/arm/fat/sha512-compress-2.asm @@ -0,0 +1,37 @@ +C arm/fat/sha3-compress-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_sha512_compress) picked up by configure + +define(, <$1_neon>) +include_src() diff --git a/arm/fat/umac-nh-2.asm b/arm/fat/umac-nh-2.asm new file mode 100644 index 0000000..fc97cc6 --- /dev/null +++ b/arm/fat/umac-nh-2.asm @@ -0,0 +1,37 @@ +C arm/fat/umac-nh-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_umac_nh) picked up by configure + +define(, <$1_neon>) +include_src() diff --git a/arm/fat/umac-nh-n-2.asm b/arm/fat/umac-nh-n-2.asm new file mode 100644 index 0000000..32b7a83 --- /dev/null +++ b/arm/fat/umac-nh-n-2.asm @@ -0,0 +1,37 @@ +C arm/fat/umac-nh-n-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +dnl PROLOGUE(_nettle_umac_nh_n) picked up by configure + +define(, <$1_neon>) +include_src() diff --git a/arm/machine.m4 b/arm/machine.m4 new file mode 100644 index 0000000..f982a66 --- /dev/null +++ b/arm/machine.m4 @@ -0,0 +1,56 @@ +define(, )>)dnl + +define(, )>)dnl + +define(, )>)dnl diff --git a/arm/memxor.asm b/arm/memxor.asm new file mode 100644 index 0000000..a50e91b --- /dev/null +++ b/arm/memxor.asm @@ -0,0 +1,229 @@ +C arm/memxor.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +C Possible speedups: +C +C The ldm instruction can do load two registers per cycle, +C if the address is two-word aligned. Or three registers in two +C cycles, regardless of alignment. + +C Register usage: + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + .syntax unified + + .file "memxor.asm" + + .text + .arm + + C memxor(void *dst, const void *src, size_t n) + .align 4 +PROLOGUE(nettle_memxor) + cmp N, #0 + beq .Lmemxor_done + + cmp N, #7 + bcs .Lmemxor_large + + C Simple byte loop +.Lmemxor_bytes: + ldrb r3, [SRC], #+1 + ldrb r12, [DST] + eor r3, r12 + strb r3, [DST], #+1 + subs N, #1 + bne .Lmemxor_bytes + +.Lmemxor_done: + bx lr + +.Lmemxor_align_loop: + ldrb r3, [SRC], #+1 + ldrb r12, [DST] + eor r3, r12 + strb r3, [DST], #+1 + sub N, #1 + +.Lmemxor_large: + tst DST, #3 + bne .Lmemxor_align_loop + + C We have at least 4 bytes left to do here. + sub N, #4 + + ands r3, SRC, #3 + beq .Lmemxor_same + + C Different alignment case. + C v original SRC + C +-------+------+ + C |SRC |SRC+4 | + C +---+---+------+ + C |DST | + C +-------+ + C + C With little-endian, we need to do + C DST[i] ^= (SRC[i] >> CNT) ^ (SRC[i+1] << TNC) + + push {r4,r5,r6} + + lsl CNT, r3, #3 + bic SRC, #3 + rsb TNC, CNT, #32 + + ldr r4, [SRC], #+4 + + tst N, #4 + itet eq + moveq r5, r4 + subne N, #4 + beq .Lmemxor_odd + +.Lmemxor_word_loop: + ldr r5, [SRC], #+4 + ldr r3, [DST] + eor r3, r3, r4, lsr CNT + eor r3, r3, r5, lsl TNC + str r3, [DST], #+4 +.Lmemxor_odd: + ldr r4, [SRC], #+4 + ldr r3, [DST] + eor r3, r3, r5, lsr CNT + eor r3, r3, r4, lsl TNC + str r3, [DST], #+4 + subs N, #8 + bcs .Lmemxor_word_loop + adds N, #8 + beq .Lmemxor_odd_done + + C We have TNC/8 left-over bytes in r4, high end + lsr r4, CNT + ldr r3, [DST] + eor r3, r4 + + pop {r4,r5,r6} + + C Store bytes, one by one. +.Lmemxor_leftover: + strb r3, [DST], #+1 + subs N, #1 + beq .Lmemxor_done + subs TNC, #8 + lsr r3, #8 + bne .Lmemxor_leftover + b .Lmemxor_bytes +.Lmemxor_odd_done: + pop {r4,r5,r6} + bx lr + +.Lmemxor_same: + push {r4,r5,r6,r7,r8,r10,r11,r14} C lr is the link register + + subs N, #8 + bcc .Lmemxor_same_end + + ldmia SRC!, {r3, r4, r5} + C Keep address for loads in r14 + mov r14, DST + ldmia r14!, {r6, r7, r8} + subs N, #12 + eor r10, r3, r6 + eor r11, r4, r7 + eor r12, r5, r8 + bcc .Lmemxor_same_final_store + subs N, #12 + ldmia r14!, {r6, r7, r8} + bcc .Lmemxor_same_wind_down + + C 6 cycles per iteration, 0.50 cycles/byte. For this speed, + C loop starts at offset 0x11c in the object file. + +.Lmemxor_same_loop: + C r10-r12 contains values to be stored at DST + C r6-r8 contains values read from r14, in advance + ldmia SRC!, {r3, r4, r5} + subs N, #12 + stmia DST!, {r10, r11, r12} + eor r10, r3, r6 + eor r11, r4, r7 + eor r12, r5, r8 + ldmia r14!, {r6, r7, r8} + bcs .Lmemxor_same_loop + +.Lmemxor_same_wind_down: + C Wind down code + ldmia SRC!, {r3, r4, r5} + stmia DST!, {r10, r11, r12} + eor r10, r3, r6 + eor r11, r4, r7 + eor r12, r5, r8 +.Lmemxor_same_final_store: + stmia DST!, {r10, r11, r12} + +.Lmemxor_same_end: + C We have 0-11 bytes left to do, and N holds number of bytes -12. + adds N, #4 + bcc .Lmemxor_same_lt_8 + C Do 8 bytes more, leftover is in N + ldmia SRC!, {r3, r4} + ldmia DST, {r6, r7} + eor r3, r6 + eor r4, r7 + stmia DST!, {r3, r4} + pop {r4,r5,r6,r7,r8,r10,r11,r14} + beq .Lmemxor_done + b .Lmemxor_bytes + +.Lmemxor_same_lt_8: + pop {r4,r5,r6,r7,r8,r10,r11,r14} + adds N, #4 + bcc .Lmemxor_same_lt_4 + + ldr r3, [SRC], #+4 + ldr r12, [DST] + eor r3, r12 + str r3, [DST], #+4 + beq .Lmemxor_done + b .Lmemxor_bytes + +.Lmemxor_same_lt_4: + adds N, #4 + beq .Lmemxor_done + b .Lmemxor_bytes + +EPILOGUE(nettle_memxor) diff --git a/arm/memxor3.asm b/arm/memxor3.asm new file mode 100644 index 0000000..139fd20 --- /dev/null +++ b/arm/memxor3.asm @@ -0,0 +1,315 @@ +C arm/memxor3.asm + +ifelse(< + Copyright (C) 2013, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +C Possible speedups: +C +C The ldm instruction can do load two registers per cycle, +C if the address is two-word aligned. Or three registers in two +C cycles, regardless of alignment. + +C Register usage: + +define(, ) +define(, ) +define(, ) +define(, ) + +C Temporaries r4-r7 +define(, ) +define(, ) +define(, ) +define(, ) + + .syntax unified + + .file "memxor3.asm" + + .text + .arm + + C memxor3(void *dst, const void *a, const void *b, size_t n) + .align 2 +PROLOGUE(nettle_memxor3) + cmp N, #0 + beq .Lmemxor3_ret + + push {r4,r5,r6,r7,r8,r10,r11} + cmp N, #7 + + add AP, N + add BP, N + add DST, N + + bcs .Lmemxor3_large + + C Simple byte loop +.Lmemxor3_bytes: + ldrb r4, [AP, #-1]! + ldrb r5, [BP, #-1]! + eor r4, r5 + strb r4, [DST, #-1]! + subs N, #1 + bne .Lmemxor3_bytes + +.Lmemxor3_done: + pop {r4,r5,r6,r7,r8,r10,r11} +.Lmemxor3_ret: + bx lr + +.Lmemxor3_align_loop: + ldrb r4, [AP, #-1]! + ldrb r5, [BP, #-1]! + eor r5, r4 + strb r5, [DST, #-1]! + sub N, #1 + +.Lmemxor3_large: + tst DST, #3 + bne .Lmemxor3_align_loop + + C We have at least 4 bytes left to do here. + sub N, #4 + ands ACNT, AP, #3 + lsl ACNT, #3 + beq .Lmemxor3_a_aligned + + ands BCNT, BP, #3 + lsl BCNT, #3 + bne .Lmemxor3_uu + + C Swap + mov r4, AP + mov AP, BP + mov BP, r4 + +.Lmemxor3_au: + C NOTE: We have the relevant shift count in ACNT, not BCNT + + C AP is aligned, BP is not + C v original SRC + C +-------+------+ + C |SRC-4 |SRC | + C +---+---+------+ + C |DST-4 | + C +-------+ + C + C With little-endian, we need to do + C DST[i-i] ^= (SRC[i-i] >> CNT) ^ (SRC[i] << TNC) + rsb ATNC, ACNT, #32 + bic BP, #3 + + ldr r4, [BP] + + tst N, #4 + itet eq + moveq r5, r4 + subne N, #4 + beq .Lmemxor3_au_odd + +.Lmemxor3_au_loop: + ldr r5, [BP, #-4]! + ldr r6, [AP, #-4]! + eor r6, r6, r4, lsl ATNC + eor r6, r6, r5, lsr ACNT + str r6, [DST, #-4]! +.Lmemxor3_au_odd: + ldr r4, [BP, #-4]! + ldr r6, [AP, #-4]! + eor r6, r6, r5, lsl ATNC + eor r6, r6, r4, lsr ACNT + str r6, [DST, #-4]! + subs N, #8 + bcs .Lmemxor3_au_loop + adds N, #8 + beq .Lmemxor3_done + + C Leftover bytes in r4, low end + ldr r5, [AP, #-4] + eor r4, r5, r4, lsl ATNC + +.Lmemxor3_au_leftover: + C Store a byte at a time + ror r4, #24 + strb r4, [DST, #-1]! + subs N, #1 + beq .Lmemxor3_done + subs ACNT, #8 + sub AP, #1 + bne .Lmemxor3_au_leftover + b .Lmemxor3_bytes + +.Lmemxor3_a_aligned: + ands ACNT, BP, #3 + lsl ACNT, #3 + bne .Lmemxor3_au ; + + C a, b and dst all have the same alignment. + subs N, #8 + bcc .Lmemxor3_aligned_word_end + + C This loop runs at 8 cycles per iteration. It has been + C observed running at only 7 cycles, for this speed, the loop + C started at offset 0x2ac in the object file. + + C FIXME: consider software pipelining, similarly to the memxor + C loop. + +.Lmemxor3_aligned_word_loop: + ldmdb AP!, {r4,r5,r6} + ldmdb BP!, {r7,r8,r10} + subs N, #12 + eor r4, r7 + eor r5, r8 + eor r6, r10 + stmdb DST!, {r4, r5,r6} + bcs .Lmemxor3_aligned_word_loop + +.Lmemxor3_aligned_word_end: + C We have 0-11 bytes left to do, and N holds number of bytes -12. + adds N, #4 + bcc .Lmemxor3_aligned_lt_8 + C Do 8 bytes more, leftover is in N + ldmdb AP!, {r4, r5} + ldmdb BP!, {r6, r7} + eor r4, r6 + eor r5, r7 + stmdb DST!, {r4,r5} + beq .Lmemxor3_done + b .Lmemxor3_bytes + +.Lmemxor3_aligned_lt_8: + adds N, #4 + bcc .Lmemxor3_aligned_lt_4 + + ldr r4, [AP,#-4]! + ldr r5, [BP,#-4]! + eor r4, r5 + str r4, [DST,#-4]! + beq .Lmemxor3_done + b .Lmemxor3_bytes + +.Lmemxor3_aligned_lt_4: + adds N, #4 + beq .Lmemxor3_done + b .Lmemxor3_bytes + +.Lmemxor3_uu: + + cmp ACNT, BCNT + bic AP, #3 + bic BP, #3 + rsb ATNC, ACNT, #32 + + bne .Lmemxor3_uud + + C AP and BP are unaligned in the same way + + ldr r4, [AP] + ldr r6, [BP] + eor r4, r6 + + tst N, #4 + itet eq + moveq r5, r4 + subne N, #4 + beq .Lmemxor3_uu_odd + +.Lmemxor3_uu_loop: + ldr r5, [AP, #-4]! + ldr r6, [BP, #-4]! + eor r5, r6 + lsl r4, ATNC + eor r4, r4, r5, lsr ACNT + str r4, [DST, #-4]! +.Lmemxor3_uu_odd: + ldr r4, [AP, #-4]! + ldr r6, [BP, #-4]! + eor r4, r6 + lsl r5, ATNC + eor r5, r5, r4, lsr ACNT + str r5, [DST, #-4]! + subs N, #8 + bcs .Lmemxor3_uu_loop + adds N, #8 + beq .Lmemxor3_done + + C Leftover bytes in a4, low end + ror r4, ACNT +.Lmemxor3_uu_leftover: + ror r4, #24 + strb r4, [DST, #-1]! + subs N, #1 + beq .Lmemxor3_done + subs ACNT, #8 + bne .Lmemxor3_uu_leftover + b .Lmemxor3_bytes + +.Lmemxor3_uud: + C Both AP and BP unaligned, and in different ways + rsb BTNC, BCNT, #32 + + ldr r4, [AP] + ldr r6, [BP] + + tst N, #4 + ittet eq + moveq r5, r4 + moveq r7, r6 + subne N, #4 + beq .Lmemxor3_uud_odd + +.Lmemxor3_uud_loop: + ldr r5, [AP, #-4]! + ldr r7, [BP, #-4]! + lsl r4, ATNC + eor r4, r4, r6, lsl BTNC + eor r4, r4, r5, lsr ACNT + eor r4, r4, r7, lsr BCNT + str r4, [DST, #-4]! +.Lmemxor3_uud_odd: + ldr r4, [AP, #-4]! + ldr r6, [BP, #-4]! + lsl r5, ATNC + eor r5, r5, r7, lsl BTNC + eor r5, r5, r4, lsr ACNT + eor r5, r5, r6, lsr BCNT + str r5, [DST, #-4]! + subs N, #8 + bcs .Lmemxor3_uud_loop + adds N, #8 + beq .Lmemxor3_done + + C FIXME: More clever left-over handling? For now, just adjust pointers. + add AP, AP, ACNT, lsr #3 + add BP, BP, BCNT, lsr #3 + b .Lmemxor3_bytes +EPILOGUE(nettle_memxor3) diff --git a/arm/neon/chacha-core-internal.asm b/arm/neon/chacha-core-internal.asm new file mode 100644 index 0000000..6f62310 --- /dev/null +++ b/arm/neon/chacha-core-internal.asm @@ -0,0 +1,136 @@ +C arm/neon/chacha-core-internal.asm + +ifelse(< + Copyright (C) 2013, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "chacha-core-internal.asm" + .fpu neon + +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, < + C x0 += x1, x3 ^= x0, x3 lrot 16 + C x2 += x3, x1 ^= x2, x1 lrot 12 + C x0 += x1, x3 ^= x0, x3 lrot 8 + C x2 += x3, x1 ^= x2, x1 lrot 7 + + vadd.i32 $1, $1, $2 + veor $4, $4, $1 + vshl.i32 T0, $4, #16 + vshr.u32 $4, $4, #16 + veor $4, $4, T0 + + vadd.i32 $3, $3, $4 + veor $2, $2, $3 + vshl.i32 T0, $2, #12 + vshr.u32 $2, $2, #20 + veor $2, $2, T0 + + vadd.i32 $1, $1, $2 + veor $4, $4, $1 + vshl.i32 T0, $4, #8 + vshr.u32 $4, $4, #24 + veor $4, $4, T0 + + vadd.i32 $3, $3, $4 + veor $2, $2, $3 + vshl.i32 T0, $2, #7 + vshr.u32 $2, $2, #25 + veor $2, $2, T0 +>) + + .text + .align 4 + C _chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds) + +PROLOGUE(_nettle_chacha_core) + vldm SRC, {X0,X1,X2,X3} + + vmov S0, X0 + vmov S1, X1 + vmov S2, X2 + vmov S3, X3 + + C Input rows: + C 0 1 2 3 X0 + C 4 5 6 7 X1 + C 8 9 10 11 X2 + C 12 13 14 15 X3 + +.Loop: + QROUND(X0, X1, X2, X3) + + C Rotate rows, to get + C 0 1 2 3 + C 5 6 7 4 >>> 3 + C 10 11 8 9 >>> 2 + C 15 12 13 14 >>> 1 + vext.32 X1, X1, X1, #1 + vext.32 X2, X2, X2, #2 + vext.32 X3, X3, X3, #3 + + QROUND(X0, X1, X2, X3) + + subs ROUNDS, ROUNDS, #2 + C Inverse rotation + vext.32 X1, X1, X1, #3 + vext.32 X2, X2, X2, #2 + vext.32 X3, X3, X3, #1 + + bhi .Loop + + vadd.u32 X0, X0, S0 + vadd.u32 X1, X1, S1 + vadd.u32 X2, X2, S2 + vadd.u32 X3, X3, S3 + + vstm DST, {X0,X1,X2,X3} + bx lr +EPILOGUE(_nettle_chacha_core) + +divert(-1) +define chachastate +p/x $q0.u32 +p/x $q1.u32 +p/x $q2.u32 +p/x $q3.u32 +end diff --git a/arm/neon/salsa20-core-internal.asm b/arm/neon/salsa20-core-internal.asm new file mode 100644 index 0000000..34eb1fb --- /dev/null +++ b/arm/neon/salsa20-core-internal.asm @@ -0,0 +1,194 @@ +C arm/neon/salsa20-core-internal.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "salsa20-core-internal.asm" + .fpu neon + +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, < + vadd.i32 T0, $1, $4 + vshl.i32 T1, T0, #7 + vshr.u32 T0, T0, #25 + veor $2, $2, T0 + veor $2, $2, T1 + + vadd.i32 T0, $1, $2 + vshl.i32 T1, T0, #9 + vshr.u32 T0, T0, #23 + veor $3, $3, T0 + veor $3, $3, T1 + + vadd.i32 T0, $2, $3 + vshl.i32 T1, T0, #13 + vshr.u32 T0, T0, #19 + veor $4, $4, T0 + veor $4, $4, T1 + + vadd.i32 T0, $3, $4 + vshl.i32 T1, T0, #18 + vshr.u32 T0, T0, #14 + veor $1, $1, T0 + veor $1, $1, T1 +>) + + .text + .align 4 +.Lmasks: + .int 0,-1, 0,-1 + .int 0,-1,-1, 0 + .int 0, 0,-1,-1 + + C _salsa20_core(uint32_t *dst, const uint32_t *src, unsigned rounds) + +PROLOGUE(_nettle_salsa20_core) + vldm SRC, {X0,X1,X2,X3} + + C Input rows: + C 0 1 2 3 X0 + C 4 5 6 7 X1 + C 8 9 10 11 X2 + C 12 13 14 15 X3 + C Permuted to: + C 0 5 10 15 + C 4 9 14 3 + C 8 13 2 7 + C 12 1 6 11 + + C FIXME: Construct in some other way? + adr r12, .Lmasks + vldm r12, {M0101, M0110, M0011} + + vmov S1, X1 + vmov S2, X2 + vmov S3, X3 + + C Swaps in columns 1, 3: + C 0 5 2 7 X0 ^ + C 4 1 6 3 T0 v + C 8 13 10 15 T1 ^ + C 12 9 14 11 X3 v + vmov T0, X1 + vmov T1, X2 + vbit T0, X0, M0101 + vbit X0, X1, M0101 + vbit T1, X3, M0101 + vbit X3, X2, M0101 + + C Swaps in column 1, 2: + C 0 5 2 7 X0 + C 4 9 14 3 X1 ^ + C 8 13 10 15 T1 | + C 12 1 6 11 X3 v + vmov X1, T0 + vbit X1, X3, M0110 + vbit X3, T0, M0110 + + C Swaps in columm 2,3: + C 0 5 10 15 X0 ^ + C 4 9 14 3 X1 | + C 8 13 2 7 X2 v + C 12 1 6 11 X3 + vmov X2, T1 + vbit X2, X0, M0011 + vbit X0, T1, M0011 + +.Loop: + QROUND(X0, X1, X2, X3) + + C Rotate rows, to get + C 0 5 10 15 + C 3 4 9 14 >>> 1 + C 2 7 8 13 >>> 2 + C 1 6 11 12 >>> 3 + vext.32 X1, X1, X1, #3 + vext.32 X2, X2, X2, #2 + vext.32 X3, X3, X3, #1 + + QROUND(X0, X3, X2, X1) + + subs ROUNDS, ROUNDS, #2 + C Inverse rotation + vext.32 X1, X1, X1, #1 + vext.32 X2, X2, X2, #2 + vext.32 X3, X3, X3, #3 + + bhi .Loop + + C Inverse swaps + vmov T1, X2 + vbit T1, X0, M0011 + vbit X0, X2, M0011 + + vmov T0, X1 + vbit T0, X3, M0110 + vbit X3, X1, M0110 + + vmov X1, T0 + vmov X2, T1 + vbit X1, X0, M0101 + vbit X0, T0, M0101 + vbit X2, X3, M0101 + vbit X3, T1, M0101 + + vld1.64 {T0}, [SRC] + vadd.u32 X0, X0, T0 + vadd.u32 X1, X1, S1 + vadd.u32 X2, X2, S2 + vadd.u32 X3, X3, S3 + + vstm DST, {X0,X1,X2,X3} + bx lr +EPILOGUE(_nettle_salsa20_core) + +divert(-1) +define salsastate +p/x $q0.u32 +p/x $q1.u32 +p/x $q2.u32 +p/x $q3.u32 +end diff --git a/arm/neon/sha3-permute.asm b/arm/neon/sha3-permute.asm new file mode 100644 index 0000000..43a523f --- /dev/null +++ b/arm/neon/sha3-permute.asm @@ -0,0 +1,279 @@ +C arm/neon/sha3-permute.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "sha3-permute.asm" + .fpu neon + +define(, ) +define(, ) +define(, ) +C First column +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + +C ROL(DST, SRC, COUNT) +C Must have SRC != DST +define(, < + vshr.u64 $1, $2, #eval(64-$3) + vsli.i64 $1, $2, #$3 + >) +C sha3_permute(struct sha3_ctx *ctx) + + .text + .align 3 +.Lrc: + .quad 0x0000000000000001 + .quad 0x0000000000008082 + .quad 0x800000000000808A + .quad 0x8000000080008000 + .quad 0x000000000000808B + .quad 0x0000000080000001 + .quad 0x8000000080008081 + .quad 0x8000000000008009 + .quad 0x000000000000008A + .quad 0x0000000000000088 + .quad 0x0000000080008009 + .quad 0x000000008000000A + .quad 0x000000008000808B + .quad 0x800000000000008B + .quad 0x8000000000008089 + .quad 0x8000000000008003 + .quad 0x8000000000008002 + .quad 0x8000000000000080 + .quad 0x000000000000800A + .quad 0x800000008000000A + .quad 0x8000000080008081 + .quad 0x8000000000008080 + .quad 0x0000000080000001 + .quad 0x8000000080008008 + +PROLOGUE(nettle_sha3_permute) + vpush {d8-d15} + + vld1.64 {A0}, [CTX]! + vldm CTX!, {A1,A2,A3,A4} + vld1.64 {A5}, [CTX]! + vldm CTX!, {A6,A7,A8,A9} + vld1.64 {A10}, [CTX]! + vldm CTX!, {A11,A12,A13,A14} + vld1.64 {A15}, [CTX]! + vldm CTX!, {A16,A17,A18,A19} + vld1.64 {A20}, [CTX]! + vldm CTX, {A21,A22,A23,A24} + sub CTX, CTX, #168 + + mov COUNT, #24 + adr RC, .Lrc + + .align 3 +.Loop: + veor QREG(T0), QREG(A5), QREG(A15) + veor C0, A0, T0 + veor C0, C0, T1 + veor QREG(C1), QREG(A1), QREG(A6) + veor QREG(C1), QREG(C1), QREG(A11) + veor QREG(C1), QREG(C1), QREG(A16) + veor QREG(C1), QREG(C1), QREG(A21) + + veor QREG(C3), QREG(A3), QREG(A8) + veor QREG(C3), QREG(C3), QREG(A13) + veor QREG(C3), QREG(C3), QREG(A18) + veor QREG(C3), QREG(C3), QREG(A23) + + C D0 = C4 ^ (C1 <<< 1) + C NOTE: Using ROL macro (and vsli) is slightly slower. + vshl.i64 T0, C1, #1 + vshr.u64 T1, C1, #63 + veor T0, T0, C4 + veor T0, T0, T1 + vmov T1, T0 + veor A0, A0, T0 + veor QREG(A5), QREG(A5), QREG(T0) + veor QREG(A15), QREG(A15), QREG(T0) + + C D1 = C0 ^ (C2 <<< 1) + C D2 = C1 ^ (C3 <<< 1) + ROL(T0, C2, 1) + ROL(T1, C3, 1) + veor T0, T0, C0 + veor T1, T1, C1 + veor QREG(A1), QREG(A1), QREG(T0) + veor QREG(A6), QREG(A6), QREG(T0) + veor QREG(A11), QREG(A11), QREG(T0) + veor QREG(A16), QREG(A16), QREG(T0) + veor QREG(A21), QREG(A21), QREG(T0) + + C D3 = C2 ^ (C4 <<< 1) + C D4 = C3 ^ (C0 <<< 1) + ROL(T0, C4, 1) + ROL(T1, C0, 1) + veor T0, T0, C2 + veor T1, T1, C3 + veor QREG(A3), QREG(A3), QREG(T0) + veor QREG(A8), QREG(A8), QREG(T0) + veor QREG(A13), QREG(A13), QREG(T0) + veor QREG(A18), QREG(A18), QREG(T0) + veor QREG(A23), QREG(A23), QREG(T0) + + ROL( T0, A1, 1) + ROL( A1, A6, 44) + ROL( A6, A9, 20) + ROL( A9, A22, 61) + ROL(A22, A14, 39) + ROL(A14, A20, 18) + ROL(A20, A2, 62) + ROL( A2, A12, 43) + ROL(A12, A13, 25) + ROL(A13, A19, 8) + ROL(A19, A23, 56) + ROL(A23, A15, 41) + ROL(A15, A4, 27) + ROL( A4, A24, 14) + ROL(A24, A21, 2) + ROL(A21, A8, 55) + ROL( A8, A16, 45) + ROL(A16, A5, 36) + ROL( A5, A3, 28) + ROL( A3, A18, 21) + ROL(A18, A17, 15) + ROL(A17, A11, 10) + ROL(A11, A7, 6) + ROL( A7, A10, 3) + C New A10 value left in T0 + + vbic C0, A2, A1 + vbic C1, A3, A2 + vbic C2, A4, A3 + vbic C3, A0, A4 + vbic C4, A1, A0 + + veor A0, A0, C0 + vld1.64 {C0}, [RC :64]! + veor QREG(A1), QREG(A1), QREG(C1) + veor QREG(A3), QREG(A3), QREG(C3) + veor A0, A0, C0 + + vbic C0, A7, A6 + vbic C1, A8, A7 + vbic C2, A9, A8 + vbic C3, A5, A9 + vbic C4, A6, A5 + + veor A5, A5, C0 + veor QREG(A6), QREG(A6), QREG(C1) + veor QREG(A8), QREG(A8), QREG(C3) + + vbic C0, A12, A11 + vbic C1, A13, A12 + vbic C2, A14, A13 + vbic C3, T0, A14 + vbic C4, A11, T0 + + veor A10, T0, C0 + veor QREG(A11), QREG(A11), QREG(C1) + veor QREG(A13), QREG(A13), QREG(C3) + + vbic C0, A17, A16 + vbic C1, A18, A17 + vbic C2, A19, A18 + vbic C3, A15, A19 + vbic C4, A16, A15 + + veor A15, A15, C0 + veor QREG(A16), QREG(A16), QREG(C1) + veor QREG(A18), QREG(A18), QREG(C3) + + vbic C0, A22, A21 + vbic C1, A23, A22 + vbic C2, A24, A23 + vbic C3, A20, A24 + vbic C4, A21, A20 + + subs COUNT, COUNT, #1 + veor A20, A20, C0 + veor QREG(A21), QREG(A21), QREG(C1) + veor QREG(A23), QREG(A23), QREG(C3) + + bne .Loop + + vst1.64 {A0}, [CTX]! + vstm CTX!, {A1,A2,A3,A4} + vst1.64 {A5}, [CTX]! + vstm CTX!, {A6,A7,A8,A9} + vst1.64 {A10}, [CTX]! + vstm CTX!, {A11,A12,A13,A14} + vst1.64 {A15}, [CTX]! + vstm CTX!, {A16,A17,A18,A19} + vst1.64 {A20}, [CTX]! + vstm CTX, {A21,A22,A23,A24} + + vpop {d8-d15} + bx lr +EPILOGUE(nettle_sha3_permute) diff --git a/arm/neon/sha512-compress.asm b/arm/neon/sha512-compress.asm new file mode 100644 index 0000000..828d9ce --- /dev/null +++ b/arm/neon/sha512-compress.asm @@ -0,0 +1,330 @@ +C arm/neon/sha512-compress.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "sha512-compress.asm" + .fpu neon + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +C d8-d15 are callee-save +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +C Used only when reading the input, can overlap with state +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, <$1>) +define(, eval(($1) % 16))>) + +C If x = W(i+14), y = w(i+1), we xor in parallel +C +C x << 45 y << 63 +C x >> 19 y >> 1 +C x << 3 y << 56 +C x >> 61 y >> 8 +C xor x >> 6 y >> 7 +C ----------------------------- +C DT0 DT1 +define(, < + vshl.i64 DT0, W($1+14), #45 + vshl.i64 DT1, W($1 + 1), #63 + vshr.u64 DT2, W($1+14), #19 + vshr.u64 DT3, W($1 + 1), #1 + vshl.i64 DT4, W($1+14), #3 + vshl.i64 DT5, W($1 + 1), #56 + veor.i64 QT01, QT01, QT23 + vshr.u64 DT2, W($1+14), #61 + vshr.u64 DT3, W($1 + 1), #8 + veor.i64 QT01, QT01, QT45 + vshr.u64 DT4, W($1+14), #6 + vshr.u64 DT5, W($1 + 1), #7 + veor.i64 QT01, QT01, QT23 + vadd.i64 W($1), W($1), W($1 + 9) + veor.i64 QT01, QT01, QT45 + vadd.i64 W($1), W($1), DT0 + vadd.i64 W($1), W($1), DT1 +>) + +C ROUND(A,B,C,D,E,F,G,H,i) +C +C H += S1(E) + Choice(E,F,G) + K + W +C D += H +C H += S0(A) + Majority(A,B,C) +C +C Where +C +C S1(E) = E<<<50 ^ E<<<46 ^ E<<<23 +C S0(A) = A<<<36 ^ A<<<30 ^ A<<<25 +C Choice (E, F, G) = G^(E&(F^G)) +C Majority (A,B,C) = (A&B) + (C&(A^B)) + +C Do S1 and S0 in parallel +C +C e << 50 a << 36 +C e >> 14 a >> 28 +C e << 46 a << 30 +C e >> 18 a >> 34 +C e << 23 a << 25 +C xor e >> 41 a >> 39 +C ---------------------------- +C DT0 DT1 +define(, < + vshl.i64 DT0, $5, #50 + vshl.i64 DT1, $1, #36 + vshr.u64 DT2, $5, #14 + vshr.u64 DT3, $1, #28 + vshl.i64 DT4, $5, #46 + vshl.i64 DT5, $1, #30 + veor QT01, QT01, QT23 + vshr.u64 DT2, $5, #18 + vshr.u64 DT3, $1, #34 + veor QT01, QT01, QT45 + vshl.i64 DT4, $5, #23 + vshl.i64 DT5, $1, #25 + veor QT01, QT01, QT23 + vshr.u64 DT2, $5, #41 + vshr.u64 DT3, $1, #39 + veor QT01, QT01, QT45 + veor DT4, $6, $7 + veor DT5, $1, $2 + vand DT4, DT4, $5 + vand DT5, DT5, $3 + veor DT4, DT4, $7 + veor QT01, QT01, QT23 + vand DT2, $1, $2 + vldr DT3, [K,#eval(8*$9)] + vadd.i64 $8, $8, W($9) + vadd.i64 QT01, QT01, QT45 + vadd.i64 $8, $8, DT3 + vadd.i64 $8, $8, DT0 + vadd.i64 DT1, DT1, DT2 + vadd.i64 $4, $4, $8 + vadd.i64 $8, $8, DT1 +>) + + C void + C _nettle_sha512_compress(uint64_t *state, const uint8_t *input, const uint64_t *k) + + .text + .align 2 + +PROLOGUE(_nettle_sha512_compress) + vpush {d8,d9,d10,d11,d12,d13} + + ands SHIFT, INPUT, #7 + and INPUT, INPUT, #-8 + vld1.8 {DT5}, [INPUT :64] + addne INPUT, INPUT, #8 + addeq SHIFT, SHIFT, #8 + lsl SHIFT, SHIFT, #3 + + C Put right shift in DT0 and DT1, aka QT01 + neg SHIFT, SHIFT + vmov.i32 DT0, #0 + vmov.32 DT0[0], SHIFT + vmov DT1, DT0 + C Put left shift in DT2 and DT3, aka QT23 + add SHIFT, SHIFT, #64 + vmov.i32 DT2, #0 + vmov.32 DT2[0], SHIFT + vmov DT3, DT2 + vshl.u64 DT5, DT5, DT0 + + C Set w[i] <-- w[i-1] >> RSHIFT + w[i] << LSHIFT + vld1.8 {W(0),W(1),W(2),W(3)}, [INPUT :64]! + vshl.u64 QT67, QW0001, QT01 C Right shift + vshl.u64 QW0001, QW0001, QT23 C Left shift + veor W(0), W(0), DT5 + veor W(1), W(1), DT6 + vrev64.8 QW0001, QW0001 + vshl.u64 QT45, QW0203, QT01 C Right shift + vshl.u64 QW0203, QW0203, QT23 C Left shift + veor W(2), W(2), DT7 + veor W(3), W(3), DT4 + vrev64.8 QW0203, QW0203 + + vld1.8 {W(4),W(5),W(6),W(7)}, [INPUT :64]! + vshl.u64 QT67, QW0405, QT01 C Right shift + vshl.u64 QW0405, QW0405, QT23 C Left shift + veor W(4), W(4), DT5 + veor W(5), W(5), DT6 + vrev64.8 QW0405, QW0405 + vshl.u64 QT45, QW0607, QT01 C Right shift + vshl.u64 QW0607, QW0607, QT23 C Left shift + veor W(6), W(6), DT7 + veor W(7), W(7), DT4 + vrev64.8 QW0607, QW0607 + + vld1.8 {W(8),W(9),W(10),W(11)}, [INPUT :64]! + vshl.u64 QT67, QW0809, QT01 C Right shift + vshl.u64 QW0809, QW0809, QT23 C Left shift + veor W(8), W(8), DT5 + veor W(9), W(9), DT6 + vrev64.8 QW0809, QW0809 + vshl.u64 QT45, QW1011, QT01 C Right shift + vshl.u64 QW1011, QW1011, QT23 C Left shift + veor W(10), W(10), DT7 + veor W(11), W(11), DT4 + vrev64.8 QW1011, QW1011 + + vld1.8 {W(12),W(13),W(14),W(15)}, [INPUT :64]! + vshl.u64 QT67, QW1213, QT01 C Right shift + vshl.u64 QW1213, QW1213, QT23 C Left shift + veor W(12), W(12), DT5 + veor W(13), W(13), DT6 + vrev64.8 QW1213, QW1213 + vshl.u64 QT45, QW1415, QT01 C Right shift + vshl.u64 QW1415, QW1415, QT23 C Left shift + veor W(14), W(14), DT7 + veor W(15), W(15), DT4 + vrev64.8 QW1415, QW1415 + + vldm STATE, {SA,SB,SC,SD,SE,SF,SG,SH} + + ROUND(SA,SB,SC,SD,SE,SF,SG,SH, 0) + ROUND(SH,SA,SB,SC,SD,SE,SF,SG, 1) + ROUND(SG,SH,SA,SB,SC,SD,SE,SF, 2) + ROUND(SF,SG,SH,SA,SB,SC,SD,SE, 3) + ROUND(SE,SF,SG,SH,SA,SB,SC,SD, 4) + ROUND(SD,SE,SF,SG,SH,SA,SB,SC, 5) + ROUND(SC,SD,SE,SF,SG,SH,SA,SB, 6) + ROUND(SB,SC,SD,SE,SF,SG,SH,SA, 7) + + ROUND(SA,SB,SC,SD,SE,SF,SG,SH, 8) + ROUND(SH,SA,SB,SC,SD,SE,SF,SG, 9) + ROUND(SG,SH,SA,SB,SC,SD,SE,SF, 10) + ROUND(SF,SG,SH,SA,SB,SC,SD,SE, 11) + ROUND(SE,SF,SG,SH,SA,SB,SC,SD, 12) + ROUND(SD,SE,SF,SG,SH,SA,SB,SC, 13) + ROUND(SC,SD,SE,SF,SG,SH,SA,SB, 14) + ROUND(SB,SC,SD,SE,SF,SG,SH,SA, 15) + + add K, K, #128 + + mov COUNT, #4 +.Loop: + + EXPN( 0) ROUND(SA,SB,SC,SD,SE,SF,SG,SH, 0) + EXPN( 1) ROUND(SH,SA,SB,SC,SD,SE,SF,SG, 1) + EXPN( 2) ROUND(SG,SH,SA,SB,SC,SD,SE,SF, 2) + EXPN( 3) ROUND(SF,SG,SH,SA,SB,SC,SD,SE, 3) + EXPN( 4) ROUND(SE,SF,SG,SH,SA,SB,SC,SD, 4) + EXPN( 5) ROUND(SD,SE,SF,SG,SH,SA,SB,SC, 5) + EXPN( 6) ROUND(SC,SD,SE,SF,SG,SH,SA,SB, 6) + EXPN( 7) ROUND(SB,SC,SD,SE,SF,SG,SH,SA, 7) + EXPN( 8) ROUND(SA,SB,SC,SD,SE,SF,SG,SH, 8) + EXPN( 9) ROUND(SH,SA,SB,SC,SD,SE,SF,SG, 9) + EXPN(10) ROUND(SG,SH,SA,SB,SC,SD,SE,SF, 10) + EXPN(11) ROUND(SF,SG,SH,SA,SB,SC,SD,SE, 11) + EXPN(12) ROUND(SE,SF,SG,SH,SA,SB,SC,SD, 12) + EXPN(13) ROUND(SD,SE,SF,SG,SH,SA,SB,SC, 13) + EXPN(14) ROUND(SC,SD,SE,SF,SG,SH,SA,SB, 14) + subs COUNT, COUNT, #1 + EXPN(15) ROUND(SB,SC,SD,SE,SF,SG,SH,SA, 15) + add K, K, #128 + bne .Loop + + vld1.64 {DW0, DW1, DW2, DW3}, [STATE] + vadd.i64 QSAB, QSAB, QW0001 + vadd.i64 QSCD, QSCD, QW0203 + vst1.64 {SA,SB,SC,SD}, [STATE]! + vld1.64 {DW0, DW1, DW2, DW3}, [STATE] + vadd.i64 QSEF, QSEF, QW0001 + vadd.i64 QSGH, QSGH, QW0203 + vst1.64 {SE,SF,SG,SH}, [STATE]! + + vpop {d8,d9,d10,d11,d12,d13} + bx lr +EPILOGUE(_nettle_sha512_compress) + +divert(-1) +define shastate +p/x $d0.u64 +p/x $d1.u64 +p/x $d2.u64 +p/x $d3.u64 +p/x $d4.u64 +p/x $d5.u64 +p/x $d6.u64 +p/x $d7.u64 +end diff --git a/arm/neon/umac-nh-n.asm b/arm/neon/umac-nh-n.asm new file mode 100644 index 0000000..42686e0 --- /dev/null +++ b/arm/neon/umac-nh-n.asm @@ -0,0 +1,311 @@ +C arm/neon/umac-nh-n.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "umac-nh.asm" + .fpu neon + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) C Accumulates for the first two operations. +define(, ) +define(, ) C Used for 3 and 4 iterations. +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +C FIXME: Try permuting subkeys using vld4, vzip or similar. + + .text + .align 3 + +PROLOGUE(_nettle_umac_nh_n) + ldr MSG, [sp] + str lr, [sp, #-4]! + + C Setup for 64-bit aligned reads + ands SHIFT, MSG, #7 + and MSG, MSG, #-8 + vld1.8 {DM}, [MSG :64] + addne MSG, MSG, #8 + addeq SHIFT, SHIFT, #8 + + C FIXME: Combine as rsb ? + lsl SHIFT, SHIFT, #3 + neg SHIFT, SHIFT + + C Right shift in QRIGHT (both halves) + vmov.i32 D0REG(QRIGHT)[0], SHIFT + vmov.32 D1REG(QRIGHT), D0REG(QRIGHT) + add SHIFT, SHIFT, #64 + + vmov.i32 D0REG(QLEFT)[0], SHIFT + vmov.32 D1REG(QLEFT), D0REG(QLEFT) + cmp r1, #3 + vmov.i64 QY0, #0 + + vshl.u64 DM, DM, D0REG(QRIGHT) + bcc .Lnh2 + beq .Lnh3 + +.Lnh4: + C Permute key words, so we in each iteration have them in order + C + C P0: [0, 4,1, 5] P1: [ 2, 6, 3, 7] P2: [ 4, 8, 5, 9] P3: [ 6,10, 7,11] + C P4: [8,12,9,13] P5: [10,14,11,15] P6: [12,16,13,17] P7: [14,18,15,19] + C + C Also arrange the message words, so we get them as + C M0: [0,0,1,1] M1: [ 2, 2, 3, 3] M2: [ 4, 4, 5, 5] M3: [ 6, 6, 7, 7] + C M4: [8,8,9,9] M5: [10,10,11,11] M6: [12,12,13,13] M7: [14,14,15,15] + C + C Then, accumulate Y0 (first two "iters") using + C + C Y0 += (M0+P0) * (M2+P2) + (M1+P1) * (M3+P3) + C Y1 += (M0+P4) * (M2+P6) + (M1+P5) * (M3+P7) + C + C Next iteration is then + C + C Y0 += (M4+P4) * (M6+P6) + (M5+P5) * (M7 + P7) + C Y1 += (M4+P6) * (M6+P8) + (M5+P7) * (M7 + P11) + C + C So we can reuse P4, P5, P6, P7 from the previous iteration. + + C How to for in registers? We need 4 Q regs for P0-P3, and one + C more for the last read key. We need at least two regiters + C for the message (QA and QB, more if we want to expand only + C once). For the Y0 update, we can let the factors overwrite + C P0-P3, and for the Y1 update, we can overwrite M0-M3. + + vpush {q4,q5,q6} + vld1.32 {QK0,QK1}, [KEY]! + vld1.32 {QK2}, [KEY]! + vmov QT0, QK1 + vmov QT1, QK2 + + C Permute keys. QK2 us untouched, permuted subkeys put in QK0,QK1,QT0,QT1 + vtrn.32 QK0, QK1 C Gives us [0, 4, 2, 6] and [1, 5, 3, 7] + vswp D1REG(QK0), D0REG(QK1) C Gives us [0, 4, 1, 5] and [2, 6, 3, 7] + vtrn.32 QT0, QT1 C Gives us [4,8,6,10] and [5 ,9,7,11] + vswp D1REG(QT0), D0REG(QT1) C Gives us [4,8,5, 9] and [6,10,7,11] + + vmov.i64 QY1, #0 +.Loop4: + C Set m[i] <-- m[i-1] >> RSHIFT + m[i] << LSHIFT + vld1.8 {QA, QB}, [MSG :64]! + vshl.u64 QC, QA, QRIGHT + vshl.u64 QD, QB, QRIGHT + vshl.u64 QA, QA, QLEFT + vshl.u64 QB, QB, QLEFT + veor D0REG(QA), D0REG(QA), DM + veor D1REG(QA), D1REG(QA), D0REG(QC) + veor D0REG(QB), D0REG(QB), D1REG(QC) + veor D1REG(QB), D1REG(QB), D0REG(QD) + vmov DM, D1REG(QD) + + C Explode message (too bad there's no vadd with scalar) + vdup.32 D1REG(QD), D1REG(QB)[1] + vdup.32 D0REG(QD), D1REG(QB)[0] + vdup.32 D1REG(QC), D0REG(QB)[1] + vdup.32 D0REG(QC), D0REG(QB)[0] + vdup.32 D1REG(QB), D1REG(QA)[1] + vdup.32 D0REG(QB), D1REG(QA)[0] + vdup.32 D1REG(QA), D0REG(QA)[1] + vdup.32 D0REG(QA), D0REG(QA)[0] + + vadd.i32 QK0, QK0, QA + vadd.i32 QK1, QK1, QB + vadd.i32 QT0, QT0, QC + vadd.i32 QT1, QT1, QD + + vmlal.u32 QY0, D0REG(QK0), D0REG(QT0) + vmlal.u32 QY0, D1REG(QK0), D1REG(QT0) + vmlal.u32 QY0, D0REG(QK1), D0REG(QT1) + vmlal.u32 QY0, D1REG(QK1), D1REG(QT1) + + C Next 4 subkeys + vld1.32 {QT0,QT1}, [KEY]! + vmov QK0, QK2 + vmov QK1, QT0 + vmov QK2, QT1 C Save + vtrn.32 QK0, QK1 C Gives us [8,12,10,14] and [9,13,11,15] + vswp D1REG(QK0), D0REG(QK1) C Gives us [8,12,9,13] and [10,14,11,15] + vtrn.32 QT0, QT1 C Gives us [12,16,14,18] and [13,17,15,19] + vswp D1REG(QT0), D0REG(QT1) C Gives us [12,16,13,17] and [14,18,15,19] + + vadd.i32 QA, QA, QK0 + vadd.i32 QB, QB, QK1 + vadd.i32 QC, QC, QT0 + vadd.i32 QD, QD, QT1 + + subs LENGTH, LENGTH, #32 + + vmlal.u32 QY1, D0REG(QA), D0REG(QC) + vmlal.u32 QY1, D1REG(QA), D1REG(QC) + vmlal.u32 QY1, D0REG(QB), D0REG(QD) + vmlal.u32 QY1, D1REG(QB), D1REG(QD) + + bhi .Loop4 + + vst1.64 {QY0, QY1}, [OUT] + + vpop {q4,q5,q6} + + ldr pc, [sp], #+4 + +.Lnh3: + vpush {q4} + vld1.32 {QK0,QK1}, [KEY]! + vmov.i64 QY1, #0 +.Loop3: + C Set m[i] <-- m[i-1] >> RSHIFT + m[i] << LSHIFT + vld1.8 {QA, QB}, [MSG :64]! + vshl.u64 QT0, QA, QRIGHT + vshl.u64 QT1, QB, QRIGHT + vshl.u64 QA, QA, QLEFT + vshl.u64 QB, QB, QLEFT + veor D0REG(QA), D0REG(QA), DM + veor D1REG(QA), D1REG(QA), D0REG(QT0) + veor D0REG(QB), D0REG(QB), D1REG(QT0) + veor D1REG(QB), D1REG(QB), D0REG(QT1) + vmov DM, D1REG(QT1) + + vld1.32 {QK2}, [KEY]! + C Construct factors, with low half corresponding to first iteration, + C and high half corresponding to the second iteration. + vmov QT0, QK1 + vtrn.32 QK0, QT0 C Gives us [0, 4, 2, 6] and [1, 5, 3, 7] + vswp D1REG(QK0), D0REG(QT0) C Gives us [0, 4, 1, 5] and [2, 6, 3, 7] + vdup.32 D0REG(QT1), D0REG(QA)[0] + vdup.32 D1REG(QT1), D0REG(QA)[1] + vadd.i32 QT1, QT1, QK0 + + vmov QK0, QK2 C Save for next iteration + vtrn.32 QK1, QK2 C Gives us [4, 8, 2, 1] and [1, 5, 3, 7] + vswp D1REG(QK1), D0REG(QK2) C Gives us [4, 8, 1, 5] and [2, 1, 3, 7] + + vdup.32 D0REG(QT2), D0REG(QB)[0] + vdup.32 D1REG(QT2), D0REG(QB)[1] + vadd.i32 QK1, QK1, QT2 + vmlal.u32 QY0, D0REG(QT1), D0REG(QK1) + vmlal.u32 QY0, D1REG(QT1), D1REG(QK1) + + vdup.32 D0REG(QT1), D1REG(QA)[0] + vdup.32 D1REG(QT1), D1REG(QA)[1] + vadd.i32 QT0, QT0, QT1 + vdup.32 D0REG(QT1), D1REG(QB)[0] + vdup.32 D1REG(QT1), D1REG(QB)[1] + vadd.i32 QK2, QK2, QT1 + + vmlal.u32 QY0, D0REG(QT0), D0REG(QK2) + vmlal.u32 QY0, D1REG(QT0), D1REG(QK2) + + vld1.32 {QK1}, [KEY]! + vadd.i32 QA, QA, QK0 + vadd.i32 QB, QB, QK1 + subs LENGTH, LENGTH, #32 + vmlal.u32 QY1, D0REG(QA), D0REG(QB) + vmlal.u32 QY1, D1REG(QA), D1REG(QB) + bhi .Loop3 + + vadd.i64 D0REG(QY1), D0REG(QY1), D1REG(QY1) + vst1.64 {D0REG(QY0), D1REG(QY0), D0REG(QY1)}, [OUT] + + vpop {q4} + + ldr pc, [sp], #+4 + +.Lnh2: + vld1.32 {QK0}, [KEY]! +.Loop2: + C Set m[i] <-- m[i-1] >> RSHIFT + m[i] << LSHIFT + vld1.8 {QA, QB}, [MSG :64]! + vshl.u64 QT0, QA, QRIGHT + vshl.u64 QT1, QB, QRIGHT + vshl.u64 QA, QA, QLEFT + vshl.u64 QB, QB, QLEFT + veor D0REG(QA), D0REG(QA), DM + veor D1REG(QA), D1REG(QA), D0REG(QT0) + veor D0REG(QB), D0REG(QB), D1REG(QT0) + veor D1REG(QB), D1REG(QB), D0REG(QT1) + vmov DM, D1REG(QT1) + + vld1.32 {QK1,QK2}, [KEY]! + C Construct factors, with low half corresponding to first iteration, + C and high half corresponding to the second iteration. + vmov QT0, QK1 + vtrn.32 QK0, QT0 C Gives us [0, 4, 2, 6] and [1, 5, 3, 7] + vswp D1REG(QK0), D0REG(QT0) C Gives us [0, 4, 1, 5] and [2, 6, 3, 7] + vdup.32 D0REG(QT1), D0REG(QA)[0] + vdup.32 D1REG(QT1), D0REG(QA)[1] + vadd.i32 QT1, QT1, QK0 + + vmov QK0, QK2 C Save for next iteration + vtrn.32 QK1, QK2 C Gives us [4, 8, 6, 10] and [5, 9, 7, 11] + vswp D1REG(QK1), D0REG(QK2) C Gives us [4, 8, 5, 9] and [6, 10, 7, 11] + + vdup.32 D0REG(QT2), D0REG(QB)[0] + vdup.32 D1REG(QT2), D0REG(QB)[1] + vadd.i32 QK1, QK1, QT2 + vmlal.u32 QY0, D0REG(QT1), D0REG(QK1) + vmlal.u32 QY0, D1REG(QT1), D1REG(QK1) + + vdup.32 D0REG(QT1), D1REG(QA)[0] + vdup.32 D1REG(QT1), D1REG(QA)[1] + vadd.i32 QT0, QT0, QT1 + vdup.32 D0REG(QT1), D1REG(QB)[0] + vdup.32 D1REG(QT1), D1REG(QB)[1] + vadd.i32 QK2, QK2, QT1 + + subs LENGTH, LENGTH, #32 + + vmlal.u32 QY0, D0REG(QT0), D0REG(QK2) + vmlal.u32 QY0, D1REG(QT0), D1REG(QK2) + + bhi .Loop2 + vst1.64 {QY0}, [OUT] + +.Lend: + ldr pc, [sp], #+4 +EPILOGUE(_nettle_umac_nh_n) diff --git a/arm/neon/umac-nh.asm b/arm/neon/umac-nh.asm new file mode 100644 index 0000000..158a568 --- /dev/null +++ b/arm/neon/umac-nh.asm @@ -0,0 +1,102 @@ +C arm/neon/umac-nh.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "umac-nh.asm" + .fpu neon + +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + + .text + .align 3 + +PROLOGUE(_nettle_umac_nh) + C Setup for 64-bit aligned reads + ands SHIFT, MSG, #7 + and MSG, MSG, #-8 + vld1.8 {DM}, [MSG :64] + addne MSG, MSG, #8 + addeq SHIFT, SHIFT, #8 + + C FIXME: Combine as rsb ? + lsl SHIFT, SHIFT, #3 + neg SHIFT, SHIFT + + C Right shift in QRIGHT (both halves) + vmov.i32 D0REG(QRIGHT)[0], SHIFT + vmov.32 D1REG(QRIGHT), D0REG(QRIGHT) + add SHIFT, SHIFT, #64 + + vmov.i32 D0REG(QLEFT)[0], SHIFT + vmov.32 D1REG(QLEFT), D0REG(QLEFT) + + vmov.i64 QY, #0 + + vshl.u64 DM, DM, D0REG(QRIGHT) +.Loop: + C Set m[i] <-- m[i-1] >> RSHIFT + m[i] << LSHIFT + vld1.8 {QA, QB}, [MSG :64]! + vshl.u64 QT0, QA, QRIGHT + vshl.u64 QT1, QB, QRIGHT + vshl.u64 QA, QA, QLEFT + vshl.u64 QB, QB, QLEFT + veor D0REG(QA), D0REG(QA), DM + veor D1REG(QA), D1REG(QA), D0REG(QT0) + veor D0REG(QB), D0REG(QB), D1REG(QT0) + veor D1REG(QB), D1REG(QB), D0REG(QT1) + vmov DM, D1REG(QT1) + + vld1.i32 {QK0, QK1}, [KEY]! + vadd.i32 QA, QA, QK0 + vadd.i32 QB, QB, QK1 + subs LENGTH, LENGTH, #32 + vmlal.u32 QY, D0REG(QA), D0REG(QB) + vmlal.u32 QY, D1REG(QA), D1REG(QB) + bhi .Loop + + vadd.i64 D0REG(QY), D0REG(QY), D1REG(QY) + vmov r0, r1, D0REG(QY) + bx lr +EPILOGUE(_nettle_umac_nh) diff --git a/arm/v6/aes-decrypt-internal.asm b/arm/v6/aes-decrypt-internal.asm new file mode 100644 index 0000000..4580105 --- /dev/null +++ b/arm/v6/aes-decrypt-internal.asm @@ -0,0 +1,194 @@ +C arm/v6/aes-decrypt-internal.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .arch armv6 + +include_src() + +define(, ) +define(, ) +define(

, ) +define(, ) +C On stack: DST, SRC + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) C Overlaps PARAM_ROUNDS and PARAM_KEYS +define(, ) +define(, ) +define(, ) C lr + +define(>, <[sp]>) +define(, <[sp, #+4]>) +C 8 saved registers +define(, <[sp, #+40]>) +define(, <[sp, #+44]>) + +define(, ) C Overlap registers used in inner loop. +define(, ) + +C AES_DECRYPT_ROUND(x0,x1,x2,x3,w0,w1,w2,w3,key) +define(, < + uxtb T0, $1 + ldr $5, [TABLE, T0, lsl #2] + uxtb T0, $2 + ldr $6, [TABLE, T0, lsl #2] + uxtb T0, $3 + ldr $7, [TABLE, T0, lsl #2] + uxtb T0, $4 + ldr $8, [TABLE, T0, lsl #2] + + uxtb T0, $4, ror #8 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0, lsl #2] + eor $5, $5, T0 + uxtb T0, $1, ror #8 + ldr T0, [TABLE, T0, lsl #2] + eor $6, $6, T0 + uxtb T0, $2, ror #8 + ldr T0, [TABLE, T0, lsl #2] + eor $7, $7, T0 + uxtb T0, $3, ror #8 + ldr T0, [TABLE, T0, lsl #2] + eor $8, $8, T0 + + uxtb T0, $3, ror #16 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0, lsl #2] + eor $5, $5, T0 + uxtb T0, $4, ror #16 + ldr T0, [TABLE, T0, lsl #2] + eor $6, $6, T0 + uxtb T0, $1, ror #16 + ldr T0, [TABLE, T0, lsl #2] + eor $7, $7, T0 + uxtb T0, $2, ror #16 + ldr T0, [TABLE, T0, lsl #2] + eor $8, $8, T0 + + uxtb T0, $2, ror #24 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0, lsl #2] + eor $5, $5, T0 + uxtb T0, $3, ror #24 + ldr T0, [TABLE, T0, lsl #2] + eor $6, $6, T0 + uxtb T0, $4, ror #24 + ldr T0, [TABLE, T0, lsl #2] + eor $7, $7, T0 + uxtb T0, $1, ror #24 + ldr T0, [TABLE, T0, lsl #2] + + ldm $9!, {$1,$2,$3,$4} + eor $8, $8, T0 + sub TABLE, TABLE, #3072 + eor $5, $5, $1 + eor $6, $6, $2 + eor $7, $7, $3 + eor $8, $8, $4 +>) + + .file "aes-decrypt-internal.asm" + + C _aes_decrypt(unsigned rounds, const uint32_t *keys, + C const struct aes_table *T, + C size_t length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_decrypt) + teq LENGTH, #0 + beq .Lend + + ldr SRC, [sp, #+4] + + push {r0,r1, r4,r5,r6,r7,r8,r10,r11,lr} + + ALIGN(16) +.Lblock_loop: + ldm sp, {COUNT, KEY} + + add TABLE, TABLE, #AES_TABLE0 + + AES_LOAD(SRC,KEY,W0) + AES_LOAD(SRC,KEY,W1) + AES_LOAD(SRC,KEY,W2) + AES_LOAD(SRC,KEY,W3) + + str SRC, FRAME_SRC + + b .Lentry + ALIGN(16) +.Lround_loop: + C Transform X -> W + AES_DECRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY) + +.Lentry: + subs COUNT, COUNT,#2 + C Transform W -> X + AES_DECRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY) + + bne .Lround_loop + + sub TABLE, TABLE, #AES_TABLE0 + + C Final round + ldr DST, FRAME_DST + + AES_FINAL_ROUND_V6(X0, X3, X2, X1, KEY, W0) + AES_FINAL_ROUND_V6(X1, X0, X3, X2, KEY, W1) + AES_FINAL_ROUND_V6(X2, X1, X0, X3, KEY, W2) + AES_FINAL_ROUND_V6(X3, X2, X1, X0, KEY, W3) + + ldr SRC, FRAME_SRC + + AES_STORE(DST,W0) + AES_STORE(DST,W1) + AES_STORE(DST,W2) + AES_STORE(DST,W3) + + str DST, FRAME_DST + subs LENGTH, LENGTH, #16 + bhi .Lblock_loop + + add sp, sp, #8 C Drop saved r0, r1 + pop {r4,r5,r6,r7,r8,r10,r11,pc} + +.Lend: + bx lr +EPILOGUE(_nettle_aes_decrypt) diff --git a/arm/v6/aes-encrypt-internal.asm b/arm/v6/aes-encrypt-internal.asm new file mode 100644 index 0000000..576cf8e --- /dev/null +++ b/arm/v6/aes-encrypt-internal.asm @@ -0,0 +1,202 @@ +C arm/v6/aes-encrypt-internal.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .arch armv6 + +include_src() + +C Benchmarked at at 706, 870, 963 cycles/block on cortex A9, +C for 128, 192 and 256 bit key sizes. + +C Possible improvements: More efficient load and store with +C aligned accesses. Better scheduling. + +define(, ) +define(, ) +define(
, ) +define(, ) +C On stack: DST, SRC + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, ) C Overlaps PARAM_ROUNDS and PARAM_KEYS +define(, ) +define(, ) +define(, ) C lr + +define(>, <[sp]>) +define(, <[sp, #+4]>) +C 8 saved registers +define(, <[sp, #+40]>) +define(, <[sp, #+44]>) + +define(, ) C Overlap registers used in inner loop. +define(, ) + +C 53 instr. +C It's tempting to use eor with rotation, but that's slower. +C AES_ENCRYPT_ROUND(x0,x1,x2,x3,w0,w1,w2,w3,key) +define(, < + uxtb T0, $1 + ldr $5, [TABLE, T0, lsl #2] + uxtb T0, $2 + ldr $6, [TABLE, T0, lsl #2] + uxtb T0, $3 + ldr $7, [TABLE, T0, lsl #2] + uxtb T0, $4 + ldr $8, [TABLE, T0, lsl #2] + + uxtb T0, $2, ror #8 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0, lsl #2] + eor $5, $5, T0 + uxtb T0, $3, ror #8 + ldr T0, [TABLE, T0, lsl #2] + eor $6, $6, T0 + uxtb T0, $4, ror #8 + ldr T0, [TABLE, T0, lsl #2] + eor $7, $7, T0 + uxtb T0, $1, ror #8 + ldr T0, [TABLE, T0, lsl #2] + eor $8, $8, T0 + + uxtb T0, $3, ror #16 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0, lsl #2] + eor $5, $5, T0 + uxtb T0, $4, ror #16 + ldr T0, [TABLE, T0, lsl #2] + eor $6, $6, T0 + uxtb T0, $1, ror #16 + ldr T0, [TABLE, T0, lsl #2] + eor $7, $7, T0 + uxtb T0, $2, ror #16 + ldr T0, [TABLE, T0, lsl #2] + eor $8, $8, T0 + + uxtb T0, $4, ror #24 + add TABLE, TABLE, #1024 + ldr T0, [TABLE, T0, lsl #2] + eor $5, $5, T0 + uxtb T0, $1, ror #24 + ldr T0, [TABLE, T0, lsl #2] + eor $6, $6, T0 + uxtb T0, $2, ror #24 + ldr T0, [TABLE, T0, lsl #2] + eor $7, $7, T0 + uxtb T0, $3, ror #24 + ldr T0, [TABLE, T0, lsl #2] + + ldm $9!, {$1,$2,$3,$4} + eor $8, $8, T0 + sub TABLE, TABLE, #3072 + eor $5, $5, $1 + eor $6, $6, $2 + eor $7, $7, $3 + eor $8, $8, $4 +>) + + .file "aes-encrypt-internal.asm" + + C _aes_encrypt(unsigned rounds, const uint32_t *keys, + C const struct aes_table *T, + C size_t length, uint8_t *dst, + C uint8_t *src) + .text + ALIGN(4) +PROLOGUE(_nettle_aes_encrypt) + teq LENGTH, #0 + beq .Lend + + ldr SRC, [sp, #+4] + + push {r0,r1, r4,r5,r6,r7,r8,r10,r11,lr} + + ALIGN(16) +.Lblock_loop: + ldm sp, {COUNT, KEY} + + add TABLE, TABLE, #AES_TABLE0 + + AES_LOAD(SRC,KEY,W0) + AES_LOAD(SRC,KEY,W1) + AES_LOAD(SRC,KEY,W2) + AES_LOAD(SRC,KEY,W3) + + str SRC, FRAME_SRC + + b .Lentry + ALIGN(16) +.Lround_loop: + C Transform X -> W + AES_ENCRYPT_ROUND(X0, X1, X2, X3, W0, W1, W2, W3, KEY) + +.Lentry: + subs COUNT, COUNT,#2 + C Transform W -> X + AES_ENCRYPT_ROUND(W0, W1, W2, W3, X0, X1, X2, X3, KEY) + + bne .Lround_loop + + sub TABLE, TABLE, #AES_TABLE0 + + C Final round + ldr DST, FRAME_DST + + AES_FINAL_ROUND_V6(X0, X1, X2, X3, KEY, W0) + AES_FINAL_ROUND_V6(X1, X2, X3, X0, KEY, W1) + AES_FINAL_ROUND_V6(X2, X3, X0, X1, KEY, W2) + AES_FINAL_ROUND_V6(X3, X0, X1, X2, KEY, W3) + + ldr SRC, FRAME_SRC + + AES_STORE(DST,W0) + AES_STORE(DST,W1) + AES_STORE(DST,W2) + AES_STORE(DST,W3) + + str DST, FRAME_DST + subs LENGTH, LENGTH, #16 + bhi .Lblock_loop + + add sp, sp, #8 C Drop saved r0, r1 + pop {r4,r5,r6,r7,r8,r10,r11,pc} + +.Lend: + bx lr +EPILOGUE(_nettle_aes_encrypt) diff --git a/arm/v6/sha1-compress.asm b/arm/v6/sha1-compress.asm new file mode 100644 index 0000000..59d6297 --- /dev/null +++ b/arm/v6/sha1-compress.asm @@ -0,0 +1,248 @@ +C arm/v6/sha1-compress.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "sha1-compress.asm" + .arch armv6 + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +C FIXME: Could avoid a mov with even and odd variants. +define(, < + ldr T0, [INPUT], #+4 + sel W, WPREV, T0 + ror W, W, SHIFT + mov WPREV, T0 + rev W, W + str W, [SP,#eval(4*$1)] +>) +define(, < + ldr W, [sp, #+eval(4*$1)] + ldr T0, [sp, #+eval(4*(($1 + 2) % 16))] + eor W, W, T0 + ldr T0, [sp, #+eval(4*(($1 + 8) % 16))] + eor W, W, T0 + ldr T0, [sp, #+eval(4*(($1 + 13) % 16))] + eor W, W, T0 + ror W, W, #31 + str W, [sp, #+eval(4*$1)] +>) + +C F1(B,C,D) = D^(B&(C^D)) +C ROUND1(A,B,C,D,E) +define(, < + eor T0, $3, $4 + add $5, $5, K + and T0, T0, $2 + add $5, $5, $1, ror #27 + eor T0, T0, $4 + add $5, $5, W + ror $2, $2, #2 + add $5, $5, T0 +>) +C F2(B,C,D) = B^C^D +define(, < + eor T0, $2, $4 + add $5, $5, K + eor T0, T0, $3 + add $5, $5, $1, ror #27 + add $5, $5, W + ror $2, $2, #2 + add $5, $5, T0 +>) +C F3(B,C,D) = (B&C) | (D & (B|C)) = (B & (C ^ D)) + (C & D) +define(, < + eor T0, $3, $4 + add $5, $5, K + and T0, T0, $2 + add $5, $5, $1, ror #27 + add $5, $5, T0 + add $5, $5, W + and T0, $3, $4 + ror $2, $2, #2 + add $5, $5, T0 +>) + C void _nettle_sha1_compress(uint32_t *state, const uint8_t *input) + + .text + .align 2 +.LK1: + .int 0x5A827999 +.LK2: + .int 0x6ED9EBA1 +.LK3: + .int 0x8F1BBCDC + +PROLOGUE(_nettle_sha1_compress) + push {r4,r5,r6,r7,r8,r10,lr} + sub sp, sp, #64 + + C Sets SHIFT to 8*low bits of input pointer. Sets up GE flags + C as follows, corresponding to bytes to be used from WPREV + C SHIFT 0 8 16 24 + C CPSR.GE 0000 1110 1100 1000 + ands SHIFT, INPUT, #3 + and INPUT, INPUT, $-4 + ldr WPREV, [INPUT] + addne INPUT, INPUT, #4 C Unaligned input + lsl SHIFT, SHIFT, #3 + mov T0, #0 + movne T0, #-1 + lsl W, T0, SHIFT + uadd8 T0, T0, W C Sets APSR.GE bits + + ldr K, .LK1 + ldm STATE, {SA,SB,SC,SD,SE} + + LOAD( 0) ROUND1(SA, SB, SC, SD, SE) + LOAD( 1) ROUND1(SE, SA, SB, SC, SD) + LOAD( 2) ROUND1(SD, SE, SA, SB, SC) + LOAD( 3) ROUND1(SC, SD, SE, SA, SB) + LOAD( 4) ROUND1(SB, SC, SD, SE, SA) + + LOAD( 5) ROUND1(SA, SB, SC, SD, SE) + LOAD( 6) ROUND1(SE, SA, SB, SC, SD) + LOAD( 7) ROUND1(SD, SE, SA, SB, SC) + LOAD( 8) ROUND1(SC, SD, SE, SA, SB) + LOAD( 9) ROUND1(SB, SC, SD, SE, SA) + + LOAD(10) ROUND1(SA, SB, SC, SD, SE) + LOAD(11) ROUND1(SE, SA, SB, SC, SD) + LOAD(12) ROUND1(SD, SE, SA, SB, SC) + LOAD(13) ROUND1(SC, SD, SE, SA, SB) + LOAD(14) ROUND1(SB, SC, SD, SE, SA) + + LOAD(15) ROUND1(SA, SB, SC, SD, SE) + EXPN( 0) ROUND1(SE, SA, SB, SC, SD) + EXPN( 1) ROUND1(SD, SE, SA, SB, SC) + EXPN( 2) ROUND1(SC, SD, SE, SA, SB) + EXPN( 3) ROUND1(SB, SC, SD, SE, SA) + + ldr K, .LK2 + EXPN( 4) ROUND2(SA, SB, SC, SD, SE) + EXPN( 5) ROUND2(SE, SA, SB, SC, SD) + EXPN( 6) ROUND2(SD, SE, SA, SB, SC) + EXPN( 7) ROUND2(SC, SD, SE, SA, SB) + EXPN( 8) ROUND2(SB, SC, SD, SE, SA) + + EXPN( 9) ROUND2(SA, SB, SC, SD, SE) + EXPN(10) ROUND2(SE, SA, SB, SC, SD) + EXPN(11) ROUND2(SD, SE, SA, SB, SC) + EXPN(12) ROUND2(SC, SD, SE, SA, SB) + EXPN(13) ROUND2(SB, SC, SD, SE, SA) + + EXPN(14) ROUND2(SA, SB, SC, SD, SE) + EXPN(15) ROUND2(SE, SA, SB, SC, SD) + EXPN( 0) ROUND2(SD, SE, SA, SB, SC) + EXPN( 1) ROUND2(SC, SD, SE, SA, SB) + EXPN( 2) ROUND2(SB, SC, SD, SE, SA) + + EXPN( 3) ROUND2(SA, SB, SC, SD, SE) + EXPN( 4) ROUND2(SE, SA, SB, SC, SD) + EXPN( 5) ROUND2(SD, SE, SA, SB, SC) + EXPN( 6) ROUND2(SC, SD, SE, SA, SB) + EXPN( 7) ROUND2(SB, SC, SD, SE, SA) + + ldr K, .LK3 + EXPN( 8) ROUND3(SA, SB, SC, SD, SE) + EXPN( 9) ROUND3(SE, SA, SB, SC, SD) + EXPN(10) ROUND3(SD, SE, SA, SB, SC) + EXPN(11) ROUND3(SC, SD, SE, SA, SB) + EXPN(12) ROUND3(SB, SC, SD, SE, SA) + + EXPN(13) ROUND3(SA, SB, SC, SD, SE) + EXPN(14) ROUND3(SE, SA, SB, SC, SD) + EXPN(15) ROUND3(SD, SE, SA, SB, SC) + EXPN( 0) ROUND3(SC, SD, SE, SA, SB) + EXPN( 1) ROUND3(SB, SC, SD, SE, SA) + + EXPN( 2) ROUND3(SA, SB, SC, SD, SE) + EXPN( 3) ROUND3(SE, SA, SB, SC, SD) + EXPN( 4) ROUND3(SD, SE, SA, SB, SC) + EXPN( 5) ROUND3(SC, SD, SE, SA, SB) + EXPN( 6) ROUND3(SB, SC, SD, SE, SA) + + EXPN( 7) ROUND3(SA, SB, SC, SD, SE) + EXPN( 8) ROUND3(SE, SA, SB, SC, SD) + EXPN( 9) ROUND3(SD, SE, SA, SB, SC) + EXPN(10) ROUND3(SC, SD, SE, SA, SB) + EXPN(11) ROUND3(SB, SC, SD, SE, SA) + + ldr K, .LK4 + EXPN(12) ROUND2(SA, SB, SC, SD, SE) + EXPN(13) ROUND2(SE, SA, SB, SC, SD) + EXPN(14) ROUND2(SD, SE, SA, SB, SC) + EXPN(15) ROUND2(SC, SD, SE, SA, SB) + EXPN( 0) ROUND2(SB, SC, SD, SE, SA) + + EXPN( 1) ROUND2(SA, SB, SC, SD, SE) + EXPN( 2) ROUND2(SE, SA, SB, SC, SD) + EXPN( 3) ROUND2(SD, SE, SA, SB, SC) + EXPN( 4) ROUND2(SC, SD, SE, SA, SB) + EXPN( 5) ROUND2(SB, SC, SD, SE, SA) + + EXPN( 6) ROUND2(SA, SB, SC, SD, SE) + EXPN( 7) ROUND2(SE, SA, SB, SC, SD) + EXPN( 8) ROUND2(SD, SE, SA, SB, SC) + EXPN( 9) ROUND2(SC, SD, SE, SA, SB) + EXPN(10) ROUND2(SB, SC, SD, SE, SA) + + EXPN(11) ROUND2(SA, SB, SC, SD, SE) + EXPN(12) ROUND2(SE, SA, SB, SC, SD) + EXPN(13) ROUND2(SD, SE, SA, SB, SC) + EXPN(14) ROUND2(SC, SD, SE, SA, SB) + EXPN(15) ROUND2(SB, SC, SD, SE, SA) + + C Use registers we no longer need. + ldm STATE, {INPUT,T0,SHIFT,W,K} + add SA, SA, INPUT + add SB, SB, T0 + add SC, SC, SHIFT + add SD, SD, W + add SE, SE, K + add sp, sp, #64 + stm STATE, {SA,SB,SC,SD,SE} + pop {r4,r5,r6,r7,r8,r10,pc} +EPILOGUE(_nettle_sha1_compress) + +.LK4: + .int 0xCA62C1D6 diff --git a/arm/v6/sha256-compress.asm b/arm/v6/sha256-compress.asm new file mode 100644 index 0000000..e6f4e1e --- /dev/null +++ b/arm/v6/sha256-compress.asm @@ -0,0 +1,218 @@ +C arm/v6/sha256-compress.asm + +ifelse(< + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + + .file "sha256-compress.asm" + .arch armv6 + +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) C Overlap INPUT +define(, ) C Overlap STATE +define(, ) + +C Used for data load +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) +define(, ) + +define(, < + ldr W, [sp, #+eval(4*$1)] + ldr T0, [sp, #+eval(4*(($1 + 14) % 16))] + ror T1, T0, #17 + eor T1, T1, T0, ror #19 + eor T1, T1, T0, lsr #10 + add W, W, T1 + ldr T0, [sp, #+eval(4*(($1 + 9) % 16))] + add W, W, T0 + ldr T0, [sp, #+eval(4*(($1 + 1) % 16))] + ror T1, T0, #7 + eor T1, T1, T0, ror #18 + eor T1, T1, T0, lsr #3 + add W, W, T1 + str W, [sp, #+eval(4*$1)] +>) + +C ROUND(A,B,C,D,E,F,G,H) +C +C H += S1(E) + Choice(E,F,G) + K + W +C D += H +C H += S0(A) + Majority(A,B,C) +C +C Where +C +C S1(E) = E<<<26 ^ E<<<21 ^ E<<<7 +C S0(A) = A<<<30 ^ A<<<19 ^ A<<<10 +C Choice (E, F, G) = G^(E&(F^G)) +C Majority (A,B,C) = (A&B) + (C&(A^B)) + +define(, < + ror T0, $5, #6 + eor T0, T0, $5, ror #11 + eor T0, T0, $5, ror #25 + add $8, $8, T0 + eor T0, $6, $7 + and T0, T0, $5 + eor T0, T0, $7 + add $8,$8, T0 + ldr T0, [K], #+4 + add $8, $8, W + add $8, $8, T0 + add $4, $4, $8 + ror T0, $1, #2 + eor T0, T0, $1, ror #13 + eor T0, T0, $1, ror #22 + add $8, $8, T0 + and T0, $1, $2 + add $8, $8, T0 + eor T0, $1, $2 + and T0, T0, $3 + add $8, $8, T0 +>) + +define(, < + ldr W, [sp, + $1] + add $1, $1, #4 +>) + C void + C _nettle_sha256_compress(uint32_t *state, const uint8_t *input, const uint32_t *k) + + .text + .align 2 + +PROLOGUE(_nettle_sha256_compress) + push {r4,r5,r6,r7,r8,r10,r11,r14} + sub sp, sp, #68 + str STATE, [sp, #+64] + + C Load data up front, since we don't have enough registers + C to load and shift on-the-fly + ands SHIFT, INPUT, #3 + and INPUT, INPUT, $-4 + ldr I0, [INPUT] + addne INPUT, INPUT, #4 + lsl SHIFT, SHIFT, #3 + mov T0, #0 + movne T0, #-1 + lsl I1, T0, SHIFT + uadd8 T0, T0, I1 C Sets APSR.GE bits + + mov DST, sp + mov ILEFT, #4 +.Lcopy: + ldm INPUT!, {I1,I2,I3,I4} + sel I0, I0, I1 + ror I0, I0, SHIFT + rev I0, I0 + sel I1, I1, I2 + ror I1, I1, SHIFT + rev I1, I1 + sel I2, I2, I3 + ror I2, I2, SHIFT + rev I2, I2 + sel I3, I3, I4 + ror I3, I3, SHIFT + rev I3, I3 + subs ILEFT, ILEFT, #1 + stm DST!, {I0,I1,I2,I3} + mov I0, I4 + bne .Lcopy + + ldm STATE, {SA,SB,SC,SD,SE,SF,SG,SH} + + mov COUNT,#0 + +.Loop1: + NOEXPN(COUNT) ROUND(SA,SB,SC,SD,SE,SF,SG,SH) + NOEXPN(COUNT) ROUND(SH,SA,SB,SC,SD,SE,SF,SG) + NOEXPN(COUNT) ROUND(SG,SH,SA,SB,SC,SD,SE,SF) + NOEXPN(COUNT) ROUND(SF,SG,SH,SA,SB,SC,SD,SE) + NOEXPN(COUNT) ROUND(SE,SF,SG,SH,SA,SB,SC,SD) + NOEXPN(COUNT) ROUND(SD,SE,SF,SG,SH,SA,SB,SC) + NOEXPN(COUNT) ROUND(SC,SD,SE,SF,SG,SH,SA,SB) + NOEXPN(COUNT) ROUND(SB,SC,SD,SE,SF,SG,SH,SA) + cmp COUNT,#64 + bne .Loop1 + + mov COUNT, #3 +.Loop2: + + EXPN( 0) ROUND(SA,SB,SC,SD,SE,SF,SG,SH) + EXPN( 1) ROUND(SH,SA,SB,SC,SD,SE,SF,SG) + EXPN( 2) ROUND(SG,SH,SA,SB,SC,SD,SE,SF) + EXPN( 3) ROUND(SF,SG,SH,SA,SB,SC,SD,SE) + EXPN( 4) ROUND(SE,SF,SG,SH,SA,SB,SC,SD) + EXPN( 5) ROUND(SD,SE,SF,SG,SH,SA,SB,SC) + EXPN( 6) ROUND(SC,SD,SE,SF,SG,SH,SA,SB) + EXPN( 7) ROUND(SB,SC,SD,SE,SF,SG,SH,SA) + EXPN( 8) ROUND(SA,SB,SC,SD,SE,SF,SG,SH) + EXPN( 9) ROUND(SH,SA,SB,SC,SD,SE,SF,SG) + EXPN(10) ROUND(SG,SH,SA,SB,SC,SD,SE,SF) + EXPN(11) ROUND(SF,SG,SH,SA,SB,SC,SD,SE) + EXPN(12) ROUND(SE,SF,SG,SH,SA,SB,SC,SD) + EXPN(13) ROUND(SD,SE,SF,SG,SH,SA,SB,SC) + EXPN(14) ROUND(SC,SD,SE,SF,SG,SH,SA,SB) + subs COUNT, COUNT, #1 + EXPN(15) ROUND(SB,SC,SD,SE,SF,SG,SH,SA) + bne .Loop2 + + ldr STATE, [sp, #+64] + C No longer needed registers + ldm STATE, {r1,r2,r12,r14} + add SA, SA, r1 + add SB, SB, r2 + add SC, SC, r12 + add SD, SD, r14 + stm STATE!, {SA,SB,SC,SD} + ldm STATE, {r1,r2,r12,r14} + add SE, SE, r1 + add SF, SF, r2 + add SG, SG, r12 + add SH, SH, r14 + stm STATE!, {SE,SF,SG,SH} + add sp, sp, #68 + pop {r4,r5,r6,r7,r8,r10,r11,pc} +EPILOGUE(_nettle_sha256_compress) diff --git a/asm.m4 b/asm.m4 new file mode 100644 index 0000000..4018c23 --- /dev/null +++ b/asm.m4 @@ -0,0 +1,97 @@ +divert(-1) +changequote(<,>)dnl +dnl (progn (modify-syntax-entry ?< "(>") (modify-syntax-entry ?> ")<") ) + +dnl FORTRAN style comment character +define(, < +dnl>)dnl +dnl Disable m4 comment processing, since the default, #, is used for +dnl constants on some architectures, in particular ARM. +changecom()dnl + +dnl Including files from the srcdir +define(, )dnl + +dnl default definition, changed in fat builds +define(, <$1>) +define(, fat_transform($1)>) + +dnl Pseudo ops +define(, +, +COFF_STYLE, yes, +<.def $1 +.scl 2 +.type 32 +.endef>, +<>)>) + +define(,<>)dnl + +define(, +<.globl C_NAME($1) +DECLARE_FUNC(C_NAME($1)) +C_NAME($1):>) + +define(, +,<>)>) + +define(, ) +define(, +, +$1, $2, $3, +)>) + +dnl Argument to ALIGN is always in bytes, and converted to a +dnl logarithmic .align if necessary. + +define(, +<.align ifelse(ALIGN_LOG,yes,,$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_table +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) + +C For 64-bit implementation +STRUCTURE(P1305) + STRUCT(R0, 8) + STRUCT(R1, 8) + STRUCT(S1, 8) + STRUCT(PAD, 12) + STRUCT(H2, 4) + STRUCT(H0, 8) + STRUCT(H1, 8) + +divert diff --git a/asn1.h b/asn1.h new file mode 100644 index 0000000..da2fbe5 --- /dev/null +++ b/asn1.h @@ -0,0 +1,152 @@ +/* asn1.h + + Limited support for ASN.1 DER decoding. + + Copyright (C) 2005 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 +{ + size_t buffer_length; + const uint8_t *buffer; + + /* Next object to parse. */ + size_t pos; + + enum asn1_type type; + + /* Pointer to the current object */ + size_t length; + const uint8_t *data; +}; + +/* Initializes the iterator. */ +enum asn1_iterator_result +asn1_der_iterator_first(struct asn1_der_iterator *iterator, + size_t 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..fc33123 --- /dev/null +++ b/base16-decode.c @@ -0,0 +1,138 @@ +/* base16-encode.c + + Hex decoding. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + char src) +{ + /* Avoid signed char for indexing. */ + unsigned char usrc = src; + int digit; + + if (usrc >= 0x80) + return -1; + + digit = hex_decode_table[usrc]; + 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, + size_t *dst_length, + uint8_t *dst, + size_t src_length, + const char *src) +{ + size_t done; + size_t i; + + for (i = done = 0; ibits == 0; +} diff --git a/base16-encode.c b/base16-encode.c new file mode 100644 index 0000000..9c7f0b1 --- /dev/null +++ b/base16-encode.c @@ -0,0 +1,65 @@ +/* base16-encode.c + + Hex encoding. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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(char *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(char *dst, + size_t length, + const uint8_t *src) +{ + size_t i; + + for (i = 0; i +#include + +#include "base64.h" + +#define TABLE_INVALID -1 +#define TABLE_SPACE -2 +#define TABLE_END -3 + +void +base64_decode_init(struct base64_decode_ctx *ctx) +{ + static const signed char base64_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, + }; + + ctx->word = ctx->bits = ctx->padding = 0; + ctx->table = base64_decode_table; +} + +int +base64_decode_single(struct base64_decode_ctx *ctx, + uint8_t *dst, + char src) +{ + int data = ctx->table[(uint8_t) 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, + size_t *dst_length, + uint8_t *dst, + size_t src_length, + const char *src) +{ + size_t done; + size_t i; + + for (i = 0, done = 0; ibits == 0; +} diff --git a/base64-encode.c b/base64-encode.c new file mode 100644 index 0000000..42fa016 --- /dev/null +++ b/base64-encode.c @@ -0,0 +1,200 @@ +/* base64-encode.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "base64.h" + +#define ENCODE(alphabet,x) ((alphabet)[0x3F & (x)]) + +static void +encode_raw(const char *alphabet, + char *dst, size_t length, const uint8_t *src) +{ + const uint8_t *in = src + length; + char *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(alphabet, (in[0] << 4)); + break; + + case 2: + *--out = ENCODE(alphabet, (in[1] << 2)); + *--out = ENCODE(alphabet, ((in[0] << 4) | (in[1] >> 4))); + break; + + default: + abort(); + } + *--out = ENCODE(alphabet, (in[0] >> 2)); + } + + while (in > src) + { + in -= 3; + *--out = ENCODE(alphabet, (in[2])); + *--out = ENCODE(alphabet, ((in[1] << 2) | (in[2] >> 6))); + *--out = ENCODE(alphabet, ((in[0] << 4) | (in[1] >> 4))); + *--out = ENCODE(alphabet, (in[0] >> 2)); + } + assert(in == src); + assert(out == dst); +} + +static const char base64_encode_table[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +void +base64_encode_raw(char *dst, size_t length, const uint8_t *src) +{ + encode_raw(base64_encode_table, dst, length, src); +} + +void +base64_encode_group(char *dst, uint32_t group) +{ + *dst++ = ENCODE(base64_encode_table, (group >> 18)); + *dst++ = ENCODE(base64_encode_table, (group >> 12)); + *dst++ = ENCODE(base64_encode_table, (group >> 6)); + *dst++ = ENCODE(base64_encode_table, group); +} + +void +base64_encode_init(struct base64_encode_ctx *ctx) +{ + ctx->word = ctx->bits = 0; + ctx->alphabet = base64_encode_table; +} + +/* Encodes a single byte. */ +size_t +base64_encode_single(struct base64_encode_ctx *ctx, + char *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(ctx->alphabet, (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). */ +size_t +base64_encode_update(struct base64_encode_ctx *ctx, + char *dst, + size_t length, + const uint8_t *src) +{ + size_t done = 0; + size_t left = length; + unsigned left_over; + size_t 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)); + + encode_raw(ctx->alphabet, 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 */ +size_t +base64_encode_final(struct base64_encode_ctx *ctx, + char *dst) +{ + unsigned done = 0; + unsigned bits = ctx->bits; + + if (bits) + { + dst[done++] = ENCODE(ctx->alphabet, (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..b46e8ab --- /dev/null +++ b/base64-meta.c @@ -0,0 +1,56 @@ +/* base64-meta.c + + Copyright (C) 2002 Dan Egnor, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "base64.h" + +/* Same as the macros with the same name */ +static nettle_armor_length_func base64_encode_length; +static size_t +base64_encode_length(size_t length) +{ + return BASE64_ENCODE_LENGTH(length); +} + +static nettle_armor_length_func base64_decode_length; +static size_t +base64_decode_length(size_t 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..8e69adb --- /dev/null +++ b/base64.h @@ -0,0 +1,172 @@ +/* base64.h + + Base-64 encoding and decoding. + + Copyright (C) 2002 Niels Möller, Dan Egnor + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 base64url_encode_init nettle_base64url_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 base64url_decode_init nettle_base64url_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 length 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 +{ + const char *alphabet; /* Alphabet to use for encoding */ + unsigned short word; /* Leftover bits */ + unsigned char bits; /* Number of bits, always 0, 2, or 4. */ +}; + +/* Initialize encoding context for base-64 */ +void +base64_encode_init(struct base64_encode_ctx *ctx); + +/* Initialize encoding context for URL safe alphabet, RFC 4648. */ +void +base64url_encode_init(struct base64_encode_ctx *ctx); + +/* Encodes a single byte. Returns amount of output (always 1 or 2). */ +size_t +base64_encode_single(struct base64_encode_ctx *ctx, + char *dst, + uint8_t src); + +/* Returns the number of output characters. DST should point to an + * area of size at least BASE64_ENCODE_LENGTH(length). */ +size_t +base64_encode_update(struct base64_encode_ctx *ctx, + char *dst, + size_t length, + const uint8_t *src); + +/* DST should point to an area of size at least + * BASE64_ENCODE_FINAL_LENGTH */ +size_t +base64_encode_final(struct base64_encode_ctx *ctx, + char *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. FIXME: Use of overlap + * is deprecated, if needed there should be a separate public fucntion + * to do that.*/ +void +base64_encode_raw(char *dst, size_t length, const uint8_t *src); + +void +base64_encode_group(char *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 +{ + const signed char *table; /* Decoding table */ + unsigned short word; /* Leftover bits */ + unsigned char bits; /* Number buffered bits */ + + /* Number of padding characters encountered */ + unsigned char padding; +}; + +/* Initialize decoding context for base-64 */ +void +base64_decode_init(struct base64_decode_ctx *ctx); + +/* Initialize encoding context for URL safe alphabet, RFC 4648. */ +void +base64url_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, + char src); + +/* Returns 1 on success, 0 on error. DST should point to an area of + * size at least BASE64_DECODE_LENGTH(length). The amount of data + * generated is returned in *DST_LENGTH. */ +int +base64_decode_update(struct base64_decode_ctx *ctx, + size_t *dst_length, + uint8_t *dst, + size_t src_length, + const char *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/base64url-decode.c b/base64url-decode.c new file mode 100644 index 0000000..448d5a6 --- /dev/null +++ b/base64url-decode.c @@ -0,0 +1,64 @@ +/* base64url-decode.c + + Copyright (C) 2015 Amos Jeffries, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "base64.h" + +void +base64url_decode_init(struct base64_decode_ctx *ctx) +{ + static const signed char base64url_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, -1, -1, 62, -1, -1, + 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, 63, + -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, + }; + + ctx->word = ctx->bits = ctx->padding = 0; + ctx->table = base64url_decode_table; +} diff --git a/base64url-encode.c b/base64url-encode.c new file mode 100644 index 0000000..d30044e --- /dev/null +++ b/base64url-encode.c @@ -0,0 +1,48 @@ +/* base64url-encode.c + + Copyright (C) 2015 Amos Jeffries, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "base64.h" + +void +base64url_encode_init(struct base64_encode_ctx *ctx) +{ + static const char base64url_encode_table[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_"; + + ctx->word = ctx->bits = 0; + ctx->alphabet = base64url_encode_table; +} diff --git a/base64url-meta.c b/base64url-meta.c new file mode 100644 index 0000000..af4afc9 --- /dev/null +++ b/base64url-meta.c @@ -0,0 +1,63 @@ +/* base64url-meta.c + + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "base64.h" + +/* Same as the macros with the same name */ +static nettle_armor_length_func base64url_encode_length; +static size_t +base64url_encode_length(size_t length) +{ + return BASE64_ENCODE_LENGTH(length); +} + +static nettle_armor_length_func base64url_decode_length; +static size_t +base64url_decode_length(size_t length) +{ + return BASE64_DECODE_LENGTH(length); +} + +#define base64url_encode_ctx base64_encode_ctx +#define base64url_encode_update base64_encode_update +#define base64url_encode_final base64_encode_final +#define base64url_decode_ctx base64_decode_ctx +#define base64url_decode_update base64_decode_update +#define base64url_decode_final base64_decode_final + +const struct nettle_armor nettle_base64url += _NETTLE_ARMOR(base64url, BASE64); diff --git a/bignum-random-prime.c b/bignum-random-prime.c new file mode 100644 index 0000000..14249e2 --- /dev/null +++ b/bignum-random-prime.c @@ -0,0 +1,533 @@ +/* bignum-random-prime.c + + Generation of random provable primes. + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, nm1dq holds (n-1)/q, with q + prime. */ +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 most basic variant of Pocklingtons theorem: + + Assume that q^e | (n-1), with q prime. If we can find an a such that + + a^{n-1} = 1 (mod n) + gcd(a^{(n-1)/q} - 1, n) = 1 + + then any prime divisor p of n satisfies p = 1 (mod q^e). + + Proof (Cohen, 8.3.2): Assume p is a prime factor of n. The central + idea of the proof is to consider the order, modulo p, of a. Denote + this by d. + + a^{n-1} = 1 (mod n) implies a^{n-1} = 1 (mod p), hence d | (n-1). + Next, the condition gcd(a^{(n-1)/q} - 1, n) = 1 implies that + a^{(n-1)/q} != 1, hence d does not divide (n-1)/q. Since q is + prime, this means that q^e | d. + + Finally, we have a^{p-1} = 1 (mod p), hence d | (p-1). So q^e | d | + (p-1), which gives the desired result: p = 1 (mod q^e). + + + * Variant, slightly stronger than Fact 4.59, HAC: + + Assume n = 1 + 2rq, q an odd prime, r <= 2q, and + + a^{n-1} = 1 (mod n) + gcd(a^{(n-1)/q} - 1, n) = 1 + + Then n is prime. + + Proof: By Pocklington's theorem, any prime factor p satisfies p = 1 + (mod q). Neither 1 or q+1 are primes, hence p >= 1 + 2q. If n is + composite, we have n >= (1+2q)^2. But the assumption r <= 2q + implies n <= 1 + 4q^2, a contradiction. + + In bits, the requirement is that #n <= 2 #q, then + + r = (n-1)/2q < 2^{#n - #q} <= 2^#q = 2 2^{#q-1}< 2 q + + + * Another variant with an extra test (Variant of Fact 4.42, HAC): + + Assume n = 1 + 2rq, n odd, q an odd prime, 8 q^3 >= n + + a^{n-1} = 1 (mod n) + gcd(a^{(n-1)/q} - 1, n) = 1 + + Also let x = floor(r / 2q), y = r mod 2q, + + If y^2 - 4x is not a square, then n is prime. + + Proof (adapted from Maurer, Journal of Cryptology, 8 (1995)): + + Assume n is composite. There are at most two factors, both odd, + + n = (1+2m_1 q)(1+2m_2 q) = 1 + 4 m_1 m_2 q^2 + 2 (m_1 + m_2) q + + where we can assume m_1 >= m_2. Then the bound n <= 8 q^3 implies m_1 + m_2 < 2q, restricting (m_1, m_2) to the domain 0 < m_2 < + sqrt(2q), 0 < m_1 < 2q / m_2. + + We have the bound + + m_1 + m_2 < 2q / m_2 + m_2 <= 2q + 1 (maximum value for m_2 = 1) + + And the case m_1 = 2q, m_2 = 1 can be excluded, because it gives n + > 8q^3. So in fact, m_1 + m_2 < 2q. + + Next, write r = (n-1)/2q = 2 m_1 m_2 q + m_1 + m_2. + + If follows that m_1 + m_2 = y and m_1 m_2 = x. m_1 and m_2 are + thus the roots of the equation + + m^2 - y m + x = 0 + + which has integer roots iff y^2 - 4 x is the square of an integer. + + In bits, the requirement is that #n <= 3 #q, then + + n < 2^#n <= 2^{3 #q} = 8 2^{3 (#q-1)} < 8 q^3 +*/ + +/* Generate a prime number p of size bits with 2 p0q dividing (p-1). + p0 must be of size >= ceil(bits/3). The extra factor q can be + omitted (then p0 and p0q should be equal). If top_bits_set is one, + the topmost two bits are set to one, suitable for RSA primes. Also + returns r = (p-1)/p0q. */ +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, e; + int need_square_test; + unsigned p0_bits; + mpz_t x, y, p04; + + p0_bits = mpz_sizeinbase (p0, 2); + + assert (bits <= 3*p0_bits); + assert (bits > p0_bits); + + need_square_test = (bits > 2 * p0_bits); + + mpz_init (r_min); + mpz_init (r_range); + mpz_init (pm1); + mpz_init (a); + + if (need_square_test) + { + mpz_init (x); + mpz_init (y); + mpz_init (p04); + mpz_mul_2exp (p04, p0, 2); + } + + if (q) + mpz_init (e); + + 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_mul (e, r, q); + if (!miller_rabin_pocklington(p, pm1, e, a)) + continue; + + if (need_square_test) + { + /* Our e corresponds to 2r in the theorem */ + mpz_tdiv_qr (x, y, e, p04); + goto square_test; + } + } + else + { + if (!miller_rabin_pocklington(p, pm1, r, a)) + continue; + if (need_square_test) + { + mpz_tdiv_qr (x, y, r, p04); + square_test: + /* We have r' = 2r, x = floor (r/2q) = floor(r'/2q), + and y' = r' - x 4q = 2 (r - x 2q) = 2y. + + Then y^2 - 4x is a square iff y'^2 - 16 x is a + square. */ + + mpz_mul (y, y, y); + mpz_submul_ui (y, x, 16); + if (mpz_perfect_square_p (y)) + continue; + } + } + + /* If we passed all the tests, we have found a prime. */ + break; + } + mpz_clear (r_min); + mpz_clear (r_range); + mpz_clear (pm1); + mpz_clear (a); + + if (need_square_test) + { + mpz_clear (x); + mpz_clear (y); + mpz_clear (p04); + } + if (q) + mpz_clear (e); +} + +/* 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..d456895 --- /dev/null +++ b/bignum-random.c @@ -0,0 +1,96 @@ +/* bignum-random.c + + Generating big random numbers + + Copyright (C) 2002, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "bignum.h" +#include "gmp-glue.h" + +void +nettle_mpz_random_size(mpz_t x, + void *ctx, nettle_random_func *random, + unsigned bits) +{ + unsigned length = (bits + 7) / 8; + TMP_GMP_DECL(data, uint8_t); + + TMP_GMP_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); + + TMP_GMP_FREE(data); +} + +/* 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. NIST FIPS 186-3 specifies 64 extra bits, for use with + * DSA. */ + + nettle_mpz_random_size(x, + ctx, random, + mpz_sizeinbase(n, 2) + 64); + + mpz_fdiv_r(x, x, n); +} diff --git a/bignum.c b/bignum.c new file mode 100644 index 0000000..3352528 --- /dev/null +++ b/bignum.c @@ -0,0 +1,186 @@ +/* bignum.c + + Bignum operations that are missing from gmp. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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. */ +size_t +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 */ + size_t 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; + } +} + +size_t +nettle_mpz_sizeinbase_256_u(const mpz_t x) +{ + return (mpz_sizeinbase(x,2) + 7) / 8; +} + +static void +nettle_mpz_to_octets(size_t length, uint8_t *s, + const mpz_t x, uint8_t sign) +{ + uint8_t *dst = s + length - 1; + size_t size = mpz_size(x); + size_t i; + + for (i = 0; i>= 8; + length--; + } + } + + if (length) + memset(s, sign, length); +} + +void +nettle_mpz_get_str_256(size_t 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 */ + +/* 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)) + +void +nettle_mpz_set_str_256_u(mpz_t x, + size_t length, const uint8_t *s) +{ + nettle_mpz_from_octets(x, length, s); +} + +void +nettle_mpz_init_set_str_256_u(mpz_t x, + size_t 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, + size_t 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, + size_t 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..9afcd29 --- /dev/null +++ b/bignum.h @@ -0,0 +1,140 @@ +/* bignum.h + + Bignum operations that are missing from gmp. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_BIGNUM_H_INCLUDED +#define NETTLE_BIGNUM_H_INCLUDED + +#include "nettle-meta.h" + +#include "nettle-types.h" + +/* For NETTLE_USE_MINI_GMP */ +#include "version.h" + +#if NETTLE_USE_MINI_GMP +# include "mini-gmp.h" + +# define GMP_NUMB_MASK (~(mp_limb_t) 0) + +/* Function missing in older gmp versions, and checked for with ifdef */ +# define mpz_limbs_read mpz_limbs_read +/* Side-channel silent powm not available in mini-gmp. */ +# define mpz_powm_sec mpz_powm +#else +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Size needed for signed encoding, including extra sign byte if + * necessary. */ +size_t +nettle_mpz_sizeinbase_256_s(const mpz_t x); + +/* Size needed for unsigned encoding */ +size_t +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(size_t 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, + size_t length, const uint8_t *s); + +void +nettle_mpz_init_set_str_256_s(mpz_t x, + size_t 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, + size_t length, const uint8_t *s); + +void +nettle_mpz_init_set_str_256_u(mpz_t x, + size_t 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_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..52040f1 --- /dev/null +++ b/blowfish.c @@ -0,0 +1,430 @@ +/* blowfish.c + + The blowfish block cipher. + + Copyright (C) 2014 Niels Möller + Copyright (C) 2010 Simon Josefsson + Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* For a description of the algorithm, see: + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. + * ISBN 0-471-11709-9. Pages 336 ff. + */ + +/* This file is derived from cipher/blowfish.c in Libgcrypt v1.4.6. + The adaption to Nettle was made by Simon Josefsson on 2010-11-23. + Changes include removing the selftest, renaming u32/byte types to + uint32_t/uint8_t, renaming BLOWFISH_ROUNDS to _BLOWFISH_ROUNDS + (from Nettle's blowfish.h), dropping the libgcrypt wrapper + functions, fixing #include's, remove support for non-16 rounds + (there are no test vectors), adding FOR_BLOCK iterations, and + running indent on the code. */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "blowfish.h" + +#include "macros.h" + +/* precomputed S boxes */ +static const struct blowfish_ctx +initial_ctx = { + { + { /* ks0 */ + 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 + }, + { /* ks1 */ + 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 + }, + { /* ks2 */ + 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 + }, + { /* ks3 */ + 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 + } + }, + { /* ps */ + 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/libgcrypt code took the address of x, and + * then read the individual bytes depending on the endianness. But + * since xr and xl ought to live in registers, copying via memory is a + * bad idea. */ + +#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 *ctx, uint32_t * ret_xl, + uint32_t * ret_xr) +{ + uint32_t xl, xr; + + xl = *ret_xl; + xr = *ret_xr; + + R (ctx, xl, xr, 0); + R (ctx, xr, xl, 1); + R (ctx, xl, xr, 2); + R (ctx, xr, xl, 3); + R (ctx, xl, xr, 4); + R (ctx, xr, xl, 5); + R (ctx, xl, xr, 6); + R (ctx, xr, xl, 7); + R (ctx, xl, xr, 8); + R (ctx, xr, xl, 9); + R (ctx, xl, xr, 10); + R (ctx, xr, xl, 11); + R (ctx, xl, xr, 12); + R (ctx, xr, xl, 13); + R (ctx, xl, xr, 14); + R (ctx, xr, xl, 15); + + xl ^= ctx->p[_BLOWFISH_ROUNDS]; + xr ^= ctx->p[_BLOWFISH_ROUNDS + 1]; + + *ret_xl = xr; + *ret_xr = xl; +} + +static void +decrypt (const struct blowfish_ctx *ctx, uint32_t * ret_xl, uint32_t * ret_xr) +{ + uint32_t xl, xr; + + xl = *ret_xl; + xr = *ret_xr; + + R (ctx, xl, xr, 17); + R (ctx, xr, xl, 16); + R (ctx, xl, xr, 15); + R (ctx, xr, xl, 14); + R (ctx, xl, xr, 13); + R (ctx, xr, xl, 12); + R (ctx, xl, xr, 11); + R (ctx, xr, xl, 10); + R (ctx, xl, xr, 9); + R (ctx, xr, xl, 8); + R (ctx, xl, xr, 7); + R (ctx, xr, xl, 6); + R (ctx, xl, xr, 5); + R (ctx, xr, xl, 4); + R (ctx, xl, xr, 3); + R (ctx, xr, xl, 2); + + xl ^= ctx->p[1]; + xr ^= ctx->p[0]; + + *ret_xl = xr; + *ret_xr = xl; +} + +#undef F +#undef R + +void +blowfish_encrypt (const struct blowfish_ctx *ctx, + size_t length, uint8_t * dst, const uint8_t * src) +{ + FOR_BLOCKS (length, dst, src, BLOWFISH_BLOCK_SIZE) + { + uint32_t d1, d2; + + d1 = READ_UINT32(src); + d2 = READ_UINT32(src+4); + encrypt (ctx, &d1, &d2); + dst[0] = (d1 >> 24) & 0xff; + dst[1] = (d1 >> 16) & 0xff; + dst[2] = (d1 >> 8) & 0xff; + dst[3] = d1 & 0xff; + dst[4] = (d2 >> 24) & 0xff; + dst[5] = (d2 >> 16) & 0xff; + dst[6] = (d2 >> 8) & 0xff; + dst[7] = d2 & 0xff; + } +} + +void +blowfish_decrypt (const struct blowfish_ctx *ctx, + size_t length, uint8_t * dst, const uint8_t * src) +{ + FOR_BLOCKS (length, dst, src, BLOWFISH_BLOCK_SIZE) + { + uint32_t d1, d2; + + d1 = READ_UINT32(src); + d2 = READ_UINT32(src+4); + decrypt (ctx, &d1, &d2); + dst[0] = (d1 >> 24) & 0xff; + dst[1] = (d1 >> 16) & 0xff; + dst[2] = (d1 >> 8) & 0xff; + dst[3] = d1 & 0xff; + dst[4] = (d2 >> 24) & 0xff; + dst[5] = (d2 >> 16) & 0xff; + dst[6] = (d2 >> 8) & 0xff; + dst[7] = d2 & 0xff; + } +} + +int +blowfish_set_key (struct blowfish_ctx *ctx, + size_t length, 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) % length] << 16) + | (key[(j+2) % length] << 8) | key[(j+3) % length]; + ctx->p[i] ^= data; + j = (j + 4) % length; + } + + 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 (j = 0; j < 4; j++) + for (i = 0; i < 256; i += 2) + { + encrypt (ctx, &datal, &datar); + ctx->s[j][i] = datal; + ctx->s[j][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; +} + +int +blowfish128_set_key(struct blowfish_ctx *ctx, const uint8_t *key) +{ + return blowfish_set_key (ctx, BLOWFISH128_KEY_SIZE, key); +} diff --git a/blowfish.h b/blowfish.h new file mode 100644 index 0000000..bcdc7cb --- /dev/null +++ b/blowfish.h @@ -0,0 +1,89 @@ +/* blowfish.h + + Blowfish block cipher. + + Copyright (C) 2014 Niels Möller + Copyright (C) 1998, 2001 FSF, Ray Dassen, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 blowfish128_set_key nettle_blowfish128_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 BLOWFISH128_KEY_SIZE 16 + +#define _BLOWFISH_ROUNDS 16 + +struct blowfish_ctx +{ + uint32_t s[4][256]; + uint32_t p[_BLOWFISH_ROUNDS+2]; +}; + +/* Returns 0 for weak keys, otherwise 1. */ +int +blowfish_set_key(struct blowfish_ctx *ctx, + size_t length, const uint8_t *key); +int +blowfish128_set_key(struct blowfish_ctx *ctx, const uint8_t *key); + +void +blowfish_encrypt(const struct blowfish_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); +void +blowfish_decrypt(const struct blowfish_ctx *ctx, + size_t 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..7e445cf --- /dev/null +++ b/buffer-init.c @@ -0,0 +1,48 @@ +/* buffer-init.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..600a8c3 --- /dev/null +++ b/buffer.c @@ -0,0 +1,142 @@ +/* buffer.c + + A bare-bones string stream. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "buffer.h" + +int +nettle_buffer_grow(struct nettle_buffer *buffer, + size_t length) +{ + assert(buffer->size <= buffer->alloc); + + if (buffer->size + length > buffer->alloc) + { + size_t 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, + size_t 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, + size_t 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, + size_t 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..9cbcfb1 --- /dev/null +++ b/buffer.h @@ -0,0 +1,106 @@ +/* buffer.h + + A bare-bones string stream. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 */ + size_t alloc; + + void *realloc_ctx; + nettle_realloc_func *realloc; + + /* Current size */ + size_t 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, + size_t 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, + size_t 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, + size_t 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, + size_t 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-absorb.c b/camellia-absorb.c new file mode 100644 index 0000000..d865dc6 --- /dev/null +++ b/camellia-absorb.c @@ -0,0 +1,149 @@ +/* camellia-absorb.c + + Final key setup processing for the camellia block cipher. + + Copyright (C) 2006,2007 NTT + (Nippon Telegraph and Telephone Corporation). + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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 + +/* For CHAR_BIT, needed by HAVE_NATIVE_64_BIT */ +#include + +#include "camellia-internal.h" + +#include "macros.h" + +void +_camellia_absorb(unsigned nkeys, uint64_t *dst, uint64_t *subkey) +{ + uint64_t kw2, kw4; + uint32_t dw, tl, tr; + unsigned i; + + /* 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 < 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 ^= ROTL32(1, dw); + + subkey[i+3] ^= kw2; + subkey[i+5] ^= kw2; + subkey[i+7] ^= kw2; + } + subkey[i] ^= kw2; + + /* absorb kw4 to other subkeys */ + kw4 = subkey[nkeys + 1]; + + for (i = 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 ^= ROTL32(1, dw); + } + + subkey[6] ^= kw4; + subkey[4] ^= kw4; + subkey[2] ^= kw4; + subkey[0] ^= kw4; + + /* key XOR is end of F-function */ + dst[0] = subkey[0] ^ subkey[2]; + dst[1] = subkey[3]; + + dst[2] = subkey[2] ^ subkey[4]; + dst[3] = subkey[3] ^ subkey[5]; + dst[4] = subkey[4] ^ subkey[6]; + dst[5] = subkey[5] ^ subkey[7]; + + for (i = 8; i < nkeys; i += 8) + { + tl = (subkey[i+2] >> 32) ^ (subkey[i+2] & ~subkey[i]); + dw = tl & (subkey[i] >> 32); + tr = subkey[i+2] ^ ROTL32(1, dw); + dst[i-2] = subkey[i-2] ^ ( ((uint64_t) tl << 32) | tr); + + dst[i-1] = subkey[i]; + dst[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] ^ ROTL32(1, dw); + dst[i+1] = subkey[i+3] ^ ( ((uint64_t) tl << 32) | tr); + + dst[i+2] = subkey[i+2] ^ subkey[i+4]; + dst[i+3] = subkey[i+3] ^ subkey[i+5]; + dst[i+4] = subkey[i+4] ^ subkey[i+6]; + dst[i+5] = subkey[i+5] ^ subkey[i+7]; + } + dst[i-2] = subkey[i-2]; + dst[i-1] = subkey[i] ^ subkey[i-1]; + +#if !HAVE_NATIVE_64_BIT + for (i = 0; i < nkeys; i += 8) + { + /* apply the inverse of the last half of F-function */ + CAMELLIA_F_HALF_INV(dst[i+1]); + CAMELLIA_F_HALF_INV(dst[i+2]); + CAMELLIA_F_HALF_INV(dst[i+3]); + CAMELLIA_F_HALF_INV(dst[i+4]); + CAMELLIA_F_HALF_INV(dst[i+5]); + CAMELLIA_F_HALF_INV(dst[i+6]); + } +#endif + +} diff --git a/camellia-crypt-internal.c b/camellia-crypt-internal.c new file mode 100644 index 0000000..6e2727b --- /dev/null +++ b/camellia-crypt-internal.c @@ -0,0 +1,183 @@ +/* camellia-crypt-internal.c + + Copyright (C) 2006,2007 NTT + (Nippon Telegraph and Telephone Corporation). + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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 + +#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 ^= ROTL32(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 ^= ROTL32(1, __t); \ + (x) = ((uint64_t) __xl << 32) | __xr; \ +} while (0) + +#if HAVE_NATIVE_64_BIT +#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) */ \ + __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 = ROTL32(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 ^= (k); \ + y ^= ((uint64_t) __ir << 32) | __il; \ + } while (0) +#else /* !HAVE_NATIVE_64_BIT */ +#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 = ROTL32(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) +#endif + +void +_camellia_crypt(unsigned nkeys, + const uint64_t *keys, + const struct camellia_table *T, + size_t 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 ^= keys[0]; + + /* main iteration */ + + CAMELLIA_ROUNDSM(T, i0, keys[1], i1); + CAMELLIA_ROUNDSM(T, i1, keys[2], i0); + CAMELLIA_ROUNDSM(T, i0, keys[3], i1); + CAMELLIA_ROUNDSM(T, i1, keys[4], i0); + CAMELLIA_ROUNDSM(T, i0, keys[5], i1); + CAMELLIA_ROUNDSM(T, i1, keys[6], i0); + + for (i = 0; i < nkeys - 8; i+= 8) + { + CAMELLIA_FL(i0, keys[i+7]); + CAMELLIA_FLINV(i1, keys[i+8]); + + CAMELLIA_ROUNDSM(T, i0, keys[i+9], i1); + CAMELLIA_ROUNDSM(T, i1, keys[i+10], i0); + CAMELLIA_ROUNDSM(T, i0, keys[i+11], i1); + CAMELLIA_ROUNDSM(T, i1, keys[i+12], i0); + CAMELLIA_ROUNDSM(T, i0, keys[i+13], i1); + CAMELLIA_ROUNDSM(T, i1, keys[i+14], i0); + } + + /* post whitening but kw4 */ + i1 ^= keys[i+7]; + + WRITE_UINT64(dst , i1); + WRITE_UINT64(dst + 8, i0); + } +} diff --git a/camellia-internal.h b/camellia-internal.h new file mode 100644 index 0000000..e09ef11 --- /dev/null +++ b/camellia-internal.h @@ -0,0 +1,137 @@ +/* camellia-internal.h + + The camellia block cipher. + + Copyright (C) 2006,2007 NTT + (Nippon Telegraph and Telephone Corporation). + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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_absorb _nettle_camellia_absorb +#define _camellia_invert_key _nettle_camellia_invert_key +#define _camellia_table _nettle_camellia_table + +/* + * macros + */ + +/* Destructive rotation of 128 bit values. */ +#define ROTL128(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]; +}; + +/* 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 = ROTL32(24, __yr); \ + __yr ^= __yl; \ + (y) = ((uint64_t) __yl << 32) | __yr; \ + } while (0) + +#if ! HAVE_NATIVE_64_BIT +#define CAMELLIA_F_HALF_INV(x) do { \ + uint32_t __t, __w; \ + __t = (x) >> 32; \ + __w = __t ^(x); \ + __w = ROTL32(8, __w); \ + (x) = ((uint64_t) __w << 32) | (__t ^ __w); \ + } while (0) +#endif + +void +_camellia_crypt(unsigned nkeys, const uint64_t *keys, + const struct camellia_table *T, + size_t length, uint8_t *dst, + const uint8_t *src); + +/* The initial NKEYS + 2 subkeys in SUBKEY are reduced to the final + NKEYS subkeys stored in DST. SUBKEY data is modified in the + process. */ +void +_camellia_absorb(unsigned nkeys, uint64_t *dst, uint64_t *subkey); + +void +_camellia_invert_key(unsigned nkeys, + uint64_t *dst, const uint64_t *src); + +extern const struct camellia_table _camellia_table; + +#endif /* NETTLE_CAMELLIA_INTERNAL_H_INCLUDED */ diff --git a/camellia-invert-key.c b/camellia-invert-key.c new file mode 100644 index 0000000..2edbfdb --- /dev/null +++ b/camellia-invert-key.c @@ -0,0 +1,54 @@ +/* camellia-invert-key.c + + Inverting a key means reversing order of subkeys. + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "camellia-internal.h" + +#define SWAP(a, b) \ +do { uint64_t t_swap = (a); (a) = (b); (b) = t_swap; } while(0) + +void +_camellia_invert_key(unsigned nkeys, + uint64_t *dst, const uint64_t *src) +{ + unsigned i; + if (dst == src) + for (i = 0; i < nkeys - 1 - i; i++) + SWAP (dst[i], dst[nkeys - 1- i]); + else + for (i = 0; i < nkeys; i++) + dst[i] = src[nkeys - 1 - i]; +} diff --git a/camellia-table.c b/camellia-table.c new file mode 100644 index 0000000..834ac4d --- /dev/null +++ b/camellia-table.c @@ -0,0 +1,321 @@ +/* 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 file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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..b035db3 --- /dev/null +++ b/camellia.h @@ -0,0 +1,143 @@ +/* camellia.h + + Copyright (C) 2006,2007 NTT + (Nippon Telegraph and Telephone Corporation). + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_CAMELLIA_H_INCLUDED +#define NETTLE_CAMELLIA_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define camellia128_set_encrypt_key nettle_camellia128_set_encrypt_key +#define camellia128_set_decrypt_key nettle_camellia_set_decrypt_key +#define camellia128_invert_key nettle_camellia128_invert_key +#define camellia128_crypt nettle_camellia128_crypt + +#define camellia192_set_encrypt_key nettle_camellia192_set_encrypt_key +#define camellia192_set_decrypt_key nettle_camellia192_set_decrypt_key + +#define camellia256_set_encrypt_key nettle_camellia256_set_encrypt_key +#define camellia256_set_decrypt_key nettle_camellia256_set_decrypt_key +#define camellia256_invert_key nettle_camellia256_invert_key +#define camellia256_crypt nettle_camellia256_crypt + + +#define CAMELLIA_BLOCK_SIZE 16 +/* Valid key sizes are 128, 192 or 256 bits (16, 24 or 32 bytes) */ +#define CAMELLIA128_KEY_SIZE 16 +#define CAMELLIA192_KEY_SIZE 24 +#define CAMELLIA256_KEY_SIZE 32 + +/* 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. */ + +#define _CAMELLIA128_NKEYS 24 +#define _CAMELLIA256_NKEYS 32 + +struct camellia128_ctx +{ + uint64_t keys[_CAMELLIA128_NKEYS]; +}; + +void +camellia128_set_encrypt_key(struct camellia128_ctx *ctx, + const uint8_t *key); + +void +camellia128_set_decrypt_key(struct camellia128_ctx *ctx, + const uint8_t *key); + +void +camellia128_invert_key(struct camellia128_ctx *dst, + const struct camellia128_ctx *src); + +void +camellia128_crypt(const struct camellia128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +struct camellia256_ctx +{ + uint64_t keys[_CAMELLIA256_NKEYS]; +}; + +void +camellia256_set_encrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key); + +void +camellia256_set_decrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key); + +void +camellia256_invert_key(struct camellia256_ctx *dst, + const struct camellia256_ctx *src); + +void +camellia256_crypt(const struct camellia256_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +/* camellia192 is the same as camellia256, except for the key + schedule. */ +/* Slightly ugly with a #define on a struct tag, since it might cause + surprises if also used as a name of a variable. */ +#define camellia192_ctx camellia256_ctx + +void +camellia192_set_encrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key); + +void +camellia192_set_decrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key); + +#define camellia192_invert_key camellia256_invert_key +#define camellia192_crypt camellia256_crypt + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CAMELLIA_H_INCLUDED */ diff --git a/camellia128-crypt.c b/camellia128-crypt.c new file mode 100644 index 0000000..a9395f2 --- /dev/null +++ b/camellia128-crypt.c @@ -0,0 +1,54 @@ +/* camellia128-crypt.c + + Crypt function for the camellia block cipher. + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 +camellia128_crypt(const struct camellia128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % CAMELLIA_BLOCK_SIZE) ); + _camellia_crypt(_CAMELLIA128_NKEYS, ctx->keys, + &_camellia_table, + length, dst, src); +} diff --git a/camellia128-meta.c b/camellia128-meta.c new file mode 100644 index 0000000..77fb7c5 --- /dev/null +++ b/camellia128-meta.c @@ -0,0 +1,49 @@ +/* camellia128-meta.c + + Copyright (C) 2010, 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "camellia.h" + +const struct nettle_cipher nettle_camellia128 = + { "camellia128", sizeof(struct camellia128_ctx), + CAMELLIA_BLOCK_SIZE, CAMELLIA128_KEY_SIZE, + (nettle_set_key_func *) camellia128_set_encrypt_key, + (nettle_set_key_func *) camellia128_set_decrypt_key, + (nettle_cipher_func *) camellia128_crypt, + (nettle_cipher_func *) camellia128_crypt + }; diff --git a/camellia128-set-decrypt-key.c b/camellia128-set-decrypt-key.c new file mode 100644 index 0000000..96050f6 --- /dev/null +++ b/camellia128-set-decrypt-key.c @@ -0,0 +1,53 @@ +/* camellia128-set-decrypt-key.c + + Inverse key setup for the camellia block cipher. + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "camellia-internal.h" + +void +camellia128_invert_key(struct camellia128_ctx *dst, + const struct camellia128_ctx *src) +{ + _camellia_invert_key (_CAMELLIA128_NKEYS, dst->keys, src->keys); +} + +void +camellia128_set_decrypt_key(struct camellia128_ctx *ctx, + const uint8_t *key) +{ + camellia128_set_encrypt_key(ctx, key); + camellia128_invert_key(ctx, ctx); +} diff --git a/camellia128-set-encrypt-key.c b/camellia128-set-encrypt-key.c new file mode 100644 index 0000000..66d8a66 --- /dev/null +++ b/camellia128-set-encrypt-key.c @@ -0,0 +1,124 @@ +/* camellia128-set-encrypt-key.c + + Key setup for the camellia block cipher. + + Copyright (C) 2006,2007 NTT + (Nippon Telegraph and Telephone Corporation). + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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 + +#include "camellia-internal.h" + +#include "macros.h" + +void +camellia128_set_encrypt_key (struct camellia128_ctx *ctx, + const uint8_t *key) +{ + uint64_t k0, k1; + + uint64_t subkey[_CAMELLIA128_NKEYS + 2]; + uint64_t w; + + k0 = READ_UINT64(key); + k1 = READ_UINT64(key + 8); + + /** + * generate KL dependent subkeys + */ + subkey[0] = k0; subkey[1] = k1; + ROTL128(15, k0, k1); + subkey[4] = k0; subkey[5] = k1; + ROTL128(30, k0, k1); + subkey[10] = k0; subkey[11] = k1; + ROTL128(15, k0, k1); + subkey[13] = k1; + ROTL128(17, k0, k1); + subkey[16] = k0; subkey[17] = k1; + ROTL128(17, k0, k1); + subkey[18] = k0; subkey[19] = k1; + ROTL128(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; + ROTL128(15, k0, k1); + subkey[6] = k0; subkey[7] = k1; + ROTL128(15, k0, k1); + subkey[8] = k0; subkey[9] = k1; + ROTL128(15, k0, k1); + subkey[12] = k0; + ROTL128(15, k0, k1); + subkey[14] = k0; subkey[15] = k1; + ROTL128(34, k0, k1); + subkey[20] = k0; subkey[21] = k1; + ROTL128(17, k0, k1); + subkey[24] = k0; subkey[25] = k1; + + /* Common final processing */ + _camellia_absorb (_CAMELLIA128_NKEYS, ctx->keys, subkey); +} diff --git a/camellia192-meta.c b/camellia192-meta.c new file mode 100644 index 0000000..c4f92f1 --- /dev/null +++ b/camellia192-meta.c @@ -0,0 +1,49 @@ +/* camellia192-meta.c + + Copyright (C) 2010, 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "camellia.h" + +const struct nettle_cipher nettle_camellia192 = + { "camellia192", sizeof(struct camellia256_ctx), + CAMELLIA_BLOCK_SIZE, CAMELLIA192_KEY_SIZE, + (nettle_set_key_func *) camellia192_set_encrypt_key, + (nettle_set_key_func *) camellia192_set_decrypt_key, + (nettle_cipher_func *) camellia256_crypt, + (nettle_cipher_func *) camellia256_crypt + }; diff --git a/camellia256-crypt.c b/camellia256-crypt.c new file mode 100644 index 0000000..dc5b11c --- /dev/null +++ b/camellia256-crypt.c @@ -0,0 +1,54 @@ +/* camellia256-crypt.c + + Crypt function for the camellia block cipher. + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 +camellia256_crypt(const struct camellia256_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % CAMELLIA_BLOCK_SIZE) ); + _camellia_crypt(_CAMELLIA256_NKEYS, ctx->keys, + &_camellia_table, + length, dst, src); +} diff --git a/camellia256-meta.c b/camellia256-meta.c new file mode 100644 index 0000000..c2ae2c4 --- /dev/null +++ b/camellia256-meta.c @@ -0,0 +1,49 @@ +/* camellia256-meta.c + + Copyright (C) 2010, 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "camellia.h" + +const struct nettle_cipher nettle_camellia256 = + { "camellia256", sizeof(struct camellia256_ctx), + CAMELLIA_BLOCK_SIZE, CAMELLIA256_KEY_SIZE, + (nettle_set_key_func *) camellia256_set_encrypt_key, + (nettle_set_key_func *) camellia256_set_decrypt_key, + (nettle_cipher_func *) camellia256_crypt, + (nettle_cipher_func *) camellia256_crypt + }; diff --git a/camellia256-set-decrypt-key.c b/camellia256-set-decrypt-key.c new file mode 100644 index 0000000..70da7c5 --- /dev/null +++ b/camellia256-set-decrypt-key.c @@ -0,0 +1,61 @@ +/* camellia256-set-decrypt-key.c + + Inverse key setup for the camellia block cipher. + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "camellia-internal.h" + +void +camellia256_invert_key(struct camellia256_ctx *dst, + const struct camellia256_ctx *src) +{ + _camellia_invert_key (_CAMELLIA256_NKEYS, dst->keys, src->keys); +} + +void +camellia256_set_decrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key) +{ + camellia256_set_encrypt_key(ctx, key); + camellia256_invert_key(ctx, ctx); +} + +void +camellia192_set_decrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key) +{ + camellia192_set_encrypt_key(ctx, key); + camellia256_invert_key(ctx, ctx); +} diff --git a/camellia256-set-encrypt-key.c b/camellia256-set-encrypt-key.c new file mode 100644 index 0000000..608224e --- /dev/null +++ b/camellia256-set-encrypt-key.c @@ -0,0 +1,168 @@ +/* camellia256-set-encrypt-key.c + + Key setup for the camellia block cipher. + + Copyright (C) 2006,2007 NTT + (Nippon Telegraph and Telephone Corporation). + + Copyright (C) 2010, 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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 + +#include "camellia-internal.h" + +#include "macros.h" + +static void +_camellia256_set_encrypt_key (struct camellia256_ctx *ctx, + uint64_t k0, uint64_t k1, + uint64_t k2, uint64_t k3) +{ + uint64_t subkey[_CAMELLIA256_NKEYS + 2]; + uint64_t w; + + /* generate KL dependent subkeys */ + subkey[0] = k0; subkey[1] = k1; + ROTL128(45, k0, k1); + subkey[12] = k0; subkey[13] = k1; + ROTL128(15, k0, k1); + subkey[16] = k0; subkey[17] = k1; + ROTL128(17, k0, k1); + subkey[22] = k0; subkey[23] = k1; + ROTL128(34, k0, k1); + subkey[30] = k0; subkey[31] = k1; + + /* generate KR dependent subkeys */ + ROTL128(15, k2, k3); + subkey[4] = k2; subkey[5] = k3; + ROTL128(15, k2, k3); + subkey[8] = k2; subkey[9] = k3; + ROTL128(30, k2, k3); + subkey[18] = k2; subkey[19] = k3; + ROTL128(34, k2, k3); + subkey[26] = k2; subkey[27] = k3; + ROTL128(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 */ + ROTL128(15, k0, k1); + subkey[6] = k0; subkey[7] = k1; + ROTL128(30, k0, k1); + subkey[14] = k0; subkey[15] = k1; + ROTL128(32, k0, k1); + subkey[24] = k0; subkey[25] = k1; + ROTL128(17, k0, k1); + subkey[28] = k0; subkey[29] = k1; + + /* generate KB dependent subkeys */ + subkey[2] = k2; subkey[3] = k3; + ROTL128(30, k2, k3); + subkey[10] = k2; subkey[11] = k3; + ROTL128(30, k2, k3); + subkey[20] = k2; subkey[21] = k3; + ROTL128(51, k2, k3); + subkey[32] = k2; subkey[33] = k3; + + /* Common final processing */ + _camellia_absorb (_CAMELLIA256_NKEYS, ctx->keys, subkey); +} + +void +camellia256_set_encrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key) +{ + uint64_t k0, k1, k2, k3; + k0 = READ_UINT64(key); + k1 = READ_UINT64(key + 8); + k2 = READ_UINT64(key + 16); + k3 = READ_UINT64(key + 24); + + _camellia256_set_encrypt_key (ctx, k0, k1, k2, k3); +} + +void +camellia192_set_encrypt_key(struct camellia256_ctx *ctx, + const uint8_t *key) +{ + uint64_t k0, k1, k2; + k0 = READ_UINT64(key); + k1 = READ_UINT64(key + 8); + k2 = READ_UINT64(key + 16); + + _camellia256_set_encrypt_key (ctx, k0, k1, k2, ~k2); +} diff --git a/cast128-meta.c b/cast128-meta.c new file mode 100644 index 0000000..4435dc2 --- /dev/null +++ b/cast128-meta.c @@ -0,0 +1,47 @@ +/* cast128-meta.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "cast128.h" + +const struct nettle_cipher nettle_cast128 = + { "cast128", sizeof(struct cast128_ctx), + CAST128_BLOCK_SIZE, CAST128_KEY_SIZE, + (nettle_set_key_func *) cast128_set_key, + (nettle_set_key_func *) cast128_set_key, + (nettle_cipher_func *) cast128_encrypt, + (nettle_cipher_func *) cast128_decrypt + }; diff --git a/cast128.c b/cast128.c new file mode 100644 index 0000000..e280197 --- /dev/null +++ b/cast128.c @@ -0,0 +1,287 @@ +/* cast128.c + + The CAST-128 block cipher, described in RFC 2144. + + Copyright (C) 2001, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Based on: + * + * CAST-128 in C + * Written by Steve Reid + * 100% Public Domain - no warranty + * Released 1997.10.11 + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "cast128.h" +#include "cast128_sboxes.h" + +#include "macros.h" + +#define CAST_SMALL_KEY 10 + +#define S1 cast_sbox1 +#define S2 cast_sbox2 +#define S3 cast_sbox3 +#define S4 cast_sbox4 +#define S5 cast_sbox5 +#define S6 cast_sbox6 +#define S7 cast_sbox7 +#define S8 cast_sbox8 + +/* Macros to access 8-bit bytes out of a 32-bit word */ +#define B0(x) ( (uint8_t) (x>>24) ) +#define B1(x) ( (uint8_t) ((x>>16)&0xff) ) +#define B2(x) ( (uint8_t) ((x>>8)&0xff) ) +#define B3(x) ( (uint8_t) ((x)&0xff) ) + +/* NOTE: Depends on ROTL32 supporting a zero shift count. */ + +/* CAST-128 uses three different round functions */ +#define F1(l, r, i) do { \ + t = ctx->Km[i] + r; \ + t = ROTL32(ctx->Kr[i], t); \ + l ^= ((S1[B0(t)] ^ S2[B1(t)]) - S3[B2(t)]) + S4[B3(t)]; \ + } while (0) +#define F2(l, r, i) do { \ + t = ctx->Km[i] ^ r; \ + t = ROTL32( ctx->Kr[i], t); \ + l ^= ((S1[B0(t)] - S2[B1(t)]) + S3[B2(t)]) ^ S4[B3(t)]; \ + } while (0) +#define F3(l, r, i) do { \ + t = ctx->Km[i] - r; \ + t = ROTL32(ctx->Kr[i], t); \ + l ^= ((S1[B0(t)] + S2[B1(t)]) ^ S3[B2(t)]) - S4[B3(t)]; \ + } while (0) + + +/***** Encryption Function *****/ + +void +cast128_encrypt(const struct cast128_ctx *ctx, + size_t 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 & 16) { + 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); + } +} + + +/***** Decryption Function *****/ + +void +cast128_decrypt(const struct cast128_ctx *ctx, + size_t 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 & 16) { + 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); + } +} + +/***** Key Schedule *****/ + +#define SET_KM(i, k) ctx->Km[i] = (k) +#define SET_KR(i, k) ctx->Kr[i] = (k) & 31 + +#define EXPAND(set, full) do { \ + z0 = x0 ^ S5[B1(x3)] ^ S6[B3(x3)] ^ S7[B0(x3)] ^ S8[B2(x3)] ^ S7[B0(x2)]; \ + z1 = x2 ^ S5[B0(z0)] ^ S6[B2(z0)] ^ S7[B1(z0)] ^ S8[B3(z0)] ^ S8[B2(x2)]; \ + z2 = x3 ^ S5[B3(z1)] ^ S6[B2(z1)] ^ S7[B1(z1)] ^ S8[B0(z1)] ^ S5[B1(x2)]; \ + z3 = x1 ^ S5[B2(z2)] ^ S6[B1(z2)] ^ S7[B3(z2)] ^ S8[B0(z2)] ^ S6[B3(x2)]; \ + \ + set(0, S5[B0(z2)] ^ S6[B1(z2)] ^ S7[B3(z1)] ^ S8[B2(z1)] ^ S5[B2(z0)]); \ + set(1, S5[B2(z2)] ^ S6[B3(z2)] ^ S7[B1(z1)] ^ S8[B0(z1)] ^ S6[B2(z1)]); \ + set(2, S5[B0(z3)] ^ S6[B1(z3)] ^ S7[B3(z0)] ^ S8[B2(z0)] ^ S7[B1(z2)]); \ + set(3, S5[B2(z3)] ^ S6[B3(z3)] ^ S7[B1(z0)] ^ S8[B0(z0)] ^ S8[B0(z3)]); \ + \ + x0 = z2 ^ S5[B1(z1)] ^ S6[B3(z1)] ^ S7[B0(z1)] ^ S8[B2(z1)] ^ S7[B0(z0)]; \ + x1 = z0 ^ S5[B0(x0)] ^ S6[B2(x0)] ^ S7[B1(x0)] ^ S8[B3(x0)] ^ S8[B2(z0)]; \ + x2 = z1 ^ S5[B3(x1)] ^ S6[B2(x1)] ^ S7[B1(x1)] ^ S8[B0(x1)] ^ S5[B1(z0)]; \ + x3 = z3 ^ S5[B2(x2)] ^ S6[B1(x2)] ^ S7[B3(x2)] ^ S8[B0(x2)] ^ S6[B3(z0)]; \ + \ + set(4, S5[B3(x0)] ^ S6[B2(x0)] ^ S7[B0(x3)] ^ S8[B1(x3)] ^ S5[B0(x2)]); \ + set(5, S5[B1(x0)] ^ S6[B0(x0)] ^ S7[B2(x3)] ^ S8[B3(x3)] ^ S6[B1(x3)]); \ + set(6, S5[B3(x1)] ^ S6[B2(x1)] ^ S7[B0(x2)] ^ S8[B1(x2)] ^ S7[B3(x0)]); \ + set(7, S5[B1(x1)] ^ S6[B0(x1)] ^ S7[B2(x2)] ^ S8[B3(x2)] ^ S8[B3(x1)]); \ + \ + z0 = x0 ^ S5[B1(x3)] ^ S6[B3(x3)] ^ S7[B0(x3)] ^ S8[B2(x3)] ^ S7[B0(x2)]; \ + z1 = x2 ^ S5[B0(z0)] ^ S6[B2(z0)] ^ S7[B1(z0)] ^ S8[B3(z0)] ^ S8[B2(x2)]; \ + z2 = x3 ^ S5[B3(z1)] ^ S6[B2(z1)] ^ S7[B1(z1)] ^ S8[B0(z1)] ^ S5[B1(x2)]; \ + z3 = x1 ^ S5[B2(z2)] ^ S6[B1(z2)] ^ S7[B3(z2)] ^ S8[B0(z2)] ^ S6[B3(x2)]; \ + \ + set(8, S5[B3(z0)] ^ S6[B2(z0)] ^ S7[B0(z3)] ^ S8[B1(z3)] ^ S5[B1(z2)]); \ + set(9, S5[B1(z0)] ^ S6[B0(z0)] ^ S7[B2(z3)] ^ S8[B3(z3)] ^ S6[B0(z3)]); \ + set(10, S5[B3(z1)] ^ S6[B2(z1)] ^ S7[B0(z2)] ^ S8[B1(z2)] ^ S7[B2(z0)]); \ + set(11, S5[B1(z1)] ^ S6[B0(z1)] ^ S7[B2(z2)] ^ S8[B3(z2)] ^ S8[B2(z1)]); \ + \ + x0 = z2 ^ S5[B1(z1)] ^ S6[B3(z1)] ^ S7[B0(z1)] ^ S8[B2(z1)] ^ S7[B0(z0)]; \ + x1 = z0 ^ S5[B0(x0)] ^ S6[B2(x0)] ^ S7[B1(x0)] ^ S8[B3(x0)] ^ S8[B2(z0)]; \ + x2 = z1 ^ S5[B3(x1)] ^ S6[B2(x1)] ^ S7[B1(x1)] ^ S8[B0(x1)] ^ S5[B1(z0)]; \ + x3 = z3 ^ S5[B2(x2)] ^ S6[B1(x2)] ^ S7[B3(x2)] ^ S8[B0(x2)] ^ S6[B3(z0)]; \ + if (full) \ + { \ + set(12, S5[B0(x2)] ^ S6[B1(x2)] ^ S7[B3(x1)] ^ S8[B2(x1)] ^ S5[B3(x0)]); \ + set(13, S5[B2(x2)] ^ S6[B3(x2)] ^ S7[B1(x1)] ^ S8[B0(x1)] ^ S6[B3(x1)]); \ + set(14, S5[B0(x3)] ^ S6[B1(x3)] ^ S7[B3(x0)] ^ S8[B2(x0)] ^ S7[B0(x2)]); \ + set(15, S5[B2(x3)] ^ S6[B3(x3)] ^ S7[B1(x0)] ^ S8[B0(x0)] ^ S8[B1(x3)]); \ + } \ +} while (0) + +void +cast5_set_key(struct cast128_ctx *ctx, + size_t length, const uint8_t *key) +{ + uint32_t x0, x1, x2, x3, z0, z1, z2, z3; + uint32_t w; + int full; + + assert (length >= CAST5_MIN_KEY_SIZE); + assert (length <= CAST5_MAX_KEY_SIZE); + + full = (length > CAST_SMALL_KEY); + + x0 = READ_UINT32 (key); + + /* Read final word, possibly zero-padded. */ + switch (length & 3) + { + case 0: + w = READ_UINT32 (key + length - 4); + break; + case 3: + w = READ_UINT24 (key + length - 3) << 8; + break; + case 2: + w = READ_UINT16 (key + length - 2) << 16; + break; + case 1: + w = (uint32_t) key[length - 1] << 24; + break; + } + + if (length <= 8) + { + x1 = w; + x2 = x3 = 0; + } + else + { + x1 = READ_UINT32 (key + 4); + if (length <= 12) + { + x2 = w; + x3 = 0; + } + else + { + x2 = READ_UINT32 (key + 8); + x3 = w; + } + } + + EXPAND(SET_KM, full); + EXPAND(SET_KR, full); + + ctx->rounds = full ? 16 : 12; +} + +void +cast128_set_key(struct cast128_ctx *ctx, const uint8_t *key) +{ + cast5_set_key (ctx, CAST128_KEY_SIZE, key); +} diff --git a/cast128.h b/cast128.h new file mode 100644 index 0000000..9d099ec --- /dev/null +++ b/cast128.h @@ -0,0 +1,86 @@ +/* cast128.h + + The CAST-128 block cipher. + + Copyright (C) 2001, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_CAST128_H_INCLUDED +#define NETTLE_CAST128_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define cast5_set_key nettle_cast5_set_key +#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 CAST5_MIN_KEY_SIZE 5 +#define CAST5_MAX_KEY_SIZE 16 + +#define CAST128_KEY_SIZE 16 + +struct cast128_ctx +{ + unsigned rounds; /* Number of rounds to use, 12 or 16 */ + /* Expanded key, rotations (5 bits only) and 32-bit masks. */ + unsigned char Kr[16]; + uint32_t Km[16]; +}; + +/* Using variable key size. */ +void +cast5_set_key(struct cast128_ctx *ctx, + size_t length, const uint8_t *key); + +void +cast128_set_key(struct cast128_ctx *ctx, const uint8_t *key); + +void +cast128_encrypt(const struct cast128_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); +void +cast128_decrypt(const struct cast128_ctx *ctx, + size_t 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..c0d33f9 --- /dev/null +++ b/cast128_sboxes.h @@ -0,0 +1,543 @@ +/* + * 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..85ad255 --- /dev/null +++ b/cbc.c @@ -0,0 +1,164 @@ +/* cbc.c + + Cipher block chaining mode. + + Copyright (C) 2001, 2011 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "cbc.h" + +#include "memxor.h" +#include "nettle-internal.h" + +void +cbc_encrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t 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); + } +} + +/* Don't allocate any more space than this on the stack */ +#define CBC_BUFFER_LIMIT 512 + +void +cbc_decrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + assert(!(length % block_size)); + + if (!length) + return; + + if (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); + } + + else + { + /* For in-place CBC, we decrypt into a temporary buffer 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, and we + depend on memxor3 working from the end of the area, allowing + certain overlapping operands. */ + + TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT); + TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + + size_t buffer_size; + + if (length <= CBC_BUFFER_LIMIT) + buffer_size = length; + else + buffer_size + = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size); + + TMP_ALLOC(buffer, buffer_size); + TMP_ALLOC(initial_iv, block_size); + + for ( ; length > buffer_size; + length -= buffer_size, src += buffer_size, dst += buffer_size) + { + f(ctx, buffer_size, buffer, src); + memcpy(initial_iv, iv, block_size); + memcpy(iv, src + buffer_size - block_size, block_size); + memxor3(dst + block_size, buffer + block_size, src, + buffer_size - block_size); + memxor3(dst, buffer, initial_iv, block_size); + } + + f(ctx, length, buffer, src); + memcpy(initial_iv, iv, block_size); + /* Copies last block */ + memcpy(iv, src + length - block_size, block_size); + /* Writes all but first block, reads all but last block. */ + memxor3(dst + block_size, buffer + block_size, src, + length - block_size); + /* Writes first block. */ + memxor3(dst, buffer, initial_iv, block_size); + } +} + +#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..93b2e73 --- /dev/null +++ b/cbc.h @@ -0,0 +1,86 @@ +/* cbc.h + + Cipher block chaining mode. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t length, uint8_t *dst, + const uint8_t *src); + +void +cbc_decrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t 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)) + +/* NOTE: Avoid using NULL, as we don't include anything defining it. */ +#define CBC_ENCRYPT(self, f, length, dst, src) \ + (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0)) \ + : cbc_encrypt((void *) &(self)->ctx, \ + (nettle_cipher_func *) (f), \ + sizeof((self)->iv), (self)->iv, \ + (length), (dst), (src))) + +#define CBC_DECRYPT(self, f, length, dst, src) \ + (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0)) \ + : cbc_decrypt((void *) &(self)->ctx, \ + (nettle_cipher_func *) (f), \ + sizeof((self)->iv), (self)->iv, \ + (length), (dst), (src))) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CBC_H_INCLUDED */ diff --git a/ccm-aes128.c b/ccm-aes128.c new file mode 100644 index 0000000..74ae51f --- /dev/null +++ b/ccm-aes128.c @@ -0,0 +1,114 @@ +/* ccm-aes128.c + + Counter with CBC-MAC mode using AES128 as the underlying cipher. + + Copyright (C) 2014 Exegin Technologies Limited + Copyright (C) 2014 Owen Kirby + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes.h" +#include "ccm.h" + +void +ccm_aes128_set_key(struct ccm_aes128_ctx *ctx, const uint8_t *key) +{ + aes128_set_encrypt_key(&ctx->cipher, key); +} + +void +ccm_aes128_set_nonce(struct ccm_aes128_ctx *ctx, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen) +{ + ccm_set_nonce(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + length, nonce, authlen, msglen, taglen); +} + +void +ccm_aes128_update(struct ccm_aes128_ctx *ctx, + size_t length, const uint8_t *data) +{ + ccm_update(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + length, data); +} + +void +ccm_aes128_encrypt(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_encrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + length, dst, src); +} + +void +ccm_aes128_decrypt(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_decrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + length, dst, src); +} + +void +ccm_aes128_digest(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *digest) +{ + ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + length, digest); +} + +void +ccm_aes128_encrypt_message(struct ccm_aes128_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src) +{ + ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + nlength, nonce, alength, adata, + tlength, clength, dst, src); +} + +int +ccm_aes128_decrypt_message(struct ccm_aes128_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src) +{ + return ccm_decrypt_message(&ctx->cipher, + (nettle_cipher_func *) aes128_encrypt, + nlength, nonce, alength, adata, + tlength, mlength, dst, src); +} diff --git a/ccm-aes192.c b/ccm-aes192.c new file mode 100644 index 0000000..6b6ebed --- /dev/null +++ b/ccm-aes192.c @@ -0,0 +1,114 @@ +/* ccm-aes192.c + + Counter with CBC-MAC mode using AES192 as the underlying cipher. + + Copyright (C) 2014 Exegin Technologies Limited + Copyright (C) 2014 Owen Kirby + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes.h" +#include "ccm.h" + + +void +ccm_aes192_set_key(struct ccm_aes192_ctx *ctx, const uint8_t *key) +{ + aes192_set_encrypt_key(&ctx->cipher, key); +} + +void +ccm_aes192_set_nonce(struct ccm_aes192_ctx *ctx, size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen) +{ + ccm_set_nonce(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + length, nonce, authlen, msglen, taglen); +} + +void +ccm_aes192_update(struct ccm_aes192_ctx *ctx, + size_t length, const uint8_t *data) +{ + ccm_update(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + length, data); +} + +void +ccm_aes192_encrypt(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_encrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + length, dst, src); +} + +void +ccm_aes192_decrypt(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_decrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + length, dst, src); +} + +void +ccm_aes192_digest(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *digest) +{ + ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + length, digest); +} + +void +ccm_aes192_encrypt_message(struct ccm_aes192_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src) +{ + ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + nlength, nonce, alength, adata, + tlength, clength, dst, src); +} + +int +ccm_aes192_decrypt_message(struct ccm_aes192_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src) +{ + return ccm_decrypt_message(&ctx->cipher, + (nettle_cipher_func *) aes192_encrypt, + nlength, nonce, alength, adata, + tlength, mlength, dst, src); +} diff --git a/ccm-aes256.c b/ccm-aes256.c new file mode 100644 index 0000000..211c411 --- /dev/null +++ b/ccm-aes256.c @@ -0,0 +1,114 @@ +/* ccm-aes256.c + + Counter with CBC-MAC mode using AES256 as the underlying cipher. + + Copyright (C) 2014 Exegin Technologies Limited + Copyright (C) 2014 Owen Kirby + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "aes.h" +#include "ccm.h" + + +void +ccm_aes256_set_key(struct ccm_aes256_ctx *ctx, const uint8_t *key) +{ + aes256_set_encrypt_key(&ctx->cipher, key); +} + +void +ccm_aes256_set_nonce(struct ccm_aes256_ctx *ctx, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen) +{ + ccm_set_nonce(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + length, nonce, authlen, msglen, taglen); +} + +void +ccm_aes256_update(struct ccm_aes256_ctx *ctx, + size_t length, const uint8_t *data) +{ + ccm_update(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + length, data); +} + +void +ccm_aes256_encrypt(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_encrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + length, dst, src); +} + +void +ccm_aes256_decrypt(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_decrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + length, dst, src); +} + +void +ccm_aes256_digest(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *digest) +{ + ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + length, digest); +} + +void +ccm_aes256_encrypt_message(struct ccm_aes256_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src) +{ + ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + nlength, nonce, alength, adata, + tlength, clength, dst, src); +} + +int +ccm_aes256_decrypt_message(struct ccm_aes256_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src) +{ + return ccm_decrypt_message(&ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + nlength, nonce, alength, adata, + tlength, mlength, dst, src); +} diff --git a/ccm.c b/ccm.c new file mode 100644 index 0000000..bdbd595 --- /dev/null +++ b/ccm.c @@ -0,0 +1,262 @@ +/* ccm.c + + Counter with CBC-MAC mode, specified by NIST, + http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + + Copyright (C) 2014 Exegin Technologies Limited + Copyright (C) 2014 Owen Kirby + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "ccm.h" +#include "ctr.h" + +#include "memops.h" +#include "nettle-internal.h" +#include "macros.h" + +/* + * The format of the CCM IV (for both CTR and CBC-MAC) is: flags | nonce | count + * flags = 1 octet + * nonce = N octets + * count >= 1 octet + * + * such that: + * sizeof(flags) + sizeof(nonce) + sizeof(count) == 1 block + */ +#define CCM_FLAG_L 0x07 +#define CCM_FLAG_M 0x38 +#define CCM_FLAG_ADATA 0x40 +#define CCM_FLAG_RESERVED 0x80 +#define CCM_FLAG_GET_L(_x_) (((_x_) & CCM_FLAG_L) + 1) +#define CCM_FLAG_SET_L(_x_) (((_x_) - 1) & CCM_FLAG_L) +#define CCM_FLAG_SET_M(_x_) ((((_x_) - 2) << 2) & CCM_FLAG_M) + +#define CCM_OFFSET_FLAGS 0 +#define CCM_OFFSET_NONCE 1 +#define CCM_L_SIZE(_nlen_) (CCM_BLOCK_SIZE - CCM_OFFSET_NONCE - (_nlen_)) + +/* + * The data input to the CBC-MAC: L(a) | adata | padding | plaintext | padding + * + * blength is the length of data that has been added to the CBC-MAC modulus the + * cipher block size. If the value of blength is non-zero then some data has + * been XOR'ed into the CBC-MAC, and we will need to pad the block (XOR with 0), + * and iterate the cipher one more time. + * + * The end of adata is detected implicitly by the first call to the encrypt() + * and decrypt() functions, and will call ccm_pad() to insert the padding if + * necessary. Because of the underlying CTR encryption, the encrypt() and + * decrypt() functions must be called with a multiple of the block size and + * therefore blength should be zero on all but the first call. + * + * Likewise, the end of the plaintext is implicitly determined by the first call + * to the digest() function, which will pad if the final CTR encryption was not + * a multiple of the block size. + */ +static void +ccm_pad(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f) +{ + if (ctx->blength) f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b); + ctx->blength = 0; +} + +static void +ccm_build_iv(uint8_t *iv, size_t noncelen, const uint8_t *nonce, + uint8_t flags, size_t count) +{ + unsigned int i; + + /* Sanity check the nonce length. */ + assert(noncelen >= CCM_MIN_NONCE_SIZE); + assert(noncelen <= CCM_MAX_NONCE_SIZE); + + /* Generate the IV */ + iv[CCM_OFFSET_FLAGS] = flags | CCM_FLAG_SET_L(CCM_L_SIZE(noncelen)); + memcpy(&iv[CCM_OFFSET_NONCE], nonce, noncelen); + for (i=(CCM_BLOCK_SIZE - 1); i >= (CCM_OFFSET_NONCE + noncelen); i--) { + iv[i] = count & 0xff; + count >>= 8; + } + + /* Ensure the count was not truncated. */ + assert(!count); +} + +void +ccm_set_nonce(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen) +{ + /* Generate the IV for the CTR and CBC-MAC */ + ctx->blength = 0; + ccm_build_iv(ctx->tag.b, length, nonce, CCM_FLAG_SET_M(taglen), msglen); + ccm_build_iv(ctx->ctr.b, length, nonce, 0, 1); + + /* If no auth data, encrypt B0 and skip L(a) */ + if (!authlen) { + f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b); + return; + } + + /* Encrypt B0 (with the adata flag), and input L(a) to the CBC-MAC. */ + ctx->tag.b[CCM_OFFSET_FLAGS] |= CCM_FLAG_ADATA; + f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b); +#if SIZEOF_SIZE_T > 4 + if (authlen >= (0x01ULL << 32)) { + /* Encode L(a) as 0xff || 0xff || <64-bit integer> */ + ctx->tag.b[ctx->blength++] ^= 0xff; + ctx->tag.b[ctx->blength++] ^= 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 56) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 48) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 40) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 32) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 24) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 16) & 0xff; + } + else +#endif + if (authlen >= ((0x1ULL << 16) - (0x1ULL << 8))) { + /* Encode L(a) as 0xff || 0xfe || <32-bit integer> */ + ctx->tag.b[ctx->blength++] ^= 0xff; + ctx->tag.b[ctx->blength++] ^= 0xfe; + ctx->tag.b[ctx->blength++] ^= (authlen >> 24) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 16) & 0xff; + } + ctx->tag.b[ctx->blength++] ^= (authlen >> 8) & 0xff; + ctx->tag.b[ctx->blength++] ^= (authlen >> 0) & 0xff; +} + +void +ccm_update(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *data) +{ + const uint8_t *end = data + length; + + /* If we don't have enough to fill a block, save the data for later. */ + if ((ctx->blength + length) < CCM_BLOCK_SIZE) { + memxor(&ctx->tag.b[ctx->blength], data, length); + ctx->blength += length; + return; + } + + /* Process a partially filled block. */ + if (ctx->blength) { + memxor(&ctx->tag.b[ctx->blength], data, CCM_BLOCK_SIZE - ctx->blength); + data += (CCM_BLOCK_SIZE - ctx->blength); + f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b); + } + + /* Process full blocks. */ + while ((data + CCM_BLOCK_SIZE) < end) { + memxor(ctx->tag.b, data, CCM_BLOCK_SIZE); + f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b); + data += CCM_BLOCK_SIZE; + } /* while */ + + /* Save leftovers for later. */ + ctx->blength = (end - data); + if (ctx->blength) memxor(&ctx->tag.b, data, ctx->blength); +} + +/* + * Because of the underlying CTR mode encryption, when called multiple times + * the data in intermediate calls must be provided in multiples of the block + * size. + */ +void +ccm_encrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ccm_pad(ctx, cipher, f); + ccm_update(ctx, cipher, f, length, src); + ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src); +} + +/* + * Because of the underlying CTR mode decryption, when called multiple times + * the data in intermediate calls must be provided in multiples of the block + * size. + */ +void +ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src); + ccm_pad(ctx, cipher, f); + ccm_update(ctx, cipher, f, length, dst); +} + +void +ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest) +{ + int i = CCM_BLOCK_SIZE - CCM_FLAG_GET_L(ctx->ctr.b[CCM_OFFSET_FLAGS]); + assert(length <= CCM_BLOCK_SIZE); + while (i < CCM_BLOCK_SIZE) ctx->ctr.b[i++] = 0; + ccm_pad(ctx, cipher, f); + ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, digest, ctx->tag.b); +} + +void +ccm_encrypt_message(const void *cipher, nettle_cipher_func *f, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src) +{ + struct ccm_ctx ctx; + uint8_t *tag = dst + (clength-tlength); + assert(clength >= tlength); + ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, clength-tlength, tlength); + ccm_update(&ctx, cipher, f, alength, adata); + ccm_encrypt(&ctx, cipher, f, clength-tlength, dst, src); + ccm_digest(&ctx, cipher, f, tlength, tag); +} + +int +ccm_decrypt_message(const void *cipher, nettle_cipher_func *f, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src) +{ + struct ccm_ctx ctx; + uint8_t tag[CCM_BLOCK_SIZE]; + ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, mlength, tlength); + ccm_update(&ctx, cipher, f, alength, adata); + ccm_decrypt(&ctx, cipher, f, mlength, dst, src); + ccm_digest(&ctx, cipher, f, tlength, tag); + return memeql_sec(tag, src + mlength, tlength); +} diff --git a/ccm.h b/ccm.h new file mode 100644 index 0000000..0a742a5 --- /dev/null +++ b/ccm.h @@ -0,0 +1,302 @@ +/* ccm.h + + Counter with CBC-MAC mode, specified by NIST, + http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + + Copyright (C) 2014 Exegin Technologies Limited + Copyright (C) 2014 Owen Kirby + + Contributed to GNU Nettle by Owen Kirby + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* NIST SP800-38C doesn't specify the particular formatting and + * counter generation algorithm for CCM, but it does include an + * example algorithm. This example has become the de-factor standard, + * and has been adopted by both the IETF and IEEE across a wide + * variety of protocols. + */ + +#ifndef NETTLE_CCM_H_INCLUDED +#define NETTLE_CCM_H_INCLUDED + +#include "aes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define ccm_set_nonce nettle_ccm_set_nonce +#define ccm_update nettle_ccm_update +#define ccm_encrypt nettle_ccm_encrypt +#define ccm_decrypt nettle_ccm_decrypt +#define ccm_digest nettle_ccm_digest +#define ccm_encrypt_message nettle_ccm_encrypt_message +#define ccm_decrypt_message nettle_ccm_decrypt_message + +#define ccm_aes128_set_key nettle_ccm_aes128_set_key +#define ccm_aes128_set_nonce nettle_ccm_aes128_set_nonce +#define ccm_aes128_update nettle_ccm_aes128_update +#define ccm_aes128_encrypt nettle_ccm_aes128_encrypt +#define ccm_aes128_decrypt nettle_ccm_aes128_decrypt +#define ccm_aes128_digest nettle_ccm_aes128_digest +#define ccm_aes128_encrypt_message nettle_ccm_aes128_encrypt_message +#define ccm_aes128_decrypt_message nettle_ccm_aes128_decrypt_message + +#define ccm_aes192_set_key nettle_ccm_aes192_set_key +#define ccm_aes192_set_nonce nettle_ccm_aes192_set_nonce +#define ccm_aes192_update nettle_ccm_aes192_update +#define ccm_aes192_encrypt nettle_ccm_aes192_encrypt +#define ccm_aes192_decrypt nettle_ccm_aes192_decrypt +#define ccm_aes192_digest nettle_ccm_aes192_digest +#define ccm_aes192_encrypt_message nettle_ccm_aes192_encrypt_message +#define ccm_aes192_decrypt_message nettle_ccm_aes192_decrypt_message + +#define ccm_aes256_set_key nettle_ccm_aes256_set_key +#define ccm_aes256_set_nonce nettle_ccm_aes256_set_nonce +#define ccm_aes256_update nettle_ccm_aes256_update +#define ccm_aes256_encrypt nettle_ccm_aes256_encrypt +#define ccm_aes256_decrypt nettle_ccm_aes256_decrypt +#define ccm_aes256_digest nettle_ccm_aes256_digest +#define ccm_aes256_encrypt_message nettle_ccm_aes256_encrypt_message +#define ccm_aes256_decrypt_message nettle_ccm_aes256_decrypt_message + +/* For CCM, the block size of the block cipher shall be 128 bits. */ +#define CCM_BLOCK_SIZE 16 +#define CCM_DIGEST_SIZE 16 +#define CCM_MIN_NONCE_SIZE 7 +#define CCM_MAX_NONCE_SIZE 14 + +/* Maximum cleartext message size, as a function of the nonce size N. + The length field is L octets, with L = 15 - N, and then the maximum + size M = 2^{8L} - 1. */ +#define CCM_MAX_MSG_SIZE(N) \ + ((sizeof(size_t) + (N) <= 15) \ + ? ~(size_t) 0 \ + : ((size_t) 1 << (8*(15 - N))) - 1) + +/* Per-message state */ +struct ccm_ctx { + union nettle_block16 ctr; /* Counter for CTR encryption. */ + union nettle_block16 tag; /* CBC-MAC message tag. */ + /* Length of data processed by the CBC-MAC modulus the block size */ + unsigned int blength; +}; + +/* + * CCM mode requires the adata and message lengths when building the IV, which + * prevents streaming processing and it incompatible with the AEAD API. + */ +void +ccm_set_nonce(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t noncelen, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen); + +void +ccm_update(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *data); + +void +ccm_encrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest); + +/* + * All-in-one encryption and decryption API: + * tlength = sizeof(digest) + * mlength = sizeof(cleartext) + * clength = sizeof(ciphertext) = mlength + tlength + * + * The ciphertext will contain the encrypted payload with the message digest + * appended to the end. + */ +void +ccm_encrypt_message(const void *cipher, nettle_cipher_func *f, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src); + +/* + * The decryption function will write the plaintext to dst and parse the digest + * from the final tlength bytes of the ciphertext. If the digest matched the + * value computed during decryption then this will return 1, or it will return + * 0 if the digest was invalid. + */ +int +ccm_decrypt_message(const void *cipher, nettle_cipher_func *f, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src); + +/* CCM Mode with AES-128 */ +struct ccm_aes128_ctx { + struct ccm_ctx ccm; + struct aes128_ctx cipher; +}; + +void +ccm_aes128_set_key(struct ccm_aes128_ctx *ctx, const uint8_t *key); + +void +ccm_aes128_set_nonce(struct ccm_aes128_ctx *ctx, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen); + +void +ccm_aes128_update (struct ccm_aes128_ctx *ctx, + size_t length, const uint8_t *data); + +void +ccm_aes128_encrypt(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes128_decrypt(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes128_digest(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *digest); + +void +ccm_aes128_encrypt_message(struct ccm_aes128_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src); + +int +ccm_aes128_decrypt_message(struct ccm_aes128_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src); + +struct ccm_aes192_ctx { + struct ccm_ctx ccm; + struct aes192_ctx cipher; +}; + +/* CCM Mode with AES-192 */ +void +ccm_aes192_set_key(struct ccm_aes192_ctx *ctx, const uint8_t *key); + +void +ccm_aes192_set_nonce(struct ccm_aes192_ctx *ctx, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen); + +void +ccm_aes192_update(struct ccm_aes192_ctx *ctx, + size_t length, const uint8_t *data); + +void +ccm_aes192_encrypt(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes192_decrypt(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes192_digest(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *digest); + +void +ccm_aes192_encrypt_message(struct ccm_aes192_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src); + +int +ccm_aes192_decrypt_message(struct ccm_aes192_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src); + +/* CCM Mode with AES-256 */ +struct ccm_aes256_ctx { + struct ccm_ctx ccm; + struct aes256_ctx cipher; +}; + +void +ccm_aes256_set_key(struct ccm_aes256_ctx *ctx, const uint8_t *key); + +void +ccm_aes256_set_nonce(struct ccm_aes256_ctx *ctx, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen); + +void +ccm_aes256_update(struct ccm_aes256_ctx *ctx, + size_t length, const uint8_t *data); + +void +ccm_aes256_encrypt(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes256_decrypt(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes256_digest(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *digest); + +void +ccm_aes256_encrypt_message(struct ccm_aes256_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t clength, uint8_t *dst, const uint8_t *src); + +int +ccm_aes256_decrypt_message(struct ccm_aes256_ctx *ctx, + size_t nlength, const uint8_t *nonce, + size_t alength, const uint8_t *adata, + size_t tlength, + size_t mlength, uint8_t *dst, const uint8_t *src); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CCM_H_INCLUDED */ diff --git a/cfb.c b/cfb.c new file mode 100644 index 0000000..82cf18f --- /dev/null +++ b/cfb.c @@ -0,0 +1,165 @@ +/* cfb.c + + Cipher feedback mode. + + Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov + Copyright (C) 2001, 2011 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "cfb.h" + +#include "memxor.h" +#include "nettle-internal.h" + +void +cfb_encrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + uint8_t *p; + TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + + TMP_ALLOC(buffer, block_size); + + if (src != dst) + { + for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size) + { + f(ctx, block_size, dst, p); + memxor(dst, src, block_size); + } + } + else + { + for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size) + { + f(ctx, block_size, buffer, p); + memxor(dst, buffer, block_size); + } + } + + if (p != iv) + memcpy(iv, p, block_size); + + if (length) + { + f(ctx, block_size, buffer, iv); + memxor3(dst, buffer, src, length); + /* We do not care about updating IV here. This is the last call in + * message sequence and one has to set IV afterwards anyway */ + } +} + +/* Don't allocate any more space than this on the stack */ +#define CFB_BUFFER_LIMIT 512 + +void +cfb_decrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + if (src != dst) + { + size_t left = length % block_size; + + length -= left; + if (length > 0) + { + /* Decrypt in ECB mode */ + f(ctx, block_size, dst, iv); + f(ctx, length - block_size, dst + block_size, src); + memcpy(iv, src + length - block_size, block_size); + memxor(dst, src, length); + } + + if (left > 0) + { + TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + TMP_ALLOC(buffer, block_size); + + f(ctx, block_size, buffer, iv); + memxor3(dst + length, src + length, buffer, left); + } + } + else + { + /* For in-place CFB, we decrypt into a temporary buffer of size + * at most CFB_BUFFER_LIMIT, and process that amount of data at + * a time. */ + + /* NOTE: We assume that block_size <= CFB_BUFFER_LIMIT */ + + TMP_DECL(buffer, uint8_t, CFB_BUFFER_LIMIT); + TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + + size_t buffer_size; + size_t left; + + buffer_size = CFB_BUFFER_LIMIT - (CFB_BUFFER_LIMIT % block_size); + + TMP_ALLOC(buffer, buffer_size); + TMP_ALLOC(initial_iv, block_size); + + left = length % block_size; + length -= left; + + while (length > 0) + { + size_t part = length > buffer_size ? buffer_size : length; + + /* length is greater that zero and is divided by block_size, so it is + * not less than block_size. So does part */ + + f(ctx, block_size, buffer, iv); + f(ctx, part - block_size, buffer + block_size, src); + memcpy(iv, src + part - block_size, block_size); + memxor(dst, buffer, part); + + length -= part; + src += part; + dst += part; + } + + if (left > 0) + { + f(ctx, block_size, buffer, iv); + memxor(dst, buffer, left); + } + } +} diff --git a/cfb.h b/cfb.h new file mode 100644 index 0000000..16660df --- /dev/null +++ b/cfb.h @@ -0,0 +1,87 @@ +/* cfb.h + + Cipher feedback mode. + + Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_CFB_H_INCLUDED +#define NETTLE_CFB_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define cfb_encrypt nettle_cfb_encrypt +#define cfb_decrypt nettle_cfb_decrypt + +void +cfb_encrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t length, uint8_t *dst, + const uint8_t *src); + +void +cfb_decrypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *iv, + size_t length, uint8_t *dst, + const uint8_t *src); + +#define CFB_CTX(type, size) \ +{ type ctx; uint8_t iv[size]; } + +#define CFB_SET_IV(ctx, data) \ +memcpy((ctx)->iv, (data), sizeof((ctx)->iv)) + +/* NOTE: Avoid using NULL, as we don't include anything defining it. */ +#define CFB_ENCRYPT(self, f, length, dst, src) \ + (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0)) \ + : cfb_encrypt((void *) &(self)->ctx, \ + (nettle_cipher_func *) (f), \ + sizeof((self)->iv), (self)->iv, \ + (length), (dst), (src))) + +#define CFB_DECRYPT(self, f, length, dst, src) \ + (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0)) \ + : cfb_decrypt((void *) &(self)->ctx, \ + (nettle_cipher_func *) (f), \ + sizeof((self)->iv), (self)->iv, \ + (length), (dst), (src))) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CFB_H_INCLUDED */ diff --git a/chacha-core-internal.c b/chacha-core-internal.c new file mode 100644 index 0000000..48545ae --- /dev/null +++ b/chacha-core-internal.c @@ -0,0 +1,127 @@ +/* chacha-core-internal.c + + Core functionality of the ChaCha stream cipher. + Heavily based on the Salsa20 implementation in Nettle. + + Copyright (C) 2013 Joachim Strömbergson + Copyright (C) 2012 Simon Josefsson, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Based on: + chacha-ref.c version 2008.01.20. + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "chacha.h" + +#include "macros.h" + +#ifndef CHACHA_DEBUG +# define CHACHA_DEBUG 0 +#endif + +#if CHACHA_DEBUG +# include +# define DEBUG(i) do { \ + unsigned debug_j; \ + for (debug_j = 0; debug_j < 16; debug_j++) \ + { \ + if (debug_j == 0) \ + fprintf(stderr, "%2d:", (i)); \ + else if (debug_j % 4 == 0) \ + fprintf(stderr, "\n "); \ + fprintf(stderr, " %8x", x[debug_j]); \ + } \ + fprintf(stderr, "\n"); \ + } while (0) +#else +# define DEBUG(i) +#endif + +#ifdef WORDS_BIGENDIAN +#define LE_SWAP32(v) \ + ((ROTL32(8, v) & 0x00FF00FFUL) | \ + (ROTL32(24, v) & 0xFF00FF00UL)) +#else +#define LE_SWAP32(v) (v) +#endif + +#define QROUND(x0, x1, x2, x3) do { \ + x0 = x0 + x1; x3 = ROTL32(16, (x0 ^ x3)); \ + x2 = x2 + x3; x1 = ROTL32(12, (x1 ^ x2)); \ + x0 = x0 + x1; x3 = ROTL32(8, (x0 ^ x3)); \ + x2 = x2 + x3; x1 = ROTL32(7, (x1 ^ x2)); \ + } while(0) + +void +_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds) +{ + uint32_t x[_CHACHA_STATE_LENGTH]; + unsigned i; + + assert ( (rounds & 1) == 0); + + memcpy (x, src, sizeof(x)); + for (i = 0; i < rounds;i += 2) + { + DEBUG (i); + QROUND(x[0], x[4], x[8], x[12]); + QROUND(x[1], x[5], x[9], x[13]); + QROUND(x[2], x[6], x[10], x[14]); + QROUND(x[3], x[7], x[11], x[15]); + + DEBUG (i+1); + QROUND(x[0], x[5], x[10], x[15]); + QROUND(x[1], x[6], x[11], x[12]); + QROUND(x[2], x[7], x[8], x[13]); + QROUND(x[3], x[4], x[9], x[14]); + } + DEBUG (i); + + for (i = 0; i < _CHACHA_STATE_LENGTH; i++) + { + uint32_t t = x[i] + src[i]; + dst[i] = LE_SWAP32 (t); + } +} + + + + + + + diff --git a/chacha-crypt.c b/chacha-crypt.c new file mode 100644 index 0000000..ed1bb57 --- /dev/null +++ b/chacha-crypt.c @@ -0,0 +1,86 @@ +/* chacha-crypt.c + + The crypt function in the ChaCha stream cipher. + Heavily based on the Salsa20 implementation in Nettle. + + Copyright (C) 2014 Niels Möller + Copyright (C) 2013 Joachim Strömbergson + Copyright (C) 2012 Simon Josefsson + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Based on: + chacha-ref.c version 2008.01.20. + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "chacha.h" + +#include "macros.h" +#include "memxor.h" + +#define CHACHA_ROUNDS 20 + +void +chacha_crypt(struct chacha_ctx *ctx, + size_t length, + uint8_t *c, + const uint8_t *m) +{ + if (!length) + return; + + for (;;) + { + uint32_t x[_CHACHA_STATE_LENGTH]; + + _chacha_core (x, ctx->state, CHACHA_ROUNDS); + + ctx->state[13] += (++ctx->state[12] == 0); + + /* stopping at 2^70 length per nonce is user's responsibility */ + + if (length <= CHACHA_BLOCK_SIZE) + { + memxor3 (c, m, x, length); + return; + } + memxor3 (c, m, x, CHACHA_BLOCK_SIZE); + + length -= CHACHA_BLOCK_SIZE; + c += CHACHA_BLOCK_SIZE; + m += CHACHA_BLOCK_SIZE; + } +} diff --git a/chacha-poly1305-meta.c b/chacha-poly1305-meta.c new file mode 100644 index 0000000..3bcb631 --- /dev/null +++ b/chacha-poly1305-meta.c @@ -0,0 +1,53 @@ +/* chacha-poly1305-meta.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "chacha-poly1305.h" + +const struct nettle_aead nettle_chacha_poly1305 = + { "chacha_poly1305", sizeof(struct chacha_poly1305_ctx), + CHACHA_POLY1305_BLOCK_SIZE, CHACHA_POLY1305_KEY_SIZE, + CHACHA_POLY1305_NONCE_SIZE, CHACHA_POLY1305_DIGEST_SIZE, + (nettle_set_key_func *) chacha_poly1305_set_key, + (nettle_set_key_func *) chacha_poly1305_set_key, + (nettle_set_key_func *) chacha_poly1305_set_nonce, + (nettle_hash_update_func *) chacha_poly1305_update, + (nettle_crypt_func *) chacha_poly1305_encrypt, + (nettle_crypt_func *) chacha_poly1305_decrypt, + (nettle_hash_digest_func *) chacha_poly1305_digest, + }; diff --git a/chacha-poly1305.c b/chacha-poly1305.c new file mode 100644 index 0000000..c5109b8 --- /dev/null +++ b/chacha-poly1305.c @@ -0,0 +1,166 @@ +/* chacha-poly1305.c + + AEAD mechanism based on chacha and poly1305. + + Copyright (C) 2014, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* This implements chacha-poly1305 according to + draft-irtf-cfrg-chacha20-poly1305-08. The inputs to poly1305 are: + + associated data + zero padding + ciphertext + zero padding + length of associated data (64-bit, little endian) + length of ciphertext (64-bit, little endian) + + where the padding fields are 0-15 zero bytes, filling up to a + 16-byte boundary. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "chacha-poly1305.h" + +#include "macros.h" + +#define CHACHA_ROUNDS 20 + +/* FIXME: Also set nonce to zero, and implement nonce + auto-increment? */ +void +chacha_poly1305_set_key (struct chacha_poly1305_ctx *ctx, + const uint8_t *key) +{ + chacha_set_key (&ctx->chacha, key); +} + +void +chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx, + const uint8_t *nonce) +{ + union { + uint32_t x[_CHACHA_STATE_LENGTH]; + uint8_t subkey[32]; + } u; + + chacha_set_nonce96 (&ctx->chacha, nonce); + /* Generate authentication key */ + _chacha_core (u.x, ctx->chacha.state, CHACHA_ROUNDS); + poly1305_set_key (&ctx->poly1305, u.subkey); + /* For final poly1305 processing */ + memcpy (ctx->s.b, u.subkey + 16, 16); + /* Increment block count */ + ctx->chacha.state[12] = 1; + + ctx->auth_size = ctx->data_size = ctx->index = 0; +} + +/* FIXME: Duplicated in poly1305-aes128.c */ +#define COMPRESS(ctx, data) _poly1305_block(&(ctx)->poly1305, (data), 1) + +static void +poly1305_update (struct chacha_poly1305_ctx *ctx, + size_t length, const uint8_t *data) +{ + MD_UPDATE (ctx, length, data, COMPRESS, (void) 0); +} + +static void +poly1305_pad (struct chacha_poly1305_ctx *ctx) +{ + if (ctx->index) + { + memset (ctx->block + ctx->index, 0, + POLY1305_BLOCK_SIZE - ctx->index); + _poly1305_block(&ctx->poly1305, ctx->block, 1); + ctx->index = 0; + } +} +void +chacha_poly1305_update (struct chacha_poly1305_ctx *ctx, + size_t length, const uint8_t *data) +{ + assert (ctx->data_size == 0); + poly1305_update (ctx, length, data); + ctx->auth_size += length; +} + + +void +chacha_poly1305_encrypt (struct chacha_poly1305_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + if (!length) + return; + + assert (ctx->data_size % CHACHA_POLY1305_BLOCK_SIZE == 0); + poly1305_pad (ctx); + + chacha_crypt (&ctx->chacha, length, dst, src); + poly1305_update (ctx, length, dst); + ctx->data_size += length; +} + +void +chacha_poly1305_decrypt (struct chacha_poly1305_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + if (!length) + return; + + assert (ctx->data_size % CHACHA_POLY1305_BLOCK_SIZE == 0); + poly1305_pad (ctx); + + poly1305_update (ctx, length, src); + chacha_crypt (&ctx->chacha, length, dst, src); + ctx->data_size += length; +} + +void +chacha_poly1305_digest (struct chacha_poly1305_ctx *ctx, + size_t length, uint8_t *digest) +{ + uint8_t buf[16]; + + poly1305_pad (ctx); + LE_WRITE_UINT64 (buf, ctx->auth_size); + LE_WRITE_UINT64 (buf + 8, ctx->data_size); + + _poly1305_block (&ctx->poly1305, buf, 1); + + poly1305_digest (&ctx->poly1305, &ctx->s); + memcpy (digest, &ctx->s.b, length); +} diff --git a/chacha-poly1305.h b/chacha-poly1305.h new file mode 100644 index 0000000..ce40b77 --- /dev/null +++ b/chacha-poly1305.h @@ -0,0 +1,98 @@ +/* chacha-poly1305.h + + AEAD mechanism based on chacha and poly1305. + See draft-agl-tls-chacha20poly1305-04. + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_CHACHA_POLY1305_H_INCLUDED +#define NETTLE_CHACHA_POLY1305_H_INCLUDED + +#include "chacha.h" +#include "poly1305.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define chacha_poly1305_set_key nettle_chacha_poly1305_set_key +#define chacha_poly1305_set_nonce nettle_chacha_poly1305_set_nonce +#define chacha_poly1305_update nettle_chacha_poly1305_update +#define chacha_poly1305_decrypt nettle_chacha_poly1305_decrypt +#define chacha_poly1305_encrypt nettle_chacha_poly1305_encrypt +#define chacha_poly1305_digest nettle_chacha_poly1305_digest + +#define CHACHA_POLY1305_BLOCK_SIZE 64 +/* FIXME: Any need for 128-bit variant? */ +#define CHACHA_POLY1305_KEY_SIZE 32 +#define CHACHA_POLY1305_NONCE_SIZE CHACHA_NONCE96_SIZE +#define CHACHA_POLY1305_DIGEST_SIZE 16 + +struct chacha_poly1305_ctx +{ + struct chacha_ctx chacha; + struct poly1305_ctx poly1305; + union nettle_block16 s; + uint64_t auth_size; + uint64_t data_size; + /* poly1305 block */ + uint8_t block[POLY1305_BLOCK_SIZE]; + unsigned index; +}; + +void +chacha_poly1305_set_key (struct chacha_poly1305_ctx *ctx, + const uint8_t *key); +void +chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx, + const uint8_t *nonce); + +void +chacha_poly1305_update (struct chacha_poly1305_ctx *ctx, + size_t length, const uint8_t *data); + +void +chacha_poly1305_encrypt (struct chacha_poly1305_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +chacha_poly1305_decrypt (struct chacha_poly1305_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +chacha_poly1305_digest (struct chacha_poly1305_ctx *ctx, + size_t length, uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CHACHA_POLY1305_H_INCLUDED */ diff --git a/chacha-set-key.c b/chacha-set-key.c new file mode 100644 index 0000000..63bfafa --- /dev/null +++ b/chacha-set-key.c @@ -0,0 +1,61 @@ +/* chacha-set-key.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "chacha.h" + +#include "macros.h" + +void +chacha_set_key(struct chacha_ctx *ctx, const uint8_t *key) +{ + static const uint32_t sigma[4] = { + /* "expand 32-byte k" */ + 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + }; + ctx->state[4] = LE_READ_UINT32(key + 0); + ctx->state[5] = LE_READ_UINT32(key + 4); + ctx->state[6] = LE_READ_UINT32(key + 8); + ctx->state[7] = LE_READ_UINT32(key + 12); + + ctx->state[8] = LE_READ_UINT32(key + 16); + ctx->state[9] = LE_READ_UINT32(key + 20); + ctx->state[10] = LE_READ_UINT32(key + 24); + ctx->state[11] = LE_READ_UINT32(key + 28); + + memcpy (ctx->state, sigma, sizeof(sigma)); +} diff --git a/chacha-set-nonce.c b/chacha-set-nonce.c new file mode 100644 index 0000000..607f176 --- /dev/null +++ b/chacha-set-nonce.c @@ -0,0 +1,70 @@ +/* chacha-set-nonce.c + + Setting the nonce the ChaCha stream cipher. + Based on the Salsa20 implementation in Nettle. + + Copyright (C) 2013 Joachim Strömbergon + Copyright (C) 2012 Simon Josefsson + Copyright (C) 2012, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Based on: + ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference + implementation dated 2008.01.20 + D. J. Bernstein + Public domain. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "chacha.h" + +#include "macros.h" + +void +chacha_set_nonce(struct chacha_ctx *ctx, const uint8_t *nonce) +{ + ctx->state[12] = 0; + ctx->state[13] = 0; + ctx->state[14] = LE_READ_UINT32(nonce + 0); + ctx->state[15] = LE_READ_UINT32(nonce + 4); +} + +void +chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce) +{ + ctx->state[12] = 0; + ctx->state[13] = LE_READ_UINT32(nonce + 0); + ctx->state[14] = LE_READ_UINT32(nonce + 4); + ctx->state[15] = LE_READ_UINT32(nonce + 8); +} diff --git a/chacha.h b/chacha.h new file mode 100644 index 0000000..3f08283 --- /dev/null +++ b/chacha.h @@ -0,0 +1,96 @@ +/* chacha.h + + The ChaCha stream cipher. + + Copyright (C) 2013 Joachim Strömbergson + Copyright (C) 2012 Simon Josefsson + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_CHACHA_H_INCLUDED +#define NETTLE_CHACHA_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define chacha_set_key nettle_chacha_set_key +#define chacha_set_nonce nettle_chacha_set_nonce +#define chacha_set_nonce96 nettle_chacha_set_nonce96 +#define chacha_crypt nettle_chacha_crypt +#define _chacha_core _nettle_chacha_core + +/* Currently, only 256-bit keys are supported. */ +#define CHACHA_KEY_SIZE 32 +#define CHACHA_BLOCK_SIZE 64 +#define CHACHA_NONCE_SIZE 8 +#define CHACHA_NONCE96_SIZE 12 + +#define _CHACHA_STATE_LENGTH 16 + +struct chacha_ctx +{ + /* Indices 0-3 holds a constant (SIGMA or TAU). + Indices 4-11 holds the key. + Indices 12-13 holds the block counter. + Indices 14-15 holds the IV: + + This creates the state matrix: + C C C C + K K K K + K K K K + B B I I + */ + uint32_t state[_CHACHA_STATE_LENGTH]; +}; + +void +chacha_set_key(struct chacha_ctx *ctx, const uint8_t *key); + +void +chacha_set_nonce(struct chacha_ctx *ctx, const uint8_t *nonce); + +void +chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce); + +void +chacha_crypt(struct chacha_ctx *ctx, size_t length, + uint8_t *dst, const uint8_t *src); + +void +_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CHACHA_H_INCLUDED */ diff --git a/cnd-copy.c b/cnd-copy.c new file mode 100644 index 0000000..d24da3d --- /dev/null +++ b/cnd-copy.c @@ -0,0 +1,51 @@ +/* cnd-copy.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc-internal.h" + +void +cnd_copy (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n) +{ + mp_limb_t mask, keep; + mp_size_t i; + + mask = -(mp_limb_t) (cnd !=0); + keep = ~mask; + + for (i = 0; i < n; i++) + rp[i] = (rp[i] & keep) + (ap[i] & mask); +} diff --git a/cnd-memcpy.c b/cnd-memcpy.c new file mode 100644 index 0000000..4aaee78 --- /dev/null +++ b/cnd-memcpy.c @@ -0,0 +1,55 @@ +/* cnd-memcpy.c + + Copyright (C) 2018 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "memops.h" + +void +cnd_memcpy(int cnd, volatile void *dst, const volatile void *src, size_t n) +{ + const volatile unsigned char *sp = src; + volatile unsigned char *dp = dst; + volatile unsigned char c; + volatile unsigned char m; + size_t i; + + m = -(unsigned char) cnd; + + for (i = 0; i < n; i++) + { + c = (sp[i] & m); + c |= (dp[i] & ~m); + dp[i] = c; + } +} diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..4438cd7 --- /dev/null +++ b/config.guess @@ -0,0 +1,1568 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-01-01' + +# 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 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +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 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + +# 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 tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #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 + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +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\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < 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..d78e543 --- /dev/null +++ b/config.h.in @@ -0,0 +1,251 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* 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 clock_gettime is available */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_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 `getline' function. */ +#undef HAVE_GETLINE + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have dlopen (with -ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the `gmp' library (-lgmp). */ +#undef HAVE_LIBGMP + +/* Define if compiler and linker supports __attribute__ ifunc */ +#undef HAVE_LINK_IFUNC + +/* 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 each of the following for which a native (ie. CPU specific) + implementation of the corresponding routine exists. */ +#undef HAVE_NATIVE_ecc_192_modp +#undef HAVE_NATIVE_ecc_192_redc +#undef HAVE_NATIVE_ecc_224_modp +#undef HAVE_NATIVE_ecc_224_redc +#undef HAVE_NATIVE_ecc_25519_modp +#undef HAVE_NATIVE_ecc_256_modp +#undef HAVE_NATIVE_ecc_256_redc +#undef HAVE_NATIVE_ecc_384_modp +#undef HAVE_NATIVE_ecc_384_redc +#undef HAVE_NATIVE_ecc_521_modp +#undef HAVE_NATIVE_ecc_521_redc +#undef HAVE_NATIVE_gcm_hash8 +#undef HAVE_NATIVE_salsa20_core +#undef HAVE_NATIVE_sha1_compress +#undef HAVE_NATIVE_sha256_compress +#undef HAVE_NATIVE_sha512_compress +#undef HAVE_NATIVE_sha3_permute +#undef HAVE_NATIVE_umac_nh +#undef HAVE_NATIVE_umac_nh_n + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_ECDSA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_EVP_H + +/* Define to 1 if you have the `secure_getenv' function. */ +#undef HAVE_SECURE_GETENV + +/* 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 `strerror' function. */ +#undef HAVE_STRERROR + +/* 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 1 if you have the header file. */ +#undef HAVE_VALGRIND_MEMCHECK_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 home page for this package. */ +#undef PACKAGE_URL + +/* 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 `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* 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 WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 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 +# else +/* Needed for alloca on windows, also with gcc */ +# if HAVE_MALLOC_H +# include +# endif +# endif +#endif + + +#if HAVE_STRERROR +#define STRERROR strerror +#else +#define STRERROR(x) (sys_errlist[x]) +#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 + + +#if defined(__x86_64__) || defined(__arch64__) +# define HAVE_NATIVE_64_BIT 1 +#else +/* Needs include of before use. */ +# define HAVE_NATIVE_64_BIT (SIZEOF_LONG * CHAR_BIT >= 64) +#endif + diff --git a/config.m4.in b/config.m4.in new file mode 100644 index 0000000..e39c880 --- /dev/null +++ b/config.m4.in @@ -0,0 +1,12 @@ +define(, <<@srcdir@>>)dnl +define(, <@ASM_SYMBOL_PREFIX@><$1>)dnl +define(, <@ASM_ELF_STYLE@>)dnl +define(, <@ASM_COFF_STYLE@>)dnl +define(, <@ASM_TYPE_FUNCTION@>)dnl +define(, <@ASM_TYPE_PROGBITS@>)dnl +define(, <@ASM_ALIGN_LOG@>)dnl +define(, <@W64_ABI@>)dnl +define(, <@ASM_RODATA@>)dnl +divert(1) +@ASM_MARK_NOEXEC_STACK@ +divert diff --git a/config.make.in b/config.make.in new file mode 100644 index 0000000..af2068c --- /dev/null +++ b/config.make.in @@ -0,0 +1,100 @@ +# Makefile settings shared between Makefiles. + +CC = @CC@ +CXX = @CXX@ +CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ +CCPIC = @CCPIC@ +CPPFLAGS = @CPPFLAGS@ +DEFS = @DEFS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +LIBOBJS = @LIBOBJS@ +EMULATOR = @EMULATOR@ +NM = @NM@ + +OBJEXT = @OBJEXT@ +EXEEXT = @EXEEXT@ + +CC_FOR_BUILD = @CC_FOR_BUILD@ +EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ + +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@ + +LIBNETTLE_MAJOR = @LIBNETTLE_MAJOR@ +LIBNETTLE_MINOR = @LIBNETTLE_MINOR@ +LIBNETTLE_SONAME = @LIBNETTLE_SONAME@ +LIBNETTLE_FILE = @LIBNETTLE_FILE@ +LIBNETTLE_FILE_SRC = @LIBNETTLE_FILE_SRC@ +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_FILE_SRC = @LIBHOGWEED_FILE_SRC@ +LIBHOGWEED_FORLINK = @LIBHOGWEED_FORLINK@ +LIBHOGWEED_LIBS = @LIBHOGWEED_LIBS@ +LIBHOGWEED_LINK = @LIBHOGWEED_LINK@ + +NUMB_BITS = @NUMB_BITS@ + +AR = @AR@ +ARFLAGS = cru +AUTOCONF = autoconf +AUTOHEADER = autoheader +M4 = @M4@ +MAKEINFO = makeinfo +RANLIB = @RANLIB@ +LN_S = @LN_S@ + +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. While EXTRA_CFLAGS are added at the end. + +COMPILE = $(CC) $(PRE_CPPFLAGS) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(DEP_FLAGS) +COMPILE_CXX = $(CXX) $(PRE_CPPFLAGS) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(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) .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..092cff0 --- /dev/null +++ b/config.sub @@ -0,0 +1,1793 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-01-01' + +# 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 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -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 \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ + | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or1k-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..2a64cd8 --- /dev/null +++ b/configure @@ -0,0 +1,9591 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for nettle 3.4.1. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: nettle-bugs@lists.lysator.liu.se about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# 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'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='nettle' +PACKAGE_TARNAME='nettle' +PACKAGE_VERSION='3.4.1' +PACKAGE_STRING='nettle 3.4.1' +PACKAGE_BUGREPORT='nettle-bugs@lists.lysator.liu.se' +PACKAGE_URL='' + +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='LTLIBOBJS +LIBOBJS +BENCH_LIBS +OPENSSL_LIBFLAGS +IF_MINI_GMP +IF_DLL +IF_DOCUMENTATION +IF_DLOPEN_TEST +IF_NOT_SHARED +IF_SHARED +IF_STATIC +IF_HOGWEED +MAKEINFO +M4 +LIBHOGWEED_LIBS +LIBHOGWEED_LINK +LIBHOGWEED_FILE_SRC +LIBHOGWEED_FILE +LIBHOGWEED_SONAME +LIBHOGWEED_FORLINK +LIBHOGWEED_MINOR +LIBHOGWEED_MAJOR +LIBNETTLE_LIBS +LIBNETTLE_LINK +LIBNETTLE_FILE_SRC +LIBNETTLE_FILE +LIBNETTLE_SONAME +LIBNETTLE_FORLINK +LIBNETTLE_MINOR +LIBNETTLE_MAJOR +EMULATOR +W64_ABI +ASM_ALIGN_LOG +ASM_MARK_NOEXEC_STACK +ASM_TYPE_PROGBITS +ASM_TYPE_FUNCTION +ASM_COFF_STYLE +ASM_ELF_STYLE +ASM_SYMBOL_PREFIX +CCPIC +IF_ASM +ASM_RODATA +OPT_NETTLE_SOURCES +OPT_HOGWEED_OBJS +OPT_NETTLE_OBJS +GMP_NUMB_BITS +NUMB_BITS +ALLOCA +EGREP +GREP +CPP +DEP_PROCESS +DEP_FLAGS +DEP_INCLUDE +EXEEXT_FOR_BUILD +CC_FOR_BUILD +LN_S +MKDIR_P +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +AR +OBJDUMP +NM +RANLIB +SET_MAKE +EXTRA_HOGWEED_LINKER_FLAGS +EXTRA_LINKER_FLAGS +IF_CXX +ac_ct_CXX +CXXFLAGS +CXX +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +HOGWEED_EXTRA_SYMBOLS +NETTLE_USE_MINI_GMP +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +MINOR_VERSION +MAJOR_VERSION +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_include_path +with_lib_path +enable_public_key +enable_assembler +enable_static +enable_shared +enable_pic +enable_openssl +enable_gcov +enable_documentation +enable_fat +enable_arm_neon +enable_x86_aesni +enable_mini_gmp +enable_ld_version_script +enable_dependency_tracking +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CC_FOR_BUILD +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +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= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures nettle 3.4.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] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --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 3.4.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-public-key Disable public key algorithms + --disable-assembler Disable assembler code + --disable-static Do not build any static library + --disable-shared Do not build any 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 + --enable-gcov Instrument for gcov (requires a modern gcc) + --disable-documentation Omit building and installing the documentation. + (default=auto) + --enable-fat Enable fat library build (default=no) + --enable-arm-neon Enable ARM Neon assembly. (default=auto) + --enable-x86-aesni Enable x86_64 aes instructions. (default=no) + --enable-mini-gmp Enable mini-gmp, used instead of libgmp. + --enable-ld-version-script + enable linker version script (default is enabled + when possible) + --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 (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CC_FOR_BUILD + build system C compiler + 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" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +nettle configure 3.4.1 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ----------------------------------------------- ## +## Report this to nettle-bugs@lists.lysator.liu.se ## +## ----------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +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 3.4.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + 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. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +# 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 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +ac_config_headers="$ac_config_headers config.h" + + +LIBNETTLE_MAJOR=6 +LIBNETTLE_MINOR=5 + +LIBHOGWEED_MAJOR=4 +LIBHOGWEED_MINOR=5 + +MAJOR_VERSION=`echo $PACKAGE_VERSION | sed 's/^\([^.]*\)\..*/\1/'` +MINOR_VERSION=`echo $PACKAGE_VERSION | sed 's/^[^.]*\.\([0-9]*\).*/\1/'` + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +# 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-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; +else + enable_static=yes +fi + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; +else + enable_shared=yes +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 + + +# Check whether --enable-gcov was given. +if test "${enable_gcov+set}" = set; then : + enableval=$enable_gcov; +else + enable_gcov=no +fi + + +# Check whether --enable-documentation was given. +if test "${enable_documentation+set}" = set; then : + enableval=$enable_documentation; +else + enable_documentation=auto +fi + + +# Check whether --enable-fat was given. +if test "${enable_fat+set}" = set; then : + enableval=$enable_fat; +else + enable_fat=no +fi + + +# Check whether --enable-arm-neon was given. +if test "${enable_arm_neon+set}" = set; then : + enableval=$enable_arm_neon; +else + enable_arm_neon=auto +fi + + +# Check whether --enable-x86-aesni was given. +if test "${enable_x86_aesni+set}" = set; then : + enableval=$enable_x86_aesni; +else + enable_x86_aesni=no +fi + + +# Check whether --enable-mini-gmp was given. +if test "${enable_mini_gmp+set}" = set; then : + enableval=$enable_mini_gmp; +else + enable_mini_gmp=no +fi + + +if test "x$enable_mini_gmp" = xyes ; then + NETTLE_USE_MINI_GMP=1 + HOGWEED_EXTRA_SYMBOLS="mpz_*;gmp_*;mpn_*;mp_*;" +else + NETTLE_USE_MINI_GMP=0 + HOGWEED_EXTRA_SYMBOLS="" +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -R flag" >&5 +$as_echo_n "checking for -R flag... " >&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*|freebsd*) RPATHFLAG="-Wl,-rpath," ;; + *) RPATHFLAG="" ;; +esac + +if test x$RPATHFLAG = x ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using $RPATHFLAG" >&5 +$as_echo "using $RPATHFLAG" >&6; } +fi + +RPATH_CANDIDATE_REAL_DIRS='' +RPATH_CANDIDATE_DIRS='' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Searching for libraries" >&5 +$as_echo "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 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $d" >&5 +$as_echo_n "checking $d... " >&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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: already added" >&5 +$as_echo "already added" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: added" >&5 +$as_echo "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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ifunc support" >&5 +$as_echo_n "checking for ifunc support... " >&6; } +if ${nettle_cv_link_ifunc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +static int +foo_imp(int x) +{ + return 1; +} + +typedef void void_func (void); + +static void_func * +foo_resolv(void) +{ + return (void_func *) foo_imp; +} + +int foo (int x) __attribute__ ((ifunc("foo_resolv"))); + +int +main () +{ + + return foo(0); + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + nettle_cv_link_ifunc=yes +else + nettle_cv_link_ifunc=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_link_ifunc" >&5 +$as_echo "$nettle_cv_link_ifunc" >&6; } + +if test "x$nettle_cv_link_ifunc" = xyes ; then + $as_echo "#define HAVE_LINK_IFUNC 1" >>confdefs.h + +fi + + +# 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling with rntcl; clearing EXEEXT and disabling assembler" >&5 +$as_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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "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:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + IF_CXX='' +else + IF_CXX='#' +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 + + + + # Check whether --enable-ld-version-script was given. +if test "${enable_ld_version_script+set}" = set; then : + enableval=$enable_ld_version_script; have_ld_version_script=$enableval +fi + + if test -z "$have_ld_version_script"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if LD -Wl,--version-script works" >&5 +$as_echo_n "checking if LD -Wl,--version-script works... " >&6; } + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" + cat > conftest.map <conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + accepts_syntax_errors=yes +else + accepts_syntax_errors=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$accepts_syntax_errors" = no; then + cat > conftest.map <conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + have_ld_version_script=yes +else + have_ld_version_script=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + else + have_ld_version_script=no + fi + rm -f conftest.map + LDFLAGS="$save_LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ld_version_script" >&5 +$as_echo "$have_ld_version_script" >&6; } + fi + if test "$have_ld_version_script" = "yes";then + EXTRA_LINKER_FLAGS="-Wl,--version-script=libnettle.map" + + EXTRA_HOGWEED_LINKER_FLAGS="-Wl,--version-script=libhogweed.map" + + fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NM+:} false; then : + $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +$as_echo "$NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NM+:} false; then : + $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NM="nm" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5 +$as_echo "$ac_ct_NM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="strings" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + + +if test "x$ac_cv_prog_cc_stdc" = xno ; then + as_fn_error $? "the C compiler doesn't handle ANSI-C" "$LINENO" 5 #' +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. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +# According to the autoconf manual, needs install-sh from +# autoconf-2.60 or automake-1.10 to avoid races. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$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 + + test -d ./--version && rmdir ./--version + 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. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +# Compiler tests for the build system + +if test -n "$CC_FOR_BUILD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system compiler $CC_FOR_BUILD" >&5 +$as_echo_n "checking build system compiler $CC_FOR_BUILD... " >&6; } +# remove anything that might look like compiler output to our "||" expression +rm -f conftest* a.out b.out a.exe a_out.exe +cat >conftest.c <&5 + (eval $gmp_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&5 2>&1; then + cc_for_build_works=yes + fi +fi +rm -f conftest* a.out b.out a.exe a_out.exe +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cc_for_build_works" >&5 +$as_echo "$cc_for_build_works" >&6; } +if test "$cc_for_build_works" = yes; then + : +else + as_fn_error $? "Specified CC_FOR_BUILD doesn't seem to work" "$LINENO" 5 +fi + +elif test -n "$HOST_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system compiler $HOST_CC" >&5 +$as_echo_n "checking build system compiler $HOST_CC... " >&6; } +# remove anything that might look like compiler output to our "||" expression +rm -f conftest* a.out b.out a.exe a_out.exe +cat >conftest.c <&5 + (eval $gmp_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&5 2>&1; then + cc_for_build_works=yes + fi +fi +rm -f conftest* a.out b.out a.exe a_out.exe +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cc_for_build_works" >&5 +$as_echo "$cc_for_build_works" >&6; } +if test "$cc_for_build_works" = yes; then + CC_FOR_BUILD=$HOST_CC +else + as_fn_error $? "Specified HOST_CC doesn't seem to work" "$LINENO" 5 +fi + +else + if test $cross_compiling = no ; then + CC_FOR_BUILD="$CC" + else + for i in gcc cc c89 c99; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system compiler $i" >&5 +$as_echo_n "checking build system compiler $i... " >&6; } +# remove anything that might look like compiler output to our "||" expression +rm -f conftest* a.out b.out a.exe a_out.exe +cat >conftest.c <&5 + (eval $gmp_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&5 2>&1; then + cc_for_build_works=yes + fi +fi +rm -f conftest* a.out b.out a.exe a_out.exe +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cc_for_build_works" >&5 +$as_echo "$cc_for_build_works" >&6; } +if test "$cc_for_build_works" = yes; then + CC_FOR_BUILD=$i + break +else + : +fi + + done + if test -z "$CC_FOR_BUILD"; then + as_fn_error $? "Cannot find a build system compiler" "$LINENO" 5 + fi + fi + if test "$CC_FOR_BUILD" = gcc ; then + CC_FOR_BUILD="$CC_FOR_BUILD -O -g" + fi +fi + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 +$as_echo_n "checking for build system executable suffix... " >&6; } +if ${gmp_cv_prog_exeext_for_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test $cross_compiling = no ; then + gmp_cv_prog_exeext_for_build="$EXEEXT" +else + cat >conftest.c <&5 + (eval $gmp_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if (./conftest) 2>&5; then + gmp_cv_prog_exeext_for_build=$i + break + fi + fi + done + rm -f conftest* + if test "${gmp_cv_prog_exeext_for_build+set}" != set; then + as_fn_error $? "Cannot determine executable suffix" "$LINENO" 5 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_prog_exeext_for_build" >&5 +$as_echo "$gmp_cv_prog_exeext_for_build" >&6; } +EXEEXT_FOR_BUILD=$gmp_cv_prog_exeext_for_build + + + +# 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Dependency tracking disabled, gcc-3.x is needed" >&5 +$as_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 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Dependency tracking disabled" >&5 +$as_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 + +if test "x$enable_gcov" = "xyes"; then + CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs" +fi + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* 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 sort of thing. */ + char tx; + char *t = &tx; + 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 sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#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 +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 +$as_echo_n "checking size of size_t... " >&6; } +if ${ac_cv_sizeof_size_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_size_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (size_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_size_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 +$as_echo "$ac_cv_sizeof_size_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t +_ACEOF + + + +for ac_header in openssl/evp.h openssl/ecdsa.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + enable_openssl=no + break +fi + +done + + +# For use by the testsuite +for ac_header in valgrind/memcheck.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "valgrind/memcheck.h" "ac_cv_header_valgrind_memcheck_h" "$ac_includes_default" +if test "x$ac_cv_header_valgrind_memcheck_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VALGRIND_MEMCHECK_H 1 +_ACEOF + +fi + +done + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + +$as_echo "#define HAVE_LIBDL 1" >>confdefs.h + +fi + + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* 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 */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +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 + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +int +main (int argc, char **argv) +{ + return find_stack_direction (0, argc + !argv + 20) < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$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 : + ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default" +if test "x$ac_cv_header_malloc_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MALLOC_H 1 +_ACEOF + +fi + +done + + +for ac_func in strerror +do : + ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" +if test "x$ac_cv_func_strerror" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRERROR 1 +_ACEOF + +fi +done + + +# getenv_secure is used for fat overrides, +# getline is used in the testsuite +for ac_func in secure_getenv getline +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #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 +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5 +$as_echo_n "checking for __attribute__... " >&6; } +if ${lsh_cv_c_attribute+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +static void foo(void) __attribute__ ((noreturn)); + +static void __attribute__ ((noreturn)) +foo(void) +{ + exit(1); +} + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + lsh_cv_c_attribute=yes +else + lsh_cv_c_attribute=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lsh_cv_c_attribute" >&5 +$as_echo "$lsh_cv_c_attribute" >&6; } + + +if test "x$lsh_cv_c_attribute" = "xyes"; then + $as_echo "#define HAVE_GCC_ATTRIBUTE 1" >>confdefs.h + +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 ------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint types" >&5 +$as_echo_n "checking for stdint types... " >&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 ${ac_cv_header_stdint_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +int_least32_t v = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h"; +else + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (are you sure you want them in ./stdint.h?)" >&5 +$as_echo "(are you sure you want them in ./stdint.h?)" >&6; } +elif test "$ac_stdint_h" = "inttypes.h" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (are you sure you want them in ./inttypes.h?)" >&5 +$as_echo "(are you sure you want them in ./inttypes.h?)" >&6; } +elif test "_$ac_cv_header_stdint_t" = "_" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (putting them into $ac_stdint_h)$v" >&5 +$as_echo "(putting them into $ac_stdint_h)$v" >&6; } +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint (shortcircuit)" >&5 +$as_echo "$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)" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uintptr_t" >&5 +$as_echo_n "checking for stdint uintptr_t... " >&6; } +if ${ac_cv_header_stdint_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +$as_echo "(..)" >&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 + ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <$i> +" +if test "x$ac_cv_type_uintptr_t" = xyes; then : + ac_cv_header_stdint_x=$i +else + continue +fi + + ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include<$i> +" +if test "x$ac_cv_type_uint64_t" = xyes; then : + and64="/uint64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" + break; + done + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uintptr_t" >&5 +$as_echo_n "checking for stdint uintptr_t... " >&6; } + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_x" >&5 +$as_echo "$ac_cv_header_stdint_x" >&6; } + +if test "_$ac_cv_header_stdint_x" = "_" ; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uint32_t" >&5 +$as_echo_n "checking for stdint uint32_t... " >&6; } +if ${ac_cv_header_stdint_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +$as_echo "(..)" >&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 + ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include <$i> +" +if test "x$ac_cv_type_uint32_t" = xyes; then : + ac_cv_header_stdint_o=$i +else + continue +fi + + ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include<$i> +" +if test "x$ac_cv_type_uint64_t" = xyes; then : + and64="/uint64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen uint32_t$and64 in $i)" + break; + done + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint uint32_t" >&5 +$as_echo_n "checking for stdint uint32_t... " >&6; } + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_o" >&5 +$as_echo "$ac_cv_header_stdint_o" >&6; } +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint u_int32_t" >&5 +$as_echo_n "checking for stdint u_int32_t... " >&6; } +if ${ac_cv_header_stdint_u+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +$as_echo "(..)" >&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 + ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "#include <$i> +" +if test "x$ac_cv_type_u_int32_t" = xyes; then : + ac_cv_header_stdint_u=$i +else + continue +fi + + ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "#include<$i> +" +if test "x$ac_cv_type_u_int64_t" = xyes; then : + and64="/u_int64_t" +else + and64="" +fi + + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" + break; + done + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint u_int32_t" >&5 +$as_echo_n "checking for stdint u_int32_t... " >&6; } + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_u" >&5 +$as_echo "$ac_cv_header_stdint_u" >&6; } +fi fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint datatype model" >&5 +$as_echo_n "checking for stdint datatype model... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +$as_echo "(..)" >&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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 +$as_echo_n "checking size of char... " >&6; } +if ${ac_cv_sizeof_char+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_char" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_char=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 +$as_echo "$ac_cv_sizeof_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void*" >&5 +$as_echo_n "checking size of void*... " >&6; } +if ${ac_cv_sizeof_voidp+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void*))" "ac_cv_sizeof_voidp" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_voidp" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void*) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_voidp=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_voidp" >&5 +$as_echo "$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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: combined for stdint datatype model... $name" >&5 +$as_echo "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 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra inttypes in chosen header" >&5 +$as_echo_n "checking for extra inttypes in chosen header... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ($ac_cv_header_stdint)" >&5 +$as_echo "($ac_cv_header_stdint)" >&6; } +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +ac_fn_c_check_type "$LINENO" "int_least32_t" "ac_cv_type_int_least32_t" "#include <$ac_cv_header_stdint> +" +if test "x$ac_cv_type_int_least32_t" = xyes; then : + +fi + +ac_fn_c_check_type "$LINENO" "int_fast32_t" "ac_cv_type_int_fast32_t" "#include<$ac_cv_header_stdint> +" +if test "x$ac_cv_type_int_fast32_t" = xyes; then : + +fi + +ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "#include <$ac_cv_header_stdint> +" +if test "x$ac_cv_type_intmax_t" = xyes; then : + +fi + + +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 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5 +$as_echo "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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fcntl file locking" >&5 +$as_echo_n "checking for fcntl file locking... " >&6; } +if ${nettle_cv_fcntl_locking+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* 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 +if ac_fn_c_try_compile "$LINENO"; then : + nettle_cv_fcntl_locking=yes +else + nettle_cv_fcntl_locking=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_fcntl_locking" >&5 +$as_echo "$nettle_cv_fcntl_locking" >&6; } + + +if test "x$nettle_cv_fcntl_locking" = "xyes" ; then + $as_echo "#define HAVE_FCNTL_LOCKING 1" >>confdefs.h + +fi + +# Checks for libraries +if test "x$enable_public_key" = "xyes" ; then + if test "x$enable_mini_gmp" = "xno" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpn_sec_div_r in -lgmp" >&5 +$as_echo_n "checking for __gmpn_sec_div_r in -lgmp... " >&6; } +if ${ac_cv_lib_gmp___gmpn_sec_div_r+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgmp $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __gmpn_sec_div_r (); +int +main () +{ +return __gmpn_sec_div_r (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gmp___gmpn_sec_div_r=yes +else + ac_cv_lib_gmp___gmpn_sec_div_r=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpn_sec_div_r" >&5 +$as_echo "$ac_cv_lib_gmp___gmpn_sec_div_r" >&6; } +if test "x$ac_cv_lib_gmp___gmpn_sec_div_r" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGMP 1 +_ACEOF + + LIBS="-lgmp $LIBS" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GNU MP not found, or too old. GMP-6.0 or later is needed, see https://gmplib.org/. + Support for public key algorithms will be unavailable." >&5 +$as_echo "$as_me: WARNING: GNU MP not found, or too old. GMP-6.0 or later is needed, see https://gmplib.org/. + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_success=yes +else + ac_success=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + + if test $ac_success = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Running simple test program failed. Trying -R flags" >&5 +$as_echo_n "checking Running simple test program failed. Trying -R flags... " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_success=yes + ac_rpath_save_LDFLAGS="$LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: adding $RPATHFLAG$d" >&5 +$as_echo "adding $RPATHFLAG$d" >&6; } + +else + 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.beam conftest.$ac_ext +fi + + LDFLAGS="$ac_rpath_save_LDFLAGS" + fi + done + RPATH_CANDIDATE_DIRS=$ac_remaining_dirs + fi + if test $ac_success = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } + fi +fi + + fi +fi + +nettle_cv_gmp_numb_bits=0 +if test "x$enable_public_key" = "xyes" ; then + # Check for gmp limb size + if test "x$enable_mini_gmp" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mini-gmp limb size" >&5 +$as_echo_n "checking for mini-gmp limb size... " >&6; } + # With mini-gmp, mp_limb_t is always unsigned long. + if ac_fn_c_compute_int "$LINENO" "(sizeof(unsigned long) * CHAR_BIT)" "nettle_cv_gmp_numb_bits" "#include "; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot find value of GMP_NUMB_BITS +See \`config.log' for more details" "$LINENO" 5; } +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_gmp_numb_bits bits" >&5 +$as_echo "$nettle_cv_gmp_numb_bits bits" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMP limb size" >&5 +$as_echo_n "checking for GMP limb size... " >&6; } + if ac_fn_c_compute_int "$LINENO" "GMP_NUMB_BITS" "nettle_cv_gmp_numb_bits" "#include "; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot find value of GMP_NUMB_BITS +See \`config.log' for more details" "$LINENO" 5; } +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_gmp_numb_bits bits" >&5 +$as_echo "$nettle_cv_gmp_numb_bits bits" >&6; } + fi +fi + +# Substituted in Makefile, passed on to the eccdata command. +NUMB_BITS="$nettle_cv_gmp_numb_bits" + + +# Substituted in version.h, used only with mini-gmp. +if test "x$enable_mini_gmp" = "xyes" ; then + GMP_NUMB_BITS="$NUMB_BITS" +else + GMP_NUMB_BITS="n/a" +fi + + +# Figure out ABI. Currently, configurable only by setting CFLAGS. +ABI=standard + +case "$host_cpu" in + x86_64 | amd64) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined(__x86_64__) || defined(__arch64__) +#error 64-bit x86 +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + ABI=32 + +else + + ABI=64 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + *sparc*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined(__sparcv9) || defined(__arch64__) +#error 64-bit sparc +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + ABI=32 + +else + + ABI=64 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + *mips*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined(__sgi) && defined(__LP64__) +#error 64-bit mips +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + ABI=32 + +else + + ABI=64 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; +esac + +if test "x$ABI" != xstandard ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Compiler uses $ABI-bit ABI. To change, set CC." >&5 +$as_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' + ;; + # Linux conventions are a mess... According to the Linux File + # Hierarchy Standard, all architectures except IA64 puts 32-bit + # libraries in lib, and 64-bit in lib64. Some distributions, + # e.g., Fedora and Gentoo, adhere to this standard, while at + # least Debian has decided to put 64-bit libraries in lib and + # 32-bit libraries in lib32. + + # We try to figure out the convention, except if we're cross + # compiling. We use lib${ABI} if /usr/lib${ABI} exists and + # appears to not be a symlink to a different name. + *:linux*:32|*:linux*:64) + if test "$cross_compiling" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib." >&5 +$as_echo "$as_me: WARNING: Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib." >&2;}; else + # The dash builtin pwd tries to be "helpful" and remember + # symlink names. Use -P option, and hope it's portable enough. + test -d /usr/lib${ABI} \ + && (cd /usr/lib${ABI} && pwd -P | grep >/dev/null "/lib${ABI}"'$') \ + && libdir='${exec_prefix}/'"lib${ABI}" + fi + ;; + # 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' + ;; + *:irix*:32) + libdir='${exec_prefix}/lib32' + ;; + *:irix*:64) + libdir='${exec_prefix}/lib64' + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know where to install $ABI-bit libraries on this system." >&5 +$as_echo "$as_me: WARNING: Don't know where to install $ABI-bit libraries on this system." >&2;}; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: Libraries to be installed in $libdir." >&5 +$as_echo "$as_me: Libraries to be installed in $libdir." >&6;} + fi +fi + +OPT_NETTLE_SOURCES="" + +# Select assembler code +asm_path= +if test "x$enable_assembler" = xyes ; then + 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 + if test "x$enable_fat" = xyes ; then + asm_path="x86_64/fat $asm_path" + OPT_NETTLE_SOURCES="fat-x86_64.c $OPT_NETTLE_SOURCES" + elif test "x$enable_x86_aesni" = xyes ; then + asm_path="x86_64/aesni $asm_path" + fi + else + asm_path=x86 + fi + ;; + *sparc*) + if test "$ABI" = 64 ; then + asm_path=sparc64 + else + asm_path=sparc32 + fi + ;; + arm*) + asm_path=arm + if test "x$enable_fat" = xyes ; then + asm_path="arm/fat $asm_path" + OPT_NETTLE_SOURCES="fat-arm.c $OPT_NETTLE_SOURCES" + else + case "$host_cpu" in + armv6* | armv7*) + if test "$enable_arm_neon" = auto ; then + if test "$cross_compiling" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler accepts Neon instructions" >&5 +$as_echo_n "checking if assembler accepts Neon instructions... " >&6; } +if ${nettle_cv_asm_arm_neon+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + cat conftest.out >&5 + nettle_cv_asm_arm_neon=yes +else + cat conftest.out >&5 + echo "configure: failed program was:" >&5 + cat conftest.s >&5 + nettle_cv_asm_arm_neon=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_arm_neon" >&5 +$as_echo "$nettle_cv_asm_arm_neon" >&6; } + enable_arm_neon="$nettle_cv_asm_arm_neon" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if /proc/cpuinfo claims neon support" >&5 +$as_echo_n "checking if /proc/cpuinfo claims neon support... " >&6; } + if grep '^Features.*:.* neon' /proc/cpuinfo >/dev/null ; then + enable_arm_neon=yes + else + enable_arm_neon=no + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_arm_neon" >&5 +$as_echo "$enable_arm_neon" >&6; } + fi +fi + + + asm_path="arm/v6 arm" + + if test "x$enable_arm_neon" = xyes ; then + asm_path="arm/neon $asm_path" + fi + ;; + esac + fi + ;; + *) + enable_assembler=no + ;; + esac +fi + +# Files which replace a C source file (or otherwise don't correspond +# to a new object file). +asm_replace_list="aes-encrypt-internal.asm aes-decrypt-internal.asm \ + arcfour-crypt.asm camellia-crypt-internal.asm \ + md5-compress.asm memxor.asm memxor3.asm \ + poly1305-internal.asm \ + chacha-core-internal.asm \ + salsa20-crypt.asm salsa20-core-internal.asm \ + serpent-encrypt.asm serpent-decrypt.asm \ + sha1-compress.asm sha256-compress.asm sha512-compress.asm \ + sha3-permute.asm umac-nh.asm umac-nh-n.asm machine.m4" + +# Assembler files which generate additional object files if they are used. +asm_nettle_optional_list="gcm-hash8.asm cpuid.asm \ + aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm memxor-2.asm \ + salsa20-core-internal-2.asm sha1-compress-2.asm sha256-compress-2.asm \ + sha3-permute-2.asm sha512-compress-2.asm \ + umac-nh-n-2.asm umac-nh-2.asm" + +asm_hogweed_optional_list="" +if test "x$enable_public_key" = "xyes" ; then + asm_hogweed_optional_list="ecc-192-modp.asm ecc-224-modp.asm \ + ecc-25519-modp.asm ecc-256-redc.asm ecc-384-modp.asm ecc-521-modp.asm" +fi + +OPT_NETTLE_OBJS="" +OPT_HOGWEED_OBJS="" + +asm_file_list="" + +if test "x$enable_assembler" = xyes ; then + if test -n "$asm_path"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Looking for assembler files in $asm_path." >&5 +$as_echo "$as_me: Looking for assembler files in $asm_path." >&6;} + for tmp_f in $asm_replace_list ; do + for asm_dir in $asm_path ; do + if test -f "$srcdir/$asm_dir/$tmp_f"; then + asm_file_list="$asm_file_list $tmp_f" + ac_config_links="$ac_config_links $tmp_f:$asm_dir/$tmp_f" + + break + fi + done + done + for tmp_n in $asm_nettle_optional_list ; do + tmp_b=`echo "$tmp_n" | sed 's/\.[^.]*$//'` + for asm_dir in $asm_path ; do + if test -f "$srcdir/$asm_dir/$tmp_n"; then + asm_file_list="$asm_file_list $tmp_n" + ac_config_links="$ac_config_links $tmp_n:$asm_dir/$tmp_n" + + while read tmp_func ; do + cat >>confdefs.h <<_ACEOF +#define HAVE_NATIVE_$tmp_func 1 +_ACEOF + + eval HAVE_NATIVE_$tmp_func=yes + done <&5 +$as_echo "$as_me: WARNING: skipping $tmp_h, because GMP_NUMB_BITS != $tmp_bits" >&2;} + continue + fi + asm_file_list="$asm_file_list $tmp_h" + ac_config_links="$ac_config_links $tmp_h:$asm_dir/$tmp_h" + + while read tmp_func ; do + cat >>confdefs.h <<_ACEOF +#define HAVE_NATIVE_$tmp_func 1 +_ACEOF + + eval HAVE_NATIVE_$tmp_func=yes + done <&5 +$as_echo "$as_me: WARNING: No assembler files found." >&2;} + fi + fi + case "$host_os" in + darwin*) + ASM_RODATA='.section __TEXT,__const' + ;; + *) + ASM_RODATA='.section .rodata' + ;; + esac +fi + + + + + +if test "x$enable_assembler" = xyes ; then + IF_ASM='' +else + IF_ASM='#' +fi + + + + +if test "x$enable_pic" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking CCPIC" >&5 +$as_echo_n "checking CCPIC... " >&6; } +if ${lsh_cv_sys_ccpic+:} false; then : + $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +exit(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + lsh_cv_sys_ccpic="$CCPIC" +else + 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" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCPIC" >&5 +$as_echo "$CCPIC" >&6; } +else + CCPIC='' +fi + + +IF_DLL='#' +LIBNETTLE_FILE_SRC='$(LIBNETTLE_FORLINK)' +LIBHOGWEED_FILE_SRC='$(LIBHOGWEED_FORLINK)' +EMULATOR='' +W64_ABI=no + +case "$host_os" in + mingw32*|cygwin*) + # The actual DLLs, e.g. libnettle-$major-$minor.dll, are normally + # installed into the bin dir (or more exactly $libdir/../bin, for + # automake), while libnettle.dll.a, which is a stub file for + # linking to the DLL, is installed into the lib dir. + case "$host_os" in + mingw32*) + LIBNETTLE_FORLINK='libnettle-$(LIBNETTLE_MAJOR).dll' + LIBHOGWEED_FORLINK='libhogweed-$(LIBHOGWEED_MAJOR).dll' + ;; + cygwin*) + LIBNETTLE_FORLINK='cygnettle-$(LIBNETTLE_MAJOR).dll' + LIBHOGWEED_FORLINK='cyghogweed-$(LIBHOGWEED_MAJOR).dll' + ;; + esac + if test "x$cross_compiling" = xyes ; then + case "$ABI" in + 64) + EMULATOR=wine64 + ;; + *) + EMULATOR=wine + ;; + esac + fi + if test "x$ABI" = x64 ; then + W64_ABI=yes + fi + LIBNETTLE_SONAME='' + LIBNETTLE_FILE='libnettle.dll.a' + LIBNETTLE_FILE_SRC='$(LIBNETTLE_FILE)' + LIBNETTLE_LINK='$(CC) $(CFLAGS) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBNETTLE_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' + LIBNETTLE_LIBS='-Wl,--no-whole-archive $(LIBS)' + + LIBHOGWEED_SONAME='' + LIBHOGWEED_FILE='libhogweed.dll.a' + LIBHOGWEED_FILE_SRC='$(LIBHOGWEED_FILE)' + LIBHOGWEED_LINK='$(CC) $(CFLAGS) $(LDFLAGS) -shared -Wl,--out-implib=$(LIBHOGWEED_FILE) -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' + LIBHOGWEED_LIBS='-Wl,--no-whole-archive $(LIBS) libnettle.dll.a' + IF_DLL='' + ;; + darwin*) + LIBNETTLE_FORLINK=libnettle.dylib + LIBNETTLE_SONAME='libnettle.$(LIBNETTLE_MAJOR).dylib' + LIBNETTLE_FILE='libnettle.$(LIBNETTLE_MAJOR).$(LIBNETTLE_MINOR).dylib' + LIBNETTLE_LINK='$(CC) $(CFLAGS) -dynamiclib $(LDFLAGS) -install_name ${libdir}/$(LIBNETTLE_SONAME) -compatibility_version $(LIBNETTLE_MAJOR) -current_version $(LIBNETTLE_MAJOR).$(LIBNETTLE_MINOR)' + LIBNETTLE_LIBS='' + + LIBHOGWEED_FORLINK=libhogweed.dylib + LIBHOGWEED_SONAME='libhogweed.$(LIBHOGWEED_MAJOR).dylib' + LIBHOGWEED_FILE='libhogweed.$(LIBHOGWEED_MAJOR).$(LIBHOGWEED_MINOR).dylib' + LIBHOGWEED_LINK='$(CC) $(CFLAGS) -dynamiclib -L. $(LDFLAGS) -install_name ${libdir}/$(LIBHOGWEED_SONAME) -compatibility_version $(LIBHOGWEED_MAJOR) -current_version $(LIBHOGWEED_MAJOR).$(LIBHOGWEED_MINOR)' + LIBHOGWEED_LIBS='-lnettle $(LIBS)' + ;; + solaris*) + # Sun's ld uses -h to set the soname, and this option is passed + # through by both Sun's compiler and gcc. Might not work with GNU + # ld, but it's unusual to use GNU ld on Solaris. + LIBNETTLE_FORLINK=libnettle.so + LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)' + LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)' + LIBNETTLE_LINK='$(CC) $(CFLAGS) $(LDFLAGS) -G -h $(LIBNETTLE_SONAME)' + LIBNETTLE_LIBS='' + + LIBHOGWEED_FORLINK=libhogweed.so + LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)' + LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)' + LIBHOGWEED_LINK='$(CC) $(CFLAGS) $(LDFLAGS) -G -h $(LIBHOGWEED_SONAME)' + LIBHOGWEED_LIBS='libnettle.so $(LIBS)' + ;; + *) + LIBNETTLE_FORLINK=libnettle.so + LIBNETTLE_SONAME='$(LIBNETTLE_FORLINK).$(LIBNETTLE_MAJOR)' + LIBNETTLE_FILE='$(LIBNETTLE_SONAME).$(LIBNETTLE_MINOR)' + LIBNETTLE_LINK='$(CC) $(CFLAGS) $(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) $(CFLAGS) $(LDFLAGS) -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. + LIBHOGWEED_LIBS='libnettle.so $(LIBS)' + ;; +esac + +ASM_SYMBOL_PREFIX='' +ASM_ELF_STYLE='no' +ASM_COFF_STYLE='no' +# GNU as default is to use @ +ASM_TYPE_FUNCTION='@function' +ASM_TYPE_PROGBITS='@progbits' +ASM_MARK_NOEXEC_STACK='' +ASM_ALIGN_LOG='' + +if test x$enable_assembler = xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if globals are prefixed by underscore" >&5 +$as_echo_n "checking if globals are prefixed by underscore... " >&6; } +if ${nettle_cv_asm_underscore+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Default is no underscore + nettle_cv_asm_underscore=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int a_global_symbol; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: nm does not list a_global_symbol at all" >&5 +$as_echo "$as_me: WARNING: nm does not list a_global_symbol at all" >&2;} + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: test program with a single global could not be compiled!?" >&5 +$as_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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_underscore" >&5 +$as_echo "$nettle_cv_asm_underscore" >&6; } + if test x$nettle_cv_asm_underscore = xyes ; then + ASM_SYMBOL_PREFIX='_' + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF-style .type,%function pseudo-ops" >&5 +$as_echo_n "checking for ELF-style .type,%function pseudo-ops... " >&6; } +if ${nettle_cv_asm_type_percent_function+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_type_percent_function" >&5 +$as_echo "$nettle_cv_asm_type_percent_function" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF-style .type,#function pseudo-ops" >&5 +$as_echo_n "checking for ELF-style .type,#function pseudo-ops... " >&6; } +if ${nettle_cv_asm_type_hash_function+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_type_hash_function" >&5 +$as_echo "$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' + ASM_TYPE_PROGBITS='%progbits' + else + if test x$nettle_cv_asm_type_hash_function = xyes ; then + ASM_ELF_STYLE='yes' + ASM_TYPE_FUNCTION='#function' + ASM_TYPE_PROGBITS='#progbits' + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for COFF-style .type directive" >&5 +$as_echo_n "checking for COFF-style .type directive... " >&6; } +if ${nettle_cv_asm_coff_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + cat conftest.out >&5 + nettle_cv_asm_coff_type=yes +else + cat conftest.out >&5 + echo "configure: failed program was:" >&5 + cat conftest.s >&5 + nettle_cv_asm_coff_type=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_coff_type" >&5 +$as_echo "$nettle_cv_asm_coff_type" >&6; } + if test "x$nettle_cv_asm_coff_type" = "xyes" ; then + ASM_COFF_STYLE=yes + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should use a .note.GNU-stack section" >&5 +$as_echo_n "checking if we should use a .note.GNU-stack section... " >&6; } +if ${nettle_cv_asm_gnu_stack+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Default + nettle_cv_asm_gnu_stack=no + + cat >conftest.c <&5 + (eval $nettle_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_gnu_stack" >&5 +$as_echo "$nettle_cv_asm_gnu_stack" >&6; } + if test x$nettle_cv_asm_gnu_stack = xyes ; then + ASM_MARK_NOEXEC_STACK='.section .note.GNU-stack,"",TYPE_PROGBITS' + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if .align assembly directive is logarithmic" >&5 +$as_echo_n "checking if .align assembly directive is logarithmic... " >&6; } +if ${nettle_cv_asm_align_log+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.s <&5 + (eval $gmp_assemble) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $nettle_cv_asm_align_log" >&5 +$as_echo "$nettle_cv_asm_align_log" >&6; } + ASM_ALIGN_LOG="$nettle_cv_asm_align_log" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# Extract the first word of "m4", so it can be a program name with args. +set dummy m4; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_M4+:} false; then : + $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_M4" && ac_cv_path_M4="m4" + ;; +esac +fi +M4=$ac_cv_path_M4 +if test -n "$M4"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5 +$as_echo "$M4" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test "x$enable_public_key" = xyes ; then + $as_echo "#define WITH_HOGWEED 1" >>confdefs.h + + IF_HOGWEED='' +else + IF_HOGWEED='#' +fi + +if test "x$enable_static" = xyes ; then + IF_STATIC='' +else + IF_STATIC='#' +fi + +IF_DLOPEN_TEST='#' +if test "x$enable_shared" = xyes ; then + IF_SHARED='' + IF_NOT_SHARED='#' + if test "x$ac_cv_lib_dl_dlopen" = xyes ; then + IF_DLOPEN_TEST='' + fi +else + IF_SHARED='#' + IF_NOT_SHARED='' +fi + +# Documentation tools +if test "x$enable_documentation" != "xno"; then + # Extract the first word of "makeinfo", so it can be a program name with args. +set dummy makeinfo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MAKEINFO+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAKEINFO in + [\\/]* | ?:[\\/]*) + ac_cv_path_MAKEINFO="$MAKEINFO" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MAKEINFO="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_MAKEINFO" && ac_cv_path_MAKEINFO="not-found" + ;; +esac +fi +MAKEINFO=$ac_cv_path_MAKEINFO +if test -n "$MAKEINFO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5 +$as_echo "$MAKEINFO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + if test "x$MAKEINFO" != "xnot-found"; then + enable_documentation=yes + + else + if test "x$enable_documentation" == "xauto" ; then + enable_documentation=no + else + as_fn_error $? "Cannot find 'makeinfo', required for documentation." "$LINENO" 5 + fi + fi +fi + +if test "x$enable_documentation" = "xyes" ; then + IF_DOCUMENTATION='' +else + IF_DOCUMENTATION='#' +fi + +if test "x$enable_mini_gmp" = "xyes" ; then + IF_MINI_GMP='' +else + IF_MINI_GMP='#' +fi + + + + + + + + + + +OPENSSL_LIBFLAGS='' + +# Check for openssl's libcrypto (used only for benchmarking) +if test x$enable_openssl = xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_new in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_new in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_new+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_new (); +int +main () +{ +return EVP_CIPHER_CTX_new (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : + OPENSSL_LIBFLAGS='-lcrypto' +else + enable_openssl=no +fi + +fi + + +if test x$enable_openssl = xyes ; then + $as_echo "#define WITH_OPENSSL 1" >>confdefs.h + +fi + + + + + +# clock_gettime is in librt on *-*-osf5.1 and on glibc, so add -lrt to +# BENCH_LIBS if needed. On linux (tested on x86_32, 2.6.26), +# clock_getres reports ns accuracy, while in a quick test on osf +# clock_getres said only 1 millisecond. + +old_LIBS="$LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +$as_echo_n "checking for library containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_clock_gettime+:} false; then : + break +fi +done +if ${ac_cv_search_clock_gettime+:} false; then : + +else + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + + +$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + +fi + +BENCH_LIBS="$LIBS" +LIBS="$old_LIBS" + + + +# 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 version.h" + +ac_config_files="$ac_config_files tools/Makefile testsuite/Makefile examples/Makefile" + +ac_config_files="$ac_config_files nettle.pc hogweed.pc libnettle.map libhogweed.map" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by nettle $as_me 3.4.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_links="$ac_config_links" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration links: +$config_links + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +nettle config.status 3.4.1 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 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' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=`$as_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 || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "dummy-dep-files") CONFIG_COMMANDS="$CONFIG_COMMANDS dummy-dep-files" ;; + "$ac_stdint_h") CONFIG_COMMANDS="$CONFIG_COMMANDS $ac_stdint_h" ;; + "$tmp_f") CONFIG_LINKS="$CONFIG_LINKS $tmp_f:$asm_dir/$tmp_f" ;; + "$tmp_n") CONFIG_LINKS="$CONFIG_LINKS $tmp_n:$asm_dir/$tmp_n" ;; + "$tmp_h") CONFIG_LINKS="$CONFIG_LINKS $tmp_h:$asm_dir/$tmp_h" ;; + "config.make") CONFIG_FILES="$CONFIG_FILES config.make" ;; + "config.m4") CONFIG_FILES="$CONFIG_FILES config.m4" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "version.h") CONFIG_FILES="$CONFIG_FILES version.h" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; + "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; + "nettle.pc") CONFIG_FILES="$CONFIG_FILES nettle.pc" ;; + "hogweed.pc") CONFIG_FILES="$CONFIG_FILES hogweed.pc" ;; + "libnettle.map") CONFIG_FILES="$CONFIG_FILES libnettle.map" ;; + "libhogweed.map") CONFIG_FILES="$CONFIG_FILES libhogweed.map" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries 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[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + :L) + # + # CONFIG_LINK + # + + if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then + : + else + # Prefer the file from the source tree if names are identical. + if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then + ac_source=$srcdir/$ac_source + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 +$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} + + if test ! -r "$ac_source"; then + as_fn_error $? "$ac_source: file not found" "$LINENO" 5 + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $ac_source in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$ac_source" "$ac_file" 2>/dev/null || + cp -p "$ac_source" "$ac_file" || + as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 + fi + ;; + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "dummy-dep-files":C) (cd "$srcdir" && find . '(' -name '*.c' -o -name '*.cxx' ')' -print) \ + | sed 's/\.cx*$//' | (while read f; do \ + test -f "$f.o.d" || echo > "$f.o.d"; \ + done) + ;; + "$ac_stdint_h":C) +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_stdint_h : $_ac_stdint_h" >&5 +$as_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 unsigned 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_stdint_h is unchanged" >&5 +$as_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 || +$as_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"; as_fn_mkdir_p + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: summary of build options: + + Version: ${PACKAGE_STRING} + Host type: ${host} + ABI: ${ABI} + Assembly files: ${asm_path:-none} + Install prefix: ${prefix} + Library directory: ${libdir} + Compiler: ${CC} + Static libraries: ${enable_static} + Shared libraries: ${enable_shared} + Public key crypto: ${enable_public_key} + Using mini-gmp: ${enable_mini_gmp} + Documentation: ${enable_documentation} +" >&5 +$as_echo "$as_me: summary of build options: + + Version: ${PACKAGE_STRING} + Host type: ${host} + ABI: ${ABI} + Assembly files: ${asm_path:-none} + Install prefix: ${prefix} + Library directory: ${libdir} + Compiler: ${CC} + Static libraries: ${enable_static} + Shared libraries: ${enable_shared} + Public key crypto: ${enable_public_key} + Using mini-gmp: ${enable_mini_gmp} + Documentation: ${enable_documentation} +" >&6;} diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..ec3fbe9 --- /dev/null +++ b/configure.ac @@ -0,0 +1,967 @@ +dnl -*- mode: shell-script; sh-indentation: 2; -*- + +dnl Process this file with autoconf to produce a configure script. + +AC_INIT([nettle], [3.4.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=6 +LIBNETTLE_MINOR=5 + +LIBHOGWEED_MAJOR=4 +LIBHOGWEED_MINOR=5 + +dnl Note double square brackets, for extra m4 quoting. +MAJOR_VERSION=`echo $PACKAGE_VERSION | sed 's/^\([[^.]]*\)\..*/\1/'` +MINOR_VERSION=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*\.\([[0-9]]*\).*/\1/'` +AC_SUBST([MAJOR_VERSION]) +AC_SUBST([MINOR_VERSION]) + +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(static, + AC_HELP_STRING([--disable-static], [Do not build any static library]),, + [enable_static=yes]) + +AC_ARG_ENABLE(shared, + AC_HELP_STRING([--disable-shared], [Do not build any shared library]),, + [enable_shared=yes]) + +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]) + +AC_ARG_ENABLE(gcov, + AC_HELP_STRING([--enable-gcov], [Instrument for gcov (requires a modern gcc)]),, + [enable_gcov=no]) + +AC_ARG_ENABLE(documentation, + AC_HELP_STRING([--disable-documentation], [Omit building and installing the documentation. (default=auto)]),, + [enable_documentation=auto]) + +AC_ARG_ENABLE(fat, AC_HELP_STRING([--enable-fat], [Enable fat library build (default=no)]),, + [enable_fat=no]) + +AC_ARG_ENABLE(arm-neon, + AC_HELP_STRING([--enable-arm-neon], [Enable ARM Neon assembly. (default=auto)]),, + [enable_arm_neon=auto]) + +AC_ARG_ENABLE(x86-aesni, + AC_HELP_STRING([--enable-x86-aesni], [Enable x86_64 aes instructions. (default=no)]),, + [enable_x86_aesni=no]) + +AC_ARG_ENABLE(mini-gmp, + AC_HELP_STRING([--enable-mini-gmp], [Enable mini-gmp, used instead of libgmp.]),, + [enable_mini_gmp=no]) + +if test "x$enable_mini_gmp" = xyes ; then + NETTLE_USE_MINI_GMP=1 + HOGWEED_EXTRA_SYMBOLS="mpz_*;gmp_*;mpn_*;mp_*;" +else + NETTLE_USE_MINI_GMP=0 + HOGWEED_EXTRA_SYMBOLS="" +fi +AC_SUBST([NETTLE_USE_MINI_GMP]) +AC_SUBST([HOGWEED_EXTRA_SYMBOLS]) + +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 + +NETTLE_CHECK_IFUNC + +# 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;],[IF_CXX=''], [IF_CXX='#']) +AC_SUBST([IF_CXX]) +AC_LANG_POP + +LD_VERSION_SCRIPT + +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) +AC_CHECK_TOOL(AR, ar, 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 + +AC_PROG_LN_S + +# Compiler tests for the build system +GMP_PROG_CC_FOR_BUILD +GMP_PROG_EXEEXT_FOR_BUILD + +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' -o -name '*.cxx' ')' -print) \ + | sed 's/\.cx*$//' | (while read f; do \ + test -f "$f.o.d" || echo > "$f.o.d"; \ + done) +]) +fi + +if test "x$enable_gcov" = "xyes"; then + CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs" +fi + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_UID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(size_t) + +AC_CHECK_HEADERS([openssl/evp.h openssl/ecdsa.h],, +[enable_openssl=no + break]) + +# For use by the testsuite +AC_CHECK_HEADERS([valgrind/memcheck.h]) +AC_CHECK_HEADERS([dlfcn.h]) +AC_CHECK_LIB([dl], [dlopen], + [AC_DEFINE([HAVE_LIBDL], 1, + [Define to 1 if you have dlopen (with -ldl).])]) + +LSH_FUNC_ALLOCA +LSH_FUNC_STRERROR +# getenv_secure is used for fat overrides, +# getline is used in the testsuite +AC_CHECK_FUNCS(secure_getenv getline) +AC_C_BIGENDIAN + +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 +if test "x$enable_public_key" = "xyes" ; then + if test "x$enable_mini_gmp" = "xno" ; then + AC_CHECK_LIB(gmp, __gmpn_sec_div_r,, + [AC_MSG_WARN( + [GNU MP not found, or too old. GMP-6.0 or later is needed, see https://gmplib.org/. + 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 + fi +fi + +nettle_cv_gmp_numb_bits=0 +if test "x$enable_public_key" = "xyes" ; then + # Check for gmp limb size + if test "x$enable_mini_gmp" = "xyes" ; then + AC_MSG_CHECKING([for mini-gmp limb size]) + # With mini-gmp, mp_limb_t is always unsigned long. + AC_COMPUTE_INT(nettle_cv_gmp_numb_bits, [(sizeof(unsigned long) * CHAR_BIT)], + [#include ], + [AC_MSG_FAILURE([cannot find value of GMP_NUMB_BITS])]) + + AC_MSG_RESULT([$nettle_cv_gmp_numb_bits bits]) + else + AC_MSG_CHECKING([for GMP limb size]) + AC_COMPUTE_INT(nettle_cv_gmp_numb_bits, [GMP_NUMB_BITS], + [#include ], + [AC_MSG_FAILURE([cannot find value of GMP_NUMB_BITS])]) + + AC_MSG_RESULT([$nettle_cv_gmp_numb_bits bits]) + fi +fi + +# Substituted in Makefile, passed on to the eccdata command. +NUMB_BITS="$nettle_cv_gmp_numb_bits" +AC_SUBST([NUMB_BITS]) + +# Substituted in version.h, used only with mini-gmp. +if test "x$enable_mini_gmp" = "xyes" ; then + GMP_NUMB_BITS="$NUMB_BITS" +else + GMP_NUMB_BITS="n/a" +fi +AC_SUBST([GMP_NUMB_BITS]) + +# Figure out ABI. Currently, configurable only by 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 + ]) + ;; + *mips*) + AC_TRY_COMPILE([ +#if defined(__sgi) && defined(__LP64__) +#error 64-bit mips +#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' + ;; + # Linux conventions are a mess... According to the Linux File + # Hierarchy Standard, all architectures except IA64 puts 32-bit + # libraries in lib, and 64-bit in lib64. Some distributions, + # e.g., Fedora and Gentoo, adhere to this standard, while at + # least Debian has decided to put 64-bit libraries in lib and + # 32-bit libraries in lib32. + + # We try to figure out the convention, except if we're cross + # compiling. We use lib${ABI} if /usr/lib${ABI} exists and + # appears to not be a symlink to a different name. + *:linux*:32|*:linux*:64) + if test "$cross_compiling" = yes ; then + AC_MSG_WARN([Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib.]); dnl ' + else + # The dash builtin pwd tries to be "helpful" and remember + # symlink names. Use -P option, and hope it's portable enough. + test -d /usr/lib${ABI} \ + && (cd /usr/lib${ABI} && pwd -P | grep >/dev/null "/lib${ABI}"'$') \ + && libdir='${exec_prefix}/'"lib${ABI}" + fi + ;; + # 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' + ;; + *:irix*:32) + libdir='${exec_prefix}/lib32' + ;; + *:irix*:64) + libdir='${exec_prefix}/lib64' + ;; + *) + AC_MSG_WARN([Don't know where to install $ABI-bit libraries on this system.]); dnl ' + + esac + AC_MSG_NOTICE([Libraries to be installed in $libdir.]) + fi +fi + +OPT_NETTLE_SOURCES="" + +# Select assembler code +asm_path= +if test "x$enable_assembler" = xyes ; then + 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 + if test "x$enable_fat" = xyes ; then + asm_path="x86_64/fat $asm_path" + OPT_NETTLE_SOURCES="fat-x86_64.c $OPT_NETTLE_SOURCES" + elif test "x$enable_x86_aesni" = xyes ; then + asm_path="x86_64/aesni $asm_path" + fi + else + asm_path=x86 + fi + ;; + *sparc*) + if test "$ABI" = 64 ; then + asm_path=sparc64 + else + asm_path=sparc32 + fi + ;; + arm*) + asm_path=arm + if test "x$enable_fat" = xyes ; then + asm_path="arm/fat $asm_path" + OPT_NETTLE_SOURCES="fat-arm.c $OPT_NETTLE_SOURCES" + else + case "$host_cpu" in + armv6* | armv7*) + NETTLE_CHECK_ARM_NEON + + asm_path="arm/v6 arm" + + if test "x$enable_arm_neon" = xyes ; then + asm_path="arm/neon $asm_path" + fi + ;; + esac + fi + ;; + *) + enable_assembler=no + ;; + esac +fi + +# Files which replace a C source file (or otherwise don't correspond +# to a new object file). +asm_replace_list="aes-encrypt-internal.asm aes-decrypt-internal.asm \ + arcfour-crypt.asm camellia-crypt-internal.asm \ + md5-compress.asm memxor.asm memxor3.asm \ + poly1305-internal.asm \ + chacha-core-internal.asm \ + salsa20-crypt.asm salsa20-core-internal.asm \ + serpent-encrypt.asm serpent-decrypt.asm \ + sha1-compress.asm sha256-compress.asm sha512-compress.asm \ + sha3-permute.asm umac-nh.asm umac-nh-n.asm machine.m4" + +# Assembler files which generate additional object files if they are used. +asm_nettle_optional_list="gcm-hash8.asm cpuid.asm \ + aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm memxor-2.asm \ + salsa20-core-internal-2.asm sha1-compress-2.asm sha256-compress-2.asm \ + sha3-permute-2.asm sha512-compress-2.asm \ + umac-nh-n-2.asm umac-nh-2.asm" + +asm_hogweed_optional_list="" +if test "x$enable_public_key" = "xyes" ; then + asm_hogweed_optional_list="ecc-192-modp.asm ecc-224-modp.asm \ + ecc-25519-modp.asm ecc-256-redc.asm ecc-384-modp.asm ecc-521-modp.asm" +fi + +OPT_NETTLE_OBJS="" +OPT_HOGWEED_OBJS="" + +asm_file_list="" + +if test "x$enable_assembler" = xyes ; then + if test -n "$asm_path"; then + AC_MSG_NOTICE([Looking for assembler files in $asm_path.]) + for tmp_f in $asm_replace_list ; do + for asm_dir in $asm_path ; do + if test -f "$srcdir/$asm_dir/$tmp_f"; then + asm_file_list="$asm_file_list $tmp_f" + AC_CONFIG_LINKS($tmp_f:$asm_dir/$tmp_f) + break + fi + done + done + dnl Workaround for AC_CONFIG_LINKS, which complains if we use the + dnl same destination argument $tmp_f multiple times. + for tmp_n in $asm_nettle_optional_list ; do + dnl Note extra pair of [] in sed expression + tmp_b=`echo "$tmp_n" | sed 's/\.[[^.]]*$//'` + for asm_dir in $asm_path ; do + if test -f "$srcdir/$asm_dir/$tmp_n"; then + asm_file_list="$asm_file_list $tmp_n" + AC_CONFIG_LINKS($tmp_n:$asm_dir/$tmp_n) + while read tmp_func ; do + AC_DEFINE_UNQUOTED(HAVE_NATIVE_$tmp_func) + eval HAVE_NATIVE_$tmp_func=yes + done <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 does not 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([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' + ASM_TYPE_PROGBITS='%progbits' + else + if test x$nettle_cv_asm_type_hash_function = xyes ; then + ASM_ELF_STYLE='yes' + ASM_TYPE_FUNCTION='#function' + ASM_TYPE_PROGBITS='#progbits' + fi + fi + + AC_CACHE_CHECK([for COFF-style .type directive], + [nettle_cv_asm_coff_type], + [GMP_TRY_ASSEMBLE([ +.text +.globl _foo +.def _foo +.scl 2 +.type 32 +.endef +_foo: +], + [nettle_cv_asm_coff_type=yes], + [nettle_cv_asm_coff_type=no])]) + if test "x$nettle_cv_asm_coff_type" = "xyes" ; then + ASM_COFF_STYLE=yes + 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,"",TYPE_PROGBITS' + 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])]) + ASM_ALIGN_LOG="$nettle_cv_asm_align_log" +fi + +AC_SUBST(ASM_SYMBOL_PREFIX) +AC_SUBST(ASM_ELF_STYLE) +AC_SUBST(ASM_COFF_STYLE) +AC_SUBST(ASM_TYPE_FUNCTION) +AC_SUBST(ASM_TYPE_PROGBITS) +AC_SUBST(ASM_MARK_NOEXEC_STACK) +AC_SUBST(ASM_ALIGN_LOG) +AC_SUBST(W64_ABI) +AC_SUBST(EMULATOR) + +AC_SUBST(LIBNETTLE_MAJOR) +AC_SUBST(LIBNETTLE_MINOR) +AC_SUBST(LIBNETTLE_FORLINK) +AC_SUBST(LIBNETTLE_SONAME) +AC_SUBST(LIBNETTLE_FILE) +AC_SUBST(LIBNETTLE_FILE_SRC) +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_FILE_SRC) +AC_SUBST(LIBHOGWEED_LINK) +AC_SUBST(LIBHOGWEED_LIBS) + +AC_PATH_PROG(M4, m4, m4) + +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_static" = xyes ; then + IF_STATIC='' +else + IF_STATIC='#' +fi + +IF_DLOPEN_TEST='#' +if test "x$enable_shared" = xyes ; then + IF_SHARED='' + IF_NOT_SHARED='#' + if test "x$ac_cv_lib_dl_dlopen" = xyes ; then + IF_DLOPEN_TEST='' + fi +else + IF_SHARED='#' + IF_NOT_SHARED='' +fi + +# Documentation tools +if test "x$enable_documentation" != "xno"; then + AC_PATH_PROG(MAKEINFO, makeinfo, not-found) + + if test "x$MAKEINFO" != "xnot-found"; then + enable_documentation=yes + AC_SUBST(MAKEINFO) + else + if test "x$enable_documentation" == "xauto" ; then + enable_documentation=no + else + AC_MSG_ERROR([Cannot find 'makeinfo', required for documentation.]) + fi + fi +fi + +if test "x$enable_documentation" = "xyes" ; then + IF_DOCUMENTATION='' +else + IF_DOCUMENTATION='#' +fi + +if test "x$enable_mini_gmp" = "xyes" ; then + IF_MINI_GMP='' +else + IF_MINI_GMP='#' +fi + +AC_SUBST(IF_HOGWEED) +AC_SUBST(IF_STATIC) +AC_SUBST(IF_SHARED) +AC_SUBST(IF_NOT_SHARED) +AC_SUBST(IF_DLOPEN_TEST) +AC_SUBST(IF_DOCUMENTATION) +AC_SUBST(IF_DLL) +AC_SUBST(IF_MINI_GMP) + +OPENSSL_LIBFLAGS='' + +# Check for openssl's libcrypto (used only for benchmarking) +if test x$enable_openssl = xyes ; then + AC_CHECK_LIB(crypto, EVP_CIPHER_CTX_new, + [OPENSSL_LIBFLAGS='-lcrypto'], + [enable_openssl=no]) +fi + +AH_TEMPLATE([WITH_OPENSSL], + [Define if you have openssl's libcrypto (used for benchmarking)]) dnl' + +if test x$enable_openssl = xyes ; then + AC_DEFINE(WITH_OPENSSL) +fi + +AC_SUBST(OPENSSL_LIBFLAGS) + +AH_BOTTOM( +[#if defined(__x86_64__) || defined(__arch64__) +# define HAVE_NATIVE_64_BIT 1 +#else +/* Needs include of before use. */ +# define HAVE_NATIVE_64_BIT (SIZEOF_LONG * CHAR_BIT >= 64) +#endif +]) + +# clock_gettime is in librt on *-*-osf5.1 and on glibc, so add -lrt to +# BENCH_LIBS if needed. On linux (tested on x86_32, 2.6.26), +# clock_getres reports ns accuracy, while in a quick test on osf +# clock_getres said only 1 millisecond. + +old_LIBS="$LIBS" +AC_SEARCH_LIBS(clock_gettime, rt, [ + AC_DEFINE([HAVE_CLOCK_GETTIME],1,[Define if clock_gettime is available])]) +BENCH_LIBS="$LIBS" +LIBS="$old_LIBS" + +AC_SUBST(BENCH_LIBS) + +# 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 version.h]) +AC_CONFIG_FILES([tools/Makefile testsuite/Makefile examples/Makefile]) +AC_CONFIG_FILES([nettle.pc hogweed.pc libnettle.map libhogweed.map]) + +AC_OUTPUT + +AC_MSG_NOTICE([summary of build options: + + Version: ${PACKAGE_STRING} + Host type: ${host} + ABI: ${ABI} + Assembly files: ${asm_path:-none} + Install prefix: ${prefix} + Library directory: ${libdir} + Compiler: ${CC} + Static libraries: ${enable_static} + Shared libraries: ${enable_shared} + Public key crypto: ${enable_public_key} + Using mini-gmp: ${enable_mini_gmp} + Documentation: ${enable_documentation} +]) diff --git a/ctr.c b/ctr.c new file mode 100644 index 0000000..f81f74a --- /dev/null +++ b/ctr.c @@ -0,0 +1,136 @@ +/* ctr.c + + Cipher counter mode. + + Copyright (C) 2005 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "ctr.h" + +#include "macros.h" +#include "memxor.h" +#include "nettle-internal.h" + +#define NBLOCKS 4 + +void +ctr_crypt(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *ctr, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + if (src != dst) + { + if (length == block_size) + { + f(ctx, block_size, dst, ctr); + INCREMENT(block_size, ctr); + memxor(dst, src, block_size); + } + else + { + size_t left; + uint8_t *p; + + for (p = dst, left = length; + left >= block_size; + left -= block_size, p += block_size) + { + memcpy (p, ctr, block_size); + INCREMENT(block_size, ctr); + } + + f(ctx, length - left, dst, dst); + memxor(dst, src, length - left); + + if (left) + { + TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + TMP_ALLOC(buffer, block_size); + + f(ctx, block_size, buffer, ctr); + INCREMENT(block_size, ctr); + memxor3(dst + length - left, src + length - left, buffer, left); + } + } + } + else + { + if (length > block_size) + { + TMP_DECL(buffer, uint8_t, NBLOCKS * NETTLE_MAX_CIPHER_BLOCK_SIZE); + size_t chunk = NBLOCKS * block_size; + + TMP_ALLOC(buffer, chunk); + + for (; length >= chunk; + length -= chunk, src += chunk, dst += chunk) + { + unsigned n; + uint8_t *p; + for (n = 0, p = buffer; n < NBLOCKS; n++, p += block_size) + { + memcpy (p, ctr, block_size); + INCREMENT(block_size, ctr); + } + f(ctx, chunk, buffer, buffer); + memxor(dst, buffer, chunk); + } + + if (length > 0) + { + /* Final, possibly partial, blocks */ + for (chunk = 0; chunk < length; chunk += block_size) + { + memcpy (buffer + chunk, ctr, block_size); + INCREMENT(block_size, ctr); + } + f(ctx, chunk, buffer, buffer); + memxor3(dst, src, buffer, length); + } + } + else if (length > 0) + { + TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE); + TMP_ALLOC(buffer, block_size); + + f(ctx, block_size, buffer, ctr); + INCREMENT(block_size, ctr); + memxor3(dst, src, buffer, length); + } + } +} diff --git a/ctr.h b/ctr.h new file mode 100644 index 0000000..7dd06a2 --- /dev/null +++ b/ctr.h @@ -0,0 +1,71 @@ +/* ctr.h + + Counter mode, using an network byte order incremented counter, + matching the testcases of NIST 800-38A. + + Copyright (C) 2005 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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(const void *ctx, nettle_cipher_func *f, + size_t block_size, uint8_t *ctr, + size_t 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, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0)) \ + : ctr_crypt((void *) &(self)->ctx, \ + (nettle_cipher_func *) (f), \ + sizeof((self)->ctr), (self)->ctr, \ + (length), (dst), (src))) + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CTR_H_INCLUDED */ diff --git a/curve25519-eh-to-x.c b/curve25519-eh-to-x.c new file mode 100644 index 0000000..3a8787f --- /dev/null +++ b/curve25519-eh-to-x.c @@ -0,0 +1,81 @@ +/* curve25519-x.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "curve25519.h" + +#include "ecc.h" +#include "ecc-internal.h" + +/* Transform a point on the twisted Edwards curve to the curve25519 + Montgomery curve, and return the x coordinate. */ +void +curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define vp (p + ecc->p.size) +#define wp (p + 2*ecc->p.size) +#define t0 scratch +#define t1 (scratch + ecc->p.size) +#define t2 (scratch + 2*ecc->p.size) + + const struct ecc_curve *ecc = &_nettle_curve25519; + mp_limb_t cy; + + /* If u = U/W and v = V/W are the coordiantes of the point on the + Edwards curve we get the curve25519 x coordinate as + + x = (1+v) / (1-v) = (W + V) / (W - V) + */ + /* NOTE: For the infinity point, this subtraction gives zero (mod + p), which isn't invertible. For curve25519, the desired output is + x = 0, and we should be fine, since ecc_modp_inv returns 0 + in this case. */ + ecc_modp_sub (ecc, t0, wp, vp); + /* Needs a total of 5*size storage. */ + ecc->p.invert (&ecc->p, t1, t0, t2 + ecc->p.size); + + ecc_modp_add (ecc, t0, wp, vp); + ecc_modp_mul (ecc, t2, t0, t1); + + cy = mpn_sub_n (xp, t2, ecc->p.m, ecc->p.size); + cnd_copy (cy, xp, t2, ecc->p.size); +#undef vp +#undef wp +#undef t0 +#undef t1 +#undef t2 +} diff --git a/curve25519-mul-g.c b/curve25519-mul-g.c new file mode 100644 index 0000000..000e098 --- /dev/null +++ b/curve25519-mul-g.c @@ -0,0 +1,73 @@ +/* curve25519-mul-g.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "curve25519.h" + +#include "ecc.h" +#include "ecc-internal.h" + +/* Intended to be compatible with NaCl's crypto_scalarmult_base. */ +void +curve25519_mul_g (uint8_t *r, const uint8_t *n) +{ + const struct ecc_curve *ecc = &_nettle_curve25519; + uint8_t t[CURVE25519_SIZE]; + mp_limb_t *scratch; + mp_size_t itch; + +#define ng scratch +#define x (scratch + 3*ecc->p.size) +#define scratch_out (scratch + 4*ecc->p.size) + + memcpy (t, n, sizeof(t)); + t[0] &= ~7; + t[CURVE25519_SIZE-1] = (t[CURVE25519_SIZE-1] & 0x3f) | 0x40; + + itch = 4*ecc->p.size + ecc->mul_g_itch; + scratch = gmp_alloc_limbs (itch); + + mpn_set_base256_le (x, ecc->p.size, t, CURVE25519_SIZE); + + ecc_mul_g_eh (ecc, ng, x, scratch_out); + curve25519_eh_to_x (x, ng, scratch_out); + + mpn_get_base256_le (r, CURVE25519_SIZE, x, ecc->p.size); + gmp_free_limbs (scratch, itch); +#undef p +#undef x +#undef scratch_out +} diff --git a/curve25519-mul.c b/curve25519-mul.c new file mode 100644 index 0000000..ba76bc0 --- /dev/null +++ b/curve25519-mul.c @@ -0,0 +1,147 @@ +/* curve25519-mul.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "curve25519.h" + +#include "ecc.h" +#include "ecc-internal.h" + +/* Intended to be compatible with NaCl's crypto_scalarmult. */ +void +curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p) +{ + const struct ecc_curve *ecc = &_nettle_curve25519; + mp_size_t itch; + mp_limb_t *scratch; + int i; + mp_limb_t cy; + + /* FIXME: Could save some more scratch space, e.g., by letting BB + overlap C, D, and CB overlap A, D. And possibly reusing some of + x2, z2, x3, z3. */ +#define x1 scratch +#define x2 (scratch + ecc->p.size) +#define z2 (scratch + 2*ecc->p.size) +#define x3 (scratch + 3*ecc->p.size) +#define z3 (scratch + 4*ecc->p.size) + +#define A (scratch + 5*ecc->p.size) +#define B (scratch + 6*ecc->p.size) +#define C (scratch + 7*ecc->p.size) +#define D (scratch + 8*ecc->p.size) +#define AA (scratch + 9*ecc->p.size) +#define BB (scratch +10*ecc->p.size) +#define E (scratch + 10*ecc->p.size) /* Overlap BB */ +#define DA (scratch + 9*ecc->p.size) /* Overlap AA */ +#define CB (scratch + 10*ecc->p.size) /* Overlap BB */ + + itch = ecc->p.size * 12; + scratch = gmp_alloc_limbs (itch); + + /* Note that 255 % GMP_NUMB_BITS == 0 isn't supported, so x1 always + holds at least 256 bits. */ + mpn_set_base256_le (x1, ecc->p.size, p, CURVE25519_SIZE); + /* Clear bit 255, as required by RFC 7748. */ + x1[255/GMP_NUMB_BITS] &= ~((mp_limb_t) 1 << (255 % GMP_NUMB_BITS)); + + /* Initialize, x2 = x1, z2 = 1 */ + mpn_copyi (x2, x1, ecc->p.size); + z2[0] = 1; + mpn_zero (z2+1, ecc->p.size - 1); + + /* Get x3, z3 from doubling. Since bit 254 is forced to 1. */ + ecc_modp_add (ecc, A, x2, z2); + ecc_modp_sub (ecc, B, x2, z2); + ecc_modp_sqr (ecc, AA, A); + ecc_modp_sqr (ecc, BB, B); + ecc_modp_mul (ecc, x3, AA, BB); + ecc_modp_sub (ecc, E, AA, BB); + ecc_modp_addmul_1 (ecc, AA, E, 121665); + ecc_modp_mul (ecc, z3, E, AA); + + for (i = 253; i >= 3; i--) + { + int bit = (n[i/8] >> (i & 7)) & 1; + + cnd_swap (bit, x2, x3, 2*ecc->p.size); + + /* Formulas from draft-turner-thecurve25519function-00-Mont. We + compute new coordinates in memory-address order, since mul + and sqr clobbers higher limbs. */ + ecc_modp_add (ecc, A, x2, z2); + ecc_modp_sub (ecc, B, x2, z2); + ecc_modp_sqr (ecc, AA, A); + ecc_modp_sqr (ecc, BB, B); + ecc_modp_mul (ecc, x2, AA, BB); /* Last use of BB */ + ecc_modp_sub (ecc, E, AA, BB); + ecc_modp_addmul_1 (ecc, AA, E, 121665); + ecc_modp_add (ecc, C, x3, z3); + ecc_modp_sub (ecc, D, x3, z3); + ecc_modp_mul (ecc, z2, E, AA); /* Last use of E and AA */ + ecc_modp_mul (ecc, DA, D, A); /* Last use of D, A. FIXME: could + let CB overlap. */ + ecc_modp_mul (ecc, CB, C, B); + + ecc_modp_add (ecc, C, DA, CB); + ecc_modp_sqr (ecc, x3, C); + ecc_modp_sub (ecc, C, DA, CB); + ecc_modp_sqr (ecc, DA, C); + ecc_modp_mul (ecc, z3, DA, x1); + + /* FIXME: Could be combined with the loop's initial cnd_swap. */ + cnd_swap (bit, x2, x3, 2*ecc->p.size); + } + /* Do the 3 low zero bits, just duplicating x2 */ + for ( ; i >= 0; i--) + { + ecc_modp_add (ecc, A, x2, z2); + ecc_modp_sub (ecc, B, x2, z2); + ecc_modp_sqr (ecc, AA, A); + ecc_modp_sqr (ecc, BB, B); + ecc_modp_mul (ecc, x2, AA, BB); + ecc_modp_sub (ecc, E, AA, BB); + ecc_modp_addmul_1 (ecc, AA, E, 121665); + ecc_modp_mul (ecc, z2, E, AA); + } + ecc->p.invert (&ecc->p, x3, z2, z3 + ecc->p.size); + ecc_modp_mul (ecc, z3, x2, x3); + cy = mpn_sub_n (x2, z3, ecc->p.m, ecc->p.size); + cnd_copy (cy, x2, z3, ecc->p.size); + mpn_get_base256_le (q, CURVE25519_SIZE, x2, ecc->p.size); + + gmp_free_limbs (scratch, itch); +} diff --git a/curve25519.h b/curve25519.h new file mode 100644 index 0000000..1dcd94d --- /dev/null +++ b/curve25519.h @@ -0,0 +1,60 @@ +/* curve25519.h + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_CURVE25519_H +#define NETTLE_CURVE25519_H + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define curve25519_mul_g nettle_curve25519_mul_g +#define curve25519_mul nettle_curve25519_mul + +#define CURVE25519_SIZE 32 + +/* Indicates that curve25519_mul conforms to RFC 7748. */ +#define NETTLE_CURVE25519_RFC7748 1 + +void +curve25519_mul_g (uint8_t *q, const uint8_t *n); + +void +curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CURVE25519_H */ diff --git a/der-iterator.c b/der-iterator.c new file mode 100644 index 0000000..8c195c0 --- /dev/null +++ b/der-iterator.c @@ -0,0 +1,279 @@ +/* der-iterator.c + + Parsing of ASN.1 DER encoded objects. + + Copyright (C) 2005 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "bignum.h" + +#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, + size_t 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(i->length)) + 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, + size_t 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; + size_t 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; +} + +/* NOTE: This is the only function in this file which needs bignums. + One could split this file in two, one in libnettle and one in + libhogweed. */ +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; +} diff --git a/der2dsa.c b/der2dsa.c new file mode 100644 index 0000000..a48b8f2 --- /dev/null +++ b/der2dsa.c @@ -0,0 +1,147 @@ +/* der2dsa.c + + Decoding of DSA keys in OpenSSL and X.509.1 format. + + Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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) + +/* If q_bits > 0, q is required to be of exactly this size. */ +int +dsa_params_from_der_iterator(struct dsa_params *params, + unsigned max_bits, unsigned q_bits, + struct asn1_der_iterator *i) +{ + /* Dss-Parms ::= SEQUENCE { + p INTEGER, + q INTEGER, + g INTEGER + } + */ + if (i->type == ASN1_INTEGER + && asn1_der_get_bignum(i, params->p, max_bits) + && mpz_sgn(params->p) > 0) + { + unsigned p_bits = mpz_sizeinbase (params->p, 2); + return (GET(i, params->q, q_bits ? q_bits : p_bits) + && (q_bits == 0 || mpz_sizeinbase(params->q, 2) == q_bits) + && mpz_cmp (params->q, params->p) < 0 + && GET(i, params->g, p_bits) + && mpz_cmp (params->g, params->p) < 0 + && asn1_der_iterator_next(i) == ASN1_ITERATOR_END); + } + else + return 0; +} + +int +dsa_public_key_from_der_iterator(const struct dsa_params *params, + mpz_t pub, + struct asn1_der_iterator *i) +{ + /* DSAPublicKey ::= INTEGER + */ + + return (i->type == ASN1_INTEGER + && asn1_der_get_bignum(i, pub, + mpz_sizeinbase (params->p, 2)) + && mpz_sgn(pub) > 0 + && mpz_cmp(pub, params->p) < 0); +} + +int +dsa_openssl_private_key_from_der_iterator(struct dsa_params *params, + mpz_t pub, + mpz_t 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; + + if (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, params->p, p_max_bits)) + { + unsigned p_bits = mpz_sizeinbase (params->p, 2); + return (GET(i, params->q, DSA_SHA1_Q_BITS) + && GET(i, params->g, p_bits) + && mpz_cmp (params->g, params->p) < 0 + && GET(i, pub, p_bits) + && mpz_cmp (pub, params->p) < 0 + && GET(i, priv, DSA_SHA1_Q_BITS) + && asn1_der_iterator_next(i) == ASN1_ITERATOR_END); + } + else + return 0; +} + +int +dsa_openssl_private_key_from_der(struct dsa_params *params, + mpz_t pub, + mpz_t priv, + unsigned p_max_bits, + size_t 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(params, pub, priv, + p_max_bits, &i)); +} diff --git a/der2rsa.c b/der2rsa.c new file mode 100644 index 0000000..dab3523 --- /dev/null +++ b/der2rsa.c @@ -0,0 +1,141 @@ +/* der2rsa.c + + Decoding of keys in PKCS#1 format. + + Copyright (C) 2005 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + size_t 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..76dfb9c --- /dev/null +++ b/des-compat.c @@ -0,0 +1,231 @@ +/* des-compat.c + + The des block cipher, old libdes/openssl-style interface. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#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, + size_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, + size_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_cipher_func *) des_encrypt, + DES_BLOCK_SIZE, *iv, + length, *dst, *src); + break; + case DES_DECRYPT: + nettle_cbc_decrypt(ctx, + (nettle_cipher_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_cipher_func *) des_compat_des3_encrypt, + DES_BLOCK_SIZE, *iv, + length, *dst, *src); + break; + case DES_DECRYPT: + nettle_cbc_decrypt(&keys, (nettle_cipher_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..bda4e75 --- /dev/null +++ b/des-compat.h @@ -0,0 +1,162 @@ +/* des-compat.h + + The des block cipher, old libdes/openssl-style interface. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..ebde935 --- /dev/null +++ b/des.c @@ -0,0 +1,307 @@ +/* des.c + + The des block cipher. + + Copyright (C) 2001, 2010 Niels Möller + Copyright (C) 1992 Dana L. How + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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(size_t length, const uint8_t *key) +{ + size_t 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; + + if (hash > 25) + return 0; + + candidate = weak_key_hash[hash]; + + 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, + size_t 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, + size_t 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..f8f3fea --- /dev/null +++ b/des.h @@ -0,0 +1,120 @@ +/* des.h + + The des block cipher. And triple des. + + Copyright (C) 1992 Dana L. How + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* + * 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, + size_t length, uint8_t *dst, + const uint8_t *src); +void +des_decrypt(const struct des_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +int +des_check_parity(size_t length, const uint8_t *key); + +void +des_fix_parity(size_t 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, + size_t length, uint8_t *dst, + const uint8_t *src); +void +des3_decrypt(const struct des3_ctx *ctx, + size_t 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..9b9d97e --- /dev/null +++ b/des3.c @@ -0,0 +1,82 @@ +/* des3.c + + Triple DES cipher. Three key encrypt-decrypt-encrypt. + + Copyright (C) 2001, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + size_t 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, + size_t 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..738569f --- /dev/null +++ b/desCode.h @@ -0,0 +1,412 @@ +/* desCode.h + * + */ + +/* 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..9c4dfcc --- /dev/null +++ b/descore.README @@ -0,0 +1,311 @@ +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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + +Author's address: how@isl.stanford.edu + + +==>> 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..f1c6504 --- /dev/null +++ b/desdata.c @@ -0,0 +1,197 @@ +/* desdata.c + * + * Generate tables used by des.c and desCode.h. + * + */ + +/* + * des - fast & portable DES encryption & decryption. + * Copyright (C) 1992 Dana L. How + * Please see the file `descore.README' for the complete copyright notice. + * + */ + +#include + +#include "desinfo.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 +main(int argc, char **argv) +{ + unsigned long d, i, j, k, l, m, n, s; /* Always at least 32 bits */ + char b[256], ksr[56]; + + if (argc <= 1) + return 1; + + switch ( argv[1][0] ) { + +default: + return 1; + /* + * <<< make the key parity table >>> + */ + +case 'p': + 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++ ) { + printf("%d,", b[i]); + if ( (i & 31) == 31 ) + printf("\n"); + } + + break; + + + /* + * <<< make the key usage table >>> + */ + +case 'r': + 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; + printf(" %2ld,", (long) m); + if ((j % 12) == 11) + printf("\n"); + } + printf("\n"); + } + + break; + + + /* + * <<< make the keymap table >>> + */ + +case 'k': + 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 |= (1UL << j); + /* rotate right (alg keeps everything rotated by 1) */ + m = (m >> 1) | ((m & 1) << 31); + /* print it out */ + printf(" 0x%08lx,", m); + if ( ( d & 3 ) == 3 ) + printf("\n"); + } + printf("\n"); + } + + break; + + } + + return 0; +} diff --git a/desinfo.h b/desinfo.h new file mode 100644 index 0000000..21af02c --- /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. + * + */ + +/* 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-compat-keygen.c b/dsa-compat-keygen.c new file mode 100644 index 0000000..dbb99ab --- /dev/null +++ b/dsa-compat-keygen.c @@ -0,0 +1,87 @@ +/* dsa-compat-keygen.c + + Generation of DSA keypairs + + Copyright (C) 2002, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "dsa-compat.h" + +#include "bignum.h" + +/* Undo name mangling */ +#undef dsa_generate_keypair +#define dsa_generate_keypair nettle_dsa_generate_keypair + +/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048, 224), + (2048, 256), (3072, 256). */ +int +dsa_compat_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) +{ + struct dsa_params *params; + + switch (q_bits) + { + case 160: + if (p_bits < DSA_SHA1_MIN_P_BITS) + return 0; + break; + case 224: + case 256: + if (p_bits < DSA_SHA256_MIN_P_BITS) + return 0; + break; + default: + return 0; + } + + /* NOTE: Depends on identical layout! */ + params = (struct dsa_params *) pub; + + if (!dsa_generate_params (params, + random_ctx, random, + progress_ctx, progress, + p_bits, q_bits)) + return 0; + + dsa_generate_keypair (params, pub->y, key->x, random_ctx, random); + + return 1; +} diff --git a/dsa-compat.c b/dsa-compat.c new file mode 100644 index 0000000..8c0eff7 --- /dev/null +++ b/dsa-compat.c @@ -0,0 +1,65 @@ +/* dsa-compat.c + + The DSA publickey algorithm, old interface. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa-compat.h" + +void +dsa_public_key_init(struct dsa_public_key *key) +{ + dsa_params_init ((struct dsa_params *) key); + mpz_init(key->y); +} + +void +dsa_public_key_clear(struct dsa_public_key *key) +{ + dsa_params_clear ((struct dsa_params *) key); + 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); +} diff --git a/dsa-compat.h b/dsa-compat.h new file mode 100644 index 0000000..4ec96ed --- /dev/null +++ b/dsa-compat.h @@ -0,0 +1,183 @@ +/* dsa-compat.h + + Old DSA publickey interface. + + Copyright (C) 2002, 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_DSA_COMPAT_H_INCLUDED +#define NETTLE_DSA_COMPAT_H_INCLUDED + +#include "dsa.h" + +#include "sha1.h" +#include "sha2.h" + +/* 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_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_compat_generate_keypair nettle_dsa_compat_generate_keypair + +/* Switch meaning of dsa_generate_keypair */ +#undef dsa_generate_keypair +#define dsa_generate_keypair nettle_dsa_compat_generate_keypair + +#ifdef __cplusplus +extern "C" { +#endif + +struct dsa_public_key +{ + /* Same as struct dsa_params, but can't use that struct here without + breaking backwards compatibility. Layout must be identical, since + this is cast to a struct dsa_param pointer for calling _dsa_sign + and _dsa_verify */ + mpz_t p; + mpz_t q; + 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; +}; + +/* 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); + +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); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DSA_COMPAT_H_INCLUDED */ diff --git a/dsa-gen-params.c b/dsa-gen-params.c new file mode 100644 index 0000000..28bc118 --- /dev/null +++ b/dsa-gen-params.c @@ -0,0 +1,115 @@ +/* dsa-gen-params.c + + Generation of DSA parameters + + Copyright (C) 2002, 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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). */ +int +dsa_generate_params(struct dsa_params *params, + void *random_ctx, nettle_random_func *random, + void *progress_ctx, nettle_progress_func *progress, + unsigned p_bits, unsigned q_bits) +{ + mpz_t r; + unsigned p0_bits; + unsigned a; + + if (q_bits < 30 || p_bits < q_bits + 30) + return 0; + + mpz_init (r); + + nettle_random_prime (params->q, q_bits, 0, random_ctx, random, + progress_ctx, progress); + + if (q_bits >= (p_bits + 2)/3) + _nettle_generate_pocklington_prime (params->p, r, p_bits, 0, + random_ctx, random, + params->q, NULL, params->q); + else + { + mpz_t p0, p0q; + mpz_init (p0); + mpz_init (p0q); + + 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. */ + mpz_mul (p0q, p0, params->q); + + _nettle_generate_pocklington_prime (params->p, r, p_bits, 0, + random_ctx, random, + p0, params->q, p0q); + + mpz_mul (r, r, p0); + + mpz_clear (p0); + mpz_clear (p0q); + } + if (progress) + progress (progress_ctx, 'p'); + + for (a = 2; ; a++) + { + mpz_set_ui (params->g, a); + mpz_powm (params->g, params->g, r, params->p); + if (mpz_cmp_ui (params->g, 1) != 0) + break; + } + + mpz_clear (r); + + if (progress) + progress (progress_ctx, 'g'); + + return 1; +} diff --git a/dsa-hash.c b/dsa-hash.c new file mode 100644 index 0000000..5fc97fc --- /dev/null +++ b/dsa-hash.c @@ -0,0 +1,56 @@ +/* dsa-hash.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +#include "bignum.h" + +/* Convert hash value to an integer. 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. */ +void +_dsa_hash (mpz_t h, unsigned bit_size, + size_t length, const uint8_t *digest) +{ + + if (length > (bit_size + 7) / 8) + length = (bit_size + 7) / 8; + + nettle_mpz_set_str_256_u(h, length, digest); + + if (8 * length > bit_size) + /* We got a few extra bits, at the low end. Discard them. */ + mpz_tdiv_q_2exp (h, h, 8*length - bit_size); +} diff --git a/dsa-keygen.c b/dsa-keygen.c new file mode 100644 index 0000000..a653ae0 --- /dev/null +++ b/dsa-keygen.c @@ -0,0 +1,63 @@ +/* dsa-keygen.c + + Generation of DSA keypairs + + Copyright (C) 2002, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "dsa.h" + +#include "bignum.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. */ +void +dsa_generate_keypair (const struct dsa_params *params, + mpz_t pub, mpz_t key, + + void *random_ctx, nettle_random_func *random) +{ + mpz_t r; + + mpz_init_set(r, params->q); + mpz_sub_ui(r, r, 2); + nettle_mpz_random(key, random_ctx, random, r); + + mpz_add_ui(key, key, 1); + mpz_powm(pub, params->g, key, params->p); + mpz_clear (r); +} diff --git a/dsa-sha1-sign.c b/dsa-sha1-sign.c new file mode 100644 index 0000000..ada81c1 --- /dev/null +++ b/dsa-sha1-sign.c @@ -0,0 +1,66 @@ +/* dsa-sha1-sign.c + + The original DSA publickey algorithm, using SHA-1. + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa-compat.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((const struct dsa_params *) pub, key->x, + 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((const struct dsa_params *) pub, key->x, + 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..bc6c2ec --- /dev/null +++ b/dsa-sha1-verify.c @@ -0,0 +1,59 @@ +/* dsa-sha1-verify.c + + The original DSA publickey algorithm, using SHA-1. + + Copyright (C) 2002, 2003, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa-compat.h" + +int +dsa_sha1_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return dsa_verify((const struct dsa_params *) key, key->y, + 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((const struct dsa_params *) key, key->y, + sizeof(digest), digest, signature); +} diff --git a/dsa-sha256-sign.c b/dsa-sha256-sign.c new file mode 100644 index 0000000..ad02a1b --- /dev/null +++ b/dsa-sha256-sign.c @@ -0,0 +1,65 @@ +/* dsa-sha256-sign.c + + The DSA publickey algorithm, using SHA-256 (FIPS186-3). + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa-compat.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((const struct dsa_params *) pub, key->x, + 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((const struct dsa_params *) pub, key->x, + 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..5669fe4 --- /dev/null +++ b/dsa-sha256-verify.c @@ -0,0 +1,59 @@ +/* dsa-sha256-verify.c + + The DSA publickey algorithm, using SHA-256 (FIPS186-3). + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa-compat.h" + +int +dsa_sha256_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return dsa_verify((const struct dsa_params *) key, key->y, + 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((const struct dsa_params *) key, key->y, + sizeof(digest), digest, signature); +} diff --git a/dsa-sign.c b/dsa-sign.c new file mode 100644 index 0000000..b713743 --- /dev/null +++ b/dsa-sign.c @@ -0,0 +1,100 @@ +/* dsa-sign.c + + The DSA publickey algorithm. + + Copyright (C) 2002, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "dsa.h" + +#include "bignum.h" + + +int +dsa_sign(const struct dsa_params *params, + const mpz_t x, + void *random_ctx, nettle_random_func *random, + size_t digest_size, + const uint8_t *digest, + struct dsa_signature *signature) +{ + mpz_t k; + mpz_t h; + mpz_t tmp; + int res; + + /* Check that p is odd, so that invalid keys don't result in a crash + inside mpz_powm_sec. */ + if (mpz_even_p (params->p)) + 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_sec(tmp, params->g, k, params->p); + mpz_fdiv_r(signature->r, tmp, params->q); + + /* Compute hash */ + mpz_init(h); + _dsa_hash (h, mpz_sizeinbase(params->q, 2), digest_size, digest); + + /* Compute k^-1 (mod q) */ + if (mpz_invert(k, k, params->q)) + { + /* Compute signature s = k^-1 (h + xr) (mod q) */ + mpz_mul(tmp, signature->r, x); + mpz_fdiv_r(tmp, tmp, params->q); + mpz_add(tmp, tmp, h); + mpz_mul(tmp, tmp, k); + mpz_fdiv_r(signature->s, tmp, params->q); + res = 1; + } + else + /* What do we do now? The key is invalid. */ + res = 0; + + mpz_clear(k); + mpz_clear(h); + mpz_clear(tmp); + + return res; +} diff --git a/dsa-verify.c b/dsa-verify.c new file mode 100644 index 0000000..cc984bd --- /dev/null +++ b/dsa-verify.c @@ -0,0 +1,107 @@ +/* dsa-verify.c + + The DSA publickey algorithm. + + Copyright (C) 2002, 2003 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "dsa.h" + +#include "bignum.h" + +int +dsa_verify(const struct dsa_params *params, + const mpz_t y, + size_t digest_size, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + mpz_t w; + mpz_t tmp; + mpz_t v; + + int res; + + /* Check that r and s are in the proper range */ + if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, params->q) >= 0) + return 0; + + if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, params->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, params->q)) + { + mpz_clear(w); + return 0; + } + + mpz_init(tmp); + mpz_init(v); + + /* The message digest */ + _dsa_hash (tmp, mpz_sizeinbase (params->q, 2), digest_size, digest); + + /* v = g^{w * h (mod q)} (mod p) */ + mpz_mul(tmp, tmp, w); + mpz_fdiv_r(tmp, tmp, params->q); + + mpz_powm(v, params->g, tmp, params->p); + + /* y^{w * r (mod q) } (mod p) */ + mpz_mul(tmp, signature->r, w); + mpz_fdiv_r(tmp, tmp, params->q); + + mpz_powm(tmp, y, tmp, params->p); + + /* v = (g^{w * h} * y^{w * r} (mod p) ) (mod q) */ + mpz_mul(v, v, tmp); + mpz_fdiv_r(v, v, params->p); + + mpz_fdiv_r(v, v, params->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..efafb79 --- /dev/null +++ b/dsa.c @@ -0,0 +1,70 @@ +/* dsa.c + + The DSA publickey algorithm. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +#include "bignum.h" + +void +dsa_params_init (struct dsa_params *params) +{ + mpz_init(params->p); + mpz_init(params->q); + mpz_init(params->g); +} + +void +dsa_params_clear (struct dsa_params *params) +{ + mpz_clear(params->p); + mpz_clear(params->q); + mpz_clear(params->g); +} + +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..7aa982a --- /dev/null +++ b/dsa.h @@ -0,0 +1,216 @@ +/* dsa.h + + The DSA publickey algorithm. + + Copyright (C) 2002, 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_DSA_H_INCLUDED +#define NETTLE_DSA_H_INCLUDED + +#include "nettle-types.h" +#include "bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define dsa_params_init nettle_dsa_params_init +#define dsa_params_clear nettle_dsa_params_clear +#define dsa_signature_init nettle_dsa_signature_init +#define dsa_signature_clear nettle_dsa_signature_clear +#define dsa_sign nettle_dsa_sign +#define dsa_verify nettle_dsa_verify +#define dsa_generate_params nettle_dsa_generate_params +#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_hash _nettle_dsa_hash + +/* For FIPS approved parameters */ +#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_params +{ + /* Modulo */ + mpz_t p; + + /* Group order */ + mpz_t q; + + /* Generator */ + mpz_t g; +}; + +void +dsa_params_init (struct dsa_params *params); + +void +dsa_params_clear (struct dsa_params *params); + +struct dsa_signature +{ + mpz_t r; + mpz_t s; +}; + +/* 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_sign(const struct dsa_params *params, + const mpz_t x, + void *random_ctx, nettle_random_func *random, + size_t digest_size, + const uint8_t *digest, + struct dsa_signature *signature); + +int +dsa_verify(const struct dsa_params *params, + const mpz_t y, + size_t digest_size, + const uint8_t *digest, + const struct dsa_signature *signature); + + +/* Key generation */ + +int +dsa_generate_params(struct dsa_params *params, + void *random_ctx, nettle_random_func *random, + void *progress_ctx, nettle_progress_func *progress, + unsigned p_bits, unsigned q_bits); + +void +dsa_generate_keypair (const struct dsa_params *params, + mpz_t pub, mpz_t key, + void *random_ctx, nettle_random_func *random); + +/* 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_params *params, + const mpz_t pub, + const mpz_t 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_params *params, + mpz_t pub, + mpz_t 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_params *params, + mpz_t pub, + mpz_t priv, + unsigned p_max_bits, + size_t length, const uint8_t *expr); + +int +dsa_sha256_keypair_from_sexp(struct dsa_params *params, + mpz_t pub, + mpz_t priv, + unsigned p_max_bits, + size_t length, const uint8_t *expr); + +/* Keys in X.509 andd OpenSSL format. */ +struct asn1_der_iterator; + +int +dsa_params_from_der_iterator(struct dsa_params *params, + unsigned max_bits, unsigned q_bits, + struct asn1_der_iterator *i); + +int +dsa_public_key_from_der_iterator(const struct dsa_params *params, + mpz_t pub, + struct asn1_der_iterator *i); + +int +dsa_openssl_private_key_from_der_iterator(struct dsa_params *params, + mpz_t pub, + mpz_t priv, + unsigned p_max_bits, + struct asn1_der_iterator *i); + +int +dsa_openssl_private_key_from_der(struct dsa_params *params, + mpz_t pub, + mpz_t priv, + unsigned p_max_bits, + size_t length, const uint8_t *data); + + +/* Internal functions. */ +void +_dsa_hash (mpz_t h, unsigned bit_size, + size_t length, const uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DSA_H_INCLUDED */ diff --git a/dsa2sexp.c b/dsa2sexp.c new file mode 100644 index 0000000..593d1f4 --- /dev/null +++ b/dsa2sexp.c @@ -0,0 +1,63 @@ +/* dsa2sexp.c + + Copyright (C) 2002, 2009, 2014 Niels Möller, Magnus Holmgren + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_params *params, + const mpz_t pub, + const mpz_t 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, params->p, params->q, + params->g, pub, priv); + + else + return sexp_format(buffer, + "(public-key(%0s(p%b)(q%b)" + "(g%b)(y%b)))", + algorithm_name, params->p, params->q, + params->g, pub); +} diff --git a/eax-aes128-meta.c b/eax-aes128-meta.c new file mode 100644 index 0000000..c3a878e --- /dev/null +++ b/eax-aes128-meta.c @@ -0,0 +1,58 @@ +/* eax-aes128-meta.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eax.h" +#include "nettle-meta.h" + +static nettle_set_key_func eax_aes128_set_nonce_wrapper; +static void +eax_aes128_set_nonce_wrapper (void *ctx, const uint8_t *nonce) +{ + eax_aes128_set_nonce (ctx, EAX_IV_SIZE, nonce); +} + +const struct nettle_aead +nettle_eax_aes128 = + { "eax_aes128", sizeof(struct eax_aes128_ctx), + EAX_BLOCK_SIZE, AES128_KEY_SIZE, + EAX_IV_SIZE, EAX_DIGEST_SIZE, + (nettle_set_key_func *) eax_aes128_set_key, + (nettle_set_key_func *) eax_aes128_set_key, + eax_aes128_set_nonce_wrapper, + (nettle_hash_update_func *) eax_aes128_update, + (nettle_crypt_func *) eax_aes128_encrypt, + (nettle_crypt_func *) eax_aes128_decrypt, + (nettle_hash_digest_func *) eax_aes128_digest + }; diff --git a/eax-aes128.c b/eax-aes128.c new file mode 100644 index 0000000..6165110 --- /dev/null +++ b/eax-aes128.c @@ -0,0 +1,78 @@ +/* eax-aes128.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eax.h" + +void +eax_aes128_set_key(struct eax_aes128_ctx *ctx, const uint8_t *key) +{ + EAX_SET_KEY(ctx, + aes128_set_encrypt_key, aes128_encrypt, + key); +} + +void +eax_aes128_set_nonce(struct eax_aes128_ctx *ctx, + size_t length, const uint8_t *iv) +{ + EAX_SET_NONCE(ctx, aes128_encrypt, length, iv); +} + +void +eax_aes128_update(struct eax_aes128_ctx *ctx, size_t length, const uint8_t *data) +{ + EAX_UPDATE(ctx, aes128_encrypt, length, data); +} + +void +eax_aes128_encrypt(struct eax_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + EAX_ENCRYPT(ctx, aes128_encrypt, length, dst, src); +} + +void +eax_aes128_decrypt(struct eax_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + EAX_DECRYPT(ctx, aes128_encrypt, length, dst, src); +} + +void +eax_aes128_digest(struct eax_aes128_ctx *ctx, + size_t length, uint8_t *digest) +{ + EAX_DIGEST(ctx, aes128_encrypt, length, digest); +} diff --git a/eax.c b/eax.c new file mode 100644 index 0000000..621020d --- /dev/null +++ b/eax.c @@ -0,0 +1,172 @@ +/* eax.c + + EAX mode, see http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "eax.h" + +#include "ctr.h" +#include "memxor.h" + +static void +omac_init (union nettle_block16 *state, unsigned t) +{ + memset (state->b, 0, EAX_BLOCK_SIZE - 1); + state->b[EAX_BLOCK_SIZE - 1] = t; +} + +/* Almost the same as gcm_gf_add */ +static void +block16_xor (union nettle_block16 *dst, const union nettle_block16 *src) +{ + dst->w[0] ^= src->w[0]; + dst->w[1] ^= src->w[1]; +#if SIZEOF_LONG == 4 + dst->w[2] ^= src->w[2]; + dst->w[3] ^= src->w[3]; +#endif +} + +static void +omac_update (union nettle_block16 *state, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *data) +{ + for (; length >= EAX_BLOCK_SIZE; + length -= EAX_BLOCK_SIZE, data += EAX_BLOCK_SIZE) + { + f (cipher, EAX_BLOCK_SIZE, state->b, state->b); + memxor (state->b, data, EAX_BLOCK_SIZE); + } + if (length > 0) + { + /* Allowed only for the last call */ + f (cipher, EAX_BLOCK_SIZE, state->b, state->b); + memxor (state->b, data, length); + state->b[length] ^= 0x80; + /* XOR with (P ^ B), since the digest processing + * unconditionally XORs with B */ + block16_xor (state, &key->pad_partial); + } +} + +static void +omac_final (union nettle_block16 *state, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f) +{ + block16_xor (state, &key->pad_block); + f (cipher, EAX_BLOCK_SIZE, state->b, state->b); +} + +/* Allows r == a */ +static void +gf2_double (uint8_t *r, const uint8_t *a) +{ + unsigned high = - (a[0] >> 7); + unsigned i; + /* Shift left */ + for (i = 0; i < EAX_BLOCK_SIZE - 1; i++) + r[i] = (a[i] << 1) + (a[i+1] >> 7); + + /* Wrap around for x^{128} = x^7 + x^2 + x + 1 */ + r[EAX_BLOCK_SIZE - 1] = (a[EAX_BLOCK_SIZE - 1] << 1) ^ (high & 0x87); +} + +void +eax_set_key (struct eax_key *key, const void *cipher, nettle_cipher_func *f) +{ + static const union nettle_block16 zero_block; + f (cipher, EAX_BLOCK_SIZE, key->pad_block.b, zero_block.b); + gf2_double (key->pad_block.b, key->pad_block.b); + gf2_double (key->pad_partial.b, key->pad_block.b); + block16_xor (&key->pad_partial, &key->pad_block); +} + +void +eax_set_nonce (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t nonce_length, const uint8_t *nonce) +{ + omac_init (&eax->omac_nonce, 0); + omac_update (&eax->omac_nonce, key, cipher, f, nonce_length, nonce); + omac_final (&eax->omac_nonce, key, cipher, f); + memcpy (eax->ctr.b, eax->omac_nonce.b, EAX_BLOCK_SIZE); + + omac_init (&eax->omac_data, 1); + omac_init (&eax->omac_message, 2); +} + +void +eax_update (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t data_length, const uint8_t *data) +{ + omac_update (&eax->omac_data, key, cipher, f, data_length, data); +} + +void +eax_encrypt (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ctr_crypt (cipher, f, EAX_BLOCK_SIZE, eax->ctr.b, length, dst, src); + omac_update (&eax->omac_message, key, cipher, f, length, dst); +} + +void +eax_decrypt (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + omac_update (&eax->omac_message, key, cipher, f, length, src); + ctr_crypt (cipher, f, EAX_BLOCK_SIZE, eax->ctr.b, length, dst, src); +} + +void +eax_digest (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest) +{ + assert (length > 0); + assert (length <= EAX_BLOCK_SIZE); + omac_final (&eax->omac_data, key, cipher, f); + omac_final (&eax->omac_message, key, cipher, f); + + block16_xor (&eax->omac_nonce, &eax->omac_data); + memxor3 (digest, eax->omac_nonce.b, eax->omac_message.b, length); +} diff --git a/eax.h b/eax.h new file mode 100644 index 0000000..e9747f3 --- /dev/null +++ b/eax.h @@ -0,0 +1,185 @@ +/* eax.h + + EAX mode, see http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_EAX_H_INCLUDED +#define NETTLE_EAX_H_INCLUDED + +#include "aes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define eax_set_key nettle_eax_set_key +#define eax_set_nonce nettle_eax_set_nonce +#define eax_update nettle_eax_update +#define eax_encrypt nettle_eax_encrypt +#define eax_decrypt nettle_eax_decrypt +#define eax_digest nettle_eax_digest + +#define eax_aes128_set_key nettle_eax_aes128_set_key +#define eax_aes128_set_nonce nettle_eax_aes128_set_nonce +#define eax_aes128_update nettle_eax_aes128_update +#define eax_aes128_encrypt nettle_eax_aes128_encrypt +#define eax_aes128_decrypt nettle_eax_aes128_decrypt +#define eax_aes128_digest nettle_eax_aes128_digest + +/* Restricted to block ciphers with 128 bit block size. FIXME: Reflect + this in naming? */ + +#define EAX_BLOCK_SIZE 16 +#define EAX_DIGEST_SIZE 16 +/* FIXME: Reasonable default? */ +#define EAX_IV_SIZE 16 + +/* Values independent of message and nonce */ +struct eax_key +{ + union nettle_block16 pad_block; + union nettle_block16 pad_partial; +}; + +struct eax_ctx +{ + union nettle_block16 omac_nonce; + union nettle_block16 omac_data; + union nettle_block16 omac_message; + union nettle_block16 ctr; +}; + +void +eax_set_key (struct eax_key *key, const void *cipher, nettle_cipher_func *f); + +void +eax_set_nonce (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t nonce_length, const uint8_t *nonce); + +void +eax_update (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t data_length, const uint8_t *data); + +void +eax_encrypt (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +eax_decrypt (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +eax_digest (struct eax_ctx *eax, const struct eax_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest); + +/* Put the cipher last, to get cipher-independent offsets for the EAX + * state. */ +#define EAX_CTX(type) \ + { struct eax_key key; struct eax_ctx eax; type cipher; } + +#define EAX_SET_KEY(ctx, set_key, encrypt, data) \ + do { \ + (set_key)(&(ctx)->cipher, (data)); \ + if (0) (encrypt) (&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0); \ + eax_set_key (&(ctx)->key, &(ctx)->cipher, (nettle_cipher_func *) encrypt); \ + } while (0) + +#define EAX_SET_NONCE(ctx, encrypt, length, nonce) \ + (0 ? (encrypt) (&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : eax_set_nonce (&(ctx)->eax, &(ctx)->key, \ + &(ctx)->cipher, (nettle_cipher_func *) (encrypt), \ + (length), (nonce))) + +#define EAX_UPDATE(ctx, encrypt, length, data) \ + (0 ? (encrypt) (&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : eax_update (&(ctx)->eax, &(ctx)->key, \ + &(ctx)->cipher, (nettle_cipher_func *) (encrypt), \ + (length), (data))) + +#define EAX_ENCRYPT(ctx, encrypt, length, dst, src) \ + (0 ? (encrypt) (&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : eax_encrypt (&(ctx)->eax, &(ctx)->key, \ + &(ctx)->cipher, (nettle_cipher_func *) (encrypt), \ + (length), (dst), (src))) + +#define EAX_DECRYPT(ctx, encrypt, length, dst, src) \ + (0 ? (encrypt) (&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : eax_decrypt (&(ctx)->eax, &(ctx)->key, \ + &(ctx)->cipher, (nettle_cipher_func *) (encrypt), \ + (length), (dst), (src))) + +#define EAX_DIGEST(ctx, encrypt, length, digest) \ + (0 ? (encrypt) (&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : eax_digest (&(ctx)->eax, &(ctx)->key, \ + &(ctx)->cipher, (nettle_cipher_func *) (encrypt), \ + (length), (digest))) + +struct eax_aes128_ctx EAX_CTX(struct aes128_ctx); + +void +eax_aes128_set_key(struct eax_aes128_ctx *ctx, const uint8_t *key); + +void +eax_aes128_set_nonce(struct eax_aes128_ctx *ctx, + size_t length, const uint8_t *iv); + +void +eax_aes128_update(struct eax_aes128_ctx *ctx, + size_t length, const uint8_t *data); + +void +eax_aes128_encrypt(struct eax_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +eax_aes128_decrypt(struct eax_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +eax_aes128_digest(struct eax_aes128_ctx *ctx, size_t length, uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_EAX_H_INCLUDED */ diff --git a/ecc-25519.c b/ecc-25519.c new file mode 100644 index 0000000..92de49b --- /dev/null +++ b/ecc-25519.c @@ -0,0 +1,353 @@ +/* ecc-25519.c + + Arithmetic and tables for curve25519, + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +#define USE_REDC 0 + +#include "ecc-25519.h" + +#define PHIGH_BITS (GMP_NUMB_BITS * ECC_LIMB_SIZE - 255) + +#if HAVE_NATIVE_ecc_25519_modp + +#define ecc_25519_modp nettle_ecc_25519_modp +void +ecc_25519_modp (const struct ecc_modulo *m, mp_limb_t *rp); +#else + +#if PHIGH_BITS == 0 +#error Unsupported limb size */ +#endif + +static void +ecc_25519_modp(const struct ecc_modulo *m UNUSED, mp_limb_t *rp) +{ + mp_limb_t hi, cy; + + cy = mpn_addmul_1 (rp, rp + ECC_LIMB_SIZE, ECC_LIMB_SIZE, + (mp_limb_t) 19 << PHIGH_BITS); + hi = rp[ECC_LIMB_SIZE-1]; + cy = (cy << PHIGH_BITS) + (hi >> (GMP_NUMB_BITS - PHIGH_BITS)); + rp[ECC_LIMB_SIZE-1] = (hi & (GMP_NUMB_MASK >> PHIGH_BITS)) + + sec_add_1 (rp, rp, ECC_LIMB_SIZE - 1, 19 * cy); +} +#endif /* HAVE_NATIVE_ecc_25519_modp */ + +#define QHIGH_BITS (GMP_NUMB_BITS * ECC_LIMB_SIZE - 252) + +#if QHIGH_BITS == 0 +#error Unsupported limb size */ +#endif + +static void +ecc_25519_modq (const struct ecc_modulo *q, mp_limb_t *rp) +{ + mp_size_t n; + mp_limb_t cy; + + /* n is the offset where we add in the next term */ + for (n = ECC_LIMB_SIZE; n-- > 0;) + { + cy = mpn_submul_1 (rp + n, + q->B_shifted, ECC_LIMB_SIZE, + rp[n + ECC_LIMB_SIZE]); + /* Top limb of mBmodq_shifted is zero, so we get cy == 0 or 1 */ + assert (cy < 2); + cnd_add_n (cy, rp+n, q->m, ECC_LIMB_SIZE); + } + + cy = mpn_submul_1 (rp, q->m, ECC_LIMB_SIZE, + rp[ECC_LIMB_SIZE-1] >> (GMP_NUMB_BITS - QHIGH_BITS)); + assert (cy < 2); + cnd_add_n (cy, rp, q->m, ECC_LIMB_SIZE); +} + +/* Needs 2*ecc->size limbs at rp, and 2*ecc->size additional limbs of + scratch space. No overlap allowed. */ +static void +ecc_mod_pow_2kp1 (const struct ecc_modulo *m, + mp_limb_t *rp, const mp_limb_t *xp, + unsigned k, mp_limb_t *tp) +{ + if (k & 1) + { + ecc_mod_sqr (m, tp, xp); + k--; + } + else + { + ecc_mod_sqr (m, rp, xp); + ecc_mod_sqr (m, tp, rp); + k -= 2; + } + while (k > 0) + { + ecc_mod_sqr (m, rp, tp); + ecc_mod_sqr (m, tp, rp); + k -= 2; + } + ecc_mod_mul (m, rp, tp, xp); +} + +/* Computes a^{(p-5)/8} = a^{2^{252-3}} mod m. Needs 5 * n scratch + space. */ +static void +ecc_mod_pow_252m3 (const struct ecc_modulo *m, + mp_limb_t *rp, const mp_limb_t *ap, mp_limb_t *scratch) +{ +#define a7 scratch +#define t0 (scratch + ECC_LIMB_SIZE) +#define t1 (scratch + 3*ECC_LIMB_SIZE) + + /* a^{2^252 - 3} = a^{(p-5)/8}, using the addition chain + 2^252 - 3 + = 1 + (2^252-4) + = 1 + 4 (2^250-1) + = 1 + 4 (2^125+1)(2^125-1) + = 1 + 4 (2^125+1)(1+2(2^124-1)) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^62-1)) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(2^31-1)) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^28-1))) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^14-1))) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^7+1)(2^7-1))) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^7+1)(1+2(2^6-1)))) + = 1 + 4 (2^125+1)(1+2(2^62+1)(2^31+1)(7+8(2^14+1)(2^7+1)(1+2(2^3+1)*7))) + */ + + ecc_mod_pow_2kp1 (m, t0, ap, 1, t1); /* a^3 */ + ecc_mod_sqr (m, rp, t0); /* a^6 */ + ecc_mod_mul (m, a7, rp, ap); /* a^7 */ + ecc_mod_pow_2kp1 (m, rp, a7, 3, t0); /* a^63 = a^{2^6-1} */ + ecc_mod_sqr (m, t0, rp); /* a^{2^7-2} */ + ecc_mod_mul (m, rp, t0, ap); /* a^{2^7-1} */ + ecc_mod_pow_2kp1 (m, t0, rp, 7, t1); /* a^{2^14-1}*/ + ecc_mod_pow_2kp1 (m, rp, t0, 14, t1); /* a^{2^28-1} */ + ecc_mod_sqr (m, t0, rp); /* a^{2^29-2} */ + ecc_mod_sqr (m, t1, t0); /* a^{2^30-4} */ + ecc_mod_sqr (m, t0, t1); /* a^{2^31-8} */ + ecc_mod_mul (m, rp, t0, a7); /* a^{2^31-1} */ + ecc_mod_pow_2kp1 (m, t0, rp, 31, t1); /* a^{2^62-1} */ + ecc_mod_pow_2kp1 (m, rp, t0, 62, t1); /* a^{2^124-1}*/ + ecc_mod_sqr (m, t0, rp); /* a^{2^125-2} */ + ecc_mod_mul (m, rp, t0, ap); /* a^{2^125-1} */ + ecc_mod_pow_2kp1 (m, t0, rp, 125, t1);/* a^{2^250-1} */ + ecc_mod_sqr (m, rp, t0); /* a^{2^251-2} */ + ecc_mod_sqr (m, t0, rp); /* a^{2^252-4} */ + ecc_mod_mul (m, rp, t0, ap); /* a^{2^252-3} */ +#undef t0 +#undef t1 +#undef a7 +} + +/* Needs 5*ECC_LIMB_SIZE scratch space. */ +#define ECC_25519_INV_ITCH (5*ECC_LIMB_SIZE) + +static void ecc_25519_inv (const struct ecc_modulo *p, + mp_limb_t *rp, const mp_limb_t *ap, + mp_limb_t *scratch) +{ +#define t0 scratch + + /* Addition chain + + p - 2 = 2^{255} - 21 + = 1 + 2 (1 + 4 (2^{252}-3)) + */ + ecc_mod_pow_252m3 (p, rp, ap, t0); + ecc_mod_sqr (p, t0, rp); + ecc_mod_sqr (p, rp, t0); + ecc_mod_mul (p, t0, ap, rp); + ecc_mod_sqr (p, rp, t0); + ecc_mod_mul (p, t0, ap, rp); + mpn_copyi (rp, t0, ECC_LIMB_SIZE); /* FIXME: Eliminate copy? */ +#undef t0 +} + +/* First, do a canonical reduction, then check if zero */ +static int +ecc_25519_zero_p (const struct ecc_modulo *p, mp_limb_t *xp) +{ + mp_limb_t cy; + mp_limb_t w; + mp_size_t i; +#if PHIGH_BITS > 0 + mp_limb_t hi = xp[ECC_LIMB_SIZE-1]; + xp[ECC_LIMB_SIZE-1] = (hi & (GMP_NUMB_MASK >> PHIGH_BITS)) + + sec_add_1 (xp, xp, ECC_LIMB_SIZE - 1, 19 * (hi >> (GMP_NUMB_BITS - PHIGH_BITS))); +#endif + cy = mpn_sub_n (xp, xp, p->m, ECC_LIMB_SIZE); + cnd_add_n (cy, xp, p->m, ECC_LIMB_SIZE); + + for (i = 0, w = 0; i < ECC_LIMB_SIZE; i++) + w |= xp[i]; + return w == 0; +} + +/* Compute x such that x^2 = u/v (mod p). Returns one on success, zero + on failure. We use the e = 2 special case of the Shanks-Tonelli + algorithm (see http://www.math.vt.edu/people/brown/doc/sqrts.pdf, + or Henri Cohen, Computational Algebraic Number Theory, 1.5.1). + + To avoid a separate inversion, we also use a trick of djb's, to + compute the candidate root as + + x = (u/v)^{(p+3)/8} = u v^3 (u v^7)^{(p-5)/8}. +*/ +#if ECC_SQRT_E != 2 +#error Broken curve25519 parameters +#endif + +/* Needs 4*n space + scratch for ecc_mod_pow_252m3. */ +#define ECC_25519_SQRT_ITCH (9*ECC_LIMB_SIZE) + +static int +ecc_25519_sqrt(const struct ecc_modulo *p, mp_limb_t *rp, + const mp_limb_t *up, const mp_limb_t *vp, + mp_limb_t *scratch) +{ + int pos, neg; + +#define uv3 scratch +#define uv7 (scratch + ECC_LIMB_SIZE) +#define uv7p (scratch + 2*ECC_LIMB_SIZE) +#define v2 (scratch + 2*ECC_LIMB_SIZE) +#define uv (scratch + 3*ECC_LIMB_SIZE) +#define v4 (scratch + 3*ECC_LIMB_SIZE) + +#define scratch_out (scratch + 4 * ECC_LIMB_SIZE) + +#define x2 scratch +#define vx2 (scratch + ECC_LIMB_SIZE) +#define t0 (scratch + 2*ECC_LIMB_SIZE) + + /* Live values */ + ecc_mod_sqr (p, v2, vp); /* v2 */ + ecc_mod_mul (p, uv, up, vp); /* uv, v2 */ + ecc_mod_mul (p, uv3, uv, v2); /* uv3, v2 */ + ecc_mod_sqr (p, v4, v2); /* uv3, v4 */ + ecc_mod_mul (p, uv7, uv3, v4); /* uv3, uv7 */ + ecc_mod_pow_252m3 (p, uv7p, uv7, scratch_out); /* uv3, uv7p */ + ecc_mod_mul (p, rp, uv7p, uv3); /* none */ + + /* Check sign. If square root exists, have v x^2 = ±u */ + ecc_mod_sqr (p, x2, rp); + ecc_mod_mul (p, vx2, x2, vp); + ecc_mod_add (p, t0, vx2, up); + neg = ecc_25519_zero_p (p, t0); + ecc_mod_sub (p, t0, up, vx2); + pos = ecc_25519_zero_p (p, t0); + + ecc_mod_mul (p, t0, rp, ecc_sqrt_z); + cnd_copy (neg, rp, t0, ECC_LIMB_SIZE); + return pos | neg; + +#undef uv3 +#undef uv7 +#undef uv7p +#undef v2 +#undef v4 +#undef scratch_out +#undef x2 +#undef vx2 +#undef t0 +} + +const struct ecc_curve _nettle_curve25519 = +{ + { + 255, + ECC_LIMB_SIZE, + ECC_BMODP_SIZE, + 0, + ECC_25519_INV_ITCH, + ECC_25519_SQRT_ITCH, + + ecc_p, + ecc_Bmodp, + ecc_Bmodp_shifted, + NULL, + ecc_pp1h, + + ecc_25519_modp, + ecc_25519_modp, + ecc_25519_inv, + ecc_25519_sqrt, + }, + { + 253, + ECC_LIMB_SIZE, + ECC_BMODQ_SIZE, + 0, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_q, + ecc_Bmodq, + ecc_mBmodq_shifted, /* Use q - 2^{252} instead. */ + NULL, + ecc_qp1h, + + ecc_25519_modq, + ecc_25519_modq, + ecc_mod_inv, + NULL, + }, + + 0, /* No redc */ + ECC_PIPPENGER_K, + ECC_PIPPENGER_C, + + ECC_ADD_EHH_ITCH (ECC_LIMB_SIZE), + ECC_MUL_A_EH_ITCH (ECC_LIMB_SIZE), + ECC_MUL_G_EH_ITCH (ECC_LIMB_SIZE), + ECC_EH_TO_A_ITCH (ECC_LIMB_SIZE, ECC_25519_INV_ITCH), + + ecc_add_ehh, + ecc_mul_a_eh, + ecc_mul_g_eh, + ecc_eh_to_a, + + ecc_d, /* Use the Edwards curve constant. */ + ecc_g, + ecc_edwards, + ecc_unit, + ecc_table +}; diff --git a/ecc-256.c b/ecc-256.c new file mode 100644 index 0000000..bf5b6b8 --- /dev/null +++ b/ecc-256.c @@ -0,0 +1,307 @@ +/* ecc-256.c + + Compile time constant (but machine dependent) tables. + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +#if HAVE_NATIVE_ecc_256_redc +# define USE_REDC 1 +#else +# define USE_REDC (ECC_REDC_SIZE != 0) +#endif + +#include "ecc-256.h" + +#if HAVE_NATIVE_ecc_256_redc +# define ecc_256_redc nettle_ecc_256_redc +void +ecc_256_redc (const struct ecc_modulo *p, mp_limb_t *rp); +#else /* !HAVE_NATIVE_ecc_256_redc */ +# if ECC_REDC_SIZE > 0 +# define ecc_256_redc ecc_pp1_redc +# elif ECC_REDC_SIZE == 0 +# define ecc_256_redc NULL +# else +# error Configuration error +# endif +#endif /* !HAVE_NATIVE_ecc_256_redc */ + +#if ECC_BMODP_SIZE < ECC_LIMB_SIZE +#define ecc_256_modp ecc_mod +#define ecc_256_modq ecc_mod +#elif GMP_NUMB_BITS == 64 + +static void +ecc_256_modp (const struct ecc_modulo *p, mp_limb_t *rp) +{ + mp_limb_t u1, u0; + mp_size_t n; + + n = 2*p->size; + u1 = rp[--n]; + u0 = rp[n-1]; + + /* This is not particularly fast, but should work well with assembly implementation. */ + for (; n >= p->size; n--) + { + mp_limb_t q2, q1, q0, t, cy; + + /* = v * u1 + , with v = 2^32 - 1: + + +---+---+ + | u1| u0| + +---+---+ + |-u1| + +-+-+-+ + | u1| + +---+-+-+-+-+ + | q2| q1| q0| + +---+---+---+ + */ + q1 = u1 - (u1 > u0); + q0 = u0 - u1; + t = u1 << 32; + q0 += t; + t = (u1 >> 32) + (q0 < t) + 1; + q1 += t; + q2 = q1 < t; + + /* Compute candidate remainder */ + u1 = u0 + (q1 << 32) - q1; + t = -(mp_limb_t) (u1 > q0); + u1 -= t & 0xffffffff; + q1 += t; + q2 += t + (q1 < t); + + assert (q2 < 2); + + /* + n-1 n-2 n-3 n-4 + +---+---+---+---+ + | u1| u0| u low | + +---+---+---+---+ + - | q1(2^96-1)| + +-------+---+ + |q2(2^.)| + +-------+ + + We multiply by two low limbs of p, 2^96 - 1, so we could use + shifts rather than mul. + */ + t = mpn_submul_1 (rp + n - 4, p->m, 2, q1); + t += cnd_sub_n (q2, rp + n - 3, p->m, 1); + t += (-q2) & 0xffffffff; + + u0 = rp[n-2]; + cy = (u0 < t); + u0 -= t; + t = (u1 < cy); + u1 -= cy; + + cy = cnd_add_n (t, rp + n - 4, p->m, 2); + u0 += cy; + u1 += (u0 < cy); + u1 -= (-t) & 0xffffffff; + } + rp[2] = u0; + rp[3] = u1; +} + +static void +ecc_256_modq (const struct ecc_modulo *q, mp_limb_t *rp) +{ + mp_limb_t u2, u1, u0; + mp_size_t n; + + n = 2*q->size; + u2 = rp[--n]; + u1 = rp[n-1]; + + /* This is not particularly fast, but should work well with assembly implementation. */ + for (; n >= q->size; n--) + { + mp_limb_t q2, q1, q0, t, c1, c0; + + u0 = rp[n-2]; + + /* = v * u2 + , same method as above. + + +---+---+ + | u2| u1| + +---+---+ + |-u2| + +-+-+-+ + | u2| + +---+-+-+-+-+ + | q2| q1| q0| + +---+---+---+ + */ + q1 = u2 - (u2 > u1); + q0 = u1 - u2; + t = u2 << 32; + q0 += t; + t = (u2 >> 32) + (q0 < t) + 1; + q1 += t; + q2 = q1 < t; + + /* Compute candidate remainder, - * (2^128 - 2^96 + 2^64 - 1) + + 2^64 q2 + (2^96 - 2^64 + 1) q1 (mod 2^128) + + +---+---+ + | u1| u0| + +---+---+ + | q2| q1| + +---+---+ + |-q1| + +-+-+-+ + | q1| + --+-+-+-+---+ + | u2| u1| + +---+---+ + */ + u2 = u1 + q2 - q1; + u1 = u0 + q1; + u2 += (u1 < q1); + u2 += (q1 << 32); + + t = -(mp_limb_t) (u2 >= q0); + q1 += t; + q2 += t + (q1 < t); + u1 += t; + u2 += (t << 32) + (u1 < t); + + assert (q2 < 2); + + c0 = cnd_sub_n (q2, rp + n - 3, q->m, 1); + c0 += (-q2) & q->m[1]; + t = mpn_submul_1 (rp + n - 4, q->m, 2, q1); + c0 += t; + c1 = c0 < t; + + /* Construct underflow condition. */ + c1 += (u1 < c0); + t = - (mp_limb_t) (u2 < c1); + + u1 -= c0; + u2 -= c1; + + /* Conditional add of p */ + u1 += t; + u2 += (t<<32) + (u1 < t); + + t = cnd_add_n (t, rp + n - 4, q->m, 2); + u1 += t; + u2 += (u1 < t); + } + rp[2] = u1; + rp[3] = u2; +} + +#else +#error Unsupported parameters +#endif + +const struct ecc_curve nettle_secp_256r1 = +{ + { + 256, + ECC_LIMB_SIZE, + ECC_BMODP_SIZE, + ECC_REDC_SIZE, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_p, + ecc_Bmodp, + ecc_Bmodp_shifted, + ecc_redc_ppm1, + + ecc_pp1h, + ecc_256_modp, + USE_REDC ? ecc_256_redc : ecc_256_modp, + ecc_mod_inv, + NULL, + }, + { + 256, + ECC_LIMB_SIZE, + ECC_BMODQ_SIZE, + 0, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_q, + ecc_Bmodq, + ecc_Bmodq_shifted, + NULL, + ecc_qp1h, + + ecc_256_modq, + ecc_256_modq, + ecc_mod_inv, + NULL, + }, + + USE_REDC, + ECC_PIPPENGER_K, + ECC_PIPPENGER_C, + + ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), + ECC_MUL_A_ITCH (ECC_LIMB_SIZE), + ECC_MUL_G_ITCH (ECC_LIMB_SIZE), + ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), + + ecc_add_jjj, + ecc_mul_a, + ecc_mul_g, + ecc_j_to_a, + + ecc_b, + ecc_g, + NULL, + ecc_unit, + ecc_table +}; + +const struct ecc_curve *nettle_get_secp_256r1(void) +{ + return &nettle_secp_256r1; +} diff --git a/ecc-384.c b/ecc-384.c new file mode 100644 index 0000000..cba0178 --- /dev/null +++ b/ecc-384.c @@ -0,0 +1,215 @@ +/* ecc-384.c + + Compile time constant (but machine dependent) tables. + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +#define USE_REDC 0 + +#include "ecc-384.h" + +#if HAVE_NATIVE_ecc_384_modp +#define ecc_384_modp nettle_ecc_384_modp +void +ecc_384_modp (const struct ecc_modulo *m, mp_limb_t *rp); +#elif GMP_NUMB_BITS == 32 + +/* Use that 2^{384} = 2^{128} + 2^{96} - 2^{32} + 1, and eliminate 256 + bits at a time. + + We can get carry == 2 in the first iteration, and I think *only* in + the first iteration. */ + +/* p is 12 limbs, and B^12 - p = B^4 + B^3 - B + 1. We can eliminate + almost 8 at a time. Do only 7, to avoid additional carry + propagation, followed by 5. */ +static void +ecc_384_modp (const struct ecc_modulo *p, mp_limb_t *rp) +{ + mp_limb_t cy, bw; + + /* Reduce from 24 to 17 limbs. */ + cy = mpn_add_n (rp + 4, rp + 4, rp + 16, 8); + cy = sec_add_1 (rp + 12, rp + 12, 3, cy); + + bw = mpn_sub_n (rp + 5, rp + 5, rp + 16, 8); + bw = sec_sub_1 (rp + 13, rp + 13, 3, bw); + + cy += mpn_add_n (rp + 7, rp + 7, rp + 16, 8); + cy = sec_add_1 (rp + 15, rp + 15, 1, cy); + + cy += mpn_add_n (rp + 8, rp + 8, rp + 16, 8); + assert (bw <= cy); + cy -= bw; + + assert (cy <= 2); + rp[16] = cy; + + /* Reduce from 17 to 12 limbs */ + cy = mpn_add_n (rp, rp, rp + 12, 5); + cy = sec_add_1 (rp + 5, rp + 5, 3, cy); + + bw = mpn_sub_n (rp + 1, rp + 1, rp + 12, 5); + bw = sec_sub_1 (rp + 6, rp + 6, 6, bw); + + cy += mpn_add_n (rp + 3, rp + 3, rp + 12, 5); + cy = sec_add_1 (rp + 8, rp + 8, 1, cy); + + cy += mpn_add_n (rp + 4, rp + 4, rp + 12, 5); + cy = sec_add_1 (rp + 9, rp + 9, 3, cy); + + assert (cy >= bw); + cy -= bw; + assert (cy <= 1); + cy = cnd_add_n (cy, rp, p->B, ECC_LIMB_SIZE); + assert (cy == 0); +} +#elif GMP_NUMB_BITS == 64 +/* p is 6 limbs, and B^6 - p = B^2 + 2^32 (B - 1) + 1. Eliminate 3 + (almost 4) limbs at a time. */ +static void +ecc_384_modp (const struct ecc_modulo *p, mp_limb_t *rp) +{ + mp_limb_t tp[6]; + mp_limb_t cy; + + /* Reduce from 12 to 9 limbs */ + tp[0] = 0; /* FIXME: Could use mpn_sub_nc */ + mpn_copyi (tp + 1, rp + 8, 3); + tp[4] = rp[11] - mpn_sub_n (tp, tp, rp + 8, 4); + tp[5] = mpn_lshift (tp, tp, 5, 32); + + cy = mpn_add_n (rp + 2, rp + 2, rp + 8, 4); + cy = sec_add_1 (rp + 6, rp + 6, 2, cy); + + cy += mpn_add_n (rp + 2, rp + 2, tp, 6); + cy += mpn_add_n (rp + 4, rp + 4, rp + 8, 4); + + assert (cy <= 2); + rp[8] = cy; + + /* Reduce from 9 to 6 limbs */ + tp[0] = 0; + mpn_copyi (tp + 1, rp + 6, 2); + tp[3] = rp[8] - mpn_sub_n (tp, tp, rp + 6, 3); + tp[4] = mpn_lshift (tp, tp, 4, 32); + + cy = mpn_add_n (rp, rp, rp + 6, 3); + cy = sec_add_1 (rp + 3, rp + 3, 2, cy); + cy += mpn_add_n (rp, rp, tp, 5); + cy += mpn_add_n (rp + 2, rp + 2, rp + 6, 3); + + cy = sec_add_1 (rp + 5, rp + 5, 1, cy); + assert (cy <= 1); + + cy = cnd_add_n (cy, rp, p->B, ECC_LIMB_SIZE); + assert (cy == 0); +} +#else +#define ecc_384_modp ecc_mod +#endif + +const struct ecc_curve nettle_secp_384r1 = +{ + { + 384, + ECC_LIMB_SIZE, + ECC_BMODP_SIZE, + ECC_REDC_SIZE, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_p, + ecc_Bmodp, + ecc_Bmodp_shifted, + ecc_redc_ppm1, + ecc_pp1h, + + ecc_384_modp, + ecc_384_modp, + ecc_mod_inv, + NULL, + }, + { + 384, + ECC_LIMB_SIZE, + ECC_BMODQ_SIZE, + 0, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_q, + ecc_Bmodq, + ecc_Bmodq_shifted, + NULL, + ecc_qp1h, + + ecc_mod, + ecc_mod, + ecc_mod_inv, + NULL, + }, + + USE_REDC, + ECC_PIPPENGER_K, + ECC_PIPPENGER_C, + + ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), + ECC_MUL_A_ITCH (ECC_LIMB_SIZE), + ECC_MUL_G_ITCH (ECC_LIMB_SIZE), + ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), + + ecc_add_jjj, + ecc_mul_a, + ecc_mul_g, + ecc_j_to_a, + + ecc_b, + ecc_g, + NULL, + ecc_unit, + ecc_table +}; + +const struct ecc_curve *nettle_get_secp_384r1(void) +{ + return &nettle_secp_384r1; +} diff --git a/ecc-521.c b/ecc-521.c new file mode 100644 index 0000000..39a1871 --- /dev/null +++ b/ecc-521.c @@ -0,0 +1,143 @@ +/* ecc-521.c + + Compile time constant (but machine dependent) tables. + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +#define USE_REDC 0 + +#include "ecc-521.h" + +#if HAVE_NATIVE_ecc_521_modp +#define ecc_521_modp nettle_ecc_521_modp +void +ecc_521_modp (const struct ecc_modulo *m, mp_limb_t *rp); + +#else + +#define B_SHIFT (521 % GMP_NUMB_BITS) +#define BMODP_SHIFT (GMP_NUMB_BITS - B_SHIFT) +#define BMODP ((mp_limb_t) 1 << BMODP_SHIFT) + +/* Result may be *slightly* larger than 2^521 */ +static void +ecc_521_modp (const struct ecc_modulo *m UNUSED, mp_limb_t *rp) +{ + /* FIXME: Should use mpn_addlsh_n_ip1 */ + mp_limb_t hi; + /* Reduce from 2*ECC_LIMB_SIZE to ECC_LIMB_SIZE + 1 */ + rp[ECC_LIMB_SIZE] + = mpn_addmul_1 (rp, rp + ECC_LIMB_SIZE, ECC_LIMB_SIZE, BMODP); + hi = mpn_addmul_1 (rp, rp + ECC_LIMB_SIZE, 1, BMODP); + hi = sec_add_1 (rp + 1, rp + 1, ECC_LIMB_SIZE - 1, hi); + + /* Combine hi with top bits, and add in. */ + hi = (hi << BMODP_SHIFT) | (rp[ECC_LIMB_SIZE-1] >> B_SHIFT); + rp[ECC_LIMB_SIZE-1] = (rp[ECC_LIMB_SIZE-1] + & (((mp_limb_t) 1 << B_SHIFT)-1)) + + sec_add_1 (rp, rp, ECC_LIMB_SIZE - 1, hi); +} +#endif + +const struct ecc_curve nettle_secp_521r1 = +{ + { + 521, + ECC_LIMB_SIZE, + ECC_BMODP_SIZE, + ECC_REDC_SIZE, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_p, + ecc_Bmodp, + ecc_Bmodp_shifted, + ecc_redc_ppm1, + ecc_pp1h, + + ecc_521_modp, + ecc_521_modp, + ecc_mod_inv, + NULL, + }, + { + 521, + ECC_LIMB_SIZE, + ECC_BMODQ_SIZE, + 0, + ECC_MOD_INV_ITCH (ECC_LIMB_SIZE), + 0, + + ecc_q, + ecc_Bmodq, + ecc_Bmodq_shifted, + NULL, + ecc_qp1h, + + ecc_mod, + ecc_mod, + ecc_mod_inv, + NULL, + }, + + USE_REDC, + ECC_PIPPENGER_K, + ECC_PIPPENGER_C, + + ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE), + ECC_MUL_A_ITCH (ECC_LIMB_SIZE), + ECC_MUL_G_ITCH (ECC_LIMB_SIZE), + ECC_J_TO_A_ITCH (ECC_LIMB_SIZE), + + ecc_add_jjj, + ecc_mul_a, + ecc_mul_g, + ecc_j_to_a, + + ecc_b, + ecc_g, + NULL, + ecc_unit, + ecc_table +}; + +const struct ecc_curve *nettle_get_secp_521r1(void) +{ + return &nettle_secp_521r1; +} diff --git a/ecc-a-to-j.c b/ecc-a-to-j.c new file mode 100644 index 0000000..9fb0d2b --- /dev/null +++ b/ecc-a-to-j.c @@ -0,0 +1,59 @@ +/* ecc-a-to-j.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_a_to_j (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p) +{ + if (ecc->use_redc) + { + mpn_copyd (r + ecc->p.size, p, 2*ecc->p.size); + + mpn_zero (r, ecc->p.size); + ecc->p.mod (&ecc->p, r); + + mpn_zero (r + ecc->p.size, ecc->p.size); + ecc->p.mod (&ecc->p, r + ecc->p.size); + } + else if (r != p) + mpn_copyi (r, p, 2*ecc->p.size); + + mpn_copyi (r + 2*ecc->p.size, ecc->unit, ecc->p.size); +} diff --git a/ecc-add-eh.c b/ecc-add-eh.c new file mode 100644 index 0000000..c07ff49 --- /dev/null +++ b/ecc-add-eh.c @@ -0,0 +1,107 @@ +/* ecc-add-eh.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +/* Add two points on an Edwards curve, with result and first point in + homogeneous coordinates. */ +void +ecc_add_eh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch) +{ +#define x1 p +#define y1 (p + ecc->p.size) +#define z1 (p + 2*ecc->p.size) + +#define x2 q +#define y2 (q + ecc->p.size) + +#define x3 r +#define y3 (r + ecc->p.size) +#define z3 (r + 2*ecc->p.size) + + /* Formulas (from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl): + + Computation Operation Live variables + + C = x1*x2 mul C + D = y1*y2 mul C, D + T = (x1+y1)(x2+y2) - C - D C, D, T + E = b*C*D 2 mul C, E, T (Replace C <-- D - C) + B = z1^2 sqr B, C, E, T + F = B - E B, C, E, F, T + G = B + E C, F, G, T + x3 = z1*F*T 3 mul C, F, G, T + y3 = z1*G*(D-C) 2 mul F, G + z3 = F*G mul + */ +#define C (scratch) +#define D (scratch + 1*ecc->p.size) +#define T (scratch + 2*ecc->p.size) +#define E (scratch + 3*ecc->p.size) +#define B (scratch + 4*ecc->p.size) +#define F D +#define G E + + ecc_modp_mul (ecc, C, x1, x2); + ecc_modp_mul (ecc, D, y1, y2); + ecc_modp_add (ecc, x3, x1, y1); + ecc_modp_add (ecc, y3, x2, y2); + ecc_modp_mul (ecc, T, x3, y3); + ecc_modp_sub (ecc, T, T, C); + ecc_modp_sub (ecc, T, T, D); + ecc_modp_mul (ecc, x3, C, D); + ecc_modp_mul (ecc, E, x3, ecc->b); + + ecc_modp_add (ecc, C, D, C); /* ! */ + ecc_modp_sqr (ecc, B, z1); + ecc_modp_sub (ecc, F, B, E); + ecc_modp_add (ecc, G, B, E); + + /* x3 */ + ecc_modp_mul (ecc, B, G, T); /* ! */ + ecc_modp_mul (ecc, x3, B, z1); + + /* y3 */ + ecc_modp_mul (ecc, B, F, z1); /* ! */ + ecc_modp_mul (ecc, y3, B, C); /* Clobbers z1 in case r == p. */ + + /* z3 */ + ecc_modp_mul (ecc, B, F, G); + mpn_copyi (z3, B, ecc->p.size); +} diff --git a/ecc-add-ehh.c b/ecc-add-ehh.c new file mode 100644 index 0000000..8fdc9ec --- /dev/null +++ b/ecc-add-ehh.c @@ -0,0 +1,115 @@ +/* ecc-add-ehh.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +/* Add two points on an Edwards curve, in homogeneous coordinates */ +void +ecc_add_ehh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch) +{ +#define x1 p +#define y1 (p + ecc->p.size) +#define z1 (p + 2*ecc->p.size) + +#define x2 q +#define y2 (q + ecc->p.size) +#define z2 (q + 2*ecc->p.size) + +#define x3 r +#define y3 (r + ecc->p.size) +#define z3 (r + 2*ecc->p.size) + + /* Formulas (from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#addition-add-2007-bl): + + Computation Operation Live variables + + C = x1*x2 mul C + D = y1*y2 mul C, D + T = (x1+y1)(x2+y2) - C - D, mul C, D, T + E = b*C*D 2 mul C, E, T (Replace C <-- D - C) + A = z1*z2 mul A, C, E, T + B = A^2 sqr A, B, C, E, T + F = B - E A, B, C, E, F, T + G = B + E A, C, F, G, T + x3 = A*F*T 2 mul A, C, G + y3 = A*G*(D-C) 2 mul F, G + z3 = F*G mul + + But when working with the twist curve, we have to negate the + factor C = x1*x2. We change subtract to add in the y3 + expression, and swap F and G. + */ +#define C scratch +#define D (scratch + ecc->p.size) +#define T (scratch + 2*ecc->p.size) +#define E (scratch + 3*ecc->p.size) +#define A (scratch + 4*ecc->p.size) +#define B (scratch + 5*ecc->p.size) +#define F D +#define G E + + ecc_modp_mul (ecc, C, x1, x2); + ecc_modp_mul (ecc, D, y1, y2); + ecc_modp_add (ecc, A, x1, y1); + ecc_modp_add (ecc, B, x2, y2); + ecc_modp_mul (ecc, T, A, B); + ecc_modp_sub (ecc, T, T, C); + ecc_modp_sub (ecc, T, T, D); + ecc_modp_mul (ecc, x3, C, D); + ecc_modp_mul (ecc, E, x3, ecc->b); + ecc_modp_add (ecc, C, D, C); /* ! */ + + ecc_modp_mul (ecc, A, z1, z2); + ecc_modp_sqr (ecc, B, A); + + ecc_modp_sub (ecc, F, B, E); + ecc_modp_add (ecc, G, B, E); + + /* x3 */ + ecc_modp_mul (ecc, B, G, T); /* ! */ + ecc_modp_mul (ecc, x3, B, A); + + /* y3 */ + ecc_modp_mul (ecc, B, F, C); /* ! */ + ecc_modp_mul (ecc, y3, B, A); + + /* z3 */ + ecc_modp_mul (ecc, B, F, G); + mpn_copyi (z3, B, ecc->p.size); +} diff --git a/ecc-add-jja.c b/ecc-add-jja.c new file mode 100644 index 0000000..9b5cab9 --- /dev/null +++ b/ecc-add-jja.c @@ -0,0 +1,125 @@ +/* ecc-add-jj.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +/* NOTE: Behaviour for corner cases: + + + p = 0 ==> r = 0 (invalid except if also q = 0) + + + q = 0 ==> r = invalid + + + p = -q ==> r = 0, correct! + + + p = q ==> r = 0, invalid +*/ + +void +ecc_add_jja (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch) +{ + /* Formulas, from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b): + + Computation Operation Live variables + + ZZ = Z_1^2 sqr ZZ + H = X_2*ZZ - X_1 mul (djb: U_2) ZZ, H + HH = H^2 sqr ZZ, H, HH + ZZZ = ZZ*Z_1 mul ZZ, H, HH, ZZZ + Z_3 = (Z_1+H)^2-ZZ-HH sqr H, HH, ZZZ + W = 2 (Y_2*ZZZ - Y_1) mul (djb: S_2) H, HH, W + I = 4*HH H, W, I + J = H*I mul W, I, J + V = X_1*I mul W, J, V + X_3 = W^2-J-2*V sqr W, J, V + Y_3 = W*(V-X_3)-2*Y_1*J mul, mul + */ +#define zz scratch +#define h (scratch + ecc->p.size) +#define hh (scratch + 2*ecc->p.size) +#define w (scratch + 3*ecc->p.size) +#define j (scratch + 4*ecc->p.size) +#define v scratch + +#define x1 p +#define y1 (p + ecc->p.size) +#define z1 (p + 2*ecc->p.size) +#define x2 q +#define y2 (q + ecc->p.size) + + /* zz */ + ecc_modp_sqr (ecc, zz, z1); + /* h*/ + ecc_modp_mul (ecc, h, x2, zz); + ecc_modp_sub (ecc, h, h, x1); + /* hh */ + ecc_modp_sqr (ecc, hh, h); + /* Do z^3 early, store at w. */ + ecc_modp_mul (ecc, w, zz, z1); + /* z_3, use j area for scratch */ + ecc_modp_add (ecc, r + 2*ecc->p.size, p + 2*ecc->p.size, h); + ecc_modp_sqr (ecc, j, r + 2*ecc->p.size); + ecc_modp_sub (ecc, j, j, zz); + ecc_modp_sub (ecc, r + 2*ecc->p.size, j, hh); + + /* w */ + ecc_modp_mul (ecc, j, y2, w); + ecc_modp_sub (ecc, w, j, y1); + ecc_modp_mul_1 (ecc, w, w, 2); + + /* i replaces hh, j */ + ecc_modp_mul_1 (ecc, hh, hh, 4); + ecc_modp_mul (ecc, j, hh, h); + + /* v */ + ecc_modp_mul (ecc, v, x1, hh); + + /* x_3, use (h, hh) as sqratch */ + ecc_modp_sqr (ecc, h, w); + ecc_modp_sub (ecc, r, h, j); + ecc_modp_submul_1 (ecc, r, v, 2); + + /* y_3, use (h, hh) as sqratch */ + ecc_modp_mul (ecc, h, y1, j); /* frees j */ + ecc_modp_sub (ecc, r + ecc->p.size, v, r); + ecc_modp_mul (ecc, j, r + ecc->p.size, w); + ecc_modp_submul_1 (ecc, j, h, 2); + mpn_copyi (r + ecc->p.size, j, ecc->p.size); +} diff --git a/ecc-add-jjj.c b/ecc-add-jjj.c new file mode 100644 index 0000000..1143e79 --- /dev/null +++ b/ecc-add-jjj.c @@ -0,0 +1,120 @@ +/* ecc-add-jjj.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_add_jjj (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch) +{ + /* Formulas, from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl: + + Computation Operation Live variables + + Z1Z1 = Z1^2 sqr Z1Z1 + Z2Z2 = Z2^2 sqr Z1Z1, Z2Z2 + U1 = X1*Z2Z2 mul Z1Z1, Z2Z2, U1 + U2 = X2*Z1Z1 mul Z1Z1, Z2Z2, U1, U2 + H = U2-U1 Z1Z1, Z2Z2, U1, H + Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H sqr, mul Z1Z1, Z2Z2, U1, H + S1 = Y1*Z2*Z2Z2 mul, mul Z1Z1, U1, H, S1 + S2 = Y2*Z1*Z1Z1 mul, mul U1, H, S1, S2 + W = 2*(S2-S1) (djb: r) U1, H, S1, W + I = (2*H)^2 sqr U1, H, S1, W, I + J = H*I mul U1, S1, W, J, V + V = U1*I mul S1, W, J, V + X3 = W^2-J-2*V sqr S1, W, J, V + Y3 = W*(V-X3)-2*S1*J mul, mul + */ + mp_limb_t *z1z1 = scratch; + mp_limb_t *z2z2 = scratch + ecc->p.size; + mp_limb_t *u1 = scratch + 2*ecc->p.size; + mp_limb_t *u2 = scratch + 3*ecc->p.size; + mp_limb_t *s1 = scratch; /* overlap z1z1 */ + mp_limb_t *s2 = scratch + ecc->p.size; /* overlap z2z2 */ + mp_limb_t *i = scratch + 4*ecc->p.size; + mp_limb_t *j = scratch + 5*ecc->p.size; + mp_limb_t *v = scratch + 6*ecc->p.size; + + /* z1^2, z2^2, u1 = x1 x2^2, u2 = x2 z1^2 - u1 */ + ecc_modp_sqr (ecc, z1z1, p + 2*ecc->p.size); + ecc_modp_sqr (ecc, z2z2, q + 2*ecc->p.size); + ecc_modp_mul (ecc, u1, p, z2z2); + ecc_modp_mul (ecc, u2, q, z1z1); + ecc_modp_sub (ecc, u2, u2, u1); /* Store h in u2 */ + + /* z3, use i, j, v as scratch, result at i. */ + ecc_modp_add (ecc, i, p + 2*ecc->p.size, q + 2*ecc->p.size); + ecc_modp_sqr (ecc, v, i); + ecc_modp_sub (ecc, v, v, z1z1); + ecc_modp_sub (ecc, v, v, z2z2); + ecc_modp_mul (ecc, i, v, u2); + /* Delayed write, to support in-place operation. */ + + /* s1 = y1 z2^3, s2 = y2 z1^3, scratch at j and v */ + ecc_modp_mul (ecc, j, z1z1, p + 2*ecc->p.size); /* z1^3 */ + ecc_modp_mul (ecc, v, z2z2, q + 2*ecc->p.size); /* z2^3 */ + ecc_modp_mul (ecc, s1, p + ecc->p.size, v); + ecc_modp_mul (ecc, v, j, q + ecc->p.size); + ecc_modp_sub (ecc, s2, v, s1); + ecc_modp_mul_1 (ecc, s2, s2, 2); + + /* Store z3 */ + mpn_copyi (r + 2*ecc->p.size, i, ecc->p.size); + + /* i, j, v */ + ecc_modp_sqr (ecc, i, u2); + ecc_modp_mul_1 (ecc, i, i, 4); + ecc_modp_mul (ecc, j, u2, i); + ecc_modp_mul (ecc, v, u1, i); + + /* now, u1, u2 and i are free for reuse .*/ + /* x3, use u1, u2 as scratch */ + ecc_modp_sqr (ecc, u1, s2); + ecc_modp_sub (ecc, r, u1, j); + ecc_modp_submul_1 (ecc, r, v, 2); + + /* y3 */ + ecc_modp_mul (ecc, u1, s1, j); /* Frees j */ + ecc_modp_sub (ecc, u2, v, r); /* Frees v */ + ecc_modp_mul (ecc, i, s2, u2); + ecc_modp_submul_1 (ecc, i, u1, 2); + mpn_copyi (r + ecc->p.size, i, ecc->p.size); +} diff --git a/ecc-curve.h b/ecc-curve.h new file mode 100644 index 0000000..c08479a --- /dev/null +++ b/ecc-curve.h @@ -0,0 +1,71 @@ +/* ecc-curve.h + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#ifndef NETTLE_ECC_CURVE_H_INCLUDED +#define NETTLE_ECC_CURVE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/* The contents of this struct is internal. */ +struct ecc_curve; + +/* FIXME: Rename with leading underscore. Due to ABI subtleties, + applications should not refer to these directly, but use the below + accessor functions. */ +extern const struct ecc_curve nettle_secp_192r1; +extern const struct ecc_curve nettle_secp_224r1; +extern const struct ecc_curve nettle_secp_256r1; +extern const struct ecc_curve nettle_secp_384r1; +extern const struct ecc_curve nettle_secp_521r1; + +#ifdef __GNUC__ +#define NETTLE_PURE __attribute__((pure)) +#else +#define NETTLE_PURE +#endif + +const struct ecc_curve * NETTLE_PURE nettle_get_secp_192r1(void); +const struct ecc_curve * NETTLE_PURE nettle_get_secp_224r1(void); +const struct ecc_curve * NETTLE_PURE nettle_get_secp_256r1(void); +const struct ecc_curve * NETTLE_PURE nettle_get_secp_384r1(void); +const struct ecc_curve * NETTLE_PURE nettle_get_secp_521r1(void); + +#undef NETTLE_PURE + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ECC_CURVE_H_INCLUDED */ diff --git a/ecc-dup-eh.c b/ecc-dup-eh.c new file mode 100644 index 0000000..2a5c5a0 --- /dev/null +++ b/ecc-dup-eh.c @@ -0,0 +1,105 @@ +/* ecc-dup-eh.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +/* Double a point on an Edwards curve, in homogeneous coordinates */ +void +ecc_dup_eh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch) +{ + /* Formulas (from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl): + + Computation Operation Live variables + + b = (x+y)^2 sqr b + c = x^2 sqr b, c + d = y^2 sqr b, c, d + e = c+d b, c, d, e + h = z^2 sqr b, c, d, e, h + j = e-2*h b, c, d, e, j + x' = (b-e)*j mul c, d, e, j + y' = e*(c-d) mul e, j + z' = e*j mul + + But for the twisted curve, we need some sign changes. + + b = (x+y)^2 sqr b + c = x^2 sqr b, c + d = y^2 sqr b, c, d + ! e = -c+d b, c, d, e + h = z^2 sqr b, c, d, e, h + ! j = -e+2*h b, c, d, e, j + ! x' = (b-c-d)*j mul c, d, e, j + ! y' = e*(c+d) mul e, j + z' = e*j mul + */ +#define b scratch +#define c (scratch + ecc->p.size) +#define d (scratch + 2*ecc->p.size) +#define e (scratch + 3*ecc->p.size) +#define j (scratch + 4*ecc->p.size) + + /* b */ + ecc_modp_add (ecc, e, p, p + ecc->p.size); + ecc_modp_sqr (ecc, b, e); + + /* c */ + ecc_modp_sqr (ecc, c, p); + /* d */ + ecc_modp_sqr (ecc, d, p + ecc->p.size); + /* h, can use r as scratch, even for in-place operation. */ + ecc_modp_sqr (ecc, r, p + 2*ecc->p.size); + /* e, */ + ecc_modp_sub (ecc, e, d, c); + /* b - c - d */ + ecc_modp_sub (ecc, b, b, c); + ecc_modp_sub (ecc, b, b, d); + /* j */ + ecc_modp_add (ecc, r, r, r); + ecc_modp_sub (ecc, j, r, e); + + /* x' */ + ecc_modp_mul (ecc, r, b, j); + /* y' */ + ecc_modp_add (ecc, c, c, d); /* Redundant */ + ecc_modp_mul (ecc, r + ecc->p.size, e, c); + /* z' */ + ecc_modp_mul (ecc, b, e, j); + mpn_copyi (r + 2*ecc->p.size, b, ecc->p.size); +} diff --git a/ecc-dup-jj.c b/ecc-dup-jj.c new file mode 100644 index 0000000..8e1cf36 --- /dev/null +++ b/ecc-dup-jj.c @@ -0,0 +1,110 @@ +/* ecc-dup-jj.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +/* NOTE: Behaviour for corner cases: + + + p = 0 ==> r = 0, correct! +*/ +void +ecc_dup_jj (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch) +{ + /* Formulas (from djb, + http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b): + + Computation Operation Live variables + delta = z^2 sqr delta + gamma = y^2 sqr delta, gamma + z' = (y+z)^2-gamma-delta sqr delta, gamma + alpha = 3*(x-delta)*(x+delta) mul gamma, beta, alpha + beta = x*gamma mul gamma, beta, alpha + x' = alpha^2-8*beta sqr gamma, beta, alpha + y' = alpha*(4*beta-x')-8*gamma^2 mul, sqr + */ + +#define delta scratch +#define gamma (scratch + ecc->p.size) +#define beta (scratch + 2*ecc->p.size) +#define g2 (scratch + 3*ecc->p.size) +#define sum (scratch + 4*ecc->p.size) +#define alpha scratch /* Overlap delta */ + +#define xp p +#define yp (p + ecc->p.size) +#define zp (p + 2*ecc->p.size) + + /* delta */ + ecc_modp_sqr (ecc, delta, zp); + + /* gamma */ + ecc_modp_sqr (ecc, gamma, yp); + + /* z'. Can use beta area as scratch. */ + ecc_modp_add (ecc, r + 2*ecc->p.size, yp, zp); + ecc_modp_sqr (ecc, beta, r + 2*ecc->p.size); + ecc_modp_sub (ecc, beta, beta, gamma); + ecc_modp_sub (ecc, r + 2*ecc->p.size, beta, delta); + + /* alpha. Can use beta area as scratch, and overwrite delta. */ + ecc_modp_add (ecc, sum, xp, delta); + ecc_modp_sub (ecc, delta, xp, delta); + ecc_modp_mul (ecc, beta, sum, delta); + ecc_modp_mul_1 (ecc, alpha, beta, 3); + + /* beta */ + ecc_modp_mul (ecc, beta, xp, gamma); + + /* Do gamma^2 and 4*beta early, to get them out of the way. We can + then use the old area at gamma as scratch. */ + ecc_modp_sqr (ecc, g2, gamma); + ecc_modp_mul_1 (ecc, sum, beta, 4); + + /* x' */ + ecc_modp_sqr (ecc, gamma, alpha); /* Overwrites gamma and beta */ + ecc_modp_submul_1 (ecc, gamma, sum, 2); + mpn_copyi (r, gamma, ecc->p.size); + + /* y' */ + ecc_modp_sub (ecc, sum, sum, r); + ecc_modp_mul (ecc, gamma, sum, alpha); + ecc_modp_submul_1 (ecc, gamma, g2, 8); + mpn_copyi (r + ecc->p.size, gamma, ecc->p.size); +} diff --git a/ecc-ecdsa-sign.c b/ecc-ecdsa-sign.c new file mode 100644 index 0000000..3b9e9cc --- /dev/null +++ b/ecc-ecdsa-sign.c @@ -0,0 +1,100 @@ +/* ecc-ecdsa-sign.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "ecdsa.h" +#include "ecc-internal.h" + +/* Low-level ECDSA signing */ + +mp_size_t +ecc_ecdsa_sign_itch (const struct ecc_curve *ecc) +{ + /* Needs 3*ecc->p.size + scratch for ecc->mul_g. Currently same for + ecc_mul_g and ecc_mul_g_eh. */ + return ECC_ECDSA_SIGN_ITCH (ecc->p.size); +} + +/* NOTE: Caller should check if r or s is zero. */ +void +ecc_ecdsa_sign (const struct ecc_curve *ecc, + const mp_limb_t *zp, + /* Random nonce, must be invertible mod ecc group + order. */ + const mp_limb_t *kp, + size_t length, const uint8_t *digest, + mp_limb_t *rp, mp_limb_t *sp, + mp_limb_t *scratch) +{ +#define P scratch +#define kinv scratch /* Needs 5*ecc->p.size for computation */ +#define hp (scratch + ecc->p.size) /* NOTE: ecc->p.size + 1 limbs! */ +#define tp (scratch + 2*ecc->p.size) + /* Procedure, according to RFC 6090, "KT-I". q denotes the group + order. + + 1. k <-- uniformly random, 0 < k < q + + 2. R <-- (r_x, r_y) = k g + + 3. s1 <-- r_x mod q + + 4. s2 <-- (h + z*s1)/k mod q. + */ + + ecc->mul_g (ecc, P, kp, P + 3*ecc->p.size); + /* x coordinate only, modulo q */ + ecc->h_to_a (ecc, 2, rp, P, P + 3*ecc->p.size); + + /* Invert k, uses 4 * ecc->p.size including scratch */ + ecc->q.invert (&ecc->q, kinv, kp, tp); /* NOTE: Also clobbers hp */ + + /* Process hash digest */ + ecc_hash (&ecc->q, hp, length, digest); + + ecc_modq_mul (ecc, tp, zp, rp); + ecc_modq_add (ecc, hp, hp, tp); + ecc_modq_mul (ecc, tp, hp, kinv); + + mpn_copyi (sp, tp, ecc->p.size); +#undef P +#undef hp +#undef kinv +#undef tp +} diff --git a/ecc-ecdsa-verify.c b/ecc-ecdsa-verify.c new file mode 100644 index 0000000..d7f5b68 --- /dev/null +++ b/ecc-ecdsa-verify.c @@ -0,0 +1,157 @@ +/* ecc-ecdsa-verify.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "ecdsa.h" +#include "ecc-internal.h" + +/* Low-level ECDSA verify */ + +/* FIXME: Use mpn_zero_p. */ +static int +zero_p (const mp_limb_t *xp, mp_size_t n) +{ + while (n > 0) + if (xp[--n] > 0) + return 0; + return 1; +} + +static int +ecdsa_in_range (const struct ecc_curve *ecc, const mp_limb_t *xp) +{ + return !zero_p (xp, ecc->p.size) + && mpn_cmp (xp, ecc->q.m, ecc->p.size) < 0; +} + +mp_size_t +ecc_ecdsa_verify_itch (const struct ecc_curve *ecc) +{ + /* Largest storage need is for the ecc->mul call. */ + return 5*ecc->p.size + ecc->mul_itch; +} + +/* FIXME: Use faster primitives, not requiring side-channel silence. */ +int +ecc_ecdsa_verify (const struct ecc_curve *ecc, + const mp_limb_t *pp, /* Public key */ + size_t length, const uint8_t *digest, + const mp_limb_t *rp, const mp_limb_t *sp, + mp_limb_t *scratch) +{ + /* Procedure, according to RFC 6090, "KT-I". q denotes the group + order. + + 1. Check 0 < r, s < q. + + 2. s' <-- s^{-1} (mod q) + + 3. u1 <-- h * s' (mod q) + + 4. u2 <-- r * s' (mod q) + + 5. R = u1 G + u2 Y + + 6. Signature is valid if R_x = r (mod q). + */ + +#define P2 scratch +#define u1 (scratch + 3*ecc->p.size) +#define u2 (scratch + 4*ecc->p.size) + +#define P1 (scratch + 4*ecc->p.size) +#define sinv (scratch) +#define hp (scratch + ecc->p.size) + + if (! (ecdsa_in_range (ecc, rp) + && ecdsa_in_range (ecc, sp))) + return 0; + + /* FIXME: Micro optimizations: Either simultaneous multiplication. + Or convert to projective coordinates (can be done without + division, I think), and write an ecc_add_ppp. */ + + /* Compute sinv */ + ecc->q.invert (&ecc->q, sinv, sp, sinv + 2*ecc->p.size); + + /* u1 = h / s, P1 = u1 * G */ + ecc_hash (&ecc->q, hp, length, digest); + ecc_modq_mul (ecc, u1, hp, sinv); + + /* u2 = r / s, P2 = u2 * Y */ + ecc_modq_mul (ecc, u2, rp, sinv); + + /* Total storage: 5*ecc->p.size + ecc->mul_itch */ + ecc->mul (ecc, P2, u2, pp, u2 + ecc->p.size); + + /* u = 0 can happen only if h = 0 or h = q, which is extremely + unlikely. */ + if (!zero_p (u1, ecc->p.size)) + { + /* Total storage: 7*ecc->p.size + ecc->mul_g_itch (ecc->p.size) */ + ecc->mul_g (ecc, P1, u1, P1 + 3*ecc->p.size); + + /* NOTE: ecc_add_jjj and/or ecc_j_to_a will produce garbage in + case u1 G = +/- u2 V. However, anyone who gets his or her + hands on a signature where this happens during verification, + can also get the private key as z = +/- u1 / u_2 (mod q). And + then it doesn't matter very much if verification of + signatures with that key succeeds or fails. + + u1 G = - u2 V can never happen for a correctly generated + signature, since it implies k = 0. + + u1 G = u2 V is possible, if we are unlucky enough to get h / + s_1 = z. Hitting that is about as unlikely as finding the + private key by guessing. + */ + /* Total storage: 6*ecc->p.size + ecc->add_hhh_itch */ + ecc->add_hhh (ecc, P1, P1, P2, P1 + 3*ecc->p.size); + } + /* x coordinate only, modulo q */ + ecc->h_to_a (ecc, 2, P2, P1, P1 + 3*ecc->p.size); + + return (mpn_cmp (rp, P2, ecc->p.size) == 0); +#undef P2 +#undef P1 +#undef sinv +#undef u2 +#undef hp +#undef u1 +} diff --git a/ecc-eh-to-a.c b/ecc-eh-to-a.c new file mode 100644 index 0000000..2acaacb --- /dev/null +++ b/ecc-eh-to-a.c @@ -0,0 +1,87 @@ +/* ecc-eh-to-a.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +/* Convert from homogeneous coordinates on the Edwards curve to affine + coordinates. */ +void +ecc_eh_to_a (const struct ecc_curve *ecc, + int op, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define izp scratch +#define tp (scratch + ecc->p.size) + + +#define xp p +#define yp (p + ecc->p.size) +#define zp (p + 2*ecc->p.size) + + mp_limb_t cy; + + /* Needs 2*size + scratch for the invert call. */ + ecc->p.invert (&ecc->p, izp, zp, tp + ecc->p.size); + + ecc_modp_mul (ecc, tp, xp, izp); + cy = mpn_sub_n (r, tp, ecc->p.m, ecc->p.size); + cnd_copy (cy, r, tp, ecc->p.size); + + if (op) + { + /* Skip y coordinate */ + if (op > 1) + { + /* Reduce modulo q. FIXME: Hardcoded for curve25519, + duplicates end of ecc_25519_modq. FIXME: Is this needed + at all? Full reduction mod p is maybe sufficient. */ + unsigned shift; + assert (ecc->p.bit_size == 255); + shift = 252 - GMP_NUMB_BITS * (ecc->p.size - 1); + cy = mpn_submul_1 (r, ecc->q.m, ecc->p.size, + r[ecc->p.size-1] >> shift); + assert (cy < 2); + cnd_add_n (cy, r, ecc->q.m, ecc->p.size); + } + return; + } + ecc_modp_mul (ecc, tp, yp, izp); + cy = mpn_sub_n (r + ecc->p.size, tp, ecc->p.m, ecc->p.size); + cnd_copy (cy, r + ecc->p.size, tp, ecc->p.size); +} diff --git a/ecc-hash.c b/ecc-hash.c new file mode 100644 index 0000000..4e830a5 --- /dev/null +++ b/ecc-hash.c @@ -0,0 +1,64 @@ +/* ecdsa-hash.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc-internal.h" + +/* Convert hash value to an integer. If the digest is larger than + the ecc bit size, then we must truncate it and use the leftmost + bits. */ + +/* NOTE: We don't considered the hash value to be secret, so it's ok + if the running time of this conversion depends on h. + + Requires m->size + 1 limbs, the extra limb may be needed for + unusual limb sizes. +*/ + +void +ecc_hash (const struct ecc_modulo *m, + mp_limb_t *hp, + size_t length, const uint8_t *digest) +{ + if (length > ((size_t) m->bit_size + 7) / 8) + length = (m->bit_size + 7) / 8; + + mpn_set_base256 (hp, m->size + 1, digest, length); + + if (8 * length > m->bit_size) + /* We got a few extra bits, at the low end. Discard them. */ + mpn_rshift (hp, hp, m->size + 1, 8*length - m->bit_size); +} diff --git a/ecc-internal.h b/ecc-internal.h new file mode 100644 index 0000000..ce1e34f --- /dev/null +++ b/ecc-internal.h @@ -0,0 +1,412 @@ +/* ecc-internal.h + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#ifndef NETTLE_ECC_INTERNAL_H_INCLUDED +#define NETTLE_ECC_INTERNAL_H_INCLUDED + +#include "nettle-types.h" +#include "bignum.h" +#include "ecc-curve.h" +#include "gmp-glue.h" + +/* Name mangling */ +#define ecc_pp1_redc _nettle_ecc_pp1_redc +#define ecc_pm1_redc _nettle_ecc_pm1_redc +#define ecc_mod_add _nettle_ecc_mod_add +#define ecc_mod_sub _nettle_ecc_mod_sub +#define ecc_mod_mul_1 _nettle_ecc_mod_mul_1 +#define ecc_mod_addmul_1 _nettle_ecc_mod_addmul_1 +#define ecc_mod_submul_1 _nettle_ecc_mod_submul_1 +#define ecc_mod_mul _nettle_ecc_mod_mul +#define ecc_mod_sqr _nettle_ecc_mod_sqr +#define ecc_mod_random _nettle_ecc_mod_random +#define ecc_mod _nettle_ecc_mod +#define ecc_mod_inv _nettle_ecc_mod_inv +#define ecc_hash _nettle_ecc_hash +#define ecc_a_to_j _nettle_ecc_a_to_j +#define ecc_j_to_a _nettle_ecc_j_to_a +#define ecc_eh_to_a _nettle_ecc_eh_to_a +#define ecc_dup_jj _nettle_ecc_dup_jj +#define ecc_add_jja _nettle_ecc_add_jja +#define ecc_add_jjj _nettle_ecc_add_jjj +#define ecc_dup_eh _nettle_ecc_dup_eh +#define ecc_add_eh _nettle_ecc_add_eh +#define ecc_add_ehh _nettle_ecc_add_ehh +#define ecc_mul_g _nettle_ecc_mul_g +#define ecc_mul_a _nettle_ecc_mul_a +#define ecc_mul_g_eh _nettle_ecc_mul_g_eh +#define ecc_mul_a_eh _nettle_ecc_mul_a_eh +#define cnd_copy _nettle_cnd_copy +#define sec_add_1 _nettle_sec_add_1 +#define sec_sub_1 _nettle_sec_sub_1 +#define sec_tabselect _nettle_sec_tabselect +#define sec_modinv _nettle_sec_modinv +#define curve25519_eh_to_x _nettle_curve25519_eh_to_x + +/* Keep this structure internal for now. It's misnamed (since it's + really implementing the equivalent twisted Edwards curve, with + different coordinates). And we're not quite ready to provide + general ecc operations over an arbitrary type of curve. */ +extern const struct ecc_curve _nettle_curve25519; + +#define ECC_MAX_SIZE ((521 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) + +/* Window size for ecc_mul_a. Using 4 bits seems like a good choice, + for both Intel x86_64 and ARM Cortex A9. For the larger curves, of + 384 and 521 bits, we could improve speed by a few percent if we go + up to 5 bits, but I don't think that's worth doubling the + storage. */ +#define ECC_MUL_A_WBITS 4 +/* And for ecc_mul_a_eh */ +#define ECC_MUL_A_EH_WBITS 4 + +struct ecc_modulo; + +/* Reduces from 2*ecc->size to ecc->size. */ +/* Required to return a result < 2q. This property is inherited by + mod_mul and mod_sqr. */ +typedef void ecc_mod_func (const struct ecc_modulo *m, mp_limb_t *rp); + +typedef void ecc_mod_inv_func (const struct ecc_modulo *m, + mp_limb_t *vp, const mp_limb_t *ap, + mp_limb_t *scratch); + +/* Computes the square root of (u/v) (mod p) */ +typedef int ecc_mod_sqrt_func (const struct ecc_modulo *m, + mp_limb_t *rp, + const mp_limb_t *up, const mp_limb_t *vp, + mp_limb_t *scratch); + +typedef void ecc_add_func (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch); + +typedef void ecc_mul_g_func (const struct ecc_curve *ecc, mp_limb_t *r, + const mp_limb_t *np, mp_limb_t *scratch); + +typedef void ecc_mul_func (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch); + +typedef void ecc_h_to_a_func (const struct ecc_curve *ecc, + int flags, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch); + +struct ecc_modulo +{ + unsigned short bit_size; + unsigned short size; + unsigned short B_size; + unsigned short redc_size; + unsigned short invert_itch; + unsigned short sqrt_itch; + + const mp_limb_t *m; + /* B^size mod m. Expected to have at least 32 leading zeros + (equality for secp_256r1). */ + const mp_limb_t *B; + /* 2^{bit_size} - p, same value as above, but shifted. */ + const mp_limb_t *B_shifted; + /* m +/- 1, for redc, excluding redc_size low limbs. */ + const mp_limb_t *redc_mpm1; + /* (m+1)/2 */ + const mp_limb_t *mp1h; + + ecc_mod_func *mod; + ecc_mod_func *reduce; + ecc_mod_inv_func *invert; + ecc_mod_sqrt_func *sqrt; +}; + +/* Represents an elliptic curve of the form + + y^2 = x^3 - 3x + b (mod p) +*/ +struct ecc_curve +{ + /* The prime p. */ + struct ecc_modulo p; + /* Group order. FIXME: Currently, many fucntions rely on q.size == + p.size. This has to change for radix-51 implementation of + curve25519 mod p arithmetic. */ + struct ecc_modulo q; + + unsigned short use_redc; + unsigned short pippenger_k; + unsigned short pippenger_c; + + unsigned short add_hhh_itch; + unsigned short mul_itch; + unsigned short mul_g_itch; + unsigned short h_to_a_itch; + + ecc_add_func *add_hhh; + ecc_mul_func *mul; + ecc_mul_g_func *mul_g; + ecc_h_to_a_func *h_to_a; + + /* Curve constant */ + const mp_limb_t *b; + /* Generator, x coordinate followed by y (affine coordinates). + Currently used only by the test suite. */ + const mp_limb_t *g; + /* If non-NULL, the constant needed for transformation to the + equivalent Edwards curve. */ + const mp_limb_t *edwards_root; + + /* For redc, same as B mod p, otherwise 1. */ + const mp_limb_t *unit; + + /* Tables for multiplying by the generator, size determined by k and + c. The first 2^c entries are defined by + + T[ j_0 + j_1 2 + ... + j_{c-1} 2^{c-1} ] + = j_0 g + j_1 2^k g + ... + j_{c-1} 2^{k(c-1)} g + + The following entries differ by powers of 2^{kc}, + + T[i] = 2^{kc} T[i-2^c] + */ + const mp_limb_t *pippenger_table; +}; + +/* In-place reduction. */ +ecc_mod_func ecc_mod; +ecc_mod_func ecc_pp1_redc; +ecc_mod_func ecc_pm1_redc; + +ecc_mod_inv_func ecc_mod_inv; + +void +ecc_mod_add (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t *bp); +void +ecc_mod_sub (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t *bp); + +void +ecc_mod_mul_1 (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t b); + +void +ecc_mod_addmul_1 (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, mp_limb_t b); +void +ecc_mod_submul_1 (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, mp_limb_t b); + +/* NOTE: mul and sqr needs 2*ecc->size limbs at rp */ +void +ecc_mod_mul (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t *bp); + +void +ecc_mod_sqr (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap); + +#define ecc_modp_add(ecc, r, a, b) \ + ecc_mod_add (&(ecc)->p, (r), (a), (b)) +#define ecc_modp_sub(ecc, r, a, b) \ + ecc_mod_sub (&(ecc)->p, (r), (a), (b)) +#define ecc_modp_mul_1(ecc, r, a, b) \ + ecc_mod_mul_1 (&(ecc)->p, (r), (a), (b)) +#define ecc_modp_addmul_1(ecc, r, a, b) \ + ecc_mod_addmul_1 (&(ecc)->p, (r), (a), (b)) +#define ecc_modp_submul_1(ecc, r, a, b) \ + ecc_mod_submul_1 (&(ecc)->p, (r), (a), (b)) +#define ecc_modp_mul(ecc, r, a, b) \ + ecc_mod_mul (&(ecc)->p, (r), (a), (b)) +#define ecc_modp_sqr(ecc, r, a) \ + ecc_mod_sqr (&(ecc)->p, (r), (a)) + +#define ecc_modq_add(ecc, r, a, b) \ + ecc_mod_add (&(ecc)->q, (r), (a), (b)) +#define ecc_modq_mul(ecc, r, a, b) \ + ecc_mod_mul (&(ecc)->q, (r), (a), (b)) + +/* mod q operations. */ +void +ecc_mod_random (const struct ecc_modulo *m, mp_limb_t *xp, + void *ctx, nettle_random_func *random, mp_limb_t *scratch); + +void +ecc_hash (const struct ecc_modulo *m, + mp_limb_t *hp, + size_t length, const uint8_t *digest); + +/* Converts a point P in affine coordinates into a point R in jacobian + coordinates. */ +void +ecc_a_to_j (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p); + +/* Converts a point P in jacobian coordinates into a point R in affine + coordinates. If op == 1, produce x coordinate only. If op == 2, + produce the x coordiante only, and in also it modulo q. FIXME: For + the public interface, have separate for the three cases, and use + this flag argument only for the internal ecc->h_to_a function. */ +void +ecc_j_to_a (const struct ecc_curve *ecc, + int op, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch); + +/* Converts a point P on an Edwards curve to affine coordinates on + the corresponding Montgomery curve. */ +void +ecc_eh_to_a (const struct ecc_curve *ecc, + int op, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch); + +/* Group operations */ + +/* Point doubling, with jacobian input and output. Corner cases: + Correctly sets R = 0 (r_Z = 0) if p = 0 or 2p = 0. */ +void +ecc_dup_jj (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch); + +/* Point addition, with jacobian output, one jacobian input and one + affine input. Corner cases: Fails for the cases + + P = Q != 0 Duplication of non-zero point + P = 0, Q != 0 or P != 0, Q = 0 One input zero + + Correctly gives R = 0 if P = Q = 0 or P = -Q. */ +void +ecc_add_jja (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch); + +/* Point addition with Jacobian input and output. */ +void +ecc_add_jjj (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch); + +/* Point doubling on an Edwards curve, with homogeneous + cooordinates. */ +void +ecc_dup_eh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch); + +void +ecc_add_eh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch); + +void +ecc_add_ehh (const struct ecc_curve *ecc, + mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, + mp_limb_t *scratch); + +/* Computes N * the group generator. N is an array of ecc_size() + limbs. It must be in the range 0 < N < group order, then R != 0, + and the algorithm can work without any intermediate values getting + to zero. */ +void +ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r, + const mp_limb_t *np, mp_limb_t *scratch); + +/* Computes N * P. The scalar N is the same as for ecc_mul_g. P is a + non-zero point on the curve, in affine coordinates. Output R is a + non-zero point, in Jacobian coordinates. */ +void +ecc_mul_a (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch); + +void +ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r, + const mp_limb_t *np, mp_limb_t *scratch); + +void +ecc_mul_a_eh (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch); + +void +cnd_copy (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n); + +mp_limb_t +sec_add_1 (mp_limb_t *rp, mp_limb_t *ap, mp_size_t n, mp_limb_t b); + +mp_limb_t +sec_sub_1 (mp_limb_t *rp, mp_limb_t *ap, mp_size_t n, mp_limb_t b); + +void +sec_tabselect (mp_limb_t *rp, mp_size_t rn, + const mp_limb_t *table, unsigned tn, + unsigned k); + +void +curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p, + mp_limb_t *scratch); + +/* Current scratch needs: */ +#define ECC_MOD_INV_ITCH(size) (2*(size)) +#define ECC_J_TO_A_ITCH(size) (5*(size)) +#define ECC_EH_TO_A_ITCH(size, inv) (2*(size)+(inv)) +#define ECC_DUP_JJ_ITCH(size) (5*(size)) +#define ECC_DUP_EH_ITCH(size) (5*(size)) +#define ECC_ADD_JJA_ITCH(size) (6*(size)) +#define ECC_ADD_JJJ_ITCH(size) (8*(size)) +#define ECC_ADD_EH_ITCH(size) (6*(size)) +#define ECC_ADD_EHH_ITCH(size) (7*(size)) +#define ECC_MUL_G_ITCH(size) (9*(size)) +#define ECC_MUL_G_EH_ITCH(size) (9*(size)) +#if ECC_MUL_A_WBITS == 0 +#define ECC_MUL_A_ITCH(size) (12*(size)) +#else +#define ECC_MUL_A_ITCH(size) \ + (((3 << ECC_MUL_A_WBITS) + 11) * (size)) +#endif +#if ECC_MUL_A_EH_WBITS == 0 +#define ECC_MUL_A_EH_ITCH(size) (13*(size)) +#else +#define ECC_MUL_A_EH_ITCH(size) \ + (((3 << ECC_MUL_A_EH_WBITS) + 10) * (size)) +#endif +#define ECC_ECDSA_SIGN_ITCH(size) (12*(size)) +#define ECC_MOD_RANDOM_ITCH(size) (size) +#define ECC_HASH_ITCH(size) (1+(size)) + +#endif /* NETTLE_ECC_INTERNAL_H_INCLUDED */ diff --git a/ecc-j-to-a.c b/ecc-j-to-a.c new file mode 100644 index 0000000..eca10f0 --- /dev/null +++ b/ecc-j-to-a.c @@ -0,0 +1,119 @@ +/* ecc-j-to-a.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_j_to_a (const struct ecc_curve *ecc, + int op, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define izp scratch +#define up (scratch + 2*ecc->p.size) +#define iz2p (scratch + ecc->p.size) +#define iz3p (scratch + 2*ecc->p.size) +#define izBp (scratch + 3*ecc->p.size) +#define tp scratch + + mp_limb_t cy; + + if (ecc->use_redc) + { + /* Set v = (r_z / B^2)^-1, + + r_x = p_x v^2 / B^3 = ((v/B * v)/B * p_x)/B + r_y = p_y v^3 / B^4 = (((v/B * v)/B * v)/B * p_y)/B + */ + + mpn_copyi (up, p + 2*ecc->p.size, ecc->p.size); + mpn_zero (up + ecc->p.size, ecc->p.size); + ecc->p.reduce (&ecc->p, up); + mpn_zero (up + ecc->p.size, ecc->p.size); + ecc->p.reduce (&ecc->p, up); + + ecc->p.invert (&ecc->p, izp, up, up + ecc->p.size); + + /* Divide this common factor by B */ + mpn_copyi (izBp, izp, ecc->p.size); + mpn_zero (izBp + ecc->p.size, ecc->p.size); + ecc->p.reduce (&ecc->p, izBp); + + ecc_modp_mul (ecc, iz2p, izp, izBp); + } + else + { + /* Set s = p_z^{-1}, r_x = p_x s^2, r_y = p_y s^3 */ + + mpn_copyi (up, p+2*ecc->p.size, ecc->p.size); /* p_z */ + ecc->p.invert (&ecc->p, izp, up, up + ecc->p.size); + + ecc_modp_sqr (ecc, iz2p, izp); + } + + ecc_modp_mul (ecc, iz3p, iz2p, p); + /* ecc_modp (and ecc_modp_mul) may return a value up to 2p - 1, so + do a conditional subtraction. */ + cy = mpn_sub_n (r, iz3p, ecc->p.m, ecc->p.size); + cnd_copy (cy, r, iz3p, ecc->p.size); + + if (op) + { + /* Skip y coordinate */ + if (op > 1) + { + /* Also reduce the x coordinate mod ecc->q. It should + already be < 2*ecc->q, so one subtraction should + suffice. */ + cy = mpn_sub_n (scratch, r, ecc->q.m, ecc->p.size); + cnd_copy (cy == 0, r, scratch, ecc->p.size); + } + return; + } + ecc_modp_mul (ecc, iz3p, iz2p, izp); + ecc_modp_mul (ecc, tp, iz3p, p + ecc->p.size); + /* And a similar subtraction. */ + cy = mpn_sub_n (r + ecc->p.size, tp, ecc->p.m, ecc->p.size); + cnd_copy (cy, r + ecc->p.size, tp, ecc->p.size); + +#undef izp +#undef up +#undef iz2p +#undef iz3p +#undef tp +} diff --git a/ecc-mod-arith.c b/ecc-mod-arith.c new file mode 100644 index 0000000..f2e47f6 --- /dev/null +++ b/ecc-mod-arith.c @@ -0,0 +1,127 @@ +/* ecc-mod-arith.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +/* Routines for modp arithmetic. All values are ecc->size limbs, but + not necessarily < p. */ + +void +ecc_mod_add (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t *bp) +{ + mp_limb_t cy; + cy = mpn_add_n (rp, ap, bp, m->size); + cy = cnd_add_n (cy, rp, m->B, m->size); + cy = cnd_add_n (cy, rp, m->B, m->size); + assert (cy == 0); +} + +void +ecc_mod_sub (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t *bp) +{ + mp_limb_t cy; + cy = mpn_sub_n (rp, ap, bp, m->size); + cy = cnd_sub_n (cy, rp, m->B, m->size); + cy = cnd_sub_n (cy, rp, m->B, m->size); + assert (cy == 0); +} + +void +ecc_mod_mul_1 (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, mp_limb_t b) +{ + mp_limb_t hi; + + assert (b <= 0xffffffff); + hi = mpn_mul_1 (rp, ap, m->size, b); + hi = mpn_addmul_1 (rp, m->B, m->size, hi); + assert (hi <= 1); + hi = cnd_add_n (hi, rp, m->B, m->size); + /* Sufficient if b < B^size / p */ + assert (hi == 0); +} + +void +ecc_mod_addmul_1 (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, mp_limb_t b) +{ + mp_limb_t hi; + + assert (b <= 0xffffffff); + hi = mpn_addmul_1 (rp, ap, m->size, b); + hi = mpn_addmul_1 (rp, m->B, m->size, hi); + assert (hi <= 1); + hi = cnd_add_n (hi, rp, m->B, m->size); + /* Sufficient roughly if b < B^size / p */ + assert (hi == 0); +} + +void +ecc_mod_submul_1 (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, mp_limb_t b) +{ + mp_limb_t hi; + + assert (b <= 0xffffffff); + hi = mpn_submul_1 (rp, ap, m->size, b); + hi = mpn_submul_1 (rp, m->B, m->size, hi); + assert (hi <= 1); + hi = cnd_sub_n (hi, rp, m->B, m->size); + /* Sufficient roughly if b < B^size / p */ + assert (hi == 0); +} + +/* NOTE: mul and sqr needs 2*m->size limbs at rp */ +void +ecc_mod_mul (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap, const mp_limb_t *bp) +{ + mpn_mul_n (rp, ap, bp, m->size); + m->reduce (m, rp); +} + +void +ecc_mod_sqr (const struct ecc_modulo *m, mp_limb_t *rp, + const mp_limb_t *ap) +{ + mpn_sqr (rp, ap, m->size); + m->reduce (m, rp); +} diff --git a/ecc-mod-inv.c b/ecc-mod-inv.c new file mode 100644 index 0000000..8cfd2e3 --- /dev/null +++ b/ecc-mod-inv.c @@ -0,0 +1,160 @@ +/* ecc-mod-inv.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +static void +cnd_neg (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n) +{ + mp_limb_t cy = (cnd != 0); + mp_limb_t mask = -cy; + mp_size_t i; + + for (i = 0; i < n; i++) + { + mp_limb_t r = (ap[i] ^ mask) + cy; + cy = r < cy; + rp[i] = r; + } +} + +/* Compute a^{-1} mod m, with running time depending only on the size. + Returns zero if a == 0 (mod m), to be consistent with a^{phi(m)-1}. + Also needs (m+1)/2, and m must be odd. + + Needs 2n limbs available at rp, and 2n additional scratch limbs. +*/ + +/* FIXME: Could use mpn_sec_invert (in GMP-6), but with a bit more + scratch need since it doesn't precompute (m+1)/2. */ +void +ecc_mod_inv (const struct ecc_modulo *m, + mp_limb_t *vp, const mp_limb_t *in_ap, + mp_limb_t *scratch) +{ +#define ap scratch +#define bp (scratch + n) +#define up (vp + n) + + mp_size_t n = m->size; + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned i; + + /* Maintain + + a = u * orig_a (mod m) + b = v * orig_a (mod m) + + and b odd at all times. Initially, + + a = a_orig, u = 1 + b = m, v = 0 + */ + + assert (ap != vp); + + up[0] = 1; + mpn_zero (up+1, n - 1); + mpn_copyi (bp, m->m, n); + mpn_zero (vp, n); + mpn_copyi (ap, in_ap, n); + + for (i = m->bit_size + GMP_NUMB_BITS * n; i-- > 0; ) + { + mp_limb_t odd, swap, cy; + + /* Always maintain b odd. The logic of the iteration is as + follows. For a, b: + + odd = a & 1 + a -= odd * b + if (underflow from a-b) + { + b += a, assigns old a + a = B^n-a + } + + a /= 2 + + For u, v: + + if (underflow from a - b) + swap u, v + u -= odd * v + if (underflow from u - v) + u += m + + u /= 2 + if (a one bit was shifted out) + u += (m+1)/2 + + As long as a > 0, the quantity + + (bitsize of a) + (bitsize of b) + + is reduced by at least one bit per iteration, hence after + (bit_size of orig_a) + (bit_size of m) - 1 iterations we + surely have a = 0. Then b = gcd(orig_a, m) and if b = 1 then + also v = orig_a^{-1} (mod m) + */ + + assert (bp[0] & 1); + odd = ap[0] & 1; + + swap = cnd_sub_n (odd, ap, bp, n); + cnd_add_n (swap, bp, ap, n); + cnd_neg (swap, ap, ap, n); + + cnd_swap (swap, up, vp, n); + cy = cnd_sub_n (odd, up, vp, n); + cy -= cnd_add_n (cy, up, m->m, n); + assert (cy == 0); + + cy = mpn_rshift (ap, ap, n, 1); + assert (cy == 0); + cy = mpn_rshift (up, up, n, 1); + cy = cnd_add_n (cy, up, m->mp1h, n); + assert (cy == 0); + } + assert ( (ap[0] | ap[n-1]) == 0); +#undef ap +#undef bp +#undef up +} diff --git a/ecc-mod.c b/ecc-mod.c new file mode 100644 index 0000000..4e77f0c --- /dev/null +++ b/ecc-mod.c @@ -0,0 +1,119 @@ +/* ecc-mod.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +/* Computes r mod m, input 2*m->size, output m->size. */ +void +ecc_mod (const struct ecc_modulo *m, mp_limb_t *rp) +{ + mp_limb_t hi; + mp_size_t mn = m->size; + mp_size_t bn = m->B_size; + mp_size_t sn = mn - bn; + mp_size_t rn = 2*mn; + mp_size_t i; + unsigned shift; + + assert (bn < mn); + + /* FIXME: Could use mpn_addmul_2. */ + /* Eliminate sn limbs at a time */ + if (m->B[bn-1] < ((mp_limb_t) 1 << (GMP_NUMB_BITS - 1))) + { + /* Multiply sn + 1 limbs at a time, so we get a mn+1 limb + product. Then we can absorb the carry in the high limb */ + while (rn > 2 * mn - bn) + { + rn -= sn; + + for (i = 0; i <= sn; i++) + rp[rn+i-1] = mpn_addmul_1 (rp + rn - mn - 1 + i, m->B, bn, rp[rn+i-1]); + rp[rn-1] = rp[rn+sn-1] + + mpn_add_n (rp + rn - sn - 1, rp + rn - sn - 1, rp + rn - 1, sn); + } + goto final_limbs; + } + else + { + /* The loop below always runs at least once. But the analyzer + doesn't realize that, and complains about hi being used later + on without a well defined value. */ +#ifdef __clang_analyzer__ + hi = 0; +#endif + while (rn >= 2 * mn - bn) + { + rn -= sn; + + for (i = 0; i < sn; i++) + rp[rn+i] = mpn_addmul_1 (rp + rn - mn + i, m->B, bn, rp[rn+i]); + + hi = mpn_add_n (rp + rn - sn, rp + rn - sn, rp + rn, sn); + hi = cnd_add_n (hi, rp + rn - mn, m->B, mn); + assert (hi == 0); + } + } + + if (rn > mn) + { + final_limbs: + sn = rn - mn; + + for (i = 0; i < sn; i++) + rp[mn+i] = mpn_addmul_1 (rp + i, m->B, bn, rp[mn+i]); + + hi = mpn_add_n (rp + bn, rp + bn, rp + mn, sn); + hi = sec_add_1 (rp + bn + sn, rp + bn + sn, mn - bn - sn, hi); + } + + shift = m->size * GMP_NUMB_BITS - m->bit_size; + if (shift > 0) + { + /* Combine hi with top bits, add in */ + hi = (hi << shift) | (rp[mn-1] >> (GMP_NUMB_BITS - shift)); + rp[mn-1] = (rp[mn-1] & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) + + mpn_addmul_1 (rp, m->B_shifted, mn-1, hi); + } + else + { + hi = cnd_add_n (hi, rp, m->B_shifted, mn); + assert (hi == 0); + } +} diff --git a/ecc-mul-a-eh.c b/ecc-mul-a-eh.c new file mode 100644 index 0000000..cf74323 --- /dev/null +++ b/ecc-mul-a-eh.c @@ -0,0 +1,176 @@ +/* ecc-mul-a-eh.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +/* Binary algorithm needs 6*ecc->p.size + scratch for ecc_add_ehh, + total 13 ecc->p.size + + Window algorithm needs (3<p.size for the table, + 3*ecc->p.size for a temporary point, and scratch for + ecc_add_ehh. */ + +#if ECC_MUL_A_EH_WBITS == 0 +void +ecc_mul_a_eh (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define pe scratch +#define tp (scratch + 3*ecc->p.size) +#define scratch_out (scratch + 6*ecc->p.size) + + unsigned i; + + ecc_a_to_j (ecc, pe, p); + + /* x = 0, y = 1, z = 1 */ + mpn_zero (r, 3*ecc->p.size); + r[ecc->p.size] = r[2*ecc->p.size] = 1; + + for (i = ecc->p.size; i-- > 0; ) + { + mp_limb_t w = np[i]; + mp_limb_t bit; + + for (bit = (mp_limb_t) 1 << (GMP_NUMB_BITS - 1); + bit > 0; + bit >>= 1) + { + int digit; + + ecc_dup_eh (ecc, r, r, scratch_out); + ecc_add_ehh (ecc, tp, r, pe, scratch_out); + + digit = (w & bit) > 0; + /* If we had a one-bit, use the sum. */ + cnd_copy (digit, r, tp, 3*ecc->p.size); + } + } +} +#else /* ECC_MUL_A_EH_WBITS > 1 */ + +#define TABLE_SIZE (1U << ECC_MUL_A_EH_WBITS) +#define TABLE_MASK (TABLE_SIZE - 1) + +#define TABLE(j) (table + (j) * 3*ecc->p.size) + +static void +table_init (const struct ecc_curve *ecc, + mp_limb_t *table, unsigned bits, + const mp_limb_t *p, + mp_limb_t *scratch) +{ + unsigned size = 1 << bits; + unsigned j; + + mpn_zero (TABLE(0), 3*ecc->p.size); + TABLE(0)[ecc->p.size] = TABLE(0)[2*ecc->p.size] = 1; + + ecc_a_to_j (ecc, TABLE(1), p); + + for (j = 2; j < size; j += 2) + { + ecc_dup_eh (ecc, TABLE(j), TABLE(j/2), scratch); + ecc_add_ehh (ecc, TABLE(j+1), TABLE(j), TABLE(1), scratch); + } +} + +void +ecc_mul_a_eh (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define tp scratch +#define table (scratch + 3*ecc->p.size) + mp_limb_t *scratch_out = table + (3*ecc->p.size << ECC_MUL_A_EH_WBITS); + + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned blocks = (ecc->p.bit_size + ECC_MUL_A_EH_WBITS - 1) / ECC_MUL_A_EH_WBITS; + unsigned bit_index = (blocks-1) * ECC_MUL_A_EH_WBITS; + + mp_size_t limb_index = bit_index / GMP_NUMB_BITS; + unsigned shift = bit_index % GMP_NUMB_BITS; + mp_limb_t w, bits; + + table_init (ecc, table, ECC_MUL_A_EH_WBITS, p, scratch_out); + + w = np[limb_index]; + bits = w >> shift; + if (limb_index < ecc->p.size - 1) + bits |= np[limb_index + 1] << (GMP_NUMB_BITS - shift); + + assert (bits < TABLE_SIZE); + + sec_tabselect (r, 3*ecc->p.size, table, TABLE_SIZE, bits); + + for (;;) + { + unsigned j; + if (shift >= ECC_MUL_A_EH_WBITS) + { + shift -= ECC_MUL_A_EH_WBITS; + bits = w >> shift; + } + else + { + if (limb_index == 0) + { + assert (shift == 0); + break; + } + bits = w << (ECC_MUL_A_EH_WBITS - shift); + w = np[--limb_index]; + shift = shift + GMP_NUMB_BITS - ECC_MUL_A_EH_WBITS; + bits |= w >> shift; + } + for (j = 0; j < ECC_MUL_A_EH_WBITS; j++) + ecc_dup_eh (ecc, r, r, scratch_out); + + bits &= TABLE_MASK; + sec_tabselect (tp, 3*ecc->p.size, table, TABLE_SIZE, bits); + ecc_add_ehh (ecc, r, tp, r, scratch_out); + } +#undef table +#undef tp +} + +#endif /* ECC_MUL_A_EH_WBITS > 1 */ diff --git a/ecc-mul-a.c b/ecc-mul-a.c new file mode 100644 index 0000000..cb9c7d4 --- /dev/null +++ b/ecc-mul-a.c @@ -0,0 +1,187 @@ +/* ecc-mul-a.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +/* Binary algorithm needs 6*ecc->p.size + scratch for ecc_add_jja. + Current total is 12 ecc->p.size, at most 864 bytes. + + Window algorithm needs (3<p.size for the table, + 3*ecc->p.size for a temporary point, and scratch for + ecc_add_jjj. */ + +#if ECC_MUL_A_WBITS == 0 +void +ecc_mul_a (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define tp scratch +#define pj (scratch + 3*ecc->p.size) +#define scratch_out (scratch + 6*ecc->p.size) + + int is_zero; + + unsigned i; + + ecc_a_to_j (ecc, pj, p); + mpn_zero (r, 3*ecc->p.size); + + for (i = ecc->p.size, is_zero = 1; i-- > 0; ) + { + mp_limb_t w = np[i]; + mp_limb_t bit; + + for (bit = (mp_limb_t) 1 << (GMP_NUMB_BITS - 1); + bit > 0; + bit >>= 1) + { + int digit; + + ecc_dup_jj (ecc, r, r, scratch_out); + ecc_add_jja (ecc, tp, r, pj, scratch_out); + + digit = (w & bit) > 0; + /* If is_zero is set, r is the zero point, + and ecc_add_jja produced garbage. */ + cnd_copy (is_zero, tp, pj, 3*ecc->p.size); + is_zero &= ~digit; + /* If we had a one-bit, use the sum. */ + cnd_copy (digit, r, tp, 3*ecc->p.size); + } + } +} +#else /* ECC_MUL_A_WBITS > 1 */ + +#define TABLE_SIZE (1U << ECC_MUL_A_WBITS) +#define TABLE_MASK (TABLE_SIZE - 1) + +#define TABLE(j) (table + (j) * 3*ecc->p.size) + +static void +table_init (const struct ecc_curve *ecc, + mp_limb_t *table, unsigned bits, + const mp_limb_t *p, + mp_limb_t *scratch) +{ + unsigned size = 1 << bits; + unsigned j; + + mpn_zero (TABLE(0), 3*ecc->p.size); + ecc_a_to_j (ecc, TABLE(1), p); + + for (j = 2; j < size; j += 2) + { + ecc_dup_jj (ecc, TABLE(j), TABLE(j/2), scratch); + ecc_add_jja (ecc, TABLE(j+1), TABLE(j), TABLE(1), scratch); + } +} + +void +ecc_mul_a (const struct ecc_curve *ecc, + mp_limb_t *r, + const mp_limb_t *np, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define tp scratch +#define table (scratch + 3*ecc->p.size) + mp_limb_t *scratch_out = table + (3*ecc->p.size << ECC_MUL_A_WBITS); + int is_zero = 0; + + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned blocks = (ecc->p.bit_size + ECC_MUL_A_WBITS - 1) / ECC_MUL_A_WBITS; + unsigned bit_index = (blocks-1) * ECC_MUL_A_WBITS; + + mp_size_t limb_index = bit_index / GMP_NUMB_BITS; + unsigned shift = bit_index % GMP_NUMB_BITS; + mp_limb_t w, bits; + + table_init (ecc, table, ECC_MUL_A_WBITS, p, scratch_out); + + w = np[limb_index]; + bits = w >> shift; + if (limb_index < ecc->p.size - 1) + bits |= np[limb_index + 1] << (GMP_NUMB_BITS - shift); + + assert (bits < TABLE_SIZE); + + sec_tabselect (r, 3*ecc->p.size, table, TABLE_SIZE, bits); + is_zero = (bits == 0); + + for (;;) + { + unsigned j; + if (shift >= ECC_MUL_A_WBITS) + { + shift -= ECC_MUL_A_WBITS; + bits = w >> shift; + } + else + { + if (limb_index == 0) + { + assert (shift == 0); + break; + } + bits = w << (ECC_MUL_A_WBITS - shift); + w = np[--limb_index]; + shift = shift + GMP_NUMB_BITS - ECC_MUL_A_WBITS; + bits |= w >> shift; + } + for (j = 0; j < ECC_MUL_A_WBITS; j++) + ecc_dup_jj (ecc, r, r, scratch_out); + + bits &= TABLE_MASK; + sec_tabselect (tp, 3*ecc->p.size, table, TABLE_SIZE, bits); + cnd_copy (is_zero, r, tp, 3*ecc->p.size); + ecc_add_jjj (ecc, tp, tp, r, scratch_out); + + /* Use the sum when valid. ecc_add_jja produced garbage if + is_zero != 0 or bits == 0, . */ + cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->p.size); + is_zero &= (bits == 0); + } +#undef table +#undef tp +} + +#endif /* ECC_MUL_A_WBITS > 1 */ diff --git a/ecc-mul-g-eh.c b/ecc-mul-g-eh.c new file mode 100644 index 0000000..a945494 --- /dev/null +++ b/ecc-mul-g-eh.c @@ -0,0 +1,101 @@ +/* ecc-mul-g-eh.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_mul_g_eh (const struct ecc_curve *ecc, mp_limb_t *r, + const mp_limb_t *np, mp_limb_t *scratch) +{ + /* Scratch need determined by the ecc_add_eh call. Current total is + 9 * ecc->p.size, at most 648 bytes. */ +#define tp scratch +#define scratch_out (scratch + 3*ecc->p.size) + + unsigned k, c; + unsigned i, j; + unsigned bit_rows; + + k = ecc->pippenger_k; + c = ecc->pippenger_c; + + bit_rows = (ecc->p.bit_size + k - 1) / k; + + /* x = 0, y = 1, z = 1 */ + mpn_zero (r, 3*ecc->p.size); + r[ecc->p.size] = r[2*ecc->p.size] = 1; + + for (i = k; i-- > 0; ) + { + ecc_dup_eh (ecc, r, r, scratch); + for (j = 0; j * c < bit_rows; j++) + { + unsigned bits; + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned bit_index; + + /* Extract c bits from n, stride k, starting at i + kcj, + ending at i + k (cj + c - 1)*/ + for (bits = 0, bit_index = i + k*(c*j+c); bit_index > i + k*c*j; ) + { + mp_size_t limb_index; + unsigned shift; + + bit_index -= k; + + limb_index = bit_index / GMP_NUMB_BITS; + if (limb_index >= ecc->p.size) + continue; + + shift = bit_index % GMP_NUMB_BITS; + bits = (bits << 1) | ((np[limb_index] >> shift) & 1); + } + sec_tabselect (tp, 2*ecc->p.size, + (ecc->pippenger_table + + (2*ecc->p.size * (mp_size_t) j << c)), + 1< + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r, + const mp_limb_t *np, mp_limb_t *scratch) +{ + /* Scratch need determined by the ecc_add_jja call. Current total is + 9 * ecc->p.size, at most 648 bytes. */ +#define tp scratch +#define scratch_out (scratch + 3*ecc->p.size) + + unsigned k, c; + unsigned i, j; + unsigned bit_rows; + + int is_zero; + + k = ecc->pippenger_k; + c = ecc->pippenger_c; + + bit_rows = (ecc->p.bit_size + k - 1) / k; + + mpn_zero (r, 3*ecc->p.size); + + for (i = k, is_zero = 1; i-- > 0; ) + { + ecc_dup_jj (ecc, r, r, scratch); + for (j = 0; j * c < bit_rows; j++) + { + unsigned bits; + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned bit_index; + + /* Extract c bits from n, stride k, starting at i + kcj, + ending at i + k (cj + c - 1)*/ + for (bits = 0, bit_index = i + k*(c*j+c); bit_index > i + k*c*j; ) + { + mp_size_t limb_index; + unsigned shift; + + bit_index -= k; + + limb_index = bit_index / GMP_NUMB_BITS; + if (limb_index >= ecc->p.size) + continue; + + shift = bit_index % GMP_NUMB_BITS; + bits = (bits << 1) | ((np[limb_index] >> shift) & 1); + } + sec_tabselect (tp, 2*ecc->p.size, + (ecc->pippenger_table + + (2*ecc->p.size * (mp_size_t) j << c)), + 1<p.size); + cnd_copy (is_zero, r + 2*ecc->p.size, ecc->unit, ecc->p.size); + + ecc_add_jja (ecc, tp, r, tp, scratch_out); + /* Use the sum when valid. ecc_add_jja produced garbage if + is_zero != 0 or bits == 0, . */ + cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->p.size); + is_zero &= (bits == 0); + } + } +#undef tp +#undef scratch_out +} diff --git a/ecc-pm1-redc.c b/ecc-pm1-redc.c new file mode 100644 index 0000000..2ed50ca --- /dev/null +++ b/ecc-pm1-redc.c @@ -0,0 +1,68 @@ +/* ecc-pm1-redc.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +/* Use that 1 = - (p - 1) (mod p), and that at least one low limb of p + - 1 is zero. */ +void +ecc_pm1_redc (const struct ecc_modulo *m, mp_limb_t *rp) +{ + unsigned i; + mp_limb_t hi, cy; + unsigned shift = m->size * GMP_NUMB_BITS - m->bit_size; + mp_size_t k = m->redc_size; + + for (i = 0; i < m->size; i++) + rp[i] = mpn_submul_1 (rp + i + k, + m->redc_mpm1, m->size - k, rp[i]); + hi = mpn_sub_n (rp, rp + m->size, rp, m->size); + cy = cnd_add_n (hi, rp, m->m, m->size); + assert (cy == hi); + + if (shift > 0) + { + /* Result is always < 2p, provided that + 2^shift * Bmodp_shifted <= p */ + hi = (rp[m->size - 1] >> (GMP_NUMB_BITS - shift)); + rp[m->size - 1] = (rp[m->size - 1] + & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) + + mpn_addmul_1 (rp, m->B_shifted, m->size-1, hi); + } +} diff --git a/ecc-point-mul-g.c b/ecc-point-mul-g.c new file mode 100644 index 0000000..46fceb8 --- /dev/null +++ b/ecc-point-mul-g.c @@ -0,0 +1,58 @@ +/* ecc-point-mul-g.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +void +ecc_point_mul_g (struct ecc_point *r, const struct ecc_scalar *n) +{ + TMP_DECL(scratch, mp_limb_t, 3*ECC_MAX_SIZE + ECC_MUL_G_ITCH (ECC_MAX_SIZE)); + const struct ecc_curve *ecc = r->ecc; + mp_limb_t size = ecc->p.size; + mp_size_t itch = 3*size + ecc->mul_g_itch; + + assert (n->ecc == ecc); + + TMP_ALLOC (scratch, itch); + + ecc->mul_g (ecc, scratch, n->p, scratch + 3*size); + ecc->h_to_a (ecc, 0, r->p, scratch, scratch + 3*size); +} diff --git a/ecc-point-mul.c b/ecc-point-mul.c new file mode 100644 index 0000000..2be1c5c --- /dev/null +++ b/ecc-point-mul.c @@ -0,0 +1,58 @@ +/* ecc-point-mul.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_point_mul (struct ecc_point *r, const struct ecc_scalar *n, + const struct ecc_point *p) +{ + const struct ecc_curve *ecc = r->ecc; + mp_limb_t size = ecc->p.size; + mp_size_t itch = 3*size + ecc->mul_itch; + mp_limb_t *scratch = gmp_alloc_limbs (itch); + + assert (n->ecc == ecc); + assert (p->ecc == ecc); + + ecc->mul (ecc, scratch, n->p, p->p, scratch + 3*size); + ecc->h_to_a (ecc, 0, r->p, scratch, scratch + 3*size); + gmp_free_limbs (scratch, itch); +} diff --git a/ecc-point.c b/ecc-point.c new file mode 100644 index 0000000..31e3115 --- /dev/null +++ b/ecc-point.c @@ -0,0 +1,119 @@ +/* ecc-point.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_point_init (struct ecc_point *p, const struct ecc_curve *ecc) +{ + p->ecc = ecc; + p->p = gmp_alloc_limbs (2*ecc->p.size); +} + +void +ecc_point_clear (struct ecc_point *p) +{ + gmp_free_limbs (p->p, 2*p->ecc->p.size); +} + +int +ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y) +{ + mp_size_t size; + mpz_t lhs, rhs; + mpz_t t; + int res; + + size = p->ecc->p.size; + + if (mpz_sgn (x) < 0 || mpz_limbs_cmp (x, p->ecc->p.m, size) >= 0 + || mpz_sgn (y) < 0 || mpz_limbs_cmp (y, p->ecc->p.m, size) >= 0) + return 0; + + mpz_init (lhs); + mpz_init (rhs); + + mpz_mul (lhs, y, y); + + if (p->ecc->p.bit_size == 255) + { + /* ed25519 special case. FIXME: Do in some cleaner way? */ + mpz_t x2; + mpz_init (x2); + mpz_mul (x2, x, x); + mpz_mul (rhs, x2, lhs); + /* Check that -x^2 + y^2 = 1 - (121665/121666) x^2 y^2 + or 121666 (1 + x^2 - y^2) = 121665 x^2 y^2 */ + mpz_sub (lhs, x2, lhs); + mpz_add_ui (lhs, lhs, 1); + mpz_mul_ui (lhs, lhs, 121666); + mpz_mul_ui (rhs, rhs, 121665); + mpz_clear (x2); + } + else + { + /* Check that y^2 = x^3 - 3*x + b (mod p) */ + mpz_mul (rhs, x, x); + mpz_sub_ui (rhs, rhs, 3); + mpz_mul (rhs, rhs, x); + mpz_add (rhs, rhs, mpz_roinit_n (t, p->ecc->b, size)); + } + + res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, p->ecc->p.m, size)); + + mpz_clear (lhs); + mpz_clear (rhs); + + if (!res) + return 0; + + mpz_limbs_copy (p->p, x, size); + mpz_limbs_copy (p->p + size, y, size); + + return 1; +} + +void +ecc_point_get (const struct ecc_point *p, mpz_t x, mpz_t y) +{ + mp_size_t size = p->ecc->p.size; + if (x) + mpz_set_n (x, p->p, size); + if (y) + mpz_set_n (y, p->p + size, size); +} diff --git a/ecc-pp1-redc.c b/ecc-pp1-redc.c new file mode 100644 index 0000000..ae5b966 --- /dev/null +++ b/ecc-pp1-redc.c @@ -0,0 +1,69 @@ +/* ecc-pp1-redc.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc-internal.h" + +/* Use that 1 = p + 1 (mod p), and that at least one low limb of p + 1 + is zero. */ +void +ecc_pp1_redc (const struct ecc_modulo *m, mp_limb_t *rp) +{ + unsigned i; + mp_limb_t hi, cy; + unsigned shift = m->size * GMP_NUMB_BITS - m->bit_size; + mp_size_t k = m->redc_size; + + for (i = 0; i < m->size; i++) + rp[i] = mpn_addmul_1 (rp + i + k, + m->redc_mpm1, m->size - k, rp[i]); + hi = mpn_add_n (rp, rp, rp + m->size, m->size); + if (shift > 0) + { + hi = (hi << shift) | (rp[m->size - 1] >> (GMP_NUMB_BITS - shift)); + rp[m->size - 1] = (rp[m->size - 1] + & (((mp_limb_t) 1 << (GMP_NUMB_BITS - shift)) - 1)) + + mpn_addmul_1 (rp, m->B_shifted, m->size-1, hi); + + } + else + { + cy = cnd_sub_n (hi, rp, m->m, m->size); + assert (cy == hi); + } +} diff --git a/ecc-random.c b/ecc-random.c new file mode 100644 index 0000000..79df511 --- /dev/null +++ b/ecc-random.c @@ -0,0 +1,95 @@ +/* ecc-random.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +static int +zero_p (const struct ecc_modulo *m, + const mp_limb_t *xp) +{ + mp_limb_t t; + mp_size_t i; + + for (i = t = 0; i < m->size; i++) + t |= xp[i]; + + return t == 0; +} + +static int +ecdsa_in_range (const struct ecc_modulo *m, + const mp_limb_t *xp, mp_limb_t *scratch) +{ + /* Check if 0 < x < q, with data independent timing. */ + return !zero_p (m, xp) + & (mpn_sub_n (scratch, xp, m->m, m->size) != 0); +} + +void +ecc_mod_random (const struct ecc_modulo *m, mp_limb_t *xp, + void *ctx, nettle_random_func *random, mp_limb_t *scratch) +{ + uint8_t *buf = (uint8_t *) scratch; + unsigned nbytes = (m->bit_size + 7)/8; + + /* The bytes ought to fit in the scratch area, unless we have very + unusual limb and byte sizes. */ + assert (nbytes <= m->size * sizeof (mp_limb_t)); + + do + { + random (ctx, nbytes, buf); + buf[0] &= 0xff >> (nbytes * 8 - m->bit_size); + + mpn_set_base256 (xp, m->size, buf, nbytes); + } + while (!ecdsa_in_range (m, xp, scratch)); +} + +void +ecc_scalar_random (struct ecc_scalar *x, + void *random_ctx, nettle_random_func *random) +{ + TMP_DECL (scratch, mp_limb_t, ECC_MOD_RANDOM_ITCH (ECC_MAX_SIZE)); + TMP_ALLOC (scratch, ECC_MOD_RANDOM_ITCH (x->ecc->q.size)); + + ecc_mod_random (&x->ecc->q, x->p, random_ctx, random, scratch); +} diff --git a/ecc-scalar.c b/ecc-scalar.c new file mode 100644 index 0000000..2111ea2 --- /dev/null +++ b/ecc-scalar.c @@ -0,0 +1,70 @@ +/* ecc-scalar.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +void +ecc_scalar_init (struct ecc_scalar *s, const struct ecc_curve *ecc) +{ + s->ecc = ecc; + s->p = gmp_alloc_limbs (ecc->p.size); +} + +void +ecc_scalar_clear (struct ecc_scalar *s) +{ + gmp_free_limbs (s->p, s->ecc->p.size); +} + +int +ecc_scalar_set (struct ecc_scalar *s, const mpz_t z) +{ + mp_size_t size = s->ecc->p.size; + + if (mpz_sgn (z) <= 0 || mpz_limbs_cmp (z, s->ecc->q.m, size) >= 0) + return 0; + + mpz_limbs_copy (s->p, z, size); + return 1; +} + +void +ecc_scalar_get (const struct ecc_scalar *s, mpz_t z) +{ + mpz_set_n (z, s->p, s->ecc->p.size); +} diff --git a/ecc-size.c b/ecc-size.c new file mode 100644 index 0000000..38b5913 --- /dev/null +++ b/ecc-size.c @@ -0,0 +1,63 @@ +/* ecc-size.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ecc.h" +#include "ecc-internal.h" + +unsigned +ecc_bit_size (const struct ecc_curve *ecc) +{ + return ecc->p.bit_size; +} + +mp_size_t +ecc_size (const struct ecc_curve *ecc) +{ + return ecc->p.size; +} + +mp_size_t +ecc_size_a (const struct ecc_curve *ecc) +{ + return 2*ecc->p.size; +} + +mp_size_t +ecc_size_j (const struct ecc_curve *ecc) +{ + return 3*ecc->p.size; +} diff --git a/ecc.h b/ecc.h new file mode 100644 index 0000000..93fc9e8 --- /dev/null +++ b/ecc.h @@ -0,0 +1,159 @@ +/* ecc.h + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#ifndef NETTLE_ECC_H_INCLUDED +#define NETTLE_ECC_H_INCLUDED + +#include "nettle-types.h" +#include "bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define ecc_point_init nettle_ecc_point_init +#define ecc_point_clear nettle_ecc_point_clear +#define ecc_point_set nettle_ecc_point_set +#define ecc_point_get nettle_ecc_point_get +#define ecc_point_mul nettle_ecc_point_mul +#define ecc_point_mul_g nettle_ecc_point_mul_g +#define ecc_scalar_init nettle_ecc_scalar_init +#define ecc_scalar_clear nettle_ecc_scalar_clear +#define ecc_scalar_set nettle_ecc_scalar_set +#define ecc_scalar_get nettle_ecc_scalar_get +#define ecc_scalar_random nettle_ecc_scalar_random +#define ecc_point_mul nettle_ecc_point_mul +#define ecc_bit_size nettle_ecc_bit_size +#define ecc_size nettle_ecc_size +#define ecc_size_a nettle_ecc_size_a +#define ecc_size_j nettle_ecc_size_j + +struct ecc_curve; + +/* High level interface, for ECDSA, DH, etc */ + +/* Represents a point on the ECC curve */ +struct ecc_point +{ + const struct ecc_curve *ecc; + /* Allocated using the same allocation function as GMP. */ + mp_limb_t *p; +}; + +/* Represents a non-zero scalar, an element of Z_q^*, where q is the + group order of the curve. */ +struct ecc_scalar +{ + const struct ecc_curve *ecc; + /* Allocated using the same allocation function as GMP. */ + mp_limb_t *p; +}; + +void +ecc_point_init (struct ecc_point *p, const struct ecc_curve *ecc); +void +ecc_point_clear (struct ecc_point *p); + +/* Fails and returns zero if the point is not on the curve. */ +int +ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y); +void +ecc_point_get (const struct ecc_point *p, mpz_t x, mpz_t y); + +void +ecc_scalar_init (struct ecc_scalar *s, const struct ecc_curve *ecc); +void +ecc_scalar_clear (struct ecc_scalar *s); + +/* Fails and returns zero if the scalar is not in the proper range. */ +int +ecc_scalar_set (struct ecc_scalar *s, const mpz_t z); +void +ecc_scalar_get (const struct ecc_scalar *s, mpz_t z); +/* Generates a random scalar, suitable as an ECDSA private key or a + ECDH exponent. */ +void +ecc_scalar_random (struct ecc_scalar *s, + void *random_ctx, nettle_random_func *random); + +/* Computes r = n p */ +void +ecc_point_mul (struct ecc_point *r, const struct ecc_scalar *n, + const struct ecc_point *p); + +/* Computes r = n g */ +void +ecc_point_mul_g (struct ecc_point *r, const struct ecc_scalar *n); + + +/* Low-level interface */ + +/* Points on a curve are represented as arrays of mp_limb_t, with + curve-specific representation. For the secp curves, we use Jacobian + coordinates (possibly in Montgomery form for mod multiplication). + For curve25519 we use homogeneous coordinates on an equivalent + Edwards curve. The suffix "_h" denotes this internal + representation. + + Since we use additive notation for the groups, the infinity point + on the curve is denoted 0. The infinity point can be represented + with x = y = 0 in affine coordinates, and Z = 0 in Jacobian + coordinates. However, note that most of the ECC functions do *not* + support infinity as an input or output. +*/ + +/* Returns the bit size of a single coordinate (and of the prime p). */ +unsigned +ecc_bit_size (const struct ecc_curve *ecc); + +/* Returns the size of a single coordinate. */ +mp_size_t +ecc_size (const struct ecc_curve *ecc); + +/* Size of a point, using affine coordinates x, y. */ +mp_size_t +ecc_size_a (const struct ecc_curve *ecc); + +/* Size of a point, using jacobian coordinates X, Y and Z. */ +mp_size_t +ecc_size_j (const struct ecc_curve *ecc); + +/* FIXME: Define a generic ecc_dup, ecc_add, for any type of curve. Do + they need to handle infinity points? */ + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ECC_H_INCLUDED */ diff --git a/eccdata.c b/eccdata.c new file mode 100644 index 0000000..e3a9649 --- /dev/null +++ b/eccdata.c @@ -0,0 +1,1107 @@ +/* eccdata.c + + Generate compile time constant (but machine dependent) tables. + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#include +#include +#include +#include + +#include "mini-gmp.c" + +/* Affine coordinates, for simplicity. Infinity point, i.e., te + neutral group element, is represented using the is_zero flag. */ +struct ecc_point +{ + int is_zero; + mpz_t x; + mpz_t y; +}; + +enum ecc_type + { + /* y^2 = x^3 - 3x + b (mod p) */ + ECC_TYPE_WEIERSTRASS, + /* y^2 = x^3 + b x^2 + x */ + ECC_TYPE_MONTGOMERY + }; + +struct ecc_curve +{ + unsigned bit_size; + unsigned pippenger_k; + unsigned pippenger_c; + + enum ecc_type type; + + /* Prime */ + mpz_t p; + mpz_t b; + + /* Curve order */ + mpz_t q; + struct ecc_point g; + + /* Non-zero if we want elements represented as point s(u, v) on an + equivalent Edwards curve, using + + u = t x / y + v = (x-1) / (x+1) + */ + int use_edwards; + mpz_t d; + mpz_t t; + + /* Table for pippenger's algorithm. + Element + + i 2^c + j_0 + j_1 2 + j_2 2^2 + ... + j_{c-1} 2^{c-1} + + holds + + 2^{ikc} ( j_0 + j_1 2^k + j_2 2^{2k} + ... + j_{c-1} 2^{(c-1)k}) g + */ + mp_size_t table_size; + struct ecc_point *table; + + /* If non-NULL, holds 2g, 3g, 4g */ + struct ecc_point *ref; +}; + +static void +ecc_init (struct ecc_point *p) +{ + mpz_init (p->x); + mpz_init (p->y); +} + +static void +ecc_clear (struct ecc_point *p) +{ + mpz_clear (p->x); + mpz_clear (p->y); +} + +static int +ecc_zero_p (const struct ecc_point *p) +{ + return p->is_zero; +} + +static int +ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q) +{ + return p->is_zero ? q->is_zero + : !q->is_zero && mpz_cmp (p->x, q->x) == 0 && mpz_cmp (p->y, q->y) == 0; +} + +static void +ecc_set_zero (struct ecc_point *r) +{ + r->is_zero = 1; +} + +static void +ecc_set (struct ecc_point *r, const struct ecc_point *p) +{ + r->is_zero = p->is_zero; + mpz_set (r->x, p->x); + mpz_set (r->y, p->y); +} + +/* Needs to support in-place operation. */ +static void +ecc_dup (const struct ecc_curve *ecc, + struct ecc_point *r, const struct ecc_point *p) +{ + if (ecc_zero_p (p)) + ecc_set_zero (r); + + else + { + mpz_t m, t, x, y; + + mpz_init (m); + mpz_init (t); + mpz_init (x); + mpz_init (y); + + /* m = (2 y)^-1 */ + mpz_mul_ui (m, p->y, 2); + mpz_invert (m, m, ecc->p); + + switch (ecc->type) + { + case ECC_TYPE_WEIERSTRASS: + /* t = 3 (x^2 - 1) * m */ + mpz_mul (t, p->x, p->x); + mpz_mod (t, t, ecc->p); + mpz_sub_ui (t, t, 1); + mpz_mul_ui (t, t, 3); + break; + case ECC_TYPE_MONTGOMERY: + /* t = (3 x^2 + 2 b x + 1) m = [x(3x+2b)+1] m */ + mpz_mul_ui (t, ecc->b, 2); + mpz_addmul_ui (t, p->x, 3); + mpz_mul (t, t, p->x); + mpz_mod (t, t, ecc->p); + mpz_add_ui (t, t, 1); + break; + } + mpz_mul (t, t, m); + mpz_mod (t, t, ecc->p); + + /* x' = t^2 - 2 x */ + mpz_mul (x, t, t); + mpz_submul_ui (x, p->x, 2); + if (ecc->type == ECC_TYPE_MONTGOMERY) + mpz_sub (x, x, ecc->b); + + mpz_mod (x, x, ecc->p); + + /* y' = (x - x') * t - y */ + mpz_sub (y, p->x, x); + mpz_mul (y, y, t); + mpz_sub (y, y, p->y); + mpz_mod (y, y, ecc->p); + + r->is_zero = 0; + mpz_swap (x, r->x); + mpz_swap (y, r->y); + + mpz_clear (m); + mpz_clear (t); + mpz_clear (x); + mpz_clear (y); + } +} + +static void +ecc_add (const struct ecc_curve *ecc, + struct ecc_point *r, const struct ecc_point *p, const struct ecc_point *q) +{ + if (ecc_zero_p (p)) + ecc_set (r, q); + + else if (ecc_zero_p (q)) + ecc_set (r, p); + + else if (mpz_cmp (p->x, q->x) == 0) + { + if (mpz_cmp (p->y, q->y) == 0) + ecc_dup (ecc, r, p); + else + ecc_set_zero (r); + } + else + { + mpz_t s, t, x, y; + mpz_init (s); + mpz_init (t); + mpz_init (x); + mpz_init (y); + + /* t = (q_y - p_y) / (q_x - p_x) */ + mpz_sub (t, q->x, p->x); + mpz_invert (t, t, ecc->p); + mpz_sub (s, q->y, p->y); + mpz_mul (t, t, s); + mpz_mod (t, t, ecc->p); + + /* x' = t^2 - p_x - q_x */ + mpz_mul (x, t, t); + mpz_sub (x, x, p->x); + mpz_sub (x, x, q->x); + /* This appears to be the only difference between formulas. */ + if (ecc->type == ECC_TYPE_MONTGOMERY) + mpz_sub (x, x, ecc->b); + mpz_mod (x, x, ecc->p); + + /* y' = (x - x') * t - y */ + mpz_sub (y, p->x, x); + mpz_mul (y, y, t); + mpz_sub (y, y, p->y); + mpz_mod (y, y, ecc->p); + + r->is_zero = 0; + mpz_swap (x, r->x); + mpz_swap (y, r->y); + + mpz_clear (s); + mpz_clear (t); + mpz_clear (x); + mpz_clear (y); + } +} + +static void +ecc_mul_binary (const struct ecc_curve *ecc, + struct ecc_point *r, const mpz_t n, const struct ecc_point *p) +{ + /* Avoid the mp_bitcnt_t type for compatibility with older GMP + versions. */ + unsigned k; + + assert (r != p); + assert (mpz_sgn (n) > 0); + + ecc_set (r, p); + + /* Index of highest one bit */ + for (k = mpz_sizeinbase (n, 2) - 1; k-- > 0; ) + { + ecc_dup (ecc, r, r); + if (mpz_tstbit (n, k)) + ecc_add (ecc, r, r, p); + } +} + +static struct ecc_point * +ecc_alloc (size_t n) +{ + struct ecc_point *p = malloc (n * sizeof(*p)); + size_t i; + + if (!p) + { + fprintf (stderr, "Virtual memory exhausted.\n"); + exit (EXIT_FAILURE); + } + for (i = 0; i < n; i++) + ecc_init (&p[i]); + + return p; +} + +static void +ecc_set_str (struct ecc_point *p, + const char *x, const char *y) +{ + p->is_zero = 0; + mpz_set_str (p->x, x, 16); + mpz_set_str (p->y, y, 16); +} + +static void +ecc_curve_init_str (struct ecc_curve *ecc, enum ecc_type type, + const char *p, const char *b, const char *q, + const char *gx, const char *gy, + const char *d, const char *t) +{ + ecc->type = type; + + mpz_init_set_str (ecc->p, p, 16); + mpz_init_set_str (ecc->b, b, 16); + mpz_init_set_str (ecc->q, q, 16); + ecc_init (&ecc->g); + ecc_set_str (&ecc->g, gx, gy); + + ecc->pippenger_k = 0; + ecc->pippenger_c = 0; + ecc->table = NULL; + + ecc->ref = NULL; + + mpz_init (ecc->d); + mpz_init (ecc->t); + + ecc->use_edwards = (t != NULL); + if (ecc->use_edwards) + { + mpz_set_str (ecc->t, t, 16); + mpz_set_str (ecc->d, d, 16); + } +} + +static void +ecc_curve_init (struct ecc_curve *ecc, unsigned bit_size) +{ + switch (bit_size) + { + case 256: + ecc_curve_init_str (ecc, ECC_TYPE_WEIERSTRASS, + /* p = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 1 */ + "FFFFFFFF000000010000000000000000" + "00000000FFFFFFFFFFFFFFFFFFFFFFFF", + + "5AC635D8AA3A93E7B3EBBD55769886BC" + "651D06B0CC53B0F63BCE3C3E27D2604B", + + "FFFFFFFF00000000FFFFFFFFFFFFFFFF" + "BCE6FAADA7179E84F3B9CAC2FC632551", + + "6B17D1F2E12C4247F8BCE6E563A440F2" + "77037D812DEB33A0F4A13945D898C296", + + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" + "2BCE33576B315ECECBB6406837BF51F5", + NULL, NULL); + + ecc->ref = ecc_alloc (3); + ecc_set_str (&ecc->ref[0], /* 2 g */ + "7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978", + "7775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d1"); + + ecc_set_str (&ecc->ref[1], /* 3 g */ + "5ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c", + "8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d5032"); + + ecc_set_str (&ecc->ref[2], /* 4 g */ + "e2534a3532d08fbba02dde659ee62bd0031fe2db785596ef509302446b030852", + "e0f1575a4c633cc719dfee5fda862d764efc96c3f30ee0055c42c23f184ed8c6"); + + break; + case 384: + ecc_curve_init_str (ecc, ECC_TYPE_WEIERSTRASS, + /* p = 2^{384} - 2^{128} - 2^{96} + 2^{32} - 1 */ + "ffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000ffffffff", + + "b3312fa7e23ee7e4988e056be3f82d19" + "181d9c6efe8141120314088f5013875a" + "c656398d8a2ed19d2a85c8edd3ec2aef", + + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffc7634d81f4372ddf" + "581a0db248b0a77aecec196accc52973", + + "aa87ca22be8b05378eb1c71ef320ad74" + "6e1d3b628ba79b9859f741e082542a38" + "5502f25dbf55296c3a545e3872760ab7", + + "3617de4a96262c6f5d9e98bf9292dc29" + "f8f41dbd289a147ce9da3113b5f0b8c0" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + NULL, NULL); + + ecc->ref = ecc_alloc (3); + ecc_set_str (&ecc->ref[0], /* 2 g */ + "8d999057ba3d2d969260045c55b97f089025959a6f434d651d207d19fb96e9e4fe0e86ebe0e64f85b96a9c75295df61", + "8e80f1fa5b1b3cedb7bfe8dffd6dba74b275d875bc6cc43e904e505f256ab4255ffd43e94d39e22d61501e700a940e80"); + + ecc_set_str (&ecc->ref[1], /* 3 g */ + "77a41d4606ffa1464793c7e5fdc7d98cb9d3910202dcd06bea4f240d3566da6b408bbae5026580d02d7e5c70500c831", + "c995f7ca0b0c42837d0bbe9602a9fc998520b41c85115aa5f7684c0edc111eacc24abd6be4b5d298b65f28600a2f1df1"); + + ecc_set_str (&ecc->ref[2], /* 4 g */ + "138251cd52ac9298c1c8aad977321deb97e709bd0b4ca0aca55dc8ad51dcfc9d1589a1597e3a5120e1efd631c63e1835", + "cacae29869a62e1631e8a28181ab56616dc45d918abc09f3ab0e63cf792aa4dced7387be37bba569549f1c02b270ed67"); + + break; + case 521: + ecc_curve_init_str (ecc, ECC_TYPE_WEIERSTRASS, + "1ff" /* p = 2^{521} - 1 */ + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffff", + + "051" + "953eb9618e1c9a1f929a21a0b68540ee" + "a2da725b99b315f3b8b489918ef109e1" + "56193951ec7e937b1652c0bd3bb1bf07" + "3573df883d2c34f1ef451fd46b503f00", + + "1ff" + "ffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffa" + "51868783bf2f966b7fcc0148f709a5d0" + "3bb5c9b8899c47aebb6fb71e91386409", + + "c6" + "858e06b70404e9cd9e3ecb662395b442" + "9c648139053fb521f828af606b4d3dba" + "a14b5e77efe75928fe1dc127a2ffa8de" + "3348b3c1856a429bf97e7e31c2e5bd66", + + "118" + "39296a789a3bc0045c8a5fb42c7d1bd9" + "98f54449579b446817afbd17273e662c" + "97ee72995ef42640c550b9013fad0761" + "353c7086a272c24088be94769fd16650", + NULL, NULL); + + ecc->ref = ecc_alloc (3); + ecc_set_str (&ecc->ref[0], /* 2 g */ + "433c219024277e7e682fcb288148c282747403279b1ccc06352c6e5505d769be97b3b204da6ef55507aa104a3a35c5af41cf2fa364d60fd967f43e3933ba6d783d", + "f4bb8cc7f86db26700a7f3eceeeed3f0b5c6b5107c4da97740ab21a29906c42dbbb3e377de9f251f6b93937fa99a3248f4eafcbe95edc0f4f71be356d661f41b02"); + + ecc_set_str (&ecc->ref[1], /* 3 g */ + "1a73d352443de29195dd91d6a64b5959479b52a6e5b123d9ab9e5ad7a112d7a8dd1ad3f164a3a4832051da6bd16b59fe21baeb490862c32ea05a5919d2ede37ad7d", + "13e9b03b97dfa62ddd9979f86c6cab814f2f1557fa82a9d0317d2f8ab1fa355ceec2e2dd4cf8dc575b02d5aced1dec3c70cf105c9bc93a590425f588ca1ee86c0e5"); + + ecc_set_str (&ecc->ref[2], /* 4 g */ + "35b5df64ae2ac204c354b483487c9070cdc61c891c5ff39afc06c5d55541d3ceac8659e24afe3d0750e8b88e9f078af066a1d5025b08e5a5e2fbc87412871902f3", + "82096f84261279d2b673e0178eb0b4abb65521aef6e6e32e1b5ae63fe2f19907f279f283e54ba385405224f750a95b85eebb7faef04699d1d9e21f47fc346e4d0d"); + + break; + case 255: + /* curve25519, y^2 = x^3 + 486662 x^2 + x (mod p), with p = 2^{255} - 19. + + According to http://cr.yp.to/papers.html#newelliptic, this + is birationally equivalent to the Edwards curve + + x^2 + y^2 = 1 + (121665/121666) x^2 y^2 (mod p). + + And since the constant is not a square, the Edwards formulas + should be "complete", with no special cases needed for + doubling, neutral element, negatives, etc. + + Generator is x = 9, with y coordinate + 14781619447589544791020593568409986887264606134616475288964881837755586237401, + according to + + x = Mod(9, 2^255-19); sqrt(x^3 + 486662*x^2 + x) + + in PARI/GP. Also, in PARI notation, + + curve25519 = Mod([0, 486662, 0, 1, 0], 2^255-19) + */ + ecc_curve_init_str (ecc, ECC_TYPE_MONTGOMERY, + "7fffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffed", + "76d06", + /* Order of the subgroup is 2^252 + q_0, where + q_0 = 27742317777372353535851937790883648493, + 125 bits. + */ + "10000000000000000000000000000000" + "14def9dea2f79cd65812631a5cf5d3ed", + "9", + /* y coordinate from PARI/GP + x = Mod(9, 2^255-19); sqrt(x^3 + 486662*x^2 + x) + */ + "20ae19a1b8a086b4e01edd2c7748d14c" + "923d4d7e6d7c61b229e9c5a27eced3d9", + /* (121665/121666) mod p, from PARI/GP + c = Mod(121665, p); c / (c+1) + */ + "2dfc9311d490018c7338bf8688861767" + "ff8ff5b2bebe27548a14b235eca6874a", + /* A square root of -486664 mod p, PARI/GP + -sqrt(Mod(-486664, p)) in PARI/GP. + + Sign is important to map to the right + generator on the twisted edwards curve + used for EdDSA. */ + "70d9120b9f5ff9442d84f723fc03b081" + "3a5e2c2eb482e57d3391fb5500ba81e7" + ); + ecc->ref = ecc_alloc (3); + ecc_set_str (&ecc->ref[0], /* 2 g */ + "20d342d51873f1b7d9750c687d157114" + "8f3f5ced1e350b5c5cae469cdd684efb", + "13b57e011700e8ae050a00945d2ba2f3" + "77659eb28d8d391ebcd70465c72df563"); + ecc_set_str (&ecc->ref[1], /* 3 g */ + "1c12bc1a6d57abe645534d91c21bba64" + "f8824e67621c0859c00a03affb713c12", + "2986855cbe387eaeaceea446532c338c" + "536af570f71ef7cf75c665019c41222b"); + + ecc_set_str (&ecc->ref[2], /* 4 g */ + "79ce98b7e0689d7de7d1d074a15b315f" + "fe1805dfcd5d2a230fee85e4550013ef", + "75af5bf4ebdc75c8fe26873427d275d7" + "3c0fb13da361077a565539f46de1c30"); + + break; + + default: + fprintf (stderr, "No known curve for size %d\n", bit_size); + exit(EXIT_FAILURE); + } + ecc->bit_size = bit_size; +} + +static void +ecc_pippenger_precompute (struct ecc_curve *ecc, unsigned k, unsigned c) +{ + unsigned p = (ecc->bit_size + k-1) / k; + unsigned M = (p + c-1)/c; + unsigned i, j; + + ecc->pippenger_k = k; + ecc->pippenger_c = c; + ecc->table_size = M << c; + ecc->table = ecc_alloc (ecc->table_size); + + /* Compute the first 2^c entries */ + ecc_set_zero (&ecc->table[0]); + ecc_set (&ecc->table[1], &ecc->g); + + for (j = 2; j < (1U<table[j], &ecc->table[j/2]); + for (i = 1; i < k; i++) + ecc_dup (ecc, &ecc->table[j], &ecc->table[j]); + + for (i = 1; i < j; i++) + ecc_add (ecc, &ecc->table[j + i], &ecc->table[j], &ecc->table[i]); + } + for (j = 1<table_size; j++) + { + /* T[j] = 2^{kc} T[j-2^c] */ + ecc_dup (ecc, &ecc->table[j], &ecc->table[j - (1<table[j], &ecc->table[j]); + } +} + +static void +ecc_mul_pippenger (const struct ecc_curve *ecc, + struct ecc_point *r, const mpz_t n_input) +{ + mpz_t n; + unsigned k, c; + unsigned i, j; + unsigned bit_rows; + + mpz_init (n); + + mpz_mod (n, n_input, ecc->q); + ecc_set_zero (r); + + k = ecc->pippenger_k; + c = ecc->pippenger_c; + + bit_rows = (ecc->bit_size + k - 1) / k; + + for (i = k; i-- > 0; ) + { + ecc_dup (ecc, r, r); + for (j = 0; j * c < bit_rows; j++) + { + unsigned bits; + mp_size_t bit_index; + + /* Extract c bits of the exponent, stride k, starting at i + kcj, ending at + i + k (cj + c - 1)*/ + for (bits = 0, bit_index = i + k*(c*j+c); bit_index > i + k*c*j; ) + { + bit_index -= k; + bits = (bits << 1) | mpz_tstbit (n, bit_index); + } + + ecc_add (ecc, r, r, &ecc->table[(j << c) | bits]); + } + } + mpz_clear (n); +} + +static void +ecc_point_out (FILE *f, const struct ecc_point *p) +{ + if (p->is_zero) + fprintf (f, "zero"); + else + { + fprintf (f, "("); + mpz_out_str (f, 16, p->x); + fprintf (f, ",\n "); + mpz_out_str (f, 16, (p)->y); + fprintf (f, ")"); + } +} +#define ASSERT_EQUAL(p, q) do { \ + if (!ecc_equal_p (p, q)) \ + { \ + fprintf (stderr, "%s:%d: ASSERT_EQUAL (%s, %s) failed.\n", \ + __FILE__, __LINE__, #p, #q); \ + fprintf (stderr, "p = "); \ + ecc_point_out (stderr, (p)); \ + fprintf (stderr, "\nq = "); \ + ecc_point_out (stderr, (q)); \ + fprintf (stderr, "\n"); \ + abort(); \ + } \ + } while (0) + +#define ASSERT_ZERO(p) do { \ + if (!ecc_zero_p (p)) \ + { \ + fprintf (stderr, "%s:%d: ASSERT_ZERO (%s) failed.\n", \ + __FILE__, __LINE__, #p); \ + fprintf (stderr, "p = "); \ + ecc_point_out (stderr, (p)); \ + fprintf (stderr, "\n"); \ + abort(); \ + } \ + } while (0) + +static void +ecc_curve_check (const struct ecc_curve *ecc) +{ + struct ecc_point p, q; + mpz_t n; + + ecc_init (&p); + ecc_init (&q); + mpz_init (n); + + ecc_dup (ecc, &p, &ecc->g); + if (ecc->ref) + ASSERT_EQUAL (&p, &ecc->ref[0]); + else + { + fprintf (stderr, "g2 = "); + mpz_out_str (stderr, 16, p.x); + fprintf (stderr, "\n "); + mpz_out_str (stderr, 16, p.y); + fprintf (stderr, "\n"); + } + ecc_add (ecc, &q, &p, &ecc->g); + if (ecc->ref) + ASSERT_EQUAL (&q, &ecc->ref[1]); + else + { + fprintf (stderr, "g3 = "); + mpz_out_str (stderr, 16, q.x); + fprintf (stderr, "\n "); + mpz_out_str (stderr, 16, q.y); + fprintf (stderr, "\n"); + } + + ecc_add (ecc, &q, &q, &ecc->g); + if (ecc->ref) + ASSERT_EQUAL (&q, &ecc->ref[2]); + else + { + fprintf (stderr, "g4 = "); + mpz_out_str (stderr, 16, q.x); + fprintf (stderr, "\n "); + mpz_out_str (stderr, 16, q.y); + fprintf (stderr, "\n"); + } + + ecc_dup (ecc, &q, &p); + if (ecc->ref) + ASSERT_EQUAL (&q, &ecc->ref[2]); + else + { + fprintf (stderr, "g4 = "); + mpz_out_str (stderr, 16, q.x); + fprintf (stderr, "\n "); + mpz_out_str (stderr, 16, q.y); + fprintf (stderr, "\n"); + } + + ecc_mul_binary (ecc, &p, ecc->q, &ecc->g); + ASSERT_ZERO (&p); + + ecc_mul_pippenger (ecc, &q, ecc->q); + ASSERT_ZERO (&q); + + ecc_clear (&p); + ecc_clear (&q); + mpz_clear (n); +} + +static void +output_digits (const mpz_t x, + unsigned size, unsigned bits_per_limb) +{ + mpz_t t; + mpz_t mask; + mpz_t limb; + unsigned i; + const char *suffix; + + mpz_init (t); + mpz_init (mask); + mpz_init (limb); + + mpz_setbit (mask, bits_per_limb); + mpz_sub_ui (mask, mask, 1); + + suffix = bits_per_limb > 32 ? "ULL" : "UL"; + + mpz_init_set (t, x); + + for (i = 0; i < size; i++) + { + if ( (i % 8) == 0) + printf("\n "); + + mpz_and (limb, mask, t); + printf (" 0x"); + mpz_out_str (stdout, 16, limb); + printf ("%s,", suffix); + mpz_tdiv_q_2exp (t, t, bits_per_limb); + } + + mpz_clear (t); + mpz_clear (mask); + mpz_clear (limb); +} + +static void +output_bignum (const char *name, const mpz_t x, + unsigned size, unsigned bits_per_limb) +{ + printf ("static const mp_limb_t %s[%d] = {", name, size); + output_digits (x, size, bits_per_limb); + printf("\n};\n"); +} + +static void +output_point (const char *name, const struct ecc_curve *ecc, + const struct ecc_point *p, int use_redc, + unsigned size, unsigned bits_per_limb) +{ + mpz_t x, y, t; + + mpz_init (x); + mpz_init (y); + mpz_init (t); + + if (name) + printf("static const mp_limb_t %s[%u] = {", name, 2*size); + + if (ecc->use_edwards) + { + if (ecc_zero_p (p)) + { + mpz_set_si (x, 0); + mpz_set_si (y, 1); + } + else if (!mpz_sgn (p->y)) + { + assert (!mpz_sgn (p->x)); + mpz_set_si (x, 0); + mpz_set_si (y, -1); + } + else + { + mpz_invert (x, p->y, ecc->p); + mpz_mul (x, x, p->x); + mpz_mul (x, x, ecc->t); + mpz_mod (x, x, ecc->p); + + mpz_sub_ui (y, p->x, 1); + mpz_add_ui (t, p->x, 1); + mpz_invert (t, t, ecc->p); + mpz_mul (y, y, t); + mpz_mod (y, y, ecc->p); + } + } + else + { + mpz_set (x, p->x); + mpz_set (y, p->y); + } + if (use_redc) + { + mpz_mul_2exp (x, x, size * bits_per_limb); + mpz_mod (x, x, ecc->p); + mpz_mul_2exp (y, y, size * bits_per_limb); + mpz_mod (y, y, ecc->p); + } + + output_digits (x, size, bits_per_limb); + output_digits (y, size, bits_per_limb); + + if (name) + printf("\n};\n"); + + mpz_clear (x); + mpz_clear (y); + mpz_clear (t); +} + +static unsigned +output_modulo (const char *name, const mpz_t x, + unsigned size, unsigned bits_per_limb) +{ + mpz_t mod; + unsigned bits; + + mpz_init (mod); + + mpz_setbit (mod, bits_per_limb * size); + mpz_mod (mod, mod, x); + + bits = mpz_sizeinbase (mod, 2); + output_bignum (name, mod, size, bits_per_limb); + + mpz_clear (mod); + return bits; +} + +static void +output_curve (const struct ecc_curve *ecc, unsigned bits_per_limb) +{ + unsigned limb_size = (ecc->bit_size + bits_per_limb - 1)/bits_per_limb; + unsigned i; + unsigned bits, e; + int redc_limbs; + mpz_t t; + + mpz_init (t); + + printf ("/* For NULL. */\n#include \n"); + + printf ("#define ECC_LIMB_SIZE %u\n", limb_size); + printf ("#define ECC_PIPPENGER_K %u\n", ecc->pippenger_k); + printf ("#define ECC_PIPPENGER_C %u\n", ecc->pippenger_c); + + output_bignum ("ecc_p", ecc->p, limb_size, bits_per_limb); + output_bignum ("ecc_b", ecc->b, limb_size, bits_per_limb); + if (ecc->use_edwards) + output_bignum ("ecc_d", ecc->d, limb_size, bits_per_limb); + output_bignum ("ecc_q", ecc->q, limb_size, bits_per_limb); + output_point ("ecc_g", ecc, &ecc->g, 0, limb_size, bits_per_limb); + + bits = output_modulo ("ecc_Bmodp", ecc->p, limb_size, bits_per_limb); + printf ("#define ECC_BMODP_SIZE %u\n", + (bits + bits_per_limb - 1) / bits_per_limb); + bits = output_modulo ("ecc_Bmodq", ecc->q, limb_size, bits_per_limb); + printf ("#define ECC_BMODQ_SIZE %u\n", + (bits + bits_per_limb - 1) / bits_per_limb); + bits = mpz_sizeinbase (ecc->q, 2); + if (bits < ecc->bit_size) + { + /* for curve25519, with q = 2^k + q', with a much smaller q' */ + unsigned mbits; + unsigned shift; + + /* Shift to align the one bit at B */ + shift = bits_per_limb * limb_size + 1 - bits; + + mpz_set (t, ecc->q); + mpz_clrbit (t, bits-1); + mbits = mpz_sizeinbase (t, 2); + + /* The shifted value must be a limb smaller than q. */ + if (mbits + shift + bits_per_limb <= bits) + { + /* q of the form 2^k + q', with q' a limb smaller */ + mpz_mul_2exp (t, t, shift); + output_bignum ("ecc_mBmodq_shifted", t, limb_size, bits_per_limb); + } + } + + if (ecc->bit_size < limb_size * bits_per_limb) + { + int shift; + + mpz_set_ui (t, 0); + mpz_setbit (t, ecc->bit_size); + mpz_sub (t, t, ecc->p); + output_bignum ("ecc_Bmodp_shifted", t, limb_size, bits_per_limb); + + shift = limb_size * bits_per_limb - ecc->bit_size; + if (shift > 0) + { + /* Check condition for reducing hi limbs. If s is the + normalization shift and n is the bit size (so that s + n + = limb_size * bite_per_limb), then we need + + (2^n - 1) + (2^s - 1) (2^n - p) < 2p + + or equivalently, + + 2^s (2^n - p) <= p + + To a allow a carry limb to be added in at the same time, + substitute s+1 for s. + */ + /* FIXME: For ecdsa verify, we actually need the stricter + inequality < 2 q. */ + mpz_mul_2exp (t, t, shift + 1); + if (mpz_cmp (t, ecc->p) > 0) + { + fprintf (stderr, "Reduction condition failed for %u-bit curve.\n", + ecc->bit_size); + exit (EXIT_FAILURE); + } + } + } + else + printf ("#define ecc_Bmodp_shifted ecc_Bmodp\n"); + + if (bits < limb_size * bits_per_limb) + { + mpz_set_ui (t, 0); + mpz_setbit (t, bits); + mpz_sub (t, t, ecc->q); + output_bignum ("ecc_Bmodq_shifted", t, limb_size, bits_per_limb); + } + else + printf ("#define ecc_Bmodq_shifted ecc_Bmodq\n"); + + mpz_add_ui (t, ecc->p, 1); + mpz_fdiv_q_2exp (t, t, 1); + output_bignum ("ecc_pp1h", t, limb_size, bits_per_limb); + + mpz_add_ui (t, ecc->q, 1); + mpz_fdiv_q_2exp (t, t, 1); + output_bignum ("ecc_qp1h", t, limb_size, bits_per_limb); + + if (ecc->use_edwards) + output_bignum ("ecc_edwards", ecc->t, limb_size, bits_per_limb); + + /* Trailing zeros in p+1 correspond to trailing ones in p. */ + redc_limbs = mpz_scan0 (ecc->p, 0) / bits_per_limb; + if (redc_limbs > 0) + { + mpz_add_ui (t, ecc->p, 1); + mpz_fdiv_q_2exp (t, t, redc_limbs * bits_per_limb); + output_bignum ("ecc_redc_ppm1", t, limb_size - redc_limbs, bits_per_limb); + } + else + { + /* Trailing zeros in p-1 correspond to zeros just above the low + bit of p */ + redc_limbs = mpz_scan1 (ecc->p, 1) / bits_per_limb; + if (redc_limbs > 0) + { + printf ("#define ecc_redc_ppm1 (ecc_p + %d)\n", + redc_limbs); + redc_limbs = -redc_limbs; + } + else + printf ("#define ecc_redc_ppm1 NULL\n"); + } + printf ("#define ECC_REDC_SIZE %d\n", redc_limbs); + + /* For mod p square root computation. */ + if (mpz_fdiv_ui (ecc->p, 4) == 3) + { + /* x = a^{(p+1)/4} gives square root of a (if it exists, + otherwise the square root of -a). */ + e = 1; + mpz_add_ui (t, ecc->p, 1); + mpz_fdiv_q_2exp (t, t, 2); + } + else + { + /* p-1 = 2^e s, s odd, t = (s-1)/2*/ + unsigned g, i; + mpz_t s; + mpz_t z; + + mpz_init (s); + mpz_init (z); + + mpz_sub_ui (s, ecc->p, 1); + e = mpz_scan1 (s, 0); + assert (e > 1); + + mpz_fdiv_q_2exp (s, s, e); + + /* Find a non-square g, g^{(p-1)/2} = -1, + and z = g^{(p-1)/4 */ + for (g = 2; ; g++) + { + mpz_set_ui (z, g); + mpz_powm (z, z, s, ecc->p); + mpz_mul (t, z, z); + mpz_mod (t, t, ecc->p); + + for (i = 2; i < e; i++) + { + mpz_mul (t, t, t); + mpz_mod (t, t, ecc->p); + } + if (mpz_cmp_ui (t, 1) != 0) + break; + } + mpz_add_ui (t, t, 1); + assert (mpz_cmp (t, ecc->p) == 0); + output_bignum ("ecc_sqrt_z", z, limb_size, bits_per_limb); + + mpz_fdiv_q_2exp (t, s, 1); + + mpz_clear (s); + mpz_clear (z); + } + printf ("#define ECC_SQRT_E %u\n", e); + printf ("#define ECC_SQRT_T_BITS %u\n", + (unsigned) mpz_sizeinbase (t, 2)); + output_bignum ("ecc_sqrt_t", t, limb_size, bits_per_limb); + + printf ("#if USE_REDC\n"); + printf ("#define ecc_unit ecc_Bmodp\n"); + + printf ("static const mp_limb_t ecc_table[%lu] = {", + (unsigned long) (2*ecc->table_size * limb_size)); + for (i = 0; i < ecc->table_size; i++) + output_point (NULL, ecc, &ecc->table[i], 1, limb_size, bits_per_limb); + + printf("\n};\n"); + + printf ("#else\n"); + + mpz_init_set_ui (t, 1); + output_bignum ("ecc_unit", t, limb_size, bits_per_limb); + + printf ("static const mp_limb_t ecc_table[%lu] = {", + (unsigned long) (2*ecc->table_size * limb_size)); + for (i = 0; i < ecc->table_size; i++) + output_point (NULL, ecc, &ecc->table[i], 0, limb_size, bits_per_limb); + + printf("\n};\n"); + printf ("#endif\n"); + + mpz_clear (t); +} + +int +main (int argc, char **argv) +{ + struct ecc_curve ecc; + + if (argc < 4) + { + fprintf (stderr, "Usage: %s CURVE-BITS K C [BITS-PER-LIMB]\n", argv[0]); + return EXIT_FAILURE; + } + + ecc_curve_init (&ecc, atoi(argv[1])); + + ecc_pippenger_precompute (&ecc, atoi(argv[2]), atoi(argv[3])); + + fprintf (stderr, "Table size: %lu entries\n", + (unsigned long) ecc.table_size); + + ecc_curve_check (&ecc); + + if (argc > 4) + output_curve (&ecc, atoi(argv[4])); + + return EXIT_SUCCESS; +} diff --git a/ecdsa-keygen.c b/ecdsa-keygen.c new file mode 100644 index 0000000..fa559a9 --- /dev/null +++ b/ecdsa-keygen.c @@ -0,0 +1,61 @@ +/* ecdsa-keygen.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "ecdsa.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +void +ecdsa_generate_keypair (struct ecc_point *pub, + struct ecc_scalar *key, + void *random_ctx, nettle_random_func *random) +{ + TMP_DECL(p, mp_limb_t, 3*ECC_MAX_SIZE + ECC_MUL_G_ITCH (ECC_MAX_SIZE)); + const struct ecc_curve *ecc = pub->ecc; + mp_size_t itch = 3*ecc->p.size + ecc->mul_g_itch; + + assert (key->ecc == ecc); + + TMP_ALLOC (p, itch); + + ecc_mod_random (&ecc->q, key->p, random_ctx, random, p); + ecc->mul_g (ecc, p, key->p, p + 3*ecc->p.size); + ecc->h_to_a (ecc, 0, pub->p, p, p + 3*ecc->p.size); +} diff --git a/ecdsa-sign.c b/ecdsa-sign.c new file mode 100644 index 0000000..e6fb328 --- /dev/null +++ b/ecdsa-sign.c @@ -0,0 +1,71 @@ +/* ecdsa-sign.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "ecdsa.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +void +ecdsa_sign (const struct ecc_scalar *key, + void *random_ctx, nettle_random_func *random, + size_t digest_length, + const uint8_t *digest, + struct dsa_signature *signature) +{ + /* At most 936 bytes. */ + TMP_DECL(k, mp_limb_t, ECC_MAX_SIZE + ECC_ECDSA_SIGN_ITCH (ECC_MAX_SIZE)); + mp_limb_t size = key->ecc->p.size; + mp_limb_t *rp = mpz_limbs_write (signature->r, size); + mp_limb_t *sp = mpz_limbs_write (signature->s, size); + + TMP_ALLOC (k, size + ECC_ECDSA_SIGN_ITCH (size)); + + /* Timing reveals the number of rounds through this loop, but the + timing is still independent of the secret k finally used. */ + do + { + ecc_mod_random (&key->ecc->q, k, random_ctx, random, k + size); + ecc_ecdsa_sign (key->ecc, key->p, k, digest_length, digest, + rp, sp, k + size); + mpz_limbs_finish (signature->r, size); + mpz_limbs_finish (signature->s, size); + } + while (mpz_sgn (signature->r) == 0 || mpz_sgn (signature->s) == 0); +} diff --git a/ecdsa-verify.c b/ecdsa-verify.c new file mode 100644 index 0000000..ab8e19f --- /dev/null +++ b/ecdsa-verify.c @@ -0,0 +1,79 @@ +/* ecc-ecdsa-verify.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "ecdsa.h" + +#include "gmp-glue.h" + +int +ecdsa_verify (const struct ecc_point *pub, + size_t length, const uint8_t *digest, + const struct dsa_signature *signature) +{ + mp_limb_t size = ecc_size (pub->ecc); + mp_size_t itch = 2*size + ecc_ecdsa_verify_itch (pub->ecc); + /* For ECC_MUL_A_WBITS == 0, at most 1512 bytes. With + ECC_MUL_A_WBITS == 4, currently needs 67 * ecc->size, at most + 4824 bytes. Don't use stack allocation for this. */ + mp_limb_t *scratch; + int res; + +#define rp scratch +#define sp (scratch + size) +#define scratch_out (scratch + 2*size) + + if (mpz_sgn (signature->r) <= 0 || mpz_size (signature->r) > size + || mpz_sgn (signature->s) <= 0 || mpz_size (signature->s) > size) + return 0; + + scratch = gmp_alloc_limbs (itch); + + mpz_limbs_copy (rp, signature->r, size); + mpz_limbs_copy (sp, signature->s, size); + + res = ecc_ecdsa_verify (pub->ecc, pub->p, length, digest, rp, sp, scratch_out); + + gmp_free_limbs (scratch, itch); + + return res; +#undef rp +#undef sp +#undef scratch_out +} diff --git a/ecdsa.h b/ecdsa.h new file mode 100644 index 0000000..693aca8 --- /dev/null +++ b/ecdsa.h @@ -0,0 +1,103 @@ +/* ecdsa.h + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#ifndef NETTLE_ECDSA_H_INCLUDED +#define NETTLE_ECDSA_H_INCLUDED + +#include "ecc.h" +#include "dsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define ecdsa_sign nettle_ecdsa_sign +#define ecdsa_verify nettle_ecdsa_verify +#define ecdsa_generate_keypair nettle_ecdsa_generate_keypair +#define ecc_ecdsa_sign nettle_ecc_ecdsa_sign +#define ecc_ecdsa_sign_itch nettle_ecc_ecdsa_sign_itch +#define ecc_ecdsa_verify nettle_ecc_ecdsa_verify +#define ecc_ecdsa_verify_itch nettle_ecc_ecdsa_verify_itch + +/* High level ECDSA functions. + * + * A public key is represented as a struct ecc_point, and a private + * key as a struct ecc_scalar. FIXME: Introduce some aliases? */ +void +ecdsa_sign (const struct ecc_scalar *key, + void *random_ctx, nettle_random_func *random, + size_t digest_length, + const uint8_t *digest, + struct dsa_signature *signature); + +int +ecdsa_verify (const struct ecc_point *pub, + size_t length, const uint8_t *digest, + const struct dsa_signature *signature); + +void +ecdsa_generate_keypair (struct ecc_point *pub, + struct ecc_scalar *key, + void *random_ctx, nettle_random_func *random); + +/* Low-level ECDSA functions. */ +mp_size_t +ecc_ecdsa_sign_itch (const struct ecc_curve *ecc); + +void +ecc_ecdsa_sign (const struct ecc_curve *ecc, + const mp_limb_t *zp, + /* Random nonce, must be invertible mod ecc group + order. */ + const mp_limb_t *kp, + size_t length, const uint8_t *digest, + mp_limb_t *rp, mp_limb_t *sp, + mp_limb_t *scratch); + +mp_size_t +ecc_ecdsa_verify_itch (const struct ecc_curve *ecc); + +int +ecc_ecdsa_verify (const struct ecc_curve *ecc, + const mp_limb_t *pp, /* Public key */ + size_t length, const uint8_t *digest, + const mp_limb_t *rp, const mp_limb_t *sp, + mp_limb_t *scratch); + + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_ECDSA_H_INCLUDED */ diff --git a/ed25519-sha512-pubkey.c b/ed25519-sha512-pubkey.c new file mode 100644 index 0000000..438446e --- /dev/null +++ b/ed25519-sha512-pubkey.c @@ -0,0 +1,59 @@ +/* ed25519-sha512-pubkey.c + + Copyright (C) 2014, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eddsa.h" + +#include "ecc-internal.h" +#include "sha2.h" + +void +ed25519_sha512_public_key (uint8_t *pub, const uint8_t *priv) +{ + const struct ecc_curve *ecc = &_nettle_curve25519; + struct sha512_ctx ctx; + uint8_t digest[SHA512_DIGEST_SIZE]; + mp_size_t itch = ecc->q.size + _eddsa_public_key_itch (ecc); + mp_limb_t *scratch = gmp_alloc_limbs (itch); + +#define k scratch +#define scratch_out (scratch + ecc->q.size) + + _eddsa_expand_key (ecc, &nettle_sha512, &ctx, priv, digest, k); + _eddsa_public_key (ecc, k, pub, scratch_out); + + gmp_free_limbs (scratch, itch); +#undef k +#undef scratch_out +} diff --git a/ed25519-sha512-sign.c b/ed25519-sha512-sign.c new file mode 100644 index 0000000..af9de20 --- /dev/null +++ b/ed25519-sha512-sign.c @@ -0,0 +1,67 @@ +/* ed25519-sha512-sign.c + + Copyright (C) 2014, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eddsa.h" + +#include "ecc-internal.h" +#include "sha2.h" + +void +ed25519_sha512_sign (const uint8_t *pub, + const uint8_t *priv, + size_t length, const uint8_t *msg, + uint8_t *signature) +{ + const struct ecc_curve *ecc = &_nettle_curve25519; + mp_size_t itch = ecc->q.size + _eddsa_sign_itch (ecc); + mp_limb_t *scratch = gmp_alloc_limbs (itch); +#define k2 scratch +#define scratch_out (scratch + ecc->q.size) + struct sha512_ctx ctx; + uint8_t digest[SHA512_DIGEST_SIZE]; +#define k1 (digest + ED25519_KEY_SIZE) + + _eddsa_expand_key (ecc, &nettle_sha512, &ctx, priv, digest, k2); + + sha512_update (&ctx, ED25519_KEY_SIZE, k1); + _eddsa_sign (ecc, &nettle_sha512, pub, + &ctx, + k2, length, msg, signature, scratch_out); + + gmp_free_limbs (scratch, itch); +#undef k1 +#undef k2 +#undef scratch_out +} diff --git a/ed25519-sha512-verify.c b/ed25519-sha512-verify.c new file mode 100644 index 0000000..e9ba5ae --- /dev/null +++ b/ed25519-sha512-verify.c @@ -0,0 +1,65 @@ +/* ed25519-sha512-verify.c + + Copyright (C) 2014, 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eddsa.h" + +#include "ecc-internal.h" +#include "sha2.h" + +int +ed25519_sha512_verify (const uint8_t *pub, + size_t length, const uint8_t *msg, + const uint8_t *signature) +{ + const struct ecc_curve *ecc = &_nettle_curve25519; + mp_size_t itch = 3*ecc->p.size + _eddsa_verify_itch (ecc); + mp_limb_t *scratch = gmp_alloc_limbs (itch); + struct sha512_ctx ctx; + int res; +#define A scratch +#define scratch_out (scratch + 3*ecc->p.size) + res = (_eddsa_decompress (ecc, + A, pub, scratch_out) + && _eddsa_verify (ecc, &nettle_sha512, + pub, A, &ctx, + length, msg, signature, + scratch_out)); + gmp_free_limbs (scratch, itch); + return res; +#undef A +#undef scratch_out +} diff --git a/eddsa-compress.c b/eddsa-compress.c new file mode 100644 index 0000000..4095958 --- /dev/null +++ b/eddsa-compress.c @@ -0,0 +1,62 @@ +/* eddsa-compress.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eddsa.h" + +#include "ecc-internal.h" +#include "gmp-glue.h" + +mp_size_t +_eddsa_compress_itch (const struct ecc_curve *ecc) +{ + return 2*ecc->p.size + ecc->h_to_a_itch; +} + +void +_eddsa_compress (const struct ecc_curve *ecc, uint8_t *r, mp_limb_t *p, + mp_limb_t *scratch) +{ +#define xp scratch +#define yp (scratch + ecc->p.size) +#define scratch_out (scratch + 2*ecc->p.size) + + ecc->h_to_a (ecc, 0, xp, p, scratch_out); + /* Encoding is the y coordinate and an appended "sign" bit, which is + the low bit of x. Bit order is not specified explicitly, but for + little-endian encoding, it makes most sense to append the bit + after the most significant bit of y. */ + mpn_get_base256_le (r, 1 + ecc->p.bit_size / 8, yp, ecc->p.size); + r[ecc->p.bit_size / 8] += (xp[0] & 1) << (ecc->p.bit_size & 7); +} diff --git a/eddsa-decompress.c b/eddsa-decompress.c new file mode 100644 index 0000000..7555016 --- /dev/null +++ b/eddsa-decompress.c @@ -0,0 +1,83 @@ +/* eddsa-decompress.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eddsa.h" + +#include "ecc-internal.h" +#include "gmp-glue.h" + +mp_size_t +_eddsa_decompress_itch (const struct ecc_curve *ecc) +{ + return 4*ecc->p.size + ecc->p.sqrt_itch; +} + +int +_eddsa_decompress (const struct ecc_curve *ecc, mp_limb_t *p, + const uint8_t *cp, + mp_limb_t *scratch) +{ + mp_limb_t sign, cy; + int res; + +#define xp p +#define yp (p + ecc->p.size) + +#define y2 scratch +#define vp (scratch + ecc->p.size) +#define up scratch +#define tp (scratch + 2*ecc->p.size) +#define scratch_out (scratch + 4*ecc->p.size) + + sign = cp[ecc->p.bit_size / 8] >> (ecc->p.bit_size & 7); + if (sign > 1) + return 0; + mpn_set_base256_le (yp, ecc->p.size, cp, 1 + ecc->p.bit_size / 8); + /* Clear out the sign bit (if it fits) */ + yp[ecc->p.size - 1] &= ~(mp_limb_t) 0 + >> (ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size); + ecc_modp_sqr (ecc, y2, yp); + ecc_modp_mul (ecc, vp, y2, ecc->b); + ecc_modp_sub (ecc, vp, vp, ecc->unit); + ecc_modp_sub (ecc, up, ecc->unit, y2); + res = ecc->p.sqrt (&ecc->p, tp, up, vp, scratch_out); + + cy = mpn_sub_n (xp, tp, ecc->p.m, ecc->p.size); + cnd_copy (cy, xp, tp, ecc->p.size); + sign ^= xp[0] & 1; + mpn_sub_n (tp, ecc->p.m, xp, ecc->p.size); + cnd_copy (sign, xp, tp, ecc->p.size); + return res; +} diff --git a/eddsa-expand.c b/eddsa-expand.c new file mode 100644 index 0000000..dc2bfaf --- /dev/null +++ b/eddsa-expand.c @@ -0,0 +1,72 @@ +/* eddsa-expand.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "eddsa.h" + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-meta.h" + +/* Expands a private key, generating the secret scalar K2 and leaving + the key K1 for nonce generation, at the end of the digest. */ +void +_eddsa_expand_key (const struct ecc_curve *ecc, + const struct nettle_hash *H, + void *ctx, + const uint8_t *key, + uint8_t *digest, + mp_limb_t *k2) +{ + size_t nbytes = 1 + ecc->p.bit_size / 8; + + assert (H->digest_size >= 2*nbytes); + + H->init (ctx); + H->update (ctx, nbytes, key); + H->digest (ctx, 2*nbytes, digest); + + mpn_set_base256_le (k2, ecc->p.size, digest, nbytes); + /* Clear low 3 bits */ + k2[0] &= ~(mp_limb_t) 7; + /* Set bit number bit_size - 1 (bit 254 for curve25519) */ + k2[(ecc->p.bit_size - 1) / GMP_NUMB_BITS] + |= (mp_limb_t) 1 << ((ecc->p.bit_size - 1) % GMP_NUMB_BITS); + /* Clear any higher bits. */ + k2[ecc->p.size - 1] &= ~(mp_limb_t) 0 + >> (GMP_NUMB_BITS * ecc->p.size - ecc->p.bit_size); +} diff --git a/eddsa-hash.c b/eddsa-hash.c new file mode 100644 index 0000000..4fb79f1 --- /dev/null +++ b/eddsa-hash.c @@ -0,0 +1,51 @@ +/* eddsa-hash.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eddsa.h" + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-internal.h" + +void +_eddsa_hash (const struct ecc_modulo *m, + mp_limb_t *rp, const uint8_t *digest) +{ + size_t nbytes = 1 + m->bit_size / 8; + mpn_set_base256_le (rp, 2*m->size, digest, 2*nbytes); + m->mod (m, rp); +} diff --git a/eddsa-pubkey.c b/eddsa-pubkey.c new file mode 100644 index 0000000..d154670 --- /dev/null +++ b/eddsa-pubkey.c @@ -0,0 +1,56 @@ +/* eddsa-pubkey.c + + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "eddsa.h" + +#include "ecc-internal.h" + +mp_size_t +_eddsa_public_key_itch (const struct ecc_curve *ecc) +{ + return 3*ecc->p.size + ecc->mul_g_itch; +} + +void +_eddsa_public_key (const struct ecc_curve *ecc, + const mp_limb_t *k, uint8_t *pub, mp_limb_t *scratch) +{ +#define P scratch +#define scratch_out (scratch + 3*ecc->p.size) + ecc->mul_g (ecc, P, k, scratch_out); + _eddsa_compress (ecc, pub, P, scratch_out); +#undef P +#undef scratch_out +} diff --git a/eddsa-sign.c b/eddsa-sign.c new file mode 100644 index 0000000..c1404f6 --- /dev/null +++ b/eddsa-sign.c @@ -0,0 +1,107 @@ +/* eddsa-sign.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eddsa.h" + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-meta.h" + +mp_size_t +_eddsa_sign_itch (const struct ecc_curve *ecc) +{ + return 5*ecc->p.size + ecc->mul_g_itch; +} + +void +_eddsa_sign (const struct ecc_curve *ecc, + const struct nettle_hash *H, + const uint8_t *pub, + void *ctx, + const mp_limb_t *k2, + size_t length, + const uint8_t *msg, + uint8_t *signature, + mp_limb_t *scratch) +{ + mp_size_t size; + size_t nbytes; +#define rp scratch +#define hp (scratch + size) +#define P (scratch + 2*size) +#define sp (scratch + 2*size) +#define hash ((uint8_t *) (scratch + 3*size)) +#define scratch_out (scratch + 5*size) + + size = ecc->p.size; + nbytes = 1 + ecc->p.bit_size / 8; + + assert (H->digest_size >= 2 * nbytes); + + H->update (ctx, length, msg); + H->digest (ctx, 2*nbytes, hash); + _eddsa_hash (&ecc->q, rp, hash); + ecc->mul_g (ecc, P, rp, scratch_out); + _eddsa_compress (ecc, signature, P, scratch_out); + + H->update (ctx, nbytes, signature); + H->update (ctx, nbytes, pub); + H->update (ctx, length, msg); + H->digest (ctx, 2*nbytes, hash); + _eddsa_hash (&ecc->q, hp, hash); + + ecc_modq_mul (ecc, sp, hp, k2); + ecc_modq_add (ecc, sp, sp, rp); /* FIXME: Can be plain add */ + /* FIXME: Special code duplicated in ecc_25519_modq and ecc_eh_to_a. + Define a suitable method? */ + { + unsigned shift; + mp_limb_t cy; + assert (ecc->p.bit_size == 255); + shift = 252 - GMP_NUMB_BITS * (ecc->p.size - 1); + cy = mpn_submul_1 (sp, ecc->q.m, ecc->p.size, + sp[ecc->p.size-1] >> shift); + assert (cy < 2); + cnd_add_n (cy, sp, ecc->q.m, ecc->p.size); + } + mpn_get_base256_le (signature + nbytes, nbytes, sp, ecc->q.size); +#undef rp +#undef hp +#undef P +#undef sp +#undef hash +} diff --git a/eddsa-verify.c b/eddsa-verify.c new file mode 100644 index 0000000..5541d97 --- /dev/null +++ b/eddsa-verify.c @@ -0,0 +1,133 @@ +/* eddsa-verify.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eddsa.h" + +#include "ecc.h" +#include "ecc-internal.h" +#include "nettle-meta.h" + +/* Checks if x1/z1 == x2/z2 (mod p). Assumes z1 and z2 are + non-zero. */ +static int +equal_h (const struct ecc_modulo *p, + const mp_limb_t *x1, const mp_limb_t *z1, + const mp_limb_t *x2, const mp_limb_t *z2, + mp_limb_t *scratch) +{ +#define t0 scratch +#define t1 (scratch + p->size) + + ecc_mod_mul (p, t0, x1, z2); + if (mpn_cmp (t0, p->m, p->size) >= 0) + mpn_sub_n (t0, t0, p->m, p->size); + + ecc_mod_mul (p, t1, x2, z1); + if (mpn_cmp (t1, p->m, p->size) >= 0) + mpn_sub_n (t1, t1, p->m, p->size); + + return mpn_cmp (t0, t1, p->size) == 0; + +#undef t0 +#undef t1 +} + +mp_size_t +_eddsa_verify_itch (const struct ecc_curve *ecc) +{ + return 8*ecc->p.size + ecc->mul_itch; +} + +int +_eddsa_verify (const struct ecc_curve *ecc, + const struct nettle_hash *H, + const uint8_t *pub, + const mp_limb_t *A, + void *ctx, + size_t length, + const uint8_t *msg, + const uint8_t *signature, + mp_limb_t *scratch) +{ + size_t nbytes; +#define R scratch +#define sp (scratch + 2*ecc->p.size) +#define hp (scratch + 3*ecc->p.size) +#define P (scratch + 5*ecc->p.size) +#define scratch_out (scratch + 8*ecc->p.size) +#define S R +#define hash ((uint8_t *) P) + + nbytes = 1 + ecc->p.bit_size / 8; + + /* Could maybe save some storage by delaying the R and S operations, + but it makes sense to check them for validity up front. */ + if (!_eddsa_decompress (ecc, R, signature, R+2*ecc->p.size)) + return 0; + + mpn_set_base256_le (sp, ecc->q.size, signature + nbytes, nbytes); + /* Check that s < q */ + if (mpn_cmp (sp, ecc->q.m, ecc->q.size) >= 0) + return 0; + + H->init (ctx); + H->update (ctx, nbytes, signature); + H->update (ctx, nbytes, pub); + H->update (ctx, length, msg); + H->digest (ctx, 2*nbytes, hash); + _eddsa_hash (&ecc->q, hp, hash); + + /* Compute h A + R - s G, which should be the neutral point */ + ecc->mul (ecc, P, hp, A, scratch_out); + ecc_add_eh (ecc, P, P, R, scratch_out); + /* Move out of the way. */ + mpn_copyi (hp, sp, ecc->q.size); + ecc->mul_g (ecc, S, hp, scratch_out); + + return equal_h (&ecc->p, + P, P + 2*ecc->p.size, + S, S + 2*ecc->p.size, scratch_out) + && equal_h (&ecc->p, + P + ecc->p.size, P + 2*ecc->p.size, + S + ecc->p.size, S + 2*ecc->p.size, scratch_out); + +#undef R +#undef sp +#undef hp +#undef P +#undef S +} diff --git a/eddsa.h b/eddsa.h new file mode 100644 index 0000000..49f1a02 --- /dev/null +++ b/eddsa.h @@ -0,0 +1,149 @@ +/* eddsa.h + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_EDDSA_H +#define NETTLE_EDDSA_H + +#include "nettle-types.h" + +#include "bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define ed25519_sha512_set_private_key nettle_ed25519_sha512_set_private_key +#define ed25519_sha512_public_key nettle_ed25519_sha512_public_key +#define ed25519_sha512_sign nettle_ed25519_sha512_sign +#define ed25519_sha512_verify nettle_ed25519_sha512_verify + +#define _eddsa_compress _nettle_eddsa_compress +#define _eddsa_compress_itch _nettle_eddsa_compress_itch +#define _eddsa_decompress _nettle_eddsa_decompress +#define _eddsa_decompress_itch _nettle_eddsa_decompress_itch +#define _eddsa_hash _nettle_eddsa_hash +#define _eddsa_expand_key _nettle_eddsa_expand_key +#define _eddsa_sign _nettle_eddsa_sign +#define _eddsa_sign_itch _nettle_eddsa_sign_itch +#define _eddsa_verify _nettle_eddsa_verify +#define _eddsa_verify_itch _nettle_eddsa_verify_itch +#define _eddsa_public_key_itch _nettle_eddsa_public_key_itch +#define _eddsa_public_key _nettle_eddsa_public_key + +#define ED25519_KEY_SIZE 32 +#define ED25519_SIGNATURE_SIZE 64 + +void +ed25519_sha512_public_key (uint8_t *pub, const uint8_t *priv); + +void +ed25519_sha512_sign (const uint8_t *pub, + const uint8_t *priv, + size_t length, const uint8_t *msg, + uint8_t *signature); + +int +ed25519_sha512_verify (const uint8_t *pub, + size_t length, const uint8_t *msg, + const uint8_t *signature); + +/* Low-level internal functions */ + +struct ecc_curve; +struct ecc_modulo; + +mp_size_t +_eddsa_compress_itch (const struct ecc_curve *ecc); +void +_eddsa_compress (const struct ecc_curve *ecc, uint8_t *r, mp_limb_t *p, + mp_limb_t *scratch); + +mp_size_t +_eddsa_decompress_itch (const struct ecc_curve *ecc); +int +_eddsa_decompress (const struct ecc_curve *ecc, mp_limb_t *p, + const uint8_t *cp, + mp_limb_t *scratch); + +void +_eddsa_hash (const struct ecc_modulo *m, + mp_limb_t *rp, const uint8_t *digest); + +mp_size_t +_eddsa_sign_itch (const struct ecc_curve *ecc); + +void +_eddsa_sign (const struct ecc_curve *ecc, + const struct nettle_hash *H, + const uint8_t *pub, + void *ctx, + const mp_limb_t *k2, + size_t length, + const uint8_t *msg, + uint8_t *signature, + mp_limb_t *scratch); + +mp_size_t +_eddsa_verify_itch (const struct ecc_curve *ecc); + +int +_eddsa_verify (const struct ecc_curve *ecc, + const struct nettle_hash *H, + const uint8_t *pub, + const mp_limb_t *A, + void *ctx, + size_t length, + const uint8_t *msg, + const uint8_t *signature, + mp_limb_t *scratch); + +void +_eddsa_expand_key (const struct ecc_curve *ecc, + const struct nettle_hash *H, + void *ctx, + const uint8_t *key, + uint8_t *digest, + mp_limb_t *k2); + +mp_size_t +_eddsa_public_key_itch (const struct ecc_curve *ecc); + +void +_eddsa_public_key (const struct ecc_curve *ecc, + const mp_limb_t *k, uint8_t *pub, mp_limb_t *scratch); + + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_EDDSA_H */ diff --git a/examples/Makefile.in b/examples/Makefile.in new file mode 100644 index 0000000..43a06bc --- /dev/null +++ b/examples/Makefile.in @@ -0,0 +1,145 @@ +@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@ +BENCH_LIBS = @BENCH_LIBS@ -lm + +HOGWEED_TARGETS = rsa-keygen$(EXEEXT) rsa-sign$(EXEEXT) \ + rsa-verify$(EXEEXT) rsa-encrypt$(EXEEXT) rsa-decrypt$(EXEEXT) \ + random-prime$(EXEEXT) \ + hogweed-benchmark$(EXEEXT) ecc-benchmark$(EXEEXT) + +ENC_TARGETS = base16enc$(EXEEXT) base16dec$(EXEEXT) \ + base64enc$(EXEEXT) base64dec$(EXEEXT) +TARGETS = nettle-benchmark$(EXEEXT) eratosthenes$(EXEEXT) \ + $(ENC_TARGETS) @IF_HOGWEED@ $(HOGWEED_TARGETS) + +SOURCES = nettle-benchmark.c hogweed-benchmark.c ecc-benchmark.c \ + eratosthenes.c random-prime.c \ + nettle-openssl.c \ + io.c read_rsa_key.c \ + rsa-encrypt.c rsa-decrypt.c rsa-keygen.c rsa-sign.c rsa-verify.c \ + base16enc.c base16dec.c base64enc.c base64dec.c timing.c + + +GETOPT_OBJS = ../getopt.$(OBJEXT) ../getopt1.$(OBJEXT) + +TS_ALL = rsa-sign-test rsa-verify-test rsa-encrypt-test + +DISTFILES= $(SOURCES) Makefile.in $(TS_ALL) setup-env teardown-env \ + io.h rsa-session.h timing.h + +all: $(TARGETS) + +.c.$(OBJEXT): + $(COMPILE) -c $< && $(DEP_PROCESS) + +# NOTE: If we required GNU make, we could use a single rule with $(@F) +# or $(notdir $@) +../getopt.$(OBJEXT): + ( cd .. && $(MAKE) getopt.$(OBJEXT)) +../getopt1.$(OBJEXT): + ( cd .. && $(MAKE) getopt1.$(OBJEXT)) +../nettle-internal.$(OBJEXT): + ( cd .. && $(MAKE) nettle-internal.$(OBJEXT)) + +# For Solaris and BSD make, we have to use an explicit rule for each executable +random-prime$(EXEEXT): random-prime.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) random-prime.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \ + -lhogweed -lnettle $(LIBS) -o random-prime$(EXEEXT) + +rsa-keygen$(EXEEXT): rsa-keygen.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) rsa-keygen.$(OBJEXT) io.$(OBJEXT) $(GETOPT_OBJS) \ + -lhogweed -lnettle $(LIBS) -o rsa-keygen$(EXEEXT) + +rsa-sign$(EXEEXT): rsa-sign.$(OBJEXT) io.$(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) io.$(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) io.$(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) io.$(OBJEXT) read_rsa_key.$(OBJEXT) + $(LINK) rsa-decrypt.$(OBJEXT) io.$(OBJEXT) read_rsa_key.$(OBJEXT) \ + -lhogweed -lnettle $(LIBS) -o rsa-decrypt$(EXEEXT) + +base16enc$(EXEEXT): base16enc.$(OBJEXT) io.$(OBJEXT) + $(LINK) base16enc.$(OBJEXT) io.$(OBJEXT) \ + -lnettle $(LIBS) -o base16enc$(EXEEXT) + +base16dec$(EXEEXT): base16dec.$(OBJEXT) io.$(OBJEXT) + $(LINK) base16dec.$(OBJEXT) io.$(OBJEXT) \ + -lnettle $(LIBS) -o base16dec$(EXEEXT) + +base64enc$(EXEEXT): base64enc.$(OBJEXT) io.$(OBJEXT) + $(LINK) base64enc.$(OBJEXT) io.$(OBJEXT) \ + -lnettle $(LIBS) -o base64enc$(EXEEXT) + +base64dec$(EXEEXT): base64dec.$(OBJEXT) io.$(OBJEXT) + $(LINK) base64dec.$(OBJEXT) io.$(OBJEXT) \ + -lnettle $(LIBS) -o base64dec$(EXEEXT) + +eratosthenes$(EXEEXT): eratosthenes.$(OBJEXT) $(GETOPT_OBJS) + $(LINK) eratosthenes.$(OBJEXT) $(GETOPT_OBJS) -o eratosthenes$(EXEEXT) + +BENCH_OBJS = nettle-benchmark.$(OBJEXT) nettle-openssl.$(OBJEXT) \ + $(GETOPT_OBJS) ../nettle-internal.$(OBJEXT) timing.$(OBJEXT) +nettle-benchmark$(EXEEXT): $(BENCH_OBJS) + $(LINK) $(BENCH_OBJS) -lnettle $(BENCH_LIBS) $(OPENSSL_LIBFLAGS) -o nettle-benchmark$(EXEEXT) + +ECC_BENCH_OBJS = ecc-benchmark.$(OBJEXT) timing.$(OBJEXT) +ecc-benchmark$(EXEEXT): $(ECC_BENCH_OBJS) + $(LINK) $(ECC_BENCH_OBJS) -lhogweed -lnettle $(BENCH_LIBS) $(LIBS) \ + -o ecc-benchmark$(EXEEXT) + +HOGWEED_BENCH_OBJS = hogweed-benchmark.$(OBJEXT) timing.$(OBJEXT) +hogweed-benchmark$(EXEEXT): $(HOGWEED_BENCH_OBJS) + $(LINK) $(HOGWEED_BENCH_OBJS) \ + -lhogweed -lnettle $(BENCH_LIBS) $(LIBS) $(OPENSSL_LIBFLAGS) \ + -o hogweed-benchmark$(EXEEXT) + +$(TARGETS) : io.$(OBJEXT) ../libnettle.stamp +$(HOGWEED_TARGETS): ../libhogweed.stamp + +# The PATH update is for windows dlls, DYLD_LIBRARY_PATH is for OSX. +check: $(TS_ALL) + LD_LIBRARY_PATH=../.lib PATH="../.lib:$$PATH" DYLD_LIBRARY_PATH=../.lib \ + srcdir="$(srcdir)" EMULATOR="$(EMULATOR)" EXEEXT="$(EXEEXT)" \ + "$(top_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/base16dec.c b/examples/base16dec.c new file mode 100644 index 0000000..1185b3e --- /dev/null +++ b/examples/base16dec.c @@ -0,0 +1,124 @@ +/* base16dec -- an decoder for base16 + + Copyright (C) 2006, 2012 Jeronimo Pellegrini, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "base16.h" + +#include "io.h" + +#define CHUNK_SIZE 16392 + +/* The maximum number of bytes generated for each chunk: */ +#define DECODED_SIZE BASE16_DECODE_LENGTH(CHUNK_SIZE) + + +/* + * Reads base-16 encoded from stdin, writes decoded to stdout. + */ +int +main(int argc UNUSED, char **argv UNUSED) +{ + /* "buffer" will hold the bytes from disk: */ + char * buffer = xalloc (CHUNK_SIZE); + + /* "result" will hold bytes before output: */ + uint8_t * result = xalloc (DECODED_SIZE); + + /* We need a Base16 context for decoding: */ + struct base16_decode_ctx b16_ctx; + + /* Init the context: */ + base16_decode_init (&b16_ctx); + +#ifdef WIN32 + _setmode(1, O_BINARY); +#endif + + for (;;) + { + int nbytes; /* Number of bytes read frmo disk at each iteration */ + size_t decoded_bytes; /* Bytes actually generated at each iteration */ + + nbytes = fread(buffer, 1, CHUNK_SIZE, stdin); + + if (nbytes < CHUNK_SIZE && ferror(stdin)) + { + werror ("Error reading file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + /* Decodes one chunk: */ + if (!base16_decode_update(&b16_ctx, &decoded_bytes, result, nbytes, buffer)) + { + werror ("Error decoding input (not base16?)\n"); + return EXIT_FAILURE; + } + + if (!write_data (stdout, decoded_bytes, result)) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + if (nbytes < CHUNK_SIZE) + { + /* Check if decoding finalized OK: */ + if (!base16_decode_final(&b16_ctx)) + { + werror("Decoding did not finish properly.\n"); + return EXIT_FAILURE; + } + break; + } + } + + if (fflush (stdout) != 0) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + free (buffer); + free (result); + + return EXIT_SUCCESS; +} + diff --git a/examples/base16enc.c b/examples/base16enc.c new file mode 100644 index 0000000..6ac08e1 --- /dev/null +++ b/examples/base16enc.c @@ -0,0 +1,107 @@ +/* base16enc -- an encoder for base16 + + Copyright (C) 2006, 2012 Jeronimo Pellegrini, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "base16.h" + +#include "io.h" + +/* The number of bytes read in each iteration, we do one line at a time: */ +#define CHUNK_SIZE 36 + +/* The *maximum* size of an encoded chunk: */ +#define ENCODED_SIZE BASE16_ENCODE_LENGTH(CHUNK_SIZE) + +/* + * Reads bytes from standard input and writes base64-encoded + * on standard output. + */ +int +main(int argc UNUSED, char **argv UNUSED) +{ + +#ifdef WIN32 + _setmode(0, O_BINARY); +#endif + + /* There is no context to initialize. */ + + for (;;) + { + /* "buffer" will hold the bytes from disk: */ + uint8_t buffer[CHUNK_SIZE]; + /* "result" will hold bytes before output: */ + char result[ENCODED_SIZE + 1]; + unsigned nbytes; /* Number of bytes read from stdin */ + int encoded_bytes; /* Total number of bytes encoded per iteration */ + + nbytes = fread(buffer,1,CHUNK_SIZE,stdin); + + /* We overwrite result with more data */ + base16_encode_update(result, nbytes, buffer); + encoded_bytes = BASE16_ENCODE_LENGTH(nbytes); + result[encoded_bytes++] = '\n'; + + if (nbytes < CHUNK_SIZE) + { + if (ferror(stdin)) + { + werror ("Error reading file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + if (!write_data (stdout, encoded_bytes, result) + || fflush (stdout) != 0) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + /* The result vector is printed */ + if (!write_data(stdout, encoded_bytes, result)) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + } +} + diff --git a/examples/base64dec.c b/examples/base64dec.c new file mode 100644 index 0000000..d05d924 --- /dev/null +++ b/examples/base64dec.c @@ -0,0 +1,124 @@ +/* base64dec -- an decoder for base64 + + Copyright (C) 2006, 2012 Jeronimo Pellegrini, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "base64.h" + +#include "io.h" + +#define CHUNK_SIZE 16392 + +/* The maximum number of bytes generated for each chunk: */ +#define DECODED_SIZE BASE64_DECODE_LENGTH(CHUNK_SIZE) + + +/* + * Reads base-64 encoded from stdin, writes decoded to stdout. + */ +int +main(int argc UNUSED, char **argv UNUSED) +{ + /* "buffer" will hold the bytes from disk: */ + char * buffer = xalloc (CHUNK_SIZE); + + /* "result" will hold bytes before output: */ + uint8_t * result = xalloc (DECODED_SIZE); + + /* We need a Base64 context for decoding: */ + struct base64_decode_ctx b64_ctx; + + /* Init the context: */ + base64_decode_init(&b64_ctx); + +#ifdef WIN32 + _setmode(1, O_BINARY); +#endif + + for (;;) + { + int nbytes; /* Number of bytes read frmo disk at each iteration */ + size_t decoded_bytes; /* Bytes actually generated at each iteration */ + + nbytes = fread(buffer, 1, CHUNK_SIZE, stdin); + + if (nbytes < CHUNK_SIZE && ferror(stdin)) + { + werror ("Error reading file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + /* Decodes one chunk: */ + if (!base64_decode_update(&b64_ctx, &decoded_bytes, result, nbytes, buffer)) + { + werror ("Error decoding input (not base64?)\n"); + return EXIT_FAILURE; + } + + if (!write_data (stdout, decoded_bytes, result)) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + if (nbytes < CHUNK_SIZE) + { + /* Check if decoding finalized OK: */ + if (!base64_decode_final(&b64_ctx)) + { + werror ("Decoding did not finish properly.\n"); + return EXIT_FAILURE; + } + break; + } + } + + if (fflush (stdout) != 0) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + free (buffer); + free (result); + + return EXIT_SUCCESS; +} diff --git a/examples/base64enc.c b/examples/base64enc.c new file mode 100644 index 0000000..cc6010c --- /dev/null +++ b/examples/base64enc.c @@ -0,0 +1,110 @@ +/* base64enc -- an encoder for base64 + + Copyright (C) 2006, 2012 Jeronimo Pellegrini, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "base64.h" + +#include "io.h" + +/* The number of bytes read in each iteration, we do one line at a time: */ +#define CHUNK_SIZE 54 + +/* The *maximum* size of an encoded chunk: */ +#define ENCODED_SIZE BASE64_ENCODE_LENGTH(CHUNK_SIZE) + +/* + * Reads bytes from standard input and writes base64-encoded + * on standard output. + */ +int +main(int argc UNUSED, char **argv UNUSED) +{ + struct base64_encode_ctx b64_ctx; + + /* Init the context: */ + base64_encode_init(&b64_ctx); + +#ifdef WIN32 + _setmode(0, O_BINARY); +#endif + + for (;;) + { + /* "buffer" will hold the bytes from disk: */ + uint8_t buffer[CHUNK_SIZE]; + /* "result" is the result vector: */ + char result[ENCODED_SIZE + BASE64_ENCODE_FINAL_LENGTH + 1]; + unsigned nbytes; /* Number of bytes read from stdin */ + int encoded_bytes; /* total number of bytes encoded per iteration */ + nbytes = fread(buffer,1,CHUNK_SIZE,stdin); + + /* We overwrite result with more data */ + encoded_bytes = base64_encode_update(&b64_ctx, result, nbytes, buffer); + + if (nbytes < CHUNK_SIZE) + { + if (ferror(stdin)) + { + werror ("Error reading file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + encoded_bytes += base64_encode_final(&b64_ctx,result + encoded_bytes); + + result[encoded_bytes++] = '\n'; + if (!write_data (stdout, encoded_bytes, result) + || fflush (stdout) != 0) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + + /* The result vector is written */ + result[encoded_bytes++] = '\n'; + if (!write_data (stdout, encoded_bytes, result)) + { + werror ("Error writing file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + } +} diff --git a/examples/ecc-benchmark.c b/examples/ecc-benchmark.c new file mode 100644 index 0000000..8e5e095 --- /dev/null +++ b/examples/ecc-benchmark.c @@ -0,0 +1,357 @@ +/* ecc-benchmark.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include + +#include + +#include "timing.h" + +#include "../ecc.h" +#include "../ecc-internal.h" +#include "../gmp-glue.h" + +#define BENCH_INTERVAL 0.1 + +static void * +xalloc (size_t size) +{ + void *p = malloc (size); + if (!p) + { + fprintf (stderr, "Virtual memory exhausted\n"); + abort (); + } + return p; +} + +static mp_limb_t * +xalloc_limbs (mp_size_t size) +{ + return xalloc (size * sizeof(mp_limb_t)); +} + +/* Returns second per function call */ +static double +time_function(void (*f)(void *arg), void *arg) +{ + unsigned ncalls; + double elapsed; + + /* Warm up */ + f(arg); + for (ncalls = 10 ;;) + { + unsigned i; + + time_start(); + for (i = 0; i < ncalls; i++) + f(arg); + elapsed = time_end(); + if (elapsed > BENCH_INTERVAL) + break; + else if (elapsed < BENCH_INTERVAL / 10) + ncalls *= 10; + else + ncalls *= 2; + } + return elapsed / ncalls; +} + +#if !NETTLE_USE_MINI_GMP +static int +modinv_gcd (const struct ecc_curve *ecc, + mp_limb_t *rp, mp_limb_t *ap, mp_limb_t *tp) +{ + mp_size_t size = ecc->p.size; + mp_limb_t *up = tp; + mp_limb_t *vp = tp + size+1; + mp_limb_t *gp = tp + 2*(size+1); + mp_limb_t *sp = tp + 3*(size+1); + mp_size_t gn, sn; + + mpn_copyi (up, ap, size); + mpn_copyi (vp, ecc->p.m, size); + gn = mpn_gcdext (gp, sp, &sn, up, size, vp, size); + if (gn != 1 || gp[0] != 1) + return 0; + + if (sn < 0) + mpn_sub (sp, ecc->p.m, size, sp, -sn); + else if (sn < size) + /* Zero-pad. */ + mpn_zero (sp + sn, size - sn); + + mpn_copyi (rp, sp, size); + return 1; +} +#endif + +struct ecc_ctx { + const struct ecc_curve *ecc; + mp_limb_t *rp; + mp_limb_t *ap; + mp_limb_t *bp; + mp_limb_t *tp; +}; + +static void +bench_modp (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size); + ctx->ecc->p.mod (&ctx->ecc->p, ctx->rp); +} + +static void +bench_reduce (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size); + ctx->ecc->p.reduce (&ctx->ecc->p, ctx->rp); +} + +static void +bench_modq (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + mpn_copyi (ctx->rp, ctx->ap, 2*ctx->ecc->p.size); + ctx->ecc->q.mod(&ctx->ecc->q, ctx->rp); +} + +static void +bench_modinv (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ctx->ecc->p.invert (&ctx->ecc->p, ctx->rp, ctx->ap, ctx->tp); +} + +#if !NETTLE_USE_MINI_GMP +static void +bench_modinv_gcd (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + mpn_copyi (ctx->rp + ctx->ecc->p.size, ctx->ap, ctx->ecc->p.size); + modinv_gcd (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->p.size, ctx->tp); +} +#endif + +#ifdef mpn_sec_powm +static void +bench_modinv_powm (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + const struct ecc_curve *ecc = ctx->ecc; + mp_size_t size = ecc->p.size; + + mpn_sub_1 (ctx->rp + size, ecc->p.m, size, 2); + mpn_sec_powm (ctx->rp, ctx->ap, size, + ctx->rp + size, ecc->p.bit_size, + ecc->p.m, size, ctx->tp); +} +#endif + +static void +bench_dup_jj (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ecc_dup_jj (ctx->ecc, ctx->rp, ctx->ap, ctx->tp); +} + +static void +bench_add_jja (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ecc_add_jja (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp); +} + +static void +bench_add_hhh (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ctx->ecc->add_hhh (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp); +} + +static void +bench_mul_g (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ctx->ecc->mul_g (ctx->ecc, ctx->rp, ctx->ap, ctx->tp); +} + +static void +bench_mul_a (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ctx->ecc->mul (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp); +} + +static void +bench_dup_eh (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ecc_dup_eh (ctx->ecc, ctx->rp, ctx->ap, ctx->tp); +} + +static void +bench_add_eh (void *p) +{ + struct ecc_ctx *ctx = (struct ecc_ctx *) p; + ecc_add_eh (ctx->ecc, ctx->rp, ctx->ap, ctx->bp, ctx->tp); +} + +#if NETTLE_USE_MINI_GMP +static void +mpn_random (mp_limb_t *xp, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + xp[i] = rand(); +} +#endif + +static void +bench_curve (const struct ecc_curve *ecc) +{ + struct ecc_ctx ctx; + double modp, reduce, modq, modinv, modinv_gcd, modinv_powm, + dup_jj, add_jja, add_hhh, + mul_g, mul_a; + + mp_limb_t mask; + mp_size_t itch; + + ctx.ecc = ecc; + ctx.rp = xalloc_limbs (3*ecc->p.size); + ctx.ap = xalloc_limbs (3*ecc->p.size); + ctx.bp = xalloc_limbs (3*ecc->p.size); + itch = ecc->mul_itch; +#ifdef mpn_sec_powm + { + mp_size_t powm_itch + = mpn_sec_powm_itch (ecc->p.size, ecc->p.bit_size, ecc->p.size); + if (powm_itch > itch) + itch = powm_itch; + } +#endif + ctx.tp = xalloc_limbs (itch); + + mpn_random (ctx.ap, 3*ecc->p.size); + mpn_random (ctx.bp, 3*ecc->p.size); + + mask = (~(mp_limb_t) 0) >> (ecc->p.size * GMP_NUMB_BITS - ecc->p.bit_size); + ctx.ap[ecc->p.size - 1] &= mask; + ctx.ap[2*ecc->p.size - 1] &= mask; + ctx.ap[3*ecc->p.size - 1] &= mask; + ctx.bp[ecc->p.size - 1] &= mask; + ctx.bp[2*ecc->p.size - 1] &= mask; + ctx.bp[3*ecc->p.size - 1] &= mask; + + modp = time_function (bench_modp, &ctx); + reduce = time_function (bench_reduce, &ctx); + + modq = time_function (bench_modq, &ctx); + + modinv = time_function (bench_modinv, &ctx); +#if !NETTLE_USE_MINI_GMP + modinv_gcd = time_function (bench_modinv_gcd, &ctx); +#else + modinv_gcd = 0; +#endif +#ifdef mpn_sec_powm + modinv_powm = time_function (bench_modinv_powm, &ctx); +#else + modinv_powm = 0; +#endif + if (ecc->p.bit_size == 255) + { + /* For now, curve25519 is a special case */ + dup_jj = time_function (bench_dup_eh, &ctx); + add_jja = time_function (bench_add_eh, &ctx); + } + else + { + dup_jj = time_function (bench_dup_jj, &ctx); + add_jja = time_function (bench_add_jja, &ctx); + } + add_hhh = time_function (bench_add_hhh, &ctx); + mul_g = time_function (bench_mul_g, &ctx); + mul_a = time_function (bench_mul_a, &ctx); + + free (ctx.rp); + free (ctx.ap); + free (ctx.bp); + free (ctx.tp); + + printf ("%4d %6.4f %6.4f %6.4f %6.2f %6.3f %6.2f %6.3f %6.3f %6.3f %6.1f %6.1f\n", + ecc->p.bit_size, 1e6 * modp, 1e6 * reduce, 1e6 * modq, + 1e6 * modinv, 1e6 * modinv_gcd, 1e6 * modinv_powm, + 1e6 * dup_jj, 1e6 * add_jja, 1e6 * add_hhh, + 1e6 * mul_g, 1e6 * mul_a); +} + +const struct ecc_curve * const curves[] = { + &nettle_secp_192r1, + &nettle_secp_224r1, + &_nettle_curve25519, + &nettle_secp_256r1, + &nettle_secp_384r1, + &nettle_secp_521r1, +}; + +#define numberof(x) (sizeof (x) / sizeof ((x)[0])) + +int +main (int argc UNUSED, char **argv UNUSED) +{ + unsigned i; + + time_init(); + printf ("%4s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s (us)\n", + "size", "modp", "reduce", "modq", "modinv", "mi_gcd", "mi_pow", + "dup_jj", "ad_jja", "ad_hhh", + "mul_g", "mul_a"); + for (i = 0; i < numberof (curves); i++) + bench_curve (curves[i]); + + return EXIT_SUCCESS; +} diff --git a/examples/eratosthenes.c b/examples/eratosthenes.c new file mode 100644 index 0000000..7a54561 --- /dev/null +++ b/examples/eratosthenes.c @@ -0,0 +1,414 @@ +/* eratosthenes.c + + An implementation of the sieve of Eratosthenes, to generate a list of primes. + + Copyright (C) 2007 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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(*vector)); + + 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] = ~0UL; +} + +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) +{ + static const unsigned char 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, + }; + + unsigned i = 0; + + /* Isolate least significant bit */ + x &= -x; + +#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; + + enum { OPT_HELP = 300 }; + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, OPT_HELP }, + { "verbose", no_argument, NULL, 'v' }, + { "block-size", required_argument, NULL, 'b' }, + { "quiet", required_argument, NULL, 'q' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "svb:", options, NULL)) != -1) + switch (c) + { + case OPT_HELP: + usage(); + return EXIT_SUCCESS; + case 'b': + block_nbits = CHAR_BIT * atosize(optarg); + if (!block_nbits) + { + usage(); + return EXIT_FAILURE; + } + break; + + case 'q': + silent = 1; + break; + + case 'v': + verbose++; + break; + + case '?': + return EXIT_FAILURE; + + 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); + } + } + + free(sieve); + free(block); + + return EXIT_SUCCESS; +} diff --git a/examples/hogweed-benchmark.c b/examples/hogweed-benchmark.c new file mode 100644 index 0000000..ebce903 --- /dev/null +++ b/examples/hogweed-benchmark.c @@ -0,0 +1,744 @@ +/* hogweed-benchmark.c + + Copyright (C) 2013, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include + +#include "timing.h" + +#include "dsa.h" +#include "rsa.h" +#include "curve25519.h" + +#include "nettle-meta.h" +#include "sexp.h" +#include "knuth-lfib.h" + +#include "../ecdsa.h" +#include "../ecc-internal.h" +#include "../gmp-glue.h" + +#if WITH_OPENSSL +#include +#include +#include +#include +#endif + +#define BENCH_INTERVAL 0.1 + +static void NORETURN PRINTF_STYLE(1,2) +die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(EXIT_FAILURE); +} + +static void * +xalloc (size_t size) +{ + void *p = malloc (size); + if (!p) + { + fprintf (stderr, "Virtual memory exhausted\n"); + abort (); + } + return p; +} + +static uint8_t * +hash_string (const struct nettle_hash *hash, const char *s) +{ + void *ctx = xalloc (hash->context_size); + uint8_t *digest = xalloc (hash->digest_size); + hash->init (ctx); + hash->update (ctx, strlen(s), (const uint8_t *) s); + hash->digest (ctx, hash->digest_size, digest); + free (ctx); + + return digest; +} + +struct alg { + const char *name; + unsigned size; + void *(*init) (unsigned size); + void (*sign) (void *); + void (*verify)(void *); + void (*clear) (void *); +}; + +/* Returns second per function call */ +static double +time_function(void (*f)(void *arg), void *arg) +{ + unsigned ncalls; + double elapsed; + + /* Warm up */ + f(arg); + for (ncalls = 10 ;;) + { + unsigned i; + + time_start(); + for (i = 0; i < ncalls; i++) + f(arg); + elapsed = time_end(); + if (elapsed > BENCH_INTERVAL) + break; + else if (elapsed < BENCH_INTERVAL / 10) + ncalls *= 10; + else + ncalls *= 2; + } + return elapsed / ncalls; +} + +static void +bench_alg (const struct alg *alg) +{ + double sign; + double verify; + void *ctx; + + ctx = alg->init(alg->size); + if (ctx == NULL) + { + printf("%15s %4d N/A\n", alg->name, alg->size); + return; + } + + sign = time_function (alg->sign, ctx); + verify = time_function (alg->verify, ctx); + + alg->clear (ctx); + + printf("%15s %4d %9.4f %9.4f\n", + alg->name, alg->size, 1e-3/sign, 1e-3/verify); +} + +struct rsa_ctx +{ + struct rsa_public_key pub; + struct rsa_private_key key; + uint8_t *digest; + mpz_t s; +}; + +static void * +bench_rsa_init (unsigned size) +{ + unsigned char rsa1024[] = + "{KDExOnByaXZhdGUta2V5KDE0OnJzYS1wa2NzMS1zaGExKDE6bjEyOToA90+K5EmjbFJBeJD" + " xP2KD2Df+0Twc9425uB+vhqTrVijtd2PnwEQDfR2VoducgkKcXJzYYyCNILQJbFAi2Km/sD" + " jImERBqDtaI217Ze+tOKEmImexYTAgFuqEptp2F3M4DqgRQ7s/3nJQ/bPE5Hfi1OZhJSShu" + " I80ATTU4fUgrPspKDE6ZTM6AQABKSgxOmQxMjk6APAhKckzvxxkWfHJOpXDACWnaSKcbbvo" + " vtWK3pGr/F2ya7CrLtE+uOx5F1sLs9G+/7flCy5k4uNILIYg4VTirZ1zQ8fNKPrjK1VMRls" + " JiRRU/0VAs9d7HdncJfs6rbvRQbCRSRYURo4hWir3Lq8V3UUQVBprc4dO+uWmplvwQ5qxKS" + " gxOnA2NToA+8aIVkdbk8Jg8dJOuzc7m/hZnwkKSs6eVDw4N/2T0CJKGJYT+B3Ct+fPkxhUR" + " ggd2DQ9OpkTra7SXHTNkzdPVSkoMTpxNjU6APt11P8vXNnGYF0OC/cPsR8zhSYuFmtRuX6G" + " ES+DdG0VCU07UeNQkok1UoW5sXqY0IGr1jkJq8AMSgKoNbLQ6w8pKDE6YTY0Ohzkxsan/8F" + " wQDHgQbrIduXKVXaj0fONzKu8EXOTfUAYf0pdBsOlnq/+QVsPIrS6v7oNHK253YFEG84SdX" + " kcktUpKDE6YjY1OgCR+cRtY3RWY+f6/TWK9gwPndv03xpasLWrMm71ky1aSbT9pasS9+opR" + " tAiGzthfSbFsBiLQgb3VOr+AeIybT+XKSgxOmM2NDojigqARWN5u1CVDVuD2L2ManpoGiM6" + " kQ6FaJjqRjxeRRKFrQxGJa9tM1hqStxokC1oJidgaOLGnn60iwzToug9KSkp}"; + + unsigned char rsa2048[] = + "{KDExOnByaXZhdGUta2V5KDE0OnJzYS1wa2NzMS1zaGExKDE6bjI1NzoAtxWXiglIdunDK48" + " 8I0vW0wTqnh/riW9pLk8n1F8MUPBFdhvkkl0bDQqSJPUvSHy+w4fLVwcEzeI4qFyo3b2Avz" + " JK20MFbt/WfHD1TbxuK8rNqXyqmqjJ9vgjtV9nPzAz7CM9ogs3/RJHpcfZPQF15ifizleUZ" + " aQT0GAXHZL7cePj10yGI2u3hgTkokVzdNC/1T34guKYpErg0pt0B/KejWpsFTb84z3tkR+B" + " YVx07p/OoByZwoABgncS/uALl31fRS8jyJ2JqUiZOqe7XoO9hkDHYNCWUGUfNGQ7ZgVp9+e" + " NQpracSjrp6Jnrj7r/oxJUx5ZDVNi18AzQadE/oKOrSkoMTplMzoBAAEpKDE6ZDI1NjogBT" + " C5vaHk2kF+LtDvw2XRBj0aZq7FHK0ioklvBSicR0l+vKYfSxVeFIk22YLphJfAjtFraRjYA" + " Uaze3E1Rt1rkxoweupKV++lWAQvElOaaR/LErirz/Vysjdck1D1ZjLOi+NNofSq2DWbsvY1" + " iznZhQRP3lVf6XBls0iXrYs4gb0pBZqXLQW+j9Ihx6eantf1/6ZMKPgCkzcAZ0ABsCfaFSg" + " ouNCzilblsgFEspEbb8QqrNQoStS3F/gMwWgDsr3+vQzBqt+7ykWoCJ9wctbYy9kEPq+hX3" + " GP0hG6HdS81r9E8pgdf3wloNNMzYUHwn7poXGpOi8tG0pmR56TqD/BKSgxOnAxMjk6AN4AJ" + " TiGPm9We2ga3Y0jpTfA3mWpUbhYgaXYLWA1/riniwq16fqxRIkWQT/O2KKpBVe6WSvNYq9u" + " lM8N6bdPtDytJs6AOXy0X5vtJ953ZYVMhHbhmUxhIL9I+s0O1+LxMF8b9U4CrFyaTxd8Un/" + " FXP1BvYJRrkoup6HYvOlGx36lKSgxOnExMjk6ANMfrfH6z/3o7K56aW6kSiloDDbKZQ0+W5" + " 8LzP2ZOBLf6LX6jLhN3olU1Z0KGTM0S/1AxvwGjuRqhu+LcOJ7oUCUH3uusR5c5nSnArYPq" + " +0wbco4BQngot/HmGN7U0EDsIWqPt/qoa/b8bCk+TOwJlknNq/PnZU26SPj48XS05lpKSgx" + " OmExMjk6AJM2n3gLNW3ZeH5BindkktQU9qWNkV5geqDCaNyrEZ3bpI1WsrEGSj9p3Zz1ipz" + " a3msdbLJqQS26c72WKUzg8tFltR0s1HJInjolGtIgdNbfNdwrn9+RbQjL2VyPokOg0wXO4W" + " 14wlmqDhax33dRJmfe50964MvaglkGA8fhorrtKSgxOmIxMjk6AKMe+vrX2xRHf3dfxU5jS" + " ZmsdqNuxZzx7UB5kazvUU/kCJ1yNH/CSoq5LULkpovVgFDwV84qEwWQ+SjkCBg1hWWsDJc3" + " ZkobZUQENigM+72LiYiQt/PlyHI2eRuEEdNN0nm0DFhdpQeHXLoq/RBerYJ8tdgpBYxgnMn" + " KLhaOykbhKSgxOmMxMjg6MVlKj2bjb7qFQVkLO1OPg28jSrtRpnQCR+qegN4ZmNam/qbest" + " 8yn0JQ6gxX7PvP382+jx7uHHWHYYqPq/Flf8gqtOOcjqS5TJgVHz3F3xHWquo1ZofGtCMro" + " Dd2c0xjRjIVGvLV6Ngs+HRdljRav40vRpTyEoEdlzHBQiILesopKSk=}"; + + struct rsa_ctx *ctx; + struct sexp_iterator i; + + int res; + + ctx = xalloc(sizeof(*ctx)); + + rsa_public_key_init (&ctx->pub); + rsa_private_key_init (&ctx->key); + mpz_init (ctx->s); + + /* NOTE: Base64-decodes the strings in-place */ + if (size == 1024) + res = sexp_transport_iterator_first (&i, sizeof(rsa1024) - 1, rsa1024); + else if (size == 2048) + res = sexp_transport_iterator_first (&i, sizeof(rsa2048) - 1, rsa2048); + else + die ("Internal error.\n"); + + if (! (res + && sexp_iterator_check_type (&i, "private-key") + && sexp_iterator_check_type (&i, "rsa-pkcs1-sha1") + && rsa_keypair_from_sexp_alist (&ctx->pub, &ctx->key, 0, &i))) + die ("Internal error.\n"); + + ctx->digest = hash_string (&nettle_sha256, "foo"); + + rsa_sha256_sign_digest (&ctx->key, ctx->digest, ctx->s); + + return ctx; +} + +static void +bench_rsa_sign (void *p) +{ + struct rsa_ctx *ctx = p; + + mpz_t s; + mpz_init (s); + rsa_sha256_sign_digest (&ctx->key, ctx->digest, s); + mpz_clear (s); +} + +static void +bench_rsa_verify (void *p) +{ + struct rsa_ctx *ctx = p; + if (! rsa_sha256_verify_digest (&ctx->pub, ctx->digest, ctx->s)) + die ("Internal error, rsa_sha256_verify_digest failed.\n"); +} + +static void +bench_rsa_clear (void *p) +{ + struct rsa_ctx *ctx = p; + + rsa_public_key_clear (&ctx->pub); + rsa_private_key_clear (&ctx->key); + mpz_clear (ctx->s); + + free (ctx->digest); + free (ctx); +} + +struct dsa_ctx +{ + struct dsa_params params; + mpz_t pub; + mpz_t key; + struct knuth_lfib_ctx lfib; + struct dsa_signature s; + uint8_t *digest; +}; + +static void * +bench_dsa_init (unsigned size) +{ + struct dsa_ctx *ctx; + struct sexp_iterator i; + + unsigned char dsa1024[] = + "{KDExOnByaXZhdGUta2V5KDM6ZHNhKDE6cDEyOToA2q4hOXEClLMXXMOl9xaPcGC/GeGmCMv" + " VCaaW0uWc50DvvmJDPQPdCehyfZr/1dv2UDbx06TC7ls/IFd+BsDzGBRxqIQ44J20cn+0gt" + " NMIXAocE1QhCCFaT5gXrk8zMlqBEGaP3RdpgxNanEXkTj2Wma8r1GtrLX3HPafio62jicpK" + " DE6cTIxOgDN9pcW3exdVAesC9WsxwCGoJK24ykoMTpnMTI5OgCJr9DmKdiE0WJZB7HACESv" + " Tpg1qZgc8E15byQ+OsHUyOTRrJRTcrgKZJW7dFRJ9cXmyi7XYCd3bJtu/2HRHLY1vd4qMvU" + " 7Y8x08ooCoABGV7nGqcmdQfEho1OY6TZh2NikmPKZLeur3PZFpcZ8Dl+KVWtwC55plNC7Om" + " iAQy8MaCkoMTp5MTI5OgDakk0LOUQwzOKt9FHOBmBKrWsvTm7549eScTUqH4OMm3btjUsXz" + " MmlqEe+imwQCOW/AE3Xw9pXZeETWK0jlLe8k5vnKcNskerFwZ1eQKtOPPQty8IqQ9PEfF6B" + " 0oVQiJg2maHUDWFnDkIBd7ZR1z8FnZMUxH9mH4kEUo6YQgtCdykoMTp4MjA6cOl3ijiiMjI" + " pesFD8jxESWb2mn8pKSk=}"; + + ctx = xalloc(sizeof(*ctx)); + + dsa_params_init (&ctx->params); + mpz_init (ctx->pub); + mpz_init (ctx->key); + dsa_signature_init (&ctx->s); + knuth_lfib_init (&ctx->lfib, 1); + + if (size != 1024) + die ("Internal error.\n"); + + if (! (sexp_transport_iterator_first (&i, sizeof(dsa1024) - 1, dsa1024) + && sexp_iterator_check_type (&i, "private-key") + && sexp_iterator_check_type (&i, "dsa") + && dsa_keypair_from_sexp_alist (&ctx->params, ctx->pub, ctx->key, + 0, DSA_SHA1_Q_BITS, &i)) ) + die ("Internal error.\n"); + + ctx->digest = hash_string (&nettle_sha1, "foo"); + + dsa_sign (&ctx->params, ctx->key, + &ctx->lfib, (nettle_random_func *)knuth_lfib_random, + SHA1_DIGEST_SIZE, ctx->digest, &ctx->s); + + return ctx; +} + +static void +bench_dsa_sign (void *p) +{ + struct dsa_ctx *ctx = p; + struct dsa_signature s; + + dsa_signature_init (&s); + dsa_sign (&ctx->params, ctx->key, + &ctx->lfib, (nettle_random_func *)knuth_lfib_random, + SHA1_DIGEST_SIZE, ctx->digest, &s); + dsa_signature_clear (&s); +} + +static void +bench_dsa_verify (void *p) +{ + struct dsa_ctx *ctx = p; + if (! dsa_verify (&ctx->params, ctx->pub, SHA1_DIGEST_SIZE, ctx->digest, &ctx->s)) + die ("Internal error, dsa_sha1_verify_digest failed.\n"); +} + +static void +bench_dsa_clear (void *p) +{ + struct dsa_ctx *ctx = p; + dsa_params_clear (&ctx->params); + mpz_clear (ctx->pub); + mpz_clear (ctx->key); + dsa_signature_clear (&ctx->s); + free (ctx->digest); + free (ctx); +} + +struct ecdsa_ctx +{ + struct ecc_point pub; + struct ecc_scalar key; + struct knuth_lfib_ctx rctx; + unsigned digest_size; + uint8_t *digest; + struct dsa_signature s; +}; + +static void * +bench_ecdsa_init (unsigned size) +{ + struct ecdsa_ctx *ctx; + const struct ecc_curve *ecc; + + const char *xs; + const char *ys; + const char *zs; + mpz_t x, y, z; + + ctx = xalloc (sizeof(*ctx)); + + dsa_signature_init (&ctx->s); + knuth_lfib_init (&ctx->rctx, 17); + + switch (size) + { + case 192: + ecc = &nettle_secp_192r1; + xs = "8e8e07360350fb6b7ad8370cfd32fa8c6bba785e6e200599"; + ys = "7f82ddb58a43d59ff8dc66053002b918b99bd01bd68d6736"; + zs = "f2e620e086d658b4b507996988480917640e4dc107808bdd"; + ctx->digest = hash_string (&nettle_sha1, "abc"); + ctx->digest_size = 20; + break; + case 224: + ecc = &nettle_secp_224r1; + xs = "993bf363f4f2bc0f255f22563980449164e9c894d9efd088d7b77334"; + ys = "b75fff9849997d02d135140e4d0030944589586e22df1fc4b629082a"; + zs = "cdfd01838247f5de3cc70b688418046f10a2bfaca6de9ec836d48c27"; + ctx->digest = hash_string (&nettle_sha224, "abc"); + ctx->digest_size = 28; + break; + + /* From RFC 4754 */ + case 256: + ecc = &nettle_secp_256r1; + xs = "2442A5CC 0ECD015F A3CA31DC 8E2BBC70 BF42D60C BCA20085 E0822CB0 4235E970"; + ys = "6FC98BD7 E50211A4 A27102FA 3549DF79 EBCB4BF2 46B80945 CDDFE7D5 09BBFD7D"; + zs = "DC51D386 6A15BACD E33D96F9 92FCA99D A7E6EF09 34E70975 59C27F16 14C88A7F"; + ctx->digest = hash_string (&nettle_sha256, "abc"); + ctx->digest_size = 32; + break; + case 384: + ecc = &nettle_secp_384r1; + xs = "96281BF8 DD5E0525 CA049C04 8D345D30 82968D10 FEDF5C5A CA0C64E6 465A97EA" + "5CE10C9D FEC21797 41571072 1F437922"; + ys = "447688BA 94708EB6 E2E4D59F 6AB6D7ED FF9301D2 49FE49C3 3096655F 5D502FAD" + "3D383B91 C5E7EDAA 2B714CC9 9D5743CA"; + zs = "0BEB6466 34BA8773 5D77AE48 09A0EBEA 865535DE 4C1E1DCB 692E8470 8E81A5AF" + "62E528C3 8B2A81B3 5309668D 73524D9F"; + ctx->digest = hash_string (&nettle_sha384, "abc"); + ctx->digest_size = 48; + break; + case 521: + ecc = &nettle_secp_521r1; + xs = "0151518F 1AF0F563 517EDD54 85190DF9 5A4BF57B 5CBA4CF2 A9A3F647 4725A35F" + "7AFE0A6D DEB8BEDB CD6A197E 592D4018 8901CECD 650699C9 B5E456AE A5ADD190" + "52A8"; + ys = "006F3B14 2EA1BFFF 7E2837AD 44C9E4FF 6D2D34C7 3184BBAD 90026DD5 E6E85317" + "D9DF45CA D7803C6C 20035B2F 3FF63AFF 4E1BA64D 1C077577 DA3F4286 C58F0AEA" + "E643"; + zs = "0065FDA3 409451DC AB0A0EAD 45495112 A3D813C1 7BFD34BD F8C1209D 7DF58491" + "20597779 060A7FF9 D704ADF7 8B570FFA D6F062E9 5C7E0C5D 5481C5B1 53B48B37" + "5FA1"; + + ctx->digest = hash_string (&nettle_sha512, "abc"); + ctx->digest_size = 64; + break; + default: + die ("Internal error.\n"); + } + ecc_point_init (&ctx->pub, ecc); + ecc_scalar_init (&ctx->key, ecc); + + mpz_init_set_str (x, xs, 16); + mpz_init_set_str (y, ys, 16); + mpz_init_set_str (z, zs, 16); + + ecc_point_set (&ctx->pub, x, y); + ecc_scalar_set (&ctx->key, z); + + mpz_clear (x); + mpz_clear (y); + mpz_clear (z); + + ecdsa_sign (&ctx->key, + &ctx->rctx, (nettle_random_func *) knuth_lfib_random, + ctx->digest_size, ctx->digest, + &ctx->s); + + return ctx; +} + +static void +bench_ecdsa_sign (void *p) +{ + struct ecdsa_ctx *ctx = p; + struct dsa_signature s; + + dsa_signature_init (&s); + ecdsa_sign (&ctx->key, + &ctx->rctx, (nettle_random_func *) knuth_lfib_random, + ctx->digest_size, ctx->digest, + &s); + dsa_signature_clear (&s); +} + +static void +bench_ecdsa_verify (void *p) +{ + struct ecdsa_ctx *ctx = p; + if (! ecdsa_verify (&ctx->pub, + ctx->digest_size, ctx->digest, + &ctx->s)) + die ("Internal error, _ecdsa_verify failed.\n"); +} + +static void +bench_ecdsa_clear (void *p) +{ + struct ecdsa_ctx *ctx = p; + + ecc_point_clear (&ctx->pub); + ecc_scalar_clear (&ctx->key); + dsa_signature_clear (&ctx->s); + free (ctx->digest); + + free (ctx); +} + +#if WITH_OPENSSL +struct openssl_rsa_ctx +{ + RSA *key; + unsigned char *ref; + unsigned char *signature; + unsigned int siglen; + uint8_t *digest; +}; + +static void * +bench_openssl_rsa_init (unsigned size) +{ + struct openssl_rsa_ctx *ctx = xalloc (sizeof (*ctx)); + + ctx->key = RSA_generate_key (size, 65537, NULL, NULL); + ctx->ref = xalloc (RSA_size (ctx->key)); + ctx->signature = xalloc (RSA_size (ctx->key)); + ctx->digest = hash_string (&nettle_sha1, "foo"); + RSA_blinding_off(ctx->key); + + if (! RSA_sign (NID_sha1, ctx->digest, SHA1_DIGEST_SIZE, + ctx->ref, &ctx->siglen, ctx->key)) + die ("OpenSSL RSA_sign failed.\n"); + + return ctx; +} + +static void +bench_openssl_rsa_sign (void *p) +{ + const struct openssl_rsa_ctx *ctx = p; + unsigned siglen; + + if (! RSA_sign (NID_sha1, ctx->digest, SHA1_DIGEST_SIZE, + ctx->signature, &siglen, ctx->key)) + die ("OpenSSL RSA_sign failed.\n"); +} + +static void +bench_openssl_rsa_verify (void *p) +{ + const struct openssl_rsa_ctx *ctx = p; + if (! RSA_verify (NID_sha1, ctx->digest, SHA1_DIGEST_SIZE, + ctx->ref, ctx->siglen, ctx->key)) + die ("OpenSSL RSA_verify failed.\n"); +} + +static void +bench_openssl_rsa_clear (void *p) +{ + struct openssl_rsa_ctx *ctx = p; + RSA_free (ctx->key); + free (ctx->ref); + free (ctx->signature); + free (ctx->digest); + free (ctx); +} + +struct openssl_ecdsa_ctx +{ + EC_KEY *key; + ECDSA_SIG *signature; + unsigned digest_length; + uint8_t *digest; +}; + +static void * +bench_openssl_ecdsa_init (unsigned size) +{ + struct openssl_ecdsa_ctx *ctx = xalloc (sizeof (*ctx)); + + switch (size) + { + case 192: + ctx->key = EC_KEY_new_by_curve_name (NID_X9_62_prime192v1); + ctx->digest_length = 24; /* truncated */ + ctx->digest = hash_string (&nettle_sha224, "abc"); + break; + case 224: + ctx->key = EC_KEY_new_by_curve_name (NID_secp224r1); + ctx->digest_length = SHA224_DIGEST_SIZE; + ctx->digest = hash_string (&nettle_sha224, "abc"); + break; + case 256: + ctx->key = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); + ctx->digest_length = SHA256_DIGEST_SIZE; + ctx->digest = hash_string (&nettle_sha256, "abc"); + break; + case 384: + ctx->key = EC_KEY_new_by_curve_name (NID_secp384r1); + ctx->digest_length = SHA384_DIGEST_SIZE; + ctx->digest = hash_string (&nettle_sha384, "abc"); + break; + case 521: + ctx->key = EC_KEY_new_by_curve_name (NID_secp521r1); + ctx->digest_length = SHA512_DIGEST_SIZE; + ctx->digest = hash_string (&nettle_sha512, "abc"); + break; + default: + die ("Internal error.\n"); + } + + /* This curve isn't supported in this build of openssl */ + if (ctx->key == NULL) + { + free(ctx); + return NULL; + } + + if (!EC_KEY_generate_key( ctx->key)) + die ("Openssl EC_KEY_generate_key failed.\n"); + + ctx->signature = ECDSA_do_sign (ctx->digest, ctx->digest_length, ctx->key); + + return ctx; +} + +static void +bench_openssl_ecdsa_sign (void *p) +{ + const struct openssl_ecdsa_ctx *ctx = p; + ECDSA_SIG *sig = ECDSA_do_sign (ctx->digest, ctx->digest_length, ctx->key); + ECDSA_SIG_free (sig); +} + +static void +bench_openssl_ecdsa_verify (void *p) +{ + const struct openssl_ecdsa_ctx *ctx = p; + if (ECDSA_do_verify (ctx->digest, ctx->digest_length, + ctx->signature, ctx->key) != 1) + die ("Openssl ECDSA_do_verify failed.\n"); +} +static void +bench_openssl_ecdsa_clear (void *p) +{ + struct openssl_ecdsa_ctx *ctx = p; + ECDSA_SIG_free (ctx->signature); + EC_KEY_free (ctx->key); + free (ctx->digest); + free (ctx); +} +#endif + +struct curve25519_ctx +{ + uint8_t x[CURVE25519_SIZE]; + uint8_t s[CURVE25519_SIZE]; +}; + +static void +bench_curve25519_mul_g (void *p) +{ + struct curve25519_ctx *ctx = p; + uint8_t q[CURVE25519_SIZE]; + curve25519_mul_g (q, ctx->s); +} + +static void +bench_curve25519_mul (void *p) +{ + struct curve25519_ctx *ctx = p; + uint8_t q[CURVE25519_SIZE]; + curve25519_mul (q, ctx->s, ctx->x); +} + +static void +bench_curve25519 (void) +{ + double mul_g; + double mul; + struct knuth_lfib_ctx lfib; + struct curve25519_ctx ctx; + knuth_lfib_init (&lfib, 2); + + knuth_lfib_random (&lfib, sizeof(ctx.s), ctx.s); + curve25519_mul_g (ctx.x, ctx.s); + + mul_g = time_function (bench_curve25519_mul_g, &ctx); + mul = time_function (bench_curve25519_mul, &ctx); + + printf("%15s %4d %9.4f %9.4f\n", + "curve25519", 255, 1e-3/mul_g, 1e-3/mul); +} + +struct alg alg_list[] = { + { "rsa", 1024, bench_rsa_init, bench_rsa_sign, bench_rsa_verify, bench_rsa_clear }, + { "rsa", 2048, bench_rsa_init, bench_rsa_sign, bench_rsa_verify, bench_rsa_clear }, +#if WITH_OPENSSL + { "rsa (openssl)", 1024, bench_openssl_rsa_init, bench_openssl_rsa_sign, bench_openssl_rsa_verify, bench_openssl_rsa_clear }, + { "rsa (openssl)", 2048, bench_openssl_rsa_init, bench_openssl_rsa_sign, bench_openssl_rsa_verify, bench_openssl_rsa_clear }, +#endif + { "dsa", 1024, bench_dsa_init, bench_dsa_sign, bench_dsa_verify, bench_dsa_clear }, +#if 0 + { "dsa",2048, bench_dsa_init, bench_dsa_sign, bench_dsa_verify, bench_dsa_clear }, +#endif + { "ecdsa", 192, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear }, + { "ecdsa", 224, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear }, + { "ecdsa", 256, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear }, + { "ecdsa", 384, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear }, + { "ecdsa", 521, bench_ecdsa_init, bench_ecdsa_sign, bench_ecdsa_verify, bench_ecdsa_clear }, +#if WITH_OPENSSL + { "ecdsa (openssl)", 192, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear }, + { "ecdsa (openssl)", 224, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear }, + { "ecdsa (openssl)", 256, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear }, + { "ecdsa (openssl)", 384, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear }, + { "ecdsa (openssl)", 521, bench_openssl_ecdsa_init, bench_openssl_ecdsa_sign, bench_openssl_ecdsa_verify, bench_openssl_ecdsa_clear }, +#endif +}; + +#define numberof(x) (sizeof (x) / sizeof ((x)[0])) + +int +main (int argc, char **argv) +{ + const char *filter = NULL; + unsigned i; + + if (argc > 1) + filter = argv[1]; + + time_init(); + printf ("%15s %4s %9s %9s\n", + "name", "size", "sign/ms", "verify/ms"); + + for (i = 0; i < numberof(alg_list); i++) + if (!filter || strstr (alg_list[i].name, filter)) + bench_alg (&alg_list[i]); + + if (!filter || strstr("curve25519", filter)) + bench_curve25519(); + + return EXIT_SUCCESS; +} diff --git a/examples/io.c b/examples/io.c new file mode 100644 index 0000000..50865f5 --- /dev/null +++ b/examples/io.c @@ -0,0 +1,201 @@ +/* io.c + + Miscellaneous functions used by the example programs. + + Copyright (C) 2002, 2012 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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); + } +} + +size_t +read_file(const char *name, size_t max_size, uint8_t **contents) +{ + size_t size, done; + uint8_t *buffer; + FILE *f; + + f = fopen(name, "rb"); + if (!f) + { + werror("Opening `%s' failed: %s\n", name, strerror(errno)); + return 0; + } + + size = 100; + + for (buffer = NULL, done = 0;; size *= 2) + { + uint8_t *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 (done < size) + { + /* Short count means EOF or read error */ + if (ferror(f)) + { + fprintf (stderr, "Reading `%s' failed: %s\n", + name, strerror(errno)); + + goto fail; + } + if (done == 0) + /* Treat empty file as error */ + goto fail; + + break; + } + + if (size == max_size) + break; + } + + fclose(f); + + /* NUL-terminate the data. */ + buffer[done] = '\0'; + *contents = buffer; + + return done; +} + +int +write_data(FILE *f, size_t size, const void *buffer) +{ + size_t res = fwrite(buffer, 1, size, f); + + return res == size; +} + +int +write_file(const char *name, size_t size, const void *buffer) +{ + FILE *f = fopen(name, "wb"); + int res; + + if (!f) + return 0; + + res = write_data(f, size, buffer); + return fclose(f) == 0 && res; +} + +int +simple_random(struct yarrow256_ctx *ctx, const char *name) +{ + unsigned length; + uint8_t *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 (;;) + { + uint8_t 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..426cb30 --- /dev/null +++ b/examples/io.h @@ -0,0 +1,80 @@ +/* io.c + + Miscellaneous functions used by the example programs. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, ...) PRINTF_STYLE(1, 2); + +/* If size is > 0, read at most that many bytes. If size == 0, read + * until EOF. Allocates the buffer dynamically. An empty file is + * treated as an error; return value is zero, and no space is + * allocated. The returned data is NUL-terminated, for convenience. */ + +size_t +read_file(const char *name, size_t size, uint8_t **buffer); + +int +write_file(const char *name, size_t size, const void *data); + +int +write_data(FILE *f, size_t size, const void *data); + +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..18f91c1 --- /dev/null +++ b/examples/nettle-benchmark.c @@ -0,0 +1,841 @@ +/* nettle-benchmark.c + + Tests the performance of the various algorithms. + + Copyright (C) 2001, 2010, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "timing.h" + +#include "aes.h" +#include "arcfour.h" +#include "blowfish.h" +#include "cast128.h" +#include "cbc.h" +#include "ctr.h" +#include "des.h" +#include "eax.h" +#include "gcm.h" +#include "memxor.h" +#include "salsa20.h" +#include "serpent.h" +#include "sha1.h" +#include "sha2.h" +#include "sha3.h" +#include "twofish.h" +#include "umac.h" +#include "poly1305.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 seconds. */ +#define BENCH_BLOCK 10240 +#define BENCH_INTERVAL 0.1 + +/* FIXME: Proper configure test for rdtsc? */ +#ifndef WITH_CYCLE_COUNTER +# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +# define WITH_CYCLE_COUNTER 1 +# else +# define WITH_CYCLE_COUNTER 0 +# endif +#endif + +#if WITH_CYCLE_COUNTER +# if defined(__i386__) +#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") +# elif defined(__x86_64__) +#define GET_CYCLE_COUNTER(hi, lo) \ + __asm__("xorl %%eax,%%eax\n" \ + "mov %%rbx, %%r10\n" \ + "cpuid\n" \ + "rdtsc\n" \ + "mov %%r10, %%rbx\n" \ + : "=a" (lo), "=d" (hi) \ + : /* No inputs. */ \ + : "%r10", "%rcx", "cc") +# endif +#define BENCH_ITERATIONS 10 +#endif + +static void NORETURN PRINTF_STYLE(1,2) +die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(EXIT_FAILURE); +} + +static double overhead = 0.0; + +/* Returns second per function call */ +static double +time_function(void (*f)(void *arg), void *arg) +{ + unsigned ncalls; + double elapsed; + + for (ncalls = 10 ;;) + { + unsigned i; + + time_start(); + for (i = 0; i < ncalls; i++) + f(arg); + elapsed = time_end(); + if (elapsed > BENCH_INTERVAL) + break; + else if (elapsed < BENCH_INTERVAL / 10) + ncalls *= 10; + else + ncalls *= 2; + } + return elapsed / ncalls - overhead; +} + +static void +bench_nothing(void *arg UNUSED) +{ + return; +} + +struct bench_memxor_info +{ + void *dst; + const void *src; + const void *other; +}; + +static void +bench_memxor(void *arg) +{ + struct bench_memxor_info *info = arg; + memxor (info->dst, info->src, BENCH_BLOCK); +} + +static void +bench_memxor3(void *arg) +{ + struct bench_memxor_info *info = arg; + memxor3 (info->dst, info->src, info->other, BENCH_BLOCK); +} + +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_cipher_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_cipher_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); +} + +static void +bench_ctr(void *arg) +{ + struct bench_cbc_info *info = arg; + ctr_crypt(info->ctx, info->crypt, + info->block_size, info->iv, + BENCH_BLOCK, info->data, info->data); +} + +struct bench_aead_info +{ + void *ctx; + nettle_crypt_func *crypt; + nettle_hash_update_func *update; + uint8_t *data; +}; + +static void +bench_aead_crypt(void *arg) +{ + const struct bench_aead_info *info = arg; + info->crypt (info->ctx, BENCH_BLOCK, info->data, info->data); +} + +static void +bench_aead_update(void *arg) +{ + const struct bench_aead_info *info = arg; + info->update (info->ctx, BENCH_BLOCK, 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) + die("Virtual memory exhausted.\n"); + + return p; +} + +static void +time_overhead(void) +{ + overhead = time_function(bench_nothing, NULL); + printf("benchmark call overhead: %7f us", overhead * 1e6); + if (frequency > 0.0) + printf("%7.2f cycles\n", overhead * frequency); + printf("\n"); +} + + + +static void +time_memxor(void) +{ + struct bench_memxor_info info; + unsigned long src[BENCH_BLOCK / sizeof(long) + 2]; + unsigned long other[BENCH_BLOCK / sizeof(long) + 2]; + unsigned long dst[BENCH_BLOCK / sizeof(long) + 1]; + + info.src = src; + info.dst = dst; + + display ("memxor", "aligned", sizeof(unsigned long), + time_function(bench_memxor, &info)); + info.src = (const char *) src + 1; + display ("memxor", "unaligned", sizeof(unsigned long), + time_function(bench_memxor, &info)); + + info.src = src; + info.other = other; + display ("memxor3", "aligned", sizeof(unsigned long), + time_function(bench_memxor3, &info)); + + info.other = (const char *) other + 1; + display ("memxor3", "unaligned01", sizeof(unsigned long), + time_function(bench_memxor3, &info)); + info.src = (const char *) src + 1; + display ("memxor3", "unaligned11", sizeof(unsigned long), + time_function(bench_memxor3, &info)); + info.other = (const char *) other + 2; + display ("memxor3", "unaligned12", sizeof(unsigned long), + time_function(bench_memxor3, &info)); +} + +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_umac(void) +{ + static uint8_t data[BENCH_BLOCK]; + struct bench_hash_info info; + struct umac32_ctx ctx32; + struct umac64_ctx ctx64; + struct umac96_ctx ctx96; + struct umac128_ctx ctx128; + + uint8_t key[16]; + + umac32_set_key (&ctx32, key); + info.ctx = &ctx32; + info.update = (nettle_hash_update_func *) umac32_update; + info.data = data; + + display("umac32", "update", UMAC_BLOCK_SIZE, + time_function(bench_hash, &info)); + + umac64_set_key (&ctx64, key); + info.ctx = &ctx64; + info.update = (nettle_hash_update_func *) umac64_update; + info.data = data; + + display("umac64", "update", UMAC_BLOCK_SIZE, + time_function(bench_hash, &info)); + + umac96_set_key (&ctx96, key); + info.ctx = &ctx96; + info.update = (nettle_hash_update_func *) umac96_update; + info.data = data; + + display("umac96", "update", UMAC_BLOCK_SIZE, + time_function(bench_hash, &info)); + + umac128_set_key (&ctx128, key); + info.ctx = &ctx128; + info.update = (nettle_hash_update_func *) umac128_update; + info.data = data; + + display("umac128", "update", UMAC_BLOCK_SIZE, + time_function(bench_hash, &info)); +} + +static void +time_poly1305_aes(void) +{ + static uint8_t data[BENCH_BLOCK]; + struct bench_hash_info info; + struct poly1305_aes_ctx ctx; + uint8_t key[32]; + + poly1305_aes_set_key (&ctx, key); + info.ctx = &ctx; + info.update = (nettle_hash_update_func *) poly1305_aes_update; + info.data = data; + + display("poly1305-aes", "update", 1024, + time_function(bench_hash, &info)); +} + +static int +prefix_p(const char *prefix, const char *s) +{ + size_t i; + for (i = 0; prefix[i]; i++) + if (prefix[i] != s[i]) + return 0; + return 1; +} + +static int +block_cipher_p(const struct nettle_cipher *cipher) +{ + /* Don't use nettle cbc and ctr for openssl ciphers. */ + return cipher->block_size > 0 && !prefix_p("openssl", cipher->name); +} + +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, 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, key); + + display(cipher->name, "ECB decrypt", cipher->block_size, + time_function(bench_cipher, &info)); + } + + if (block_cipher_p(cipher)) + { + 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, cipher->block_size); + + cipher->set_encrypt_key(ctx, 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, cipher->block_size); + + cipher->set_decrypt_key(ctx, key); + + display(cipher->name, "CBC decrypt", cipher->block_size, + time_function(bench_cbc_decrypt, &info)); + } + + /* Do CTR 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, cipher->block_size); + + cipher->set_encrypt_key(ctx, key); + + display(cipher->name, "CTR", cipher->block_size, + time_function(bench_ctr, &info)); + } + + free(iv); + } + free(ctx); + free(key); +} + +static void +time_aead(const struct nettle_aead *aead) +{ + void *ctx = xalloc(aead->context_size); + uint8_t *key = xalloc(aead->key_size); + uint8_t *nonce = xalloc(aead->nonce_size); + static uint8_t data[BENCH_BLOCK]; + + printf("\n"); + + init_data(data); + if (aead->set_nonce) + init_nonce (aead->nonce_size, nonce); + + { + /* Decent initializers are a GNU extension, so don't use it here. */ + struct bench_aead_info info; + info.ctx = ctx; + info.crypt = aead->encrypt; + info.data = data; + + init_key(aead->key_size, key); + aead->set_encrypt_key(ctx, key); + if (aead->set_nonce) + aead->set_nonce (ctx, nonce); + + display(aead->name, "encrypt", aead->block_size, + time_function(bench_aead_crypt, &info)); + } + + { + struct bench_aead_info info; + info.ctx = ctx; + info.crypt = aead->decrypt; + info.data = data; + + init_key(aead->key_size, key); + aead->set_decrypt_key(ctx, key); + if (aead->set_nonce) + aead->set_nonce (ctx, nonce); + + display(aead->name, "decrypt", aead->block_size, + time_function(bench_aead_crypt, &info)); + } + + if (aead->update) + { + struct bench_aead_info info; + info.ctx = ctx; + info.update = aead->update; + info.data = data; + + aead->set_encrypt_key(ctx, key); + + if (aead->set_nonce) + aead->set_nonce (ctx, nonce); + + display(aead->name, "update", aead->block_size, + time_function(bench_aead_update, &info)); + } + free(ctx); + free(key); + free(nonce); +} + +/* Try to get accurate cycle times for assembler functions. */ +#if WITH_CYCLE_COUNTER +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; +} + +#define TIME_CYCLES(t, code) do { \ + double tc_count[5]; \ + uint32_t tc_start_lo, tc_start_hi, tc_end_lo, tc_end_hi; \ + unsigned tc_i, tc_j; \ + for (tc_j = 0; tc_j < 5; tc_j++) \ + { \ + tc_i = 0; \ + GET_CYCLE_COUNTER(tc_start_hi, tc_start_lo); \ + for (; tc_i < BENCH_ITERATIONS; tc_i++) \ + { code; } \ + \ + GET_CYCLE_COUNTER(tc_end_hi, tc_end_lo); \ + \ + tc_end_hi -= (tc_start_hi + (tc_start_lo > tc_end_lo)); \ + tc_end_lo -= tc_start_lo; \ + \ + tc_count[tc_j] = ldexp(tc_end_hi, 32) + tc_end_lo; \ + } \ + qsort(tc_count, 5, sizeof(double), compare_double); \ + (t) = tc_count[2] / BENCH_ITERATIONS; \ +} while (0) + +static void +bench_sha1_compress(void) +{ + uint32_t state[_SHA1_DIGEST_LENGTH]; + uint8_t data[SHA1_BLOCK_SIZE]; + double t; + + TIME_CYCLES (t, _nettle_sha1_compress(state, data)); + + printf("sha1_compress: %.2f cycles\n", t); +} + +static void +bench_salsa20_core(void) +{ + uint32_t state[_SALSA20_INPUT_LENGTH]; + double t; + + TIME_CYCLES (t, _nettle_salsa20_core(state, state, 20)); + printf("salsa20_core: %.2f cycles\n", t); +} + +static void +bench_sha3_permute(void) +{ + struct sha3_state state; + double t; + + TIME_CYCLES (t, sha3_permute (&state)); + printf("sha3_permute: %.2f cycles (%.2f / round)\n", t, t / 24.0); +} +#else +#define bench_sha1_compress() +#define bench_salsa20_core() +#define bench_sha3_permute() +#endif + +#if WITH_OPENSSL +# define OPENSSL(x) x, +#else +# define OPENSSL(x) +#endif + +int +main(int argc, char **argv) +{ + unsigned i; + int c; + const char *alg; + +#if WITH_OPENSSL + nettle_openssl_init(); +#endif + + 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, + &nettle_sha512_224, &nettle_sha512_256, + &nettle_sha3_224, &nettle_sha3_256, + &nettle_sha3_384, &nettle_sha3_512, + &nettle_ripemd160, &nettle_gosthash94, + 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_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 + }; + + const struct nettle_aead *aeads[] = + { + /* Stream ciphers */ + &nettle_arcfour128, OPENSSL(&nettle_openssl_arcfour128) + &nettle_salsa20, &nettle_salsa20r12, &nettle_chacha, + /* Proper AEAD algorithme. */ + &nettle_gcm_aes128, + &nettle_gcm_aes192, + &nettle_gcm_aes256, + &nettle_gcm_camellia128, + &nettle_gcm_camellia256, + &nettle_eax_aes128, + &nettle_chacha_poly1305, + NULL + }; + + enum { OPT_HELP = 300 }; + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, OPT_HELP }, + { "clock-frequency", required_argument, NULL, 'f' }, + { NULL, 0, NULL, 0 } + }; + + while ( (c = getopt_long(argc, argv, "f:", options, NULL)) != -1) + switch (c) + { + case 'f': + frequency = atof(optarg); + if (frequency > 0.0) + break; + /* Fall through */ + + case OPT_HELP: + printf("Usage: nettle-benchmark [-f clock frequency] [alg]\n"); + return EXIT_SUCCESS; + + case '?': + return EXIT_FAILURE; + + default: + abort(); + } + + alg = argv[optind]; + + time_init(); + bench_sha1_compress(); + bench_salsa20_core(); + bench_sha3_permute(); + printf("\n"); + time_overhead(); + + header(); + + if (!alg || strstr ("memxor", alg)) + { + time_memxor(); + printf("\n"); + } + + for (i = 0; hashes[i]; i++) + if (!alg || strstr(hashes[i]->name, alg)) + time_hash(hashes[i]); + + if (!alg || strstr ("umac", alg)) + time_umac(); + + if (!alg || strstr ("poly1305-aes", alg)) + time_poly1305_aes(); + + for (i = 0; ciphers[i]; i++) + if (!alg || strstr(ciphers[i]->name, alg)) + time_cipher(ciphers[i]); + + for (i = 0; aeads[i]; i++) + if (!alg || strstr(aeads[i]->name, alg)) + time_aead(aeads[i]); + + return 0; +} diff --git a/examples/nettle-openssl.c b/examples/nettle-openssl.c new file mode 100644 index 0000000..b549ba5 --- /dev/null +++ b/examples/nettle-openssl.c @@ -0,0 +1,342 @@ +/* nettle-openssl.c + + Glue that's used only by the benchmark, and subject to change. + + Copyright (C) 2002, 2017 Niels Möller + Copyright (C) 2017 Red Hat, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 "nettle-internal.h" + +/* We use Openssl's EVP api for all openssl ciphers. This API selects + platform-specific implementations if appropriate, e.g., using x86 + AES-NI instructions. */ +struct openssl_cipher_ctx { + EVP_CIPHER_CTX *evp; +}; + +void +nettle_openssl_init(void) +{ + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); +#if OPENSSL_VERSION_NUMBER >= 0x1010000 + CONF_modules_load_file(NULL, NULL, 0); +#else + OPENSSL_config(NULL); +#endif +} + +static void +openssl_evp_set_encrypt_key(void *p, const uint8_t *key, + const EVP_CIPHER *cipher) +{ + struct openssl_cipher_ctx *ctx = p; + ctx->evp = EVP_CIPHER_CTX_new(); + assert(EVP_EncryptInit_ex(ctx->evp, cipher, NULL, key, NULL) == 1); + EVP_CIPHER_CTX_set_padding(ctx->evp, 0); +} +static void +openssl_evp_set_decrypt_key(void *p, const uint8_t *key, + const EVP_CIPHER *cipher) +{ + struct openssl_cipher_ctx *ctx = p; + ctx->evp = EVP_CIPHER_CTX_new(); + assert(EVP_DecryptInit_ex(ctx->evp, cipher, NULL, key, NULL) == 1); + EVP_CIPHER_CTX_set_padding(ctx->evp, 0); +} + +static void +openssl_evp_encrypt(const void *p, size_t length, + uint8_t *dst, const uint8_t *src) +{ + const struct openssl_cipher_ctx *ctx = p; + int len; + assert(EVP_EncryptUpdate(ctx->evp, dst, &len, src, length) == 1); +} +static void +openssl_evp_decrypt(const void *p, size_t length, + uint8_t *dst, const uint8_t *src) +{ + const struct openssl_cipher_ctx *ctx = p; + int len; + assert(EVP_DecryptUpdate(ctx->evp, dst, &len, src, length) == 1); +} + +/* AES */ +static nettle_set_key_func openssl_aes128_set_encrypt_key; +static nettle_set_key_func openssl_aes128_set_decrypt_key; +static nettle_set_key_func openssl_aes192_set_encrypt_key; +static nettle_set_key_func openssl_aes192_set_decrypt_key; +static nettle_set_key_func openssl_aes256_set_encrypt_key; +static nettle_set_key_func openssl_aes256_set_decrypt_key; + +static void +openssl_aes128_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_aes_128_ecb()); +} +static void +openssl_aes128_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_aes_128_ecb()); +} + +static void +openssl_aes192_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_aes_192_ecb()); +} +static void +openssl_aes192_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_aes_192_ecb()); +} + +static void +openssl_aes256_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_aes_256_ecb()); +} +static void +openssl_aes256_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_aes_256_ecb()); +} + +const struct nettle_cipher +nettle_openssl_aes128 = { + "openssl aes128", sizeof(struct openssl_cipher_ctx), + 16, 16, + openssl_aes128_set_encrypt_key, openssl_aes128_set_decrypt_key, + openssl_evp_encrypt, openssl_evp_decrypt +}; + +const struct nettle_cipher +nettle_openssl_aes192 = { + "openssl aes192", sizeof(struct openssl_cipher_ctx), + 16, 24, + openssl_aes192_set_encrypt_key, openssl_aes192_set_decrypt_key, + openssl_evp_encrypt, openssl_evp_decrypt +}; + +const struct nettle_cipher +nettle_openssl_aes256 = { + "openssl aes256", sizeof(struct openssl_cipher_ctx), + 16, 32, + openssl_aes256_set_encrypt_key, openssl_aes256_set_decrypt_key, + openssl_evp_encrypt, openssl_evp_decrypt +}; + +/* Arcfour */ +static void +openssl_arcfour128_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_rc4()); +} + +static void +openssl_arcfour128_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_rc4()); +} + +const struct nettle_aead +nettle_openssl_arcfour128 = { + "openssl arcfour128", sizeof(struct openssl_cipher_ctx), + 1, 16, 0, 0, + openssl_arcfour128_set_encrypt_key, + openssl_arcfour128_set_decrypt_key, + NULL, NULL, + (nettle_crypt_func *)openssl_evp_encrypt, + (nettle_crypt_func *)openssl_evp_decrypt, + NULL, +}; + +/* Blowfish */ +static void +openssl_bf128_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_bf_ecb()); +} + +static void +openssl_bf128_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_bf_ecb()); +} + +const struct nettle_cipher +nettle_openssl_blowfish128 = { + "openssl bf128", sizeof(struct openssl_cipher_ctx), + 8, 16, + openssl_bf128_set_encrypt_key, openssl_bf128_set_decrypt_key, + openssl_evp_encrypt, openssl_evp_decrypt +}; + + +/* DES */ +static void +openssl_des_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_des_ecb()); +} + +static void +openssl_des_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_des_ecb()); +} + +const struct nettle_cipher +nettle_openssl_des = { + "openssl des", sizeof(struct openssl_cipher_ctx), + 8, 8, + openssl_des_set_encrypt_key, openssl_des_set_decrypt_key, + openssl_evp_encrypt, openssl_evp_decrypt +}; + + +/* Cast128 */ +static void +openssl_cast128_set_encrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_encrypt_key(ctx, key, EVP_cast5_ecb()); +} + +static void +openssl_cast128_set_decrypt_key(void *ctx, const uint8_t *key) +{ + openssl_evp_set_decrypt_key(ctx, key, EVP_cast5_ecb()); +} + +const struct nettle_cipher +nettle_openssl_cast128 = { + "openssl cast128", sizeof(struct openssl_cipher_ctx), + 8, 16, + openssl_cast128_set_encrypt_key, openssl_cast128_set_decrypt_key, + openssl_evp_encrypt, openssl_evp_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, + size_t 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, + size_t 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, + size_t 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, + size_t 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/random-prime.c b/examples/random-prime.c new file mode 100644 index 0000000..f463dfd --- /dev/null +++ b/examples/random-prime.c @@ -0,0 +1,153 @@ +/* random-prime.c + + Command line tool for prime generation. + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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; + + enum { OPT_HELP = 300 }; + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, OPT_HELP }, + { "verbose", no_argument, NULL, 'v' }, + { "random", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "vr:", options, NULL)) != -1) + switch (c) + { + case 'v': + verbose = 1; + break; + case 'r': + random_file = optarg; + break; + case OPT_HELP: + usage(); + return EXIT_SUCCESS; + case '?': + 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..f225666 --- /dev/null +++ b/examples/read_rsa_key.c @@ -0,0 +1,61 @@ +/* read_rsa_key.c + + Used by the rsa example programs. + + Copyright (C) 2002, 2007 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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; + uint8_t *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..94c2219 --- /dev/null +++ b/examples/rsa-decrypt.c @@ -0,0 +1,262 @@ +/* rsa-decrypt.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +/* 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 "memops.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) + { + if (ferror(in)) + werror("Reading input failed: %s\n", strerror(errno)); + else + werror("Unexpected EOF on input.\n"); + return 0; + } + + do + { + size = fread(buffer + BUF_FINAL, 1, BUF_SIZE, in); + + if (size < BUF_SIZE && 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_data(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_data(out, leftover, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + } + hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, digest); + if (!memeql_sec(digest, buffer + AES_BLOCK_SIZE, SHA1_DIGEST_SIZE)) + { + 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; + + size_t 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; + } + +#ifdef WIN32 + _setmode(0, O_BINARY); + _setmode(1, O_BINARY); +#endif + + 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..ff935fb --- /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$EXEEXT ] ; then + if $EMULATOR ./rsa-encrypt -r rsa-decrypt$EXEEXT testkey.pub < "$data" > testciphertext ; then + : + else + exit 1 + fi + if $EMULATOR ./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..9106125 --- /dev/null +++ b/examples/rsa-encrypt.c @@ -0,0 +1,273 @@ +/* rsa-encrypt.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#endif + +/* 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_data(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_data(f, size, p); + free(p); + return res; +} + +#define BLOCK_SIZE (AES_BLOCK_SIZE * 100) + +static int +process_file(struct rsa_session *ctx, + FILE *in, FILE *out) +{ + uint8_t buffer[BLOCK_SIZE + SHA1_DIGEST_SIZE]; + + for (;;) + { + size_t size = fread(buffer, 1, BLOCK_SIZE, in); + hmac_sha1_update(&ctx->hmac, size, buffer); + + if (size < BLOCK_SIZE) + { + unsigned leftover; + unsigned padding; + + if (ferror(in)) + { + werror("Reading input failed: %s\n", strerror(errno)); + return 0; + } + + leftover = size % AES_BLOCK_SIZE; + padding = AES_BLOCK_SIZE - leftover; + + assert (size + padding <= BLOCK_SIZE); + + if (padding > 1) + yarrow256_random(&ctx->yarrow, padding - 1, buffer + size); + + size += padding; + + buffer[size - 1] = padding; + CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer); + + assert (size + SHA1_DIGEST_SIZE <= sizeof(buffer)); + + hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, buffer + size); + size += SHA1_DIGEST_SIZE; + + if (!write_data(out, size, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + return 1; + } + + CBC_ENCRYPT(&ctx->aes, aes_encrypt, size, buffer, buffer); + if (!write_data(out, size, buffer)) + { + werror("Writing output failed: %s\n", strerror(errno)); + return 0; + } + } +} + +static void +usage (FILE *out) +{ + fprintf (out, "Usage: rsa-encrypt [OPTIONS] PUBLIC-KEY < cleartext\n" + "Options:\n" + " -r, --random=FILE seed file for randomness generator\n" + " --help display this help\n"); +} + +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; + + enum { OPT_HELP = 300 }; + + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, OPT_HELP }, + { "random", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "o:r:", options, NULL)) != -1) + switch (c) + { + case 'r': + random_name = optarg; + break; + + case '?': + return EXIT_FAILURE; + + case OPT_HELP: + usage(stdout); + return EXIT_SUCCESS; + default: + abort(); + } + + argv += optind; + argc -= optind; + + if (argc != 1) + { + usage (stderr); + 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); + +#ifdef WIN32 + _setmode(0, O_BINARY); + _setmode(1, O_BINARY); +#endif + + 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); + + mpz_clear (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..4db8d92 --- /dev/null +++ b/examples/rsa-keygen.c @@ -0,0 +1,207 @@ +/* rsa-keygen.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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 DEFAULT_KEYSIZE 2048 +#define ESIZE 30 + +static void +progress(void *ctx, int c) +{ + (void) ctx; + fputc(c, stderr); +} + +static unsigned long +uint_arg (char c, const char *arg) +{ + unsigned long val; + char *end; + + val = strtoul(arg, &end, 0); + if (*arg == '\0' || *end != '\0') + { + werror ("Invalid integer argument for -%c option.\n", c); + exit (EXIT_FAILURE); + } + + return val; +} + +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; + + unsigned long key_size = DEFAULT_KEYSIZE; + unsigned long key_e = 0; + + enum { OPT_HELP = 300 }; + static const struct option options[] = + { + /* Name, args, flag, val */ + { "help", no_argument, NULL, OPT_HELP }, + { "random", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0} + }; + + while ( (c = getopt_long(argc, argv, "o:r:e:s:", options, NULL)) != -1) + switch (c) + { + case 'o': + priv_name = optarg; + break; + + case 'r': + random_name = optarg; + break; + + case 's': + key_size = uint_arg ('s', optarg); + break; + + case 'e': + key_e = uint_arg ('e', optarg); + break; + + case OPT_HELP: + printf("FIXME: Usage information.\n"); + return EXIT_SUCCESS; + + case '?': + 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 (key_e) + mpz_set_ui (pub.e, key_e); + + if (!rsa_generate_keypair + (&pub, &priv, + (void *) &yarrow, (nettle_random_func *) yarrow256_random, + NULL, progress, + key_size, key_e == 0 ? ESIZE : 0)) + { + 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; + } + + nettle_buffer_clear(&priv_buffer); + nettle_buffer_clear(&pub_buffer); + rsa_public_key_clear(&pub); + rsa_private_key_clear(&priv); + free (pub_name); + + 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..99d90df --- /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$EXEEXT ] ; then + if $EMULATOR ./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..a6439dc --- /dev/null +++ b/examples/rsa-sign.c @@ -0,0 +1,94 @@ +/* rsa-sign.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..13c143c --- /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$EXEEXT ] ; then + $EMULATOR ./rsa-sign testkey < "$data" > testsignature \ + && $EMULATOR ./rsa-verify testkey.pub testsignature < "$data" \ + || exit 1; + + # Try modifying the data + sed s/128/129/ < "$data" >testdata + + if $EMULATOR ./rsa-verify testkey.pub testsignature < testdata 2>/dev/null; then + exit 1 + fi + + # Try modifying the signature + sed s/1/2/ testsignature2 + if $EMULATOR ./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..297903e --- /dev/null +++ b/examples/rsa-verify.c @@ -0,0 +1,109 @@ +/* rsa-verify.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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) +{ + uint8_t *buffer; + unsigned length; + int res; + + length = read_file(name, 0, &buffer); + if (!length) + return 0; + + res = (mpz_set_str(s, (const char *) 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/setup-env b/examples/setup-env new file mode 100755 index 0000000..e59b283 --- /dev/null +++ b/examples/setup-env @@ -0,0 +1,16 @@ +#! /bin/sh + +set -e + +# Workaround, it seems difficult to convince wine to put ../lib into PATH. +case "$EMULATOR" in + wine*) + for f in ../.lib/*.dll ; do + ln -sf "$f" . + done + ;; +esac + +if [ -x rsa-keygen$EXEEXT ] ; then + $EMULATOR ./rsa-keygen -r rsa-decrypt$EXEEXT -o testkey || exit 1 +fi diff --git a/examples/teardown-env b/examples/teardown-env new file mode 100755 index 0000000..0b0e040 --- /dev/null +++ b/examples/teardown-env @@ -0,0 +1,11 @@ +#! /bin/sh + +rm -rf testkey testkey.pub testsignature testsignature2 \ + testdata testtmp \ + testciphertext testcleartext + +case "$EMULATOR" in + wine*) + find . -type l -name '*.dll' -exec rm -f '{}' ';' + ;; +esac diff --git a/examples/timing.c b/examples/timing.c new file mode 100644 index 0000000..3088c97 --- /dev/null +++ b/examples/timing.c @@ -0,0 +1,119 @@ +/* timing.c + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "timing.h" + +#include +#include +#include +#include +#include +#include + +#if HAVE_CLOCK_GETTIME && defined CLOCK_PROCESS_CPUTIME_ID +#define TRY_CLOCK_GETTIME 1 +struct timespec cgt_start; + +static void NORETURN PRINTF_STYLE(1,2) +die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(EXIT_FAILURE); +} + +static int +cgt_works_p(void) +{ + struct timespec now; + return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now) == 0; +} + +static void +cgt_time_start(void) +{ + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cgt_start) < 0) + die("clock_gettime failed: %s\n", strerror(errno)); +} + +static double +cgt_time_end(void) +{ + struct timespec end; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) + die("clock_gettime failed: %s\n", strerror(errno)); + + return end.tv_sec - cgt_start.tv_sec + + 1e-9 * (end.tv_nsec - cgt_start.tv_nsec); +} +#endif /* !HAVE_CLOCK_GETTIME */ + +static clock_t clock_start; + +static void +clock_time_start(void) +{ + clock_start = clock(); +} + +static double +clock_time_end(void) +{ + return (double) (clock() - (clock_start)) / CLOCKS_PER_SEC; +} + +void (*time_start)(void) = clock_time_start; +double (*time_end)(void) = clock_time_end; + +void time_init(void) +{ + /* Choose timing function */ +#if TRY_CLOCK_GETTIME + if (cgt_works_p()) + { + time_start = cgt_time_start; + time_end = cgt_time_end; + } + else + { + fprintf(stderr, "clock_gettime not working, falling back to clock\n"); + time_start = clock_time_start; + time_end = clock_time_end; + } +#endif +} diff --git a/examples/timing.h b/examples/timing.h new file mode 100644 index 0000000..3d7a913 --- /dev/null +++ b/examples/timing.h @@ -0,0 +1,39 @@ +/* timing.h + + Copyright (C) 2013 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_EXAMPLES_TIMING_H_INCLUDED +#define NETTLE_EXAMPLES_TIMING_H_INCLUDED + +void time_init(void); +extern void (*time_start)(void); +extern double (*time_end)(void); + +#endif /* NETTLE_EXAMPLES_TIMING_H_INCLUDED */ diff --git a/fat-arm.c b/fat-arm.c new file mode 100644 index 0000000..d52b143 --- /dev/null +++ b/fat-arm.c @@ -0,0 +1,269 @@ +/* fat-arm.c + + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#define _GNU_SOURCE + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "nettle-types.h" + +#include "aes-internal.h" +#include "fat-setup.h" + +struct arm_features +{ + /* /proc/cpuinfo "CPU Architecture" doesn't correspond exactly to + ARM architecture version, but it's good enough for our purposes. + Will be set to 5, 6, 7 or 8. */ + unsigned arch_version; + int have_neon; +}; + +#define SKIP(s, slen, literal, llen) \ + (((slen) >= (llen) && memcmp ((s), (literal), llen) == 0) \ + ? ((slen) -= (llen), (s) += (llen), 1) : 0) +#define MATCH(s, slen, literal, llen) \ + ((slen) == (llen) && memcmp ((s), (literal), llen) == 0) + +static void +get_arm_features (struct arm_features *features) +{ + const char *s; + features->arch_version = 5; + features->have_neon = 0; + + s = secure_getenv (ENV_OVERRIDE); + if (s) + for (;;) + { + const char *sep = strchr (s, ','); + size_t length = sep ? (size_t) (sep - s) : strlen(s); + + if (SKIP (s, length, "arch:", 5)) + { + if (length == 1 && *s >= '0' && *s <= '9') + features->arch_version = *s - '0'; + } + else if (MATCH (s, length, "neon", 4)) + features->have_neon = 1; + if (!sep) + break; + s = sep + 1; + } + else + { + FILE *f; + char line[200]; + int seen_arch = 0; + int seen_features = 0; + + f = fopen ("/proc/cpuinfo", "r"); + if (!f) + return; + while (seen_features + seen_arch < 2 + && fgets (line, sizeof(line), f)) + { + char *sep; + char *p; + sep = strchr (line, ':'); + if (!sep) + continue; + for (p = sep; p - line > 0 && p[-1] == '\t'; p--) + ; + + *p = '\0'; + p = sep+1; + + if (strcmp (line, "Features") == 0) + { + features->have_neon = (strstr (p, " neon ") != NULL); + seen_features = 1; + } + else if (strcmp (line, "CPU architecture") == 0) + { + /* Don't use strtol, since it's locale dependent. */ + while (p[0] == ' ') + p++; + if (p[0] > '5' && p[0] <= '9') + features->arch_version = p[0] - '0'; + else if (strcmp (p, "AArch64") == 0) + features->arch_version = 8; + seen_arch = 1; + } + } + if (features->arch_version >= 8) + { + /* Neon is not required, and maybe not listed in feature flags */ + features->have_neon = 1; + } + fclose (f); + } +} + +DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func) +DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, arm) +DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, armv6) + +DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func) +DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, arm) +DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, armv6) + +DECLARE_FAT_FUNC(_nettle_salsa20_core, salsa20_core_func) +DECLARE_FAT_FUNC_VAR(salsa20_core, salsa20_core_func, c) +DECLARE_FAT_FUNC_VAR(salsa20_core, salsa20_core_func, neon) + +DECLARE_FAT_FUNC(_nettle_sha1_compress, sha1_compress_func) +DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, c) +DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, armv6) + +DECLARE_FAT_FUNC(_nettle_sha256_compress, sha256_compress_func) +DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, c) +DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, armv6) + +DECLARE_FAT_FUNC(_nettle_sha512_compress, sha512_compress_func) +DECLARE_FAT_FUNC_VAR(sha512_compress, sha512_compress_func, c) +DECLARE_FAT_FUNC_VAR(sha512_compress, sha512_compress_func, neon) + +DECLARE_FAT_FUNC(nettle_sha3_permute, sha3_permute_func) +DECLARE_FAT_FUNC_VAR(sha3_permute, sha3_permute_func, c) +DECLARE_FAT_FUNC_VAR(sha3_permute, sha3_permute_func, neon) + +DECLARE_FAT_FUNC(_nettle_umac_nh, umac_nh_func) +DECLARE_FAT_FUNC_VAR(umac_nh, umac_nh_func, c); +DECLARE_FAT_FUNC_VAR(umac_nh, umac_nh_func, neon); + +DECLARE_FAT_FUNC(_nettle_umac_nh_n, umac_nh_n_func) +DECLARE_FAT_FUNC_VAR(umac_nh_n, umac_nh_n_func, c); +DECLARE_FAT_FUNC_VAR(umac_nh_n, umac_nh_n_func, neon); + +static void CONSTRUCTOR +fat_init (void) +{ + struct arm_features features; + int verbose; + + get_arm_features (&features); + + verbose = getenv (ENV_VERBOSE) != NULL; + if (verbose) + fprintf (stderr, "libnettle: cpu features: arch:%d%s\n", + features.arch_version, + features.have_neon ? ",neon" : ""); + + if (features.arch_version >= 6) + { + if (verbose) + fprintf (stderr, "libnettle: enabling armv6 code.\n"); + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_armv6; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_armv6; + _nettle_sha1_compress_vec = _nettle_sha1_compress_armv6; + _nettle_sha256_compress_vec = _nettle_sha256_compress_armv6; + } + else + { + if (verbose) + fprintf (stderr, "libnettle: not enabling armv6 code.\n"); + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_arm; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_arm; + _nettle_sha1_compress_vec = _nettle_sha1_compress_c; + _nettle_sha256_compress_vec = _nettle_sha256_compress_c; + } + if (features.have_neon) + { + if (verbose) + fprintf (stderr, "libnettle: enabling neon code.\n"); + _nettle_salsa20_core_vec = _nettle_salsa20_core_neon; + _nettle_sha512_compress_vec = _nettle_sha512_compress_neon; + nettle_sha3_permute_vec = _nettle_sha3_permute_neon; + _nettle_umac_nh_vec = _nettle_umac_nh_neon; + _nettle_umac_nh_n_vec = _nettle_umac_nh_n_neon; + } + else + { + if (verbose) + fprintf (stderr, "libnettle: not enabling neon code.\n"); + _nettle_salsa20_core_vec = _nettle_salsa20_core_c; + _nettle_sha512_compress_vec = _nettle_sha512_compress_c; + nettle_sha3_permute_vec = _nettle_sha3_permute_c; + _nettle_umac_nh_vec = _nettle_umac_nh_c; + _nettle_umac_nh_n_vec = _nettle_umac_nh_n_c; + } +} + +DEFINE_FAT_FUNC(_nettle_aes_encrypt, void, + (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src), + (rounds, keys, T, length, dst, src)) + +DEFINE_FAT_FUNC(_nettle_aes_decrypt, void, + (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src), + (rounds, keys, T, length, dst, src)) + +DEFINE_FAT_FUNC(_nettle_salsa20_core, void, + (uint32_t *dst, const uint32_t *src, unsigned rounds), + (dst, src, rounds)) + +DEFINE_FAT_FUNC(_nettle_sha1_compress, void, + (uint32_t *state, const uint8_t *input), + (state, input)) + +DEFINE_FAT_FUNC(_nettle_sha256_compress, void, + (uint32_t *state, const uint8_t *input, const uint32_t *k), + (state, input, k)) + +DEFINE_FAT_FUNC(_nettle_sha512_compress, void, + (uint64_t *state, const uint8_t *input, const uint64_t *k), + (state, input, k)) + +DEFINE_FAT_FUNC(nettle_sha3_permute, void, + (struct sha3_state *state), (state)) + +DEFINE_FAT_FUNC(_nettle_umac_nh, uint64_t, + (const uint32_t *key, unsigned length, const uint8_t *msg), + (key, length, msg)) + +DEFINE_FAT_FUNC(_nettle_umac_nh_n, void, + (uint64_t *out, unsigned n, const uint32_t *key, + unsigned length, const uint8_t *msg), + (out, n, key, length, msg)) + diff --git a/fat-setup.h b/fat-setup.h new file mode 100644 index 0000000..eb7166a --- /dev/null +++ b/fat-setup.h @@ -0,0 +1,176 @@ +/* fat-setup.h + + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Fat library initialization works as follows. The main function is + fat_init. We try to do initialization only once, but since it is + idempotent, there's no harm if it is in some cases called multiple + times from several threads. For correctness, we rely on atomic + writes, but not on memory barriers or any other synchronization + mechanism. + + The fat_init function checks the cpuid flags, and sets function + pointers, e.g, _nettle_aes_encrypt_vec, to point to the appropriate + implementation. + + To get everything hooked in, we use a belt-and-suspenders approach. + + We try to register fat_init as a constructor function to be called + at load time. If this is unavailable or non-working, we instead + arrange fat_init to be called lazily. + + For the actual indirection, there are two cases. + + * If ifunc support is available, function pointers are statically + initialized to NULL, and we register resolver functions, e.g., + _nettle_aes_encrypt_resolve, which call fat_init, and then return + the function pointer, e.g., the value of _nettle_aes_encrypt_vec. + + * If ifunc is not available, we have to define a wrapper function + to jump via the function pointer. (FIXME: For internal calls, we + could do this as a macro). + + We statically initialize each function pointer to point to a + special initialization function, e.g., _nettle_aes_encrypt_init, + which calls fat_init, and then invokes the right function. This + way, all pointers are setup correctly at the first call to any + fat function. + + And atomic writes are required for correctness in the case that + several threads do "first call to any fat function" at the same + time. +*/ + +#if HAVE_GCC_ATTRIBUTE +# define CONSTRUCTOR __attribute__ ((constructor)) +#else +# define CONSTRUCTOR +# if defined (__sun) +# pragma init(fat_init) +# endif +#endif + +/* Disable use of ifunc for now. Problem is, there's no guarantee that + one can call any libc functions from the ifunc resolver. On x86 and + x86_64, the corresponding IRELATIVE relocs are supposed to be + processed last, but that doesn't seem to happen, and its a + platform-specific feature. To trigger problems, simply try dlopen + ("libnettle.so", RTLD_NOW), which crashes in an uninitialized plt + entry. */ +#undef HAVE_LINK_IFUNC + +#if !HAVE_SECURE_GETENV +#define secure_getenv(s) NULL +#endif + +#define ENV_VERBOSE "NETTLE_FAT_VERBOSE" +#define ENV_OVERRIDE "NETTLE_FAT_OVERRIDE" + +/* DECLARE_FAT_FUNC(name, ftype) + * + * name is the public function, e.g., _nettle_aes_encrypt. + * ftype is its type, e.g., aes_crypt_internal_func. + * + * DECLARE_FAT_VAR(name, type, var) + * + * name is name without _nettle prefix. + * type is its type. + * var is the variant, used as a suffix on the symbol name. + * + * DEFINE_FAT_FUNC(name, rtype, prototype, args) + * + * name is the public function. + * rtype its return type. + * prototype is the list of formal arguments, with types. + * args contain the argument list without any types. + */ + +#if HAVE_LINK_IFUNC +#define IFUNC(resolve) __attribute__ ((ifunc (resolve))) +#define DECLARE_FAT_FUNC(name, ftype) \ + ftype name IFUNC(#name"_resolve"); \ + static ftype *name##_vec = NULL; + +#define DEFINE_FAT_FUNC(name, rtype, prototype, args) \ + static void_func * name##_resolve(void) \ + { \ + if (getenv (ENV_VERBOSE)) \ + fprintf (stderr, "libnettle: "#name"_resolve\n"); \ + if (!name##_vec) \ + fat_init(); \ + return (void_func *) name##_vec; \ + } + +#else /* !HAVE_LINK_IFUNC */ +#define DECLARE_FAT_FUNC(name, ftype) \ + ftype name; \ + static ftype name##_init; \ + static ftype *name##_vec = name##_init; + +#define DEFINE_FAT_FUNC(name, rtype, prototype, args) \ + rtype name prototype \ + { \ + return name##_vec args; \ + } \ + static rtype name##_init prototype { \ + if (getenv (ENV_VERBOSE)) \ + fprintf (stderr, "libnettle: "#name"_init\n"); \ + if (name##_vec == name##_init) \ + fat_init(); \ + assert (name##_vec != name##_init); \ + return name##_vec args; \ + } +#endif /* !HAVE_LINK_IFUNC */ + +#define DECLARE_FAT_FUNC_VAR(name, type, var) \ + type _nettle_##name##_##var; + +typedef void void_func (void); + +typedef void aes_crypt_internal_func (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src); + +typedef void *(memxor_func)(void *dst, const void *src, size_t n); + +typedef void salsa20_core_func (uint32_t *dst, const uint32_t *src, unsigned rounds); + +typedef void sha1_compress_func(uint32_t *state, const uint8_t *input); +typedef void sha256_compress_func(uint32_t *state, const uint8_t *input, const uint32_t *k); + +struct sha3_state; +typedef void sha3_permute_func (struct sha3_state *state); + +typedef void sha512_compress_func (uint64_t *state, const uint8_t *input, const uint64_t *k); + +typedef uint64_t umac_nh_func (const uint32_t *key, unsigned length, const uint8_t *msg); +typedef void umac_nh_n_func (uint64_t *out, unsigned n, const uint32_t *key, + unsigned length, const uint8_t *msg); diff --git a/fat-x86_64.c b/fat-x86_64.c new file mode 100644 index 0000000..2e97d1e --- /dev/null +++ b/fat-x86_64.c @@ -0,0 +1,187 @@ +/* fat-x86_64.c + + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#define _GNU_SOURCE + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "nettle-types.h" + +#include "aes-internal.h" +#include "memxor.h" +#include "fat-setup.h" + +void _nettle_cpuid (uint32_t input, uint32_t regs[4]); + +struct x86_features +{ + enum x86_vendor { X86_OTHER, X86_INTEL, X86_AMD } vendor; + int have_aesni; +}; + +#define SKIP(s, slen, literal, llen) \ + (((slen) >= (llen) && memcmp ((s), (literal), llen) == 0) \ + ? ((slen) -= (llen), (s) += (llen), 1) : 0) +#define MATCH(s, slen, literal, llen) \ + ((slen) == (llen) && memcmp ((s), (literal), llen) == 0) + +static void +get_x86_features (struct x86_features *features) +{ + const char *s; + features->vendor = X86_OTHER; + features->have_aesni = 0; + + s = secure_getenv (ENV_OVERRIDE); + if (s) + for (;;) + { + const char *sep = strchr (s, ','); + size_t length = sep ? (size_t) (sep - s) : strlen(s); + + if (SKIP (s, length, "vendor:", 7)) + { + if (MATCH(s, length, "intel", 5)) + features->vendor = X86_INTEL; + else if (MATCH(s, length, "amd", 3)) + features->vendor = X86_AMD; + + } + else if (MATCH (s, length, "aesni", 5)) + features->have_aesni = 1; + if (!sep) + break; + s = sep + 1; + } + else + { + uint32_t cpuid_data[4]; + _nettle_cpuid (0, cpuid_data); + if (memcmp (cpuid_data + 1, "Genu" "ntel" "ineI", 12) == 0) + features->vendor = X86_INTEL; + else if (memcmp (cpuid_data + 1, "Auth" "cAMD" "enti", 12) == 0) + features->vendor = X86_AMD; + + _nettle_cpuid (1, cpuid_data); + if (cpuid_data[2] & 0x02000000) + features->have_aesni = 1; + } +} + +DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func) +DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, x86_64) +DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, aesni) + +DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func) +DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, x86_64) +DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, aesni) + +DECLARE_FAT_FUNC(nettle_memxor, memxor_func) +DECLARE_FAT_FUNC_VAR(memxor, memxor_func, x86_64) +DECLARE_FAT_FUNC_VAR(memxor, memxor_func, sse2) + +/* This function should usually be called only once, at startup. But + it is idempotent, and on x86, pointer updates are atomic, so + there's no danger if it is called simultaneously from multiple + threads. */ +static void CONSTRUCTOR +fat_init (void) +{ + struct x86_features features; + int verbose; + + /* FIXME: Replace all getenv calls by getenv_secure? */ + verbose = getenv (ENV_VERBOSE) != NULL; + if (verbose) + fprintf (stderr, "libnettle: fat library initialization.\n"); + + get_x86_features (&features); + if (verbose) + { + const char * const vendor_names[3] = + { "other", "intel", "amd" }; + fprintf (stderr, "libnettle: cpu features: vendor:%s%s\n", + vendor_names[features.vendor], + features.have_aesni ? ",aesni" : ""); + } + if (features.have_aesni) + { + if (verbose) + fprintf (stderr, "libnettle: using aes instructions.\n"); + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_aesni; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_aesni; + } + else + { + if (verbose) + fprintf (stderr, "libnettle: not using aes instructions.\n"); + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_x86_64; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_x86_64; + } + + if (features.vendor == X86_INTEL) + { + if (verbose) + fprintf (stderr, "libnettle: intel SSE2 will be used for memxor.\n"); + nettle_memxor_vec = _nettle_memxor_sse2; + } + else + { + if (verbose) + fprintf (stderr, "libnettle: intel SSE2 will not be used for memxor.\n"); + nettle_memxor_vec = _nettle_memxor_x86_64; + } +} + +DEFINE_FAT_FUNC(_nettle_aes_encrypt, void, + (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src), + (rounds, keys, T, length, dst, src)) + +DEFINE_FAT_FUNC(_nettle_aes_decrypt, void, + (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src), + (rounds, keys, T, length, dst, src)) + +DEFINE_FAT_FUNC(nettle_memxor, void *, + (void *dst, const void *src, size_t n), + (dst, src, n)) diff --git a/gcm-aes.c b/gcm-aes.c new file mode 100644 index 0000000..9c67355 --- /dev/null +++ b/gcm-aes.c @@ -0,0 +1,80 @@ +/* gcm-aes.c + + Galois counter mode using AES as the underlying cipher. + + Copyright (C) 2011 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "gcm.h" + +void +gcm_aes_set_key(struct gcm_aes_ctx *ctx, size_t length, const uint8_t *key) +{ + aes_set_encrypt_key (&ctx->cipher, length, key); + gcm_set_key (&ctx->key, &ctx->cipher, + (nettle_cipher_func *) aes_encrypt); +} + +void +gcm_aes_set_iv(struct gcm_aes_ctx *ctx, + size_t length, const uint8_t *iv) +{ + GCM_SET_IV(ctx, length, iv); +} + +void +gcm_aes_update(struct gcm_aes_ctx *ctx, size_t length, const uint8_t *data) +{ + GCM_UPDATE(ctx, length, data); +} + +void +gcm_aes_encrypt(struct gcm_aes_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_ENCRYPT(ctx, aes_encrypt, length, dst, src); +} + +void +gcm_aes_decrypt(struct gcm_aes_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_DECRYPT(ctx, aes_encrypt, length, dst, src); +} + +void +gcm_aes_digest(struct gcm_aes_ctx *ctx, + size_t length, uint8_t *digest) +{ + GCM_DIGEST(ctx, aes_encrypt, length, digest); +} diff --git a/gcm-aes128-meta.c b/gcm-aes128-meta.c new file mode 100644 index 0000000..81e005e --- /dev/null +++ b/gcm-aes128-meta.c @@ -0,0 +1,60 @@ +/* gcm-aes128-meta.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "gcm.h" + +static nettle_set_key_func gcm_aes128_set_nonce_wrapper; +static void +gcm_aes128_set_nonce_wrapper (void *ctx, const uint8_t *nonce) +{ + gcm_aes128_set_iv (ctx, GCM_IV_SIZE, nonce); +} + +const struct nettle_aead nettle_gcm_aes128 = + { "gcm_aes128", sizeof(struct gcm_aes128_ctx), + GCM_BLOCK_SIZE, AES128_KEY_SIZE, + GCM_IV_SIZE, GCM_DIGEST_SIZE, + (nettle_set_key_func *) gcm_aes128_set_key, + (nettle_set_key_func *) gcm_aes128_set_key, + gcm_aes128_set_nonce_wrapper, + (nettle_hash_update_func *) gcm_aes128_update, + (nettle_crypt_func *) gcm_aes128_encrypt, + (nettle_crypt_func *) gcm_aes128_decrypt, + (nettle_hash_digest_func *) gcm_aes128_digest, + }; diff --git a/gcm-aes128.c b/gcm-aes128.c new file mode 100644 index 0000000..ace2f31 --- /dev/null +++ b/gcm-aes128.c @@ -0,0 +1,81 @@ +/* gcm-aes128.c + + Galois counter mode using AES128 as the underlying cipher. + + Copyright (C) 2011, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "gcm.h" + +void +gcm_aes128_set_key(struct gcm_aes128_ctx *ctx, const uint8_t *key) +{ + GCM_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key); +} + +void +gcm_aes128_set_iv (struct gcm_aes128_ctx *ctx, + size_t length, const uint8_t *iv) +{ + GCM_SET_IV (ctx, length, iv); +} + +void +gcm_aes128_update (struct gcm_aes128_ctx *ctx, + size_t length, const uint8_t *data) +{ + GCM_UPDATE (ctx, length, data); +} + +void +gcm_aes128_encrypt(struct gcm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_ENCRYPT(ctx, aes128_encrypt, length, dst, src); +} + +void +gcm_aes128_decrypt(struct gcm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_DECRYPT(ctx, aes128_encrypt, length, dst, src); +} + +void +gcm_aes128_digest(struct gcm_aes128_ctx *ctx, + size_t length, uint8_t *digest) +{ + GCM_DIGEST(ctx, aes128_encrypt, length, digest); +} diff --git a/gcm-aes192-meta.c b/gcm-aes192-meta.c new file mode 100644 index 0000000..1907317 --- /dev/null +++ b/gcm-aes192-meta.c @@ -0,0 +1,60 @@ +/* gcm-aes192-meta.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "gcm.h" + +static nettle_set_key_func gcm_aes192_set_nonce_wrapper; +static void +gcm_aes192_set_nonce_wrapper (void *ctx, const uint8_t *nonce) +{ + gcm_aes192_set_iv (ctx, GCM_IV_SIZE, nonce); +} + +const struct nettle_aead nettle_gcm_aes192 = + { "gcm_aes192", sizeof(struct gcm_aes192_ctx), + GCM_BLOCK_SIZE, AES192_KEY_SIZE, + GCM_IV_SIZE, GCM_DIGEST_SIZE, + (nettle_set_key_func *) gcm_aes192_set_key, + (nettle_set_key_func *) gcm_aes192_set_key, + gcm_aes192_set_nonce_wrapper, + (nettle_hash_update_func *) gcm_aes192_update, + (nettle_crypt_func *) gcm_aes192_encrypt, + (nettle_crypt_func *) gcm_aes192_decrypt, + (nettle_hash_digest_func *) gcm_aes192_digest, + }; diff --git a/gcm-aes192.c b/gcm-aes192.c new file mode 100644 index 0000000..2321e28 --- /dev/null +++ b/gcm-aes192.c @@ -0,0 +1,81 @@ +/* gcm-aes192.c + + Galois counter mode using AES192 as the underlying cipher. + + Copyright (C) 2011, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "gcm.h" + +void +gcm_aes192_set_key(struct gcm_aes192_ctx *ctx, const uint8_t *key) +{ + GCM_SET_KEY(ctx, aes192_set_encrypt_key, aes192_encrypt, key); +} + +void +gcm_aes192_set_iv (struct gcm_aes192_ctx *ctx, + size_t length, const uint8_t *iv) +{ + GCM_SET_IV (ctx, length, iv); +} + +void +gcm_aes192_update (struct gcm_aes192_ctx *ctx, + size_t length, const uint8_t *data) +{ + GCM_UPDATE (ctx, length, data); +} + +void +gcm_aes192_encrypt(struct gcm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_ENCRYPT(ctx, aes192_encrypt, length, dst, src); +} + +void +gcm_aes192_decrypt(struct gcm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_DECRYPT(ctx, aes192_encrypt, length, dst, src); +} + +void +gcm_aes192_digest(struct gcm_aes192_ctx *ctx, + size_t length, uint8_t *digest) +{ + GCM_DIGEST(ctx, aes192_encrypt, length, digest); +} diff --git a/gcm-aes256-meta.c b/gcm-aes256-meta.c new file mode 100644 index 0000000..ce52b1e --- /dev/null +++ b/gcm-aes256-meta.c @@ -0,0 +1,60 @@ +/* gcm-aes256-meta.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "gcm.h" + +static nettle_set_key_func gcm_aes256_set_nonce_wrapper; +static void +gcm_aes256_set_nonce_wrapper (void *ctx, const uint8_t *nonce) +{ + gcm_aes256_set_iv (ctx, GCM_IV_SIZE, nonce); +} + +const struct nettle_aead nettle_gcm_aes256 = + { "gcm_aes256", sizeof(struct gcm_aes256_ctx), + GCM_BLOCK_SIZE, AES256_KEY_SIZE, + GCM_IV_SIZE, GCM_DIGEST_SIZE, + (nettle_set_key_func *) gcm_aes256_set_key, + (nettle_set_key_func *) gcm_aes256_set_key, + gcm_aes256_set_nonce_wrapper, + (nettle_hash_update_func *) gcm_aes256_update, + (nettle_crypt_func *) gcm_aes256_encrypt, + (nettle_crypt_func *) gcm_aes256_decrypt, + (nettle_hash_digest_func *) gcm_aes256_digest, + }; diff --git a/gcm-aes256.c b/gcm-aes256.c new file mode 100644 index 0000000..a90fc5a --- /dev/null +++ b/gcm-aes256.c @@ -0,0 +1,81 @@ +/* gcm-aes256.c + + Galois counter mode using AES256 as the underlying cipher. + + Copyright (C) 2011, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "gcm.h" + +void +gcm_aes256_set_key(struct gcm_aes256_ctx *ctx, const uint8_t *key) +{ + GCM_SET_KEY(ctx, aes256_set_encrypt_key, aes256_encrypt, key); +} + +void +gcm_aes256_set_iv (struct gcm_aes256_ctx *ctx, + size_t length, const uint8_t *iv) +{ + GCM_SET_IV (ctx, length, iv); +} + +void +gcm_aes256_update (struct gcm_aes256_ctx *ctx, + size_t length, const uint8_t *data) +{ + GCM_UPDATE (ctx, length, data); +} + +void +gcm_aes256_encrypt(struct gcm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_ENCRYPT(ctx, aes256_encrypt, length, dst, src); +} + +void +gcm_aes256_decrypt(struct gcm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_DECRYPT(ctx, aes256_encrypt, length, dst, src); +} + +void +gcm_aes256_digest(struct gcm_aes256_ctx *ctx, + size_t length, uint8_t *digest) +{ + GCM_DIGEST(ctx, aes256_encrypt, length, digest); +} diff --git a/gcm-camellia128-meta.c b/gcm-camellia128-meta.c new file mode 100644 index 0000000..50b9622 --- /dev/null +++ b/gcm-camellia128-meta.c @@ -0,0 +1,60 @@ +/* gcm-camellia128-meta.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "gcm.h" + +static nettle_set_key_func gcm_camellia128_set_nonce_wrapper; +static void +gcm_camellia128_set_nonce_wrapper (void *ctx, const uint8_t *nonce) +{ + gcm_camellia128_set_iv (ctx, GCM_IV_SIZE, nonce); +} + +const struct nettle_aead nettle_gcm_camellia128 = + { "gcm_camellia128", sizeof(struct gcm_camellia128_ctx), + GCM_BLOCK_SIZE, CAMELLIA128_KEY_SIZE, + GCM_IV_SIZE, GCM_DIGEST_SIZE, + (nettle_set_key_func *) gcm_camellia128_set_key, + (nettle_set_key_func *) gcm_camellia128_set_key, + gcm_camellia128_set_nonce_wrapper, + (nettle_hash_update_func *) gcm_camellia128_update, + (nettle_crypt_func *) gcm_camellia128_encrypt, + (nettle_crypt_func *) gcm_camellia128_decrypt, + (nettle_hash_digest_func *) gcm_camellia128_digest, + }; diff --git a/gcm-camellia128.c b/gcm-camellia128.c new file mode 100644 index 0000000..e6630f5 --- /dev/null +++ b/gcm-camellia128.c @@ -0,0 +1,79 @@ +/* gcm-camellia128.c + + Copyright (C) 2011, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "gcm.h" + +void +gcm_camellia128_set_key(struct gcm_camellia128_ctx *ctx, const uint8_t *key) +{ + GCM_SET_KEY(ctx, camellia128_set_encrypt_key, camellia128_crypt, key); +} + +void +gcm_camellia128_set_iv (struct gcm_camellia128_ctx *ctx, + size_t length, const uint8_t *iv) +{ + GCM_SET_IV (ctx, length, iv); +} + +void +gcm_camellia128_update (struct gcm_camellia128_ctx *ctx, + size_t length, const uint8_t *data) +{ + GCM_UPDATE (ctx, length, data); +} + +void +gcm_camellia128_encrypt(struct gcm_camellia128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_ENCRYPT(ctx, camellia128_crypt, length, dst, src); +} + +void +gcm_camellia128_decrypt(struct gcm_camellia128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_DECRYPT(ctx, camellia128_crypt, length, dst, src); +} + +void +gcm_camellia128_digest(struct gcm_camellia128_ctx *ctx, + size_t length, uint8_t *digest) +{ + GCM_DIGEST(ctx, camellia128_crypt, length, digest); +} diff --git a/gcm-camellia256-meta.c b/gcm-camellia256-meta.c new file mode 100644 index 0000000..16b51db --- /dev/null +++ b/gcm-camellia256-meta.c @@ -0,0 +1,60 @@ +/* gcm-camellia256-meta.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#include "gcm.h" + +static nettle_set_key_func gcm_camellia256_set_nonce_wrapper; +static void +gcm_camellia256_set_nonce_wrapper (void *ctx, const uint8_t *nonce) +{ + gcm_camellia256_set_iv (ctx, GCM_IV_SIZE, nonce); +} + +const struct nettle_aead nettle_gcm_camellia256 = + { "gcm_camellia256", sizeof(struct gcm_camellia256_ctx), + GCM_BLOCK_SIZE, CAMELLIA256_KEY_SIZE, + GCM_IV_SIZE, GCM_DIGEST_SIZE, + (nettle_set_key_func *) gcm_camellia256_set_key, + (nettle_set_key_func *) gcm_camellia256_set_key, + gcm_camellia256_set_nonce_wrapper, + (nettle_hash_update_func *) gcm_camellia256_update, + (nettle_crypt_func *) gcm_camellia256_encrypt, + (nettle_crypt_func *) gcm_camellia256_decrypt, + (nettle_hash_digest_func *) gcm_camellia256_digest, + }; diff --git a/gcm-camellia256.c b/gcm-camellia256.c new file mode 100644 index 0000000..c725ef4 --- /dev/null +++ b/gcm-camellia256.c @@ -0,0 +1,79 @@ +/* gcm-camellia256.c + + Copyright (C) 2011, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "gcm.h" + +void +gcm_camellia256_set_key(struct gcm_camellia256_ctx *ctx, const uint8_t *key) +{ + GCM_SET_KEY(ctx, camellia256_set_encrypt_key, camellia256_crypt, key); +} + +void +gcm_camellia256_set_iv (struct gcm_camellia256_ctx *ctx, + size_t length, const uint8_t *iv) +{ + GCM_SET_IV (ctx, length, iv); +} + +void +gcm_camellia256_update (struct gcm_camellia256_ctx *ctx, + size_t length, const uint8_t *data) +{ + GCM_UPDATE (ctx, length, data); +} + +void +gcm_camellia256_encrypt(struct gcm_camellia256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_ENCRYPT(ctx, camellia256_crypt, length, dst, src); +} + +void +gcm_camellia256_decrypt(struct gcm_camellia256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + GCM_DECRYPT(ctx, camellia256_crypt, length, dst, src); +} + +void +gcm_camellia256_digest(struct gcm_camellia256_ctx *ctx, + size_t length, uint8_t *digest) +{ + GCM_DIGEST(ctx, camellia256_crypt, length, digest); +} diff --git a/gcm.c b/gcm.c new file mode 100644 index 0000000..d3e3011 --- /dev/null +++ b/gcm.c @@ -0,0 +1,515 @@ +/* gcm.c + + Galois counter mode, specified by NIST, + http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + + See also the gcm paper at + http://www.cryptobarn.com/papers/gcm-spec.pdf. + + Copyright (C) 2011, 2013 Niels Möller + Copyright (C) 2011 Katholieke Universiteit Leuven + + Contributed by Nikos Mavrogiannopoulos + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "gcm.h" + +#include "memxor.h" +#include "nettle-internal.h" +#include "macros.h" + +#define GHASH_POLYNOMIAL 0xE1UL + +static void +gcm_gf_add (union nettle_block16 *r, + const union nettle_block16 *x, const union nettle_block16 *y) +{ + r->w[0] = x->w[0] ^ y->w[0]; + r->w[1] = x->w[1] ^ y->w[1]; +#if SIZEOF_LONG == 4 + r->w[2] = x->w[2] ^ y->w[2]; + r->w[3] = x->w[3] ^ y->w[3]; +#endif +} +/* Multiplication by 010...0; a big-endian shift right. If the bit + shifted out is one, the defining polynomial is added to cancel it + out. r == x is allowed. */ +static void +gcm_gf_shift (union nettle_block16 *r, const union nettle_block16 *x) +{ + long mask; + + /* Shift uses big-endian representation. */ +#if WORDS_BIGENDIAN +# if SIZEOF_LONG == 4 + mask = - (x->w[3] & 1); + r->w[3] = (x->w[3] >> 1) | ((x->w[2] & 1) << 31); + r->w[2] = (x->w[2] >> 1) | ((x->w[1] & 1) << 31); + r->w[1] = (x->w[1] >> 1) | ((x->w[0] & 1) << 31); + r->w[0] = (x->w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 24)); +# elif SIZEOF_LONG == 8 + mask = - (x->w[1] & 1); + r->w[1] = (x->w[1] >> 1) | ((x->w[0] & 1) << 63); + r->w[0] = (x->w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56)); +# else +# error Unsupported word size. */ +#endif +#else /* ! WORDS_BIGENDIAN */ +# if SIZEOF_LONG == 4 +#define RSHIFT_WORD(x) \ + ((((x) & 0xfefefefeUL) >> 1) \ + | (((x) & 0x00010101) << 15)) + mask = - ((x->w[3] >> 24) & 1); + r->w[3] = RSHIFT_WORD(x->w[3]) | ((x->w[2] >> 17) & 0x80); + r->w[2] = RSHIFT_WORD(x->w[2]) | ((x->w[1] >> 17) & 0x80); + r->w[1] = RSHIFT_WORD(x->w[1]) | ((x->w[0] >> 17) & 0x80); + r->w[0] = RSHIFT_WORD(x->w[0]) ^ (mask & GHASH_POLYNOMIAL); +# elif SIZEOF_LONG == 8 +#define RSHIFT_WORD(x) \ + ((((x) & 0xfefefefefefefefeUL) >> 1) \ + | (((x) & 0x0001010101010101UL) << 15)) + mask = - ((x->w[1] >> 56) & 1); + r->w[1] = RSHIFT_WORD(x->w[1]) | ((x->w[0] >> 49) & 0x80); + r->w[0] = RSHIFT_WORD(x->w[0]) ^ (mask & GHASH_POLYNOMIAL); +# else +# error Unsupported word size. */ +# endif +# undef RSHIFT_WORD +#endif /* ! WORDS_BIGENDIAN */ +} + +#if GCM_TABLE_BITS == 0 +/* Sets x <- x * y mod r, using the plain bitwise algorithm from the + specification. y may be shorter than a full block, missing bytes + are assumed zero. */ +static void +gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *y) +{ + union nettle_block16 V; + union nettle_block16 Z; + unsigned i; + + memcpy(V.b, x, sizeof(V)); + memset(Z.b, 0, sizeof(Z)); + + for (i = 0; i < GCM_BLOCK_SIZE; i++) + { + uint8_t b = y->b[i]; + unsigned j; + for (j = 0; j < 8; j++, b <<= 1) + { + if (b & 0x80) + gcm_gf_add(&Z, &Z, &V); + + gcm_gf_shift(&V, &V); + } + } + memcpy (x->b, Z.b, sizeof(Z)); +} +#else /* GCM_TABLE_BITS != 0 */ + +# if WORDS_BIGENDIAN +# define W(left,right) (0x##left##right) +# else +# define W(left,right) (0x##right##left) +# endif + +# if GCM_TABLE_BITS == 4 +static const uint16_t +shift_table[0x10] = { + W(00,00),W(1c,20),W(38,40),W(24,60),W(70,80),W(6c,a0),W(48,c0),W(54,e0), + W(e1,00),W(fd,20),W(d9,40),W(c5,60),W(91,80),W(8d,a0),W(a9,c0),W(b5,e0), +}; + +static void +gcm_gf_shift_4(union nettle_block16 *x) +{ + unsigned long *w = x->w; + unsigned long reduce; + + /* Shift uses big-endian representation. */ +#if WORDS_BIGENDIAN +# if SIZEOF_LONG == 4 + reduce = shift_table[w[3] & 0xf]; + w[3] = (w[3] >> 4) | ((w[2] & 0xf) << 28); + w[2] = (w[2] >> 4) | ((w[1] & 0xf) << 28); + w[1] = (w[1] >> 4) | ((w[0] & 0xf) << 28); + w[0] = (w[0] >> 4) ^ (reduce << 16); +# elif SIZEOF_LONG == 8 + reduce = shift_table[w[1] & 0xf]; + w[1] = (w[1] >> 4) | ((w[0] & 0xf) << 60); + w[0] = (w[0] >> 4) ^ (reduce << 48); +# else +# error Unsupported word size. */ +#endif +#else /* ! WORDS_BIGENDIAN */ +# if SIZEOF_LONG == 4 +#define RSHIFT_WORD(x) \ + ((((x) & 0xf0f0f0f0UL) >> 4) \ + | (((x) & 0x000f0f0f) << 12)) + reduce = shift_table[(w[3] >> 24) & 0xf]; + w[3] = RSHIFT_WORD(w[3]) | ((w[2] >> 20) & 0xf0); + w[2] = RSHIFT_WORD(w[2]) | ((w[1] >> 20) & 0xf0); + w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 20) & 0xf0); + w[0] = RSHIFT_WORD(w[0]) ^ reduce; +# elif SIZEOF_LONG == 8 +#define RSHIFT_WORD(x) \ + ((((x) & 0xf0f0f0f0f0f0f0f0UL) >> 4) \ + | (((x) & 0x000f0f0f0f0f0f0fUL) << 12)) + reduce = shift_table[(w[1] >> 56) & 0xf]; + w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 52) & 0xf0); + w[0] = RSHIFT_WORD(w[0]) ^ reduce; +# else +# error Unsupported word size. */ +# endif +# undef RSHIFT_WORD +#endif /* ! WORDS_BIGENDIAN */ +} + +static void +gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table) +{ + union nettle_block16 Z; + unsigned i; + + memset(Z.b, 0, sizeof(Z)); + + for (i = GCM_BLOCK_SIZE; i-- > 0;) + { + uint8_t b = x->b[i]; + + gcm_gf_shift_4(&Z); + gcm_gf_add(&Z, &Z, &table[b & 0xf]); + gcm_gf_shift_4(&Z); + gcm_gf_add(&Z, &Z, &table[b >> 4]); + } + memcpy (x->b, Z.b, sizeof(Z)); +} +# elif GCM_TABLE_BITS == 8 +# if HAVE_NATIVE_gcm_hash8 + +#define gcm_hash _nettle_gcm_hash8 +void +_nettle_gcm_hash8 (const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data); +# else /* !HAVE_NATIVE_gcm_hash8 */ +static const uint16_t +shift_table[0x100] = { + W(00,00),W(01,c2),W(03,84),W(02,46),W(07,08),W(06,ca),W(04,8c),W(05,4e), + W(0e,10),W(0f,d2),W(0d,94),W(0c,56),W(09,18),W(08,da),W(0a,9c),W(0b,5e), + W(1c,20),W(1d,e2),W(1f,a4),W(1e,66),W(1b,28),W(1a,ea),W(18,ac),W(19,6e), + W(12,30),W(13,f2),W(11,b4),W(10,76),W(15,38),W(14,fa),W(16,bc),W(17,7e), + W(38,40),W(39,82),W(3b,c4),W(3a,06),W(3f,48),W(3e,8a),W(3c,cc),W(3d,0e), + W(36,50),W(37,92),W(35,d4),W(34,16),W(31,58),W(30,9a),W(32,dc),W(33,1e), + W(24,60),W(25,a2),W(27,e4),W(26,26),W(23,68),W(22,aa),W(20,ec),W(21,2e), + W(2a,70),W(2b,b2),W(29,f4),W(28,36),W(2d,78),W(2c,ba),W(2e,fc),W(2f,3e), + W(70,80),W(71,42),W(73,04),W(72,c6),W(77,88),W(76,4a),W(74,0c),W(75,ce), + W(7e,90),W(7f,52),W(7d,14),W(7c,d6),W(79,98),W(78,5a),W(7a,1c),W(7b,de), + W(6c,a0),W(6d,62),W(6f,24),W(6e,e6),W(6b,a8),W(6a,6a),W(68,2c),W(69,ee), + W(62,b0),W(63,72),W(61,34),W(60,f6),W(65,b8),W(64,7a),W(66,3c),W(67,fe), + W(48,c0),W(49,02),W(4b,44),W(4a,86),W(4f,c8),W(4e,0a),W(4c,4c),W(4d,8e), + W(46,d0),W(47,12),W(45,54),W(44,96),W(41,d8),W(40,1a),W(42,5c),W(43,9e), + W(54,e0),W(55,22),W(57,64),W(56,a6),W(53,e8),W(52,2a),W(50,6c),W(51,ae), + W(5a,f0),W(5b,32),W(59,74),W(58,b6),W(5d,f8),W(5c,3a),W(5e,7c),W(5f,be), + W(e1,00),W(e0,c2),W(e2,84),W(e3,46),W(e6,08),W(e7,ca),W(e5,8c),W(e4,4e), + W(ef,10),W(ee,d2),W(ec,94),W(ed,56),W(e8,18),W(e9,da),W(eb,9c),W(ea,5e), + W(fd,20),W(fc,e2),W(fe,a4),W(ff,66),W(fa,28),W(fb,ea),W(f9,ac),W(f8,6e), + W(f3,30),W(f2,f2),W(f0,b4),W(f1,76),W(f4,38),W(f5,fa),W(f7,bc),W(f6,7e), + W(d9,40),W(d8,82),W(da,c4),W(db,06),W(de,48),W(df,8a),W(dd,cc),W(dc,0e), + W(d7,50),W(d6,92),W(d4,d4),W(d5,16),W(d0,58),W(d1,9a),W(d3,dc),W(d2,1e), + W(c5,60),W(c4,a2),W(c6,e4),W(c7,26),W(c2,68),W(c3,aa),W(c1,ec),W(c0,2e), + W(cb,70),W(ca,b2),W(c8,f4),W(c9,36),W(cc,78),W(cd,ba),W(cf,fc),W(ce,3e), + W(91,80),W(90,42),W(92,04),W(93,c6),W(96,88),W(97,4a),W(95,0c),W(94,ce), + W(9f,90),W(9e,52),W(9c,14),W(9d,d6),W(98,98),W(99,5a),W(9b,1c),W(9a,de), + W(8d,a0),W(8c,62),W(8e,24),W(8f,e6),W(8a,a8),W(8b,6a),W(89,2c),W(88,ee), + W(83,b0),W(82,72),W(80,34),W(81,f6),W(84,b8),W(85,7a),W(87,3c),W(86,fe), + W(a9,c0),W(a8,02),W(aa,44),W(ab,86),W(ae,c8),W(af,0a),W(ad,4c),W(ac,8e), + W(a7,d0),W(a6,12),W(a4,54),W(a5,96),W(a0,d8),W(a1,1a),W(a3,5c),W(a2,9e), + W(b5,e0),W(b4,22),W(b6,64),W(b7,a6),W(b2,e8),W(b3,2a),W(b1,6c),W(b0,ae), + W(bb,f0),W(ba,32),W(b8,74),W(b9,b6),W(bc,f8),W(bd,3a),W(bf,7c),W(be,be), +}; + +static void +gcm_gf_shift_8(union nettle_block16 *x) +{ + unsigned long *w = x->w; + unsigned long reduce; + + /* Shift uses big-endian representation. */ +#if WORDS_BIGENDIAN +# if SIZEOF_LONG == 4 + reduce = shift_table[w[3] & 0xff]; + w[3] = (w[3] >> 8) | ((w[2] & 0xff) << 24); + w[2] = (w[2] >> 8) | ((w[1] & 0xff) << 24); + w[1] = (w[1] >> 8) | ((w[0] & 0xff) << 24); + w[0] = (w[0] >> 8) ^ (reduce << 16); +# elif SIZEOF_LONG == 8 + reduce = shift_table[w[1] & 0xff]; + w[1] = (w[1] >> 8) | ((w[0] & 0xff) << 56); + w[0] = (w[0] >> 8) ^ (reduce << 48); +# else +# error Unsupported word size. */ +#endif +#else /* ! WORDS_BIGENDIAN */ +# if SIZEOF_LONG == 4 + reduce = shift_table[(w[3] >> 24) & 0xff]; + w[3] = (w[3] << 8) | (w[2] >> 24); + w[2] = (w[2] << 8) | (w[1] >> 24); + w[1] = (w[1] << 8) | (w[0] >> 24); + w[0] = (w[0] << 8) ^ reduce; +# elif SIZEOF_LONG == 8 + reduce = shift_table[(w[1] >> 56) & 0xff]; + w[1] = (w[1] << 8) | (w[0] >> 56); + w[0] = (w[0] << 8) ^ reduce; +# else +# error Unsupported word size. */ +# endif +#endif /* ! WORDS_BIGENDIAN */ +} + +static void +gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table) +{ + union nettle_block16 Z; + unsigned i; + + memcpy(Z.b, table[x->b[GCM_BLOCK_SIZE-1]].b, GCM_BLOCK_SIZE); + + for (i = GCM_BLOCK_SIZE-2; i > 0; i--) + { + gcm_gf_shift_8(&Z); + gcm_gf_add(&Z, &Z, &table[x->b[i]]); + } + gcm_gf_shift_8(&Z); + gcm_gf_add(x, &Z, &table[x->b[0]]); +} +# endif /* ! HAVE_NATIVE_gcm_hash8 */ +# else /* GCM_TABLE_BITS != 8 */ +# error Unsupported table size. +# endif /* GCM_TABLE_BITS != 8 */ + +#undef W + +#endif /* GCM_TABLE_BITS */ + +/* Increment the rightmost 32 bits. */ +#define INC32(block) INCREMENT(4, (block.b) + GCM_BLOCK_SIZE - 4) + +/* Initialization of GCM. + * @ctx: The context of GCM + * @cipher: The context of the underlying block cipher + * @f: The underlying cipher encryption function + */ +void +gcm_set_key(struct gcm_key *key, + const void *cipher, nettle_cipher_func *f) +{ + /* Middle element if GCM_TABLE_BITS > 0, otherwise the first + element */ + unsigned i = (1<h[0].b, 0, GCM_BLOCK_SIZE); + f (cipher, GCM_BLOCK_SIZE, key->h[i].b, key->h[0].b); + +#if GCM_TABLE_BITS + /* Algorithm 3 from the gcm paper. First do powers of two, then do + the rest by adding. */ + while (i /= 2) + gcm_gf_shift(&key->h[i], &key->h[2*i]); + for (i = 2; i < 1<h[i+j], &key->h[i],&key->h[j]); + } +#endif +} + +#ifndef gcm_hash +static void +gcm_hash(const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data) +{ + for (; length >= GCM_BLOCK_SIZE; + length -= GCM_BLOCK_SIZE, data += GCM_BLOCK_SIZE) + { + memxor (x->b, data, GCM_BLOCK_SIZE); + gcm_gf_mul (x, key->h); + } + if (length > 0) + { + memxor (x->b, data, length); + gcm_gf_mul (x, key->h); + } +} +#endif /* !gcm_hash */ + +static void +gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x, + uint64_t auth_size, uint64_t data_size) +{ + uint8_t buffer[GCM_BLOCK_SIZE]; + + data_size *= 8; + auth_size *= 8; + + WRITE_UINT64 (buffer, auth_size); + WRITE_UINT64 (buffer + 8, data_size); + + gcm_hash(key, x, GCM_BLOCK_SIZE, buffer); +} + +/* NOTE: The key is needed only if length != GCM_IV_SIZE */ +void +gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key, + size_t length, const uint8_t *iv) +{ + if (length == GCM_IV_SIZE) + { + memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4); + ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0; + ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0; + ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0; + ctx->iv.b[GCM_BLOCK_SIZE - 1] = 1; + } + else + { + memset(ctx->iv.b, 0, GCM_BLOCK_SIZE); + gcm_hash(key, &ctx->iv, length, iv); + gcm_hash_sizes(key, &ctx->iv, 0, length); + } + + memcpy (ctx->ctr.b, ctx->iv.b, GCM_BLOCK_SIZE); + INC32 (ctx->ctr); + + /* Reset the rest of the message-dependent state. */ + memset(ctx->x.b, 0, sizeof(ctx->x)); + ctx->auth_size = ctx->data_size = 0; +} + +void +gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key, + size_t length, const uint8_t *data) +{ + assert(ctx->auth_size % GCM_BLOCK_SIZE == 0); + assert(ctx->data_size == 0); + + gcm_hash(key, &ctx->x, length, data); + + ctx->auth_size += length; +} + +static void +gcm_crypt(struct gcm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + uint8_t buffer[GCM_BLOCK_SIZE]; + + if (src != dst) + { + for (; length >= GCM_BLOCK_SIZE; + (length -= GCM_BLOCK_SIZE, + src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE)) + { + f (cipher, GCM_BLOCK_SIZE, dst, ctx->ctr.b); + memxor (dst, src, GCM_BLOCK_SIZE); + INC32 (ctx->ctr); + } + } + else + { + for (; length >= GCM_BLOCK_SIZE; + (length -= GCM_BLOCK_SIZE, + src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE)) + { + f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b); + memxor3 (dst, src, buffer, GCM_BLOCK_SIZE); + INC32 (ctx->ctr); + } + } + if (length > 0) + { + /* A final partial block */ + f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b); + memxor3 (dst, src, buffer, length); + INC32 (ctx->ctr); + } +} + +void +gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + assert(ctx->data_size % GCM_BLOCK_SIZE == 0); + + gcm_crypt(ctx, cipher, f, length, dst, src); + gcm_hash(key, &ctx->x, length, dst); + + ctx->data_size += length; +} + +void +gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src) +{ + assert(ctx->data_size % GCM_BLOCK_SIZE == 0); + + gcm_hash(key, &ctx->x, length, src); + gcm_crypt(ctx, cipher, f, length, dst, src); + + ctx->data_size += length; +} + +void +gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest) +{ + uint8_t buffer[GCM_BLOCK_SIZE]; + + assert (length <= GCM_BLOCK_SIZE); + + gcm_hash_sizes(key, &ctx->x, ctx->auth_size, ctx->data_size); + + f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b); + memxor3 (digest, ctx->x.b, buffer, length); + + return; +} diff --git a/gcm.h b/gcm.h new file mode 100644 index 0000000..766019a --- /dev/null +++ b/gcm.h @@ -0,0 +1,327 @@ +/* gcm.h + + Galois counter mode, specified by NIST, + http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + + Copyright (C) 2011 Katholieke Universiteit Leuven + Copyright (C) 2011, 2014 Niels Möller + + Contributed by Nikos Mavrogiannopoulos + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_GCM_H_INCLUDED +#define NETTLE_GCM_H_INCLUDED + +#include "aes.h" +#include "camellia.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define gcm_set_key nettle_gcm_set_key +#define gcm_set_iv nettle_gcm_set_iv +#define gcm_update nettle_gcm_update +#define gcm_encrypt nettle_gcm_encrypt +#define gcm_decrypt nettle_gcm_decrypt +#define gcm_digest nettle_gcm_digest + +#define gcm_aes128_set_key nettle_gcm_aes128_set_key +#define gcm_aes128_set_iv nettle_gcm_aes128_set_iv +#define gcm_aes128_update nettle_gcm_aes128_update +#define gcm_aes128_encrypt nettle_gcm_aes128_encrypt +#define gcm_aes128_decrypt nettle_gcm_aes128_decrypt +#define gcm_aes128_digest nettle_gcm_aes128_digest + +#define gcm_aes192_set_key nettle_gcm_aes192_set_key +#define gcm_aes192_set_iv nettle_gcm_aes192_set_iv +#define gcm_aes192_update nettle_gcm_aes192_update +#define gcm_aes192_encrypt nettle_gcm_aes192_encrypt +#define gcm_aes192_decrypt nettle_gcm_aes192_decrypt +#define gcm_aes192_digest nettle_gcm_aes192_digest + +#define gcm_aes256_set_key nettle_gcm_aes256_set_key +#define gcm_aes256_set_iv nettle_gcm_aes256_set_iv +#define gcm_aes256_update nettle_gcm_aes256_update +#define gcm_aes256_encrypt nettle_gcm_aes256_encrypt +#define gcm_aes256_decrypt nettle_gcm_aes256_decrypt +#define gcm_aes256_digest nettle_gcm_aes256_digest + +#define gcm_aes_set_key nettle_gcm_aes_set_key +#define gcm_aes_set_iv nettle_gcm_aes_set_iv +#define gcm_aes_update nettle_gcm_aes_update +#define gcm_aes_encrypt nettle_gcm_aes_encrypt +#define gcm_aes_decrypt nettle_gcm_aes_decrypt +#define gcm_aes_digest nettle_gcm_aes_digest + +#define gcm_camellia128_set_key nettle_gcm_camellia128_set_key +#define gcm_camellia128_set_iv nettle_gcm_camellia128_set_iv +#define gcm_camellia128_update nettle_gcm_camellia128_update +#define gcm_camellia128_encrypt nettle_gcm_camellia128_encrypt +#define gcm_camellia128_decrypt nettle_gcm_camellia128_decrypt +#define gcm_camellia128_digest nettle_gcm_camellia128_digest + +#define gcm_camellia256_set_key nettle_gcm_camellia256_set_key +#define gcm_camellia256_set_iv nettle_gcm_camellia256_set_iv +#define gcm_camellia256_update nettle_gcm_camellia256_update +#define gcm_camellia256_encrypt nettle_gcm_camellia256_encrypt +#define gcm_camellia256_decrypt nettle_gcm_camellia256_decrypt +#define gcm_camellia256_digest nettle_gcm_camellia256_digest + +#define GCM_BLOCK_SIZE 16 +#define GCM_IV_SIZE (GCM_BLOCK_SIZE - 4) +#define GCM_DIGEST_SIZE 16 +#define GCM_TABLE_BITS 8 + +/* Hashing subkey */ +struct gcm_key +{ + union nettle_block16 h[1 << GCM_TABLE_BITS]; +}; + +/* Per-message state, depending on the iv */ +struct gcm_ctx { + /* Original counter block */ + union nettle_block16 iv; + /* Updated for each block. */ + union nettle_block16 ctr; + /* Hashing state */ + union nettle_block16 x; + uint64_t auth_size; + uint64_t data_size; +}; + +void +gcm_set_key(struct gcm_key *key, + const void *cipher, nettle_cipher_func *f); + +void +gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key, + size_t length, const uint8_t *iv); + +void +gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key, + size_t length, const uint8_t *data); + +void +gcm_encrypt(struct gcm_ctx *ctx, const struct gcm_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest); + +/* Convenience macrology (not sure how useful it is) */ +/* All-in-one context, with hash subkey, message state, and cipher. */ +#define GCM_CTX(type) \ + { struct gcm_key key; struct gcm_ctx gcm; type cipher; } + +/* NOTE: Avoid using NULL, as we don't include anything defining it. */ +#define GCM_SET_KEY(ctx, set_key, encrypt, gcm_key) \ + do { \ + (set_key)(&(ctx)->cipher, (gcm_key)); \ + if (0) (encrypt)(&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0); \ + gcm_set_key(&(ctx)->key, &(ctx)->cipher, \ + (nettle_cipher_func *) (encrypt)); \ + } while (0) + +#define GCM_SET_IV(ctx, length, data) \ + gcm_set_iv(&(ctx)->gcm, &(ctx)->key, (length), (data)) + +#define GCM_UPDATE(ctx, length, data) \ + gcm_update(&(ctx)->gcm, &(ctx)->key, (length), (data)) + +#define GCM_ENCRYPT(ctx, encrypt, length, dst, src) \ + (0 ? (encrypt)(&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : gcm_encrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, \ + (nettle_cipher_func *) (encrypt), \ + (length), (dst), (src))) + +#define GCM_DECRYPT(ctx, encrypt, length, dst, src) \ + (0 ? (encrypt)(&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : gcm_decrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, \ + (nettle_cipher_func *) (encrypt), \ + (length), (dst), (src))) + +#define GCM_DIGEST(ctx, encrypt, length, digest) \ + (0 ? (encrypt)(&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : gcm_digest(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, \ + (nettle_cipher_func *) (encrypt), \ + (length), (digest))) + +struct gcm_aes128_ctx GCM_CTX(struct aes128_ctx); + +void +gcm_aes128_set_key(struct gcm_aes128_ctx *ctx, const uint8_t *key); + +/* FIXME: Define _update and _set_iv as some kind of aliaes, + there's nothing aes-specific. */ +void +gcm_aes128_update (struct gcm_aes128_ctx *ctx, + size_t length, const uint8_t *data); +void +gcm_aes128_set_iv (struct gcm_aes128_ctx *ctx, + size_t length, const uint8_t *iv); + +void +gcm_aes128_encrypt(struct gcm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes128_decrypt(struct gcm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes128_digest(struct gcm_aes128_ctx *ctx, + size_t length, uint8_t *digest); + +struct gcm_aes192_ctx GCM_CTX(struct aes192_ctx); + +void +gcm_aes192_set_key(struct gcm_aes192_ctx *ctx, const uint8_t *key); + +void +gcm_aes192_update (struct gcm_aes192_ctx *ctx, + size_t length, const uint8_t *data); +void +gcm_aes192_set_iv (struct gcm_aes192_ctx *ctx, + size_t length, const uint8_t *iv); + +void +gcm_aes192_encrypt(struct gcm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes192_decrypt(struct gcm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes192_digest(struct gcm_aes192_ctx *ctx, + size_t length, uint8_t *digest); + +struct gcm_aes256_ctx GCM_CTX(struct aes256_ctx); + +void +gcm_aes256_set_key(struct gcm_aes256_ctx *ctx, const uint8_t *key); + +void +gcm_aes256_update (struct gcm_aes256_ctx *ctx, + size_t length, const uint8_t *data); +void +gcm_aes256_set_iv (struct gcm_aes256_ctx *ctx, + size_t length, const uint8_t *iv); + +void +gcm_aes256_encrypt(struct gcm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes256_decrypt(struct gcm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes256_digest(struct gcm_aes256_ctx *ctx, + size_t length, uint8_t *digest); + +/* Old aes interface, for backwards compatibility */ +struct gcm_aes_ctx GCM_CTX(struct aes_ctx); + +void +gcm_aes_set_key(struct gcm_aes_ctx *ctx, + size_t length, const uint8_t *key); + +void +gcm_aes_set_iv(struct gcm_aes_ctx *ctx, + size_t length, const uint8_t *iv); + +void +gcm_aes_update(struct gcm_aes_ctx *ctx, + size_t length, const uint8_t *data); + +void +gcm_aes_encrypt(struct gcm_aes_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes_decrypt(struct gcm_aes_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +gcm_aes_digest(struct gcm_aes_ctx *ctx, size_t length, uint8_t *digest); + + +struct gcm_camellia128_ctx GCM_CTX(struct camellia128_ctx); + +void gcm_camellia128_set_key(struct gcm_camellia128_ctx *ctx, + const uint8_t *key); +void gcm_camellia128_set_iv(struct gcm_camellia128_ctx *ctx, + size_t length, const uint8_t *iv); +void gcm_camellia128_update(struct gcm_camellia128_ctx *ctx, + size_t length, const uint8_t *data); +void gcm_camellia128_encrypt(struct gcm_camellia128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); +void gcm_camellia128_decrypt(struct gcm_camellia128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); +void gcm_camellia128_digest(struct gcm_camellia128_ctx *ctx, + size_t length, uint8_t *digest); + + +struct gcm_camellia256_ctx GCM_CTX(struct camellia256_ctx); + +void gcm_camellia256_set_key(struct gcm_camellia256_ctx *ctx, + const uint8_t *key); +void gcm_camellia256_set_iv(struct gcm_camellia256_ctx *ctx, + size_t length, const uint8_t *iv); +void gcm_camellia256_update(struct gcm_camellia256_ctx *ctx, + size_t length, const uint8_t *data); +void gcm_camellia256_encrypt(struct gcm_camellia256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); +void gcm_camellia256_decrypt(struct gcm_camellia256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); +void gcm_camellia256_digest(struct gcm_camellia256_ctx *ctx, + size_t length, uint8_t *digest); + + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_GCM_H_INCLUDED */ diff --git a/gcmdata.c b/gcmdata.c new file mode 100644 index 0000000..2d57b46 --- /dev/null +++ b/gcmdata.c @@ -0,0 +1,84 @@ +/* gcmdata.c + + Galois counter mode, specified by NIST, + http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + + Generation of fixed multiplication tables. + + Copyright (C) 2011 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#include +#include + +#define GHASH_POLYNOMIAL 0xE1 + + +/* When x is shifted out over the block edge, add multiples of the + defining polynomial to eliminate each bit. */ +static unsigned +reduce(unsigned x) +{ + unsigned p = GHASH_POLYNOMIAL << 1; + unsigned y = 0; + for (; x; x >>= 1, p <<= 1) + if (x & 1) + y ^= p; + return y; +} + +int +main(int argc, char **argv) +{ + unsigned i; + printf("4-bit table:\n"); + + for (i = 0; i<16; i++) + { + unsigned x; + if (i && !(i%8)) + printf("\n"); + + x = reduce(i << 4); + printf("W(%02x,%02x),", x >> 8, x & 0xff); + } + printf("\n\n"); + printf("8-bit table:\n"); + for (i = 0; i<256; i++) + { + unsigned x; + if (i && !(i%8)) + printf("\n"); + + x = reduce(i); + printf("W(%02x,%02x),", x >> 8, x & 0xff); + } + printf("\n"); + return EXIT_SUCCESS; +} diff --git a/getopt.c b/getopt.c new file mode 100644 index 0000000..6be0aaf --- /dev/null +++ b/getopt.c @@ -0,0 +1,1277 @@ +/* Getopt for GNU. + NOTE: getopt is 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-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* 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 + +#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. */ + +#include + +#ifdef VMS +# include +#endif + +#ifdef _LIBC +# include +#else +/* The glibc version includes "gettext.h" here, but Nettle currently doesn't + have that. */ +# define _(msgid) msgid +#endif + +#if defined _LIBC +# include +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#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" +#include "getopt_int.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; + +/* 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 = '?'; + +/* Keep a global copy of all internal members of getopt_data. */ + +static struct _getopt_data getopt_data; + + +#ifndef __GNU_LIBRARY__ + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +#endif /* not __GNU_LIBRARY__ */ + +#ifdef _LIBC +/* Stored original parameters. + 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). */ +extern int __libc_argc; +extern char **__libc_argv; + +/* 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; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (d->__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. */ + +static void +exchange (char **argv, struct _getopt_data *d) +{ + int bottom = d->__first_nonopt; + int middle = d->__last_nonopt; + int top = d->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 (d->__nonoption_flags_len > 0 && top >= d->__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) + d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + d->__nonoption_flags_max_len), + '\0', top + 1 - d->__nonoption_flags_max_len); + d->__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; + 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; + 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. */ + + d->__first_nonopt += (d->optind - d->__last_nonopt); + d->__last_nonopt = d->optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (int argc, char *const *argv, const char *optstring, + struct _getopt_data *d, int posixly_correct) +{ + /* 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. */ + + d->__first_nonopt = d->__last_nonopt = d->optind; + + d->__nextchar = NULL; + + d->__posixly_correct = posixly_correct | !!getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + d->__ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + d->__ordering = REQUIRE_ORDER; + ++optstring; + } + else if (d->__posixly_correct) + d->__ordering = REQUIRE_ORDER; + else + d->__ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (!d->__posixly_correct + && argc == __libc_argc && argv == __libc_argv) + { + if (d->__nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + d->__nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = d->__nonoption_flags_max_len = strlen (orig_str); + if (d->__nonoption_flags_max_len < argc) + d->__nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (d->__nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + d->__nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', d->__nonoption_flags_max_len - len); + } + } + d->__nonoption_flags_len = d->__nonoption_flags_max_len; + } + else + d->__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_r (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d, int posixly_correct) +{ + int print_errors = d->opterr; + + if (argc < 1) + return -1; + + d->optarg = NULL; + + if (d->optind == 0 || !d->__initialized) + { + if (d->optind == 0) + d->optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring, d, + posixly_correct); + d->__initialized = 1; + } + else if (optstring[0] == '-' || optstring[0] == '+') + optstring++; + if (optstring[0] == ':') + print_errors = 0; + + /* 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[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ + || (d->optind < d->__nonoption_flags_len \ + && __getopt_nonoption_flags[d->optind] == '1')) +#else +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') +#endif + + if (d->__nextchar == NULL || *d->__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 (d->__last_nonopt > d->optind) + d->__last_nonopt = d->optind; + if (d->__first_nonopt > d->optind) + d->__first_nonopt = d->optind; + + if (d->__ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__last_nonopt != d->optind) + d->__first_nonopt = d->optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (d->optind < argc && NONOPTION_P) + d->optind++; + d->__last_nonopt = d->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 (d->optind != argc && !strcmp (argv[d->optind], "--")) + { + d->optind++; + + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__first_nonopt == d->__last_nonopt) + d->__first_nonopt = d->optind; + d->__last_nonopt = argc; + + d->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 (d->optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (d->__first_nonopt != d->__last_nonopt) + d->optind = d->__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 (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + d->__nextchar = (argv[d->optind] + 1 + + (longopts != NULL && argv[d->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[d->optind][1] == '-' + || (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))))) + { + char *nameend; + unsigned int namelen; + const struct option *p; + const struct option *pfound = NULL; + struct option_list + { + const struct option *p; + struct option_list *next; + } *ambig_list = NULL; + int exact = 0; + int indfound = -1; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + namelen = nameend - d->__nextchar; + + /* 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, d->__nextchar, namelen)) + { + if (namelen == (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. */ + struct option_list *newp = alloca (sizeof (*newp)); + newp->p = p; + newp->next = ambig_list; + ambig_list = newp; + } + } + + if (ambig_list != NULL && !exact) + { + if (print_errors) + { + struct option_list first; + first.p = pfound; + first.next = ambig_list; + ambig_list = &first; + +#if defined _LIBC + char *buf = NULL; + size_t buflen = 0; + + FILE *fp = open_memstream (&buf, &buflen); + if (fp != NULL) + { + fprintf (fp, + _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); + + do + { + fprintf (fp, " '--%s'", ambig_list->p->name); + ambig_list = ambig_list->next; + } + while (ambig_list != NULL); + + fputc_unlocked ('\n', fp); + + if (__builtin_expect (fclose (fp) != EOF, 1)) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } + } +#else + fprintf (stderr, + _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); + do + { + fprintf (stderr, " '--%s'", ambig_list->p->name); + ambig_list = ambig_list->next; + } + while (ambig_list != NULL); + + fputc ('\n', stderr); +#endif + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + d->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) + d->optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC + char *buf; + int n; +#endif + + if (argv[d->optind - 1][1] == '-') + { + /* --option */ +#if defined _LIBC + n = __asprintf (&buf, _("\ +%s: option '--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option '--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC + n = __asprintf (&buf, _("\ +%s: option '%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option '%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#endif + } + +#if defined _LIBC + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + + d->__nextchar += strlen (d->__nextchar); + + d->optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { +#if defined _LIBC + char *buf; + + if (__asprintf (&buf, _("\ +%s: option '--%s' requires an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option '--%s' requires an argument\n"), + argv[0], pfound->name); +#endif + } + d->__nextchar += strlen (d->__nextchar); + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->__nextchar += strlen (d->__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[d->optind][1] == '-' + || strchr (optstring, *d->__nextchar) == NULL) + { + if (print_errors) + { +#if defined _LIBC + char *buf; + int n; +#endif + + if (argv[d->optind][1] == '-') + { + /* --option */ +#if defined _LIBC + n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); +#endif + } + else + { + /* +option or -option */ +#if defined _LIBC + n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#endif + } + +#if defined _LIBC + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + d->__nextchar = (char *) ""; + d->optind++; + d->optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *d->__nextchar++; + char *temp = strchr (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*d->__nextchar == '\0') + ++d->optind; + + if (temp == NULL || c == ':' || c == ';') + { + if (print_errors) + { +#if defined _LIBC + char *buf; + int n; +#endif + +#if defined _LIBC + n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); +#endif + +#if defined _LIBC + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + d->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; + + if (longopts == NULL) + goto no_longs; + + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { +#if defined _LIBC + char *buf; + + if (__asprintf (&buf, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `d->optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (d->__nextchar = nameend = d->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, d->__nextchar, nameend - d->__nextchar)) + { + if ((unsigned int) (nameend - d->__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 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) + { +#if defined _LIBC + char *buf; + + if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), + argv[0], d->optarg) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), + argv[0], d->optarg); +#endif + } + d->__nextchar += strlen (d->__nextchar); + d->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) + d->optarg = nameend + 1; + else + { + if (print_errors) + { +#if defined _LIBC + char *buf; + + if (__asprintf (&buf, _("\ +%s: option '-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option '-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + d->__nextchar += strlen (d->__nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { +#if defined _LIBC + char *buf; + + if (__asprintf (&buf, _("\ +%s: option '-W %s' requires an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option '-W %s' requires an argument\n"), + argv[0], pfound->name); +#endif + } + d->__nextchar += strlen (d->__nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + else + d->optarg = NULL; + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + no_longs: + d->__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 (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { +#if defined _LIBC + char *buf; + + if (__asprintf (&buf, _("\ +%s: option requires an argument -- '%c'\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } + } + return c; + } +} + +int +_getopt_internal (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, int long_only, + int posixly_correct) +{ + int result; + + getopt_data.optind = optind; + getopt_data.opterr = opterr; + + result = _getopt_internal_r (argc, argv, optstring, longopts, + longind, long_only, &getopt_data, + posixly_correct); + + optind = getopt_data.optind; + optarg = getopt_data.optarg; + optopt = getopt_data.optopt; + + return result; +} + +int +getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0, 0); +} + +#ifdef _LIBC +int +__posix_getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0, 1); +} +#endif + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (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/getopt.h b/getopt.h new file mode 100644 index 0000000..da1a01f --- /dev/null +++ b/getopt.h @@ -0,0 +1,191 @@ +/* Declarations for getopt. + Copyright (C) 1989-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#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 + +#ifndef __THROW +# ifndef __GNUC_PREREQ +# define __GNUC_PREREQ(maj, min) (0) +# endif +# if defined __cplusplus && __GNUC_PREREQ (2,8) +# define __THROW throw () +# else +# define __THROW +# endif +#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 +{ + const char *name; + /* 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'. */ + +#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) + __THROW; + +# if defined __need_getopt && defined __USE_POSIX2 \ + && !defined __USE_POSIX_IMPLICITLY && !defined __USE_GNU +/* The GNU getopt has more functionality than the standard version. The + additional functionality can be disable at runtime. This redirection + helps to also do this at runtime. */ +# ifdef __REDIRECT + extern int __REDIRECT_NTH (getopt, (int ___argc, char *const *___argv, + const char *__shortopts), + __posix_getopt); +# else +extern int __posix_getopt (int ___argc, char *const *___argv, + const char *__shortopts) __THROW; +# define getopt __posix_getopt +# endif +# endif +#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) + __THROW; +extern int getopt_long_only (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW; + +#endif + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/getopt1.c b/getopt1.c new file mode 100644 index 0000000..75d6b9c --- /dev/null +++ b/getopt1.c @@ -0,0 +1,190 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef _LIBC +# include +#else +# include "getopt.h" +#endif +#include "getopt_int.h" + +#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 (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, 0); +} + +int +_getopt_long_r (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index, + struct _getopt_data *d) +{ + return _getopt_internal_r (argc, argv, options, long_options, opt_index, + 0, d, 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 (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, 0); +} + +int +_getopt_long_only_r (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index, + struct _getopt_data *d) +{ + return _getopt_internal_r (argc, argv, options, long_options, opt_index, + 1, d, 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (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/getopt_int.h b/getopt_int.h new file mode 100644 index 0000000..d255c8e --- /dev/null +++ b/getopt_int.h @@ -0,0 +1,129 @@ +/* Internal declarations for getopt. + Copyright (C) 1989-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _GETOPT_INT_H +#define _GETOPT_INT_H 1 + +extern int _getopt_internal (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, int posixly_correct); + + +/* Reentrant versions which can handle parsing multiple argument + vectors at the same time. */ + +/* Data type for reentrant functions. */ +struct _getopt_data +{ + /* These have exactly the same meaning as the corresponding global + variables, except that they are used for the reentrant + versions of getopt. */ + int optind; + int opterr; + int optopt; + char *optarg; + + /* Internal members. */ + + /* True if the internal members have been initialized. */ + int __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. */ + char *__nextchar; + + /* 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. */ + + enum + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + } __ordering; + + /* If the POSIXLY_CORRECT environment variable is set. */ + int __posixly_correct; + + + /* 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. */ + + int __first_nonopt; + int __last_nonopt; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + int __nonoption_flags_max_len; + int __nonoption_flags_len; +# endif +}; + +/* The initializer is necessary to set OPTIND and OPTERR to their + default values and to clear the initialization flag. */ +#define _GETOPT_DATA_INITIALIZER { 1, 1 } + +extern int _getopt_internal_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, struct _getopt_data *__data, + int posixly_correct); + +extern int _getopt_long_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + struct _getopt_data *__data); + +extern int _getopt_long_only_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, + int *__longind, + struct _getopt_data *__data); + +#endif /* getopt_int.h */ diff --git a/gmp-glue.c b/gmp-glue.c new file mode 100644 index 0000000..805b50c --- /dev/null +++ b/gmp-glue.c @@ -0,0 +1,357 @@ +/* gmp-glue.c + + Copyright (C) 2013 Niels Möller + Copyright (C) 2013 Red Hat + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "gmp-glue.h" + +#if !GMP_HAVE_mpz_limbs_read + +/* This implementation tries to make a minimal use of GMP internals. + We access and _mp_size and _mp_d, but not _mp_alloc. */ + +/* Use macros compatible with gmp-impl.h. */ +#define ABS(x) ((x) >= 0 ? (x) : -(x)) +#define PTR(x) ((x)->_mp_d) +#define SIZ(x) ((x)->_mp_size) +#define ABSIZ(x) ABS (SIZ (x)) + +#define MPN_NORMALIZE(xp, xn) do { \ + while ( (xn) > 0 && (xp)[xn-1] == 0) \ + (xn)--; \ + } while (0) + +/* NOTE: Makes an unnecessary realloc if allocation is already large + enough, but looking at _mp_alloc may break in future GMP + versions. */ +#define MPZ_REALLOC(x, n) \ + (ABSIZ(x) >= (n) ? PTR(x) : (_mpz_realloc ((x),(n)), PTR (x))) + +#define MPZ_NEWALLOC MPZ_REALLOC + +/* Read access to mpz numbers. */ + +/* Return limb pointer, for read-only operations. Use mpz_size to get + the number of limbs. */ +const mp_limb_t * +mpz_limbs_read (mpz_srcptr x) +{ + return PTR (x); +} + +/* Write access to mpz numbers. */ + +/* Get a limb pointer for writing, previous contents may be + destroyed. */ +mp_limb_t * +mpz_limbs_write (mpz_ptr x, mp_size_t n) +{ + assert (n > 0); + return MPZ_NEWALLOC (x, n); +} + +/* Get a limb pointer for writing, previous contents is intact. */ +mp_limb_t * +mpz_limbs_modify (mpz_ptr x, mp_size_t n) +{ + assert (n > 0); + return MPZ_REALLOC (x, n); +} + +void +mpz_limbs_finish (mpz_ptr x, mp_size_t n) +{ + assert (n >= 0); + MPN_NORMALIZE (PTR(x), n); + + SIZ (x) = n; +} + +/* Needs some ugly casts. */ +mpz_srcptr +mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs) +{ + mp_size_t xn = ABS (xs); + + MPN_NORMALIZE (xp, xn); + + x->_mp_size = xs < 0 ? -xn : xn; + x->_mp_alloc = 0; + x->_mp_d = (mp_limb_t *) xp; + return x; +} +#endif /* !GMP_HAVE_mpz_limbs_read */ + +void +cnd_swap (mp_limb_t cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n) +{ + mp_limb_t mask = - (mp_limb_t) (cnd != 0); + mp_size_t i; + for (i = 0; i < n; i++) + { + mp_limb_t a, b, t; + a = ap[i]; + b = bp[i]; + t = (a ^ b) & mask; + ap[i] = a ^ t; + bp[i] = b ^ t; + } +} + +/* Additional convenience functions. */ + +int +mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn) +{ + mp_size_t an = mpz_size (a); + assert (mpz_sgn (a) >= 0); + assert (bn >= 0); + + if (an < bn) + return -1; + if (an > bn) + return 1; + if (an == 0) + return 0; + + return mpn_cmp (mpz_limbs_read(a), bp, an); +} + +/* Get a pointer to an n limb area, for read-only operation. n must be + greater or equal to the current size, and the mpz is zero-padded if + needed. */ +const mp_limb_t * +mpz_limbs_read_n (mpz_ptr x, mp_size_t n) +{ + mp_size_t xn = mpz_size (x); + mp_ptr xp; + + assert (xn <= n); + + xp = mpz_limbs_modify (x, n); + + if (xn < n) + mpn_zero (xp + xn, n - xn); + + return xp; +} + +void +mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n) +{ + mp_size_t xn = mpz_size (x); + + assert (xn <= n); + mpn_copyi (xp, mpz_limbs_read (x), xn); + if (xn < n) + mpn_zero (xp + xn, n - xn); +} + +void +mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn) +{ + mpn_copyi (mpz_limbs_write (r, xn), xp, xn); + mpz_limbs_finish (r, xn); +} + +void +mpn_set_base256 (mp_limb_t *rp, mp_size_t rn, + const uint8_t *xp, size_t xn) +{ + size_t xi; + mp_limb_t out; + unsigned bits; + for (xi = xn, out = bits = 0; xi > 0 && rn > 0; ) + { + mp_limb_t in = xp[--xi]; + out |= (in << bits) & GMP_NUMB_MASK; + bits += 8; + if (bits >= GMP_NUMB_BITS) + { + *rp++ = out; + rn--; + + bits -= GMP_NUMB_BITS; + out = in >> (8 - bits); + } + } + if (rn > 0) + { + *rp++ = out; + if (--rn > 0) + mpn_zero (rp, rn); + } +} + +void +mpn_set_base256_le (mp_limb_t *rp, mp_size_t rn, + const uint8_t *xp, size_t xn) +{ + size_t xi; + mp_limb_t out; + unsigned bits; + for (xi = 0, out = bits = 0; xi < xn && rn > 0; ) + { + mp_limb_t in = xp[xi++]; + out |= (in << bits) & GMP_NUMB_MASK; + bits += 8; + if (bits >= GMP_NUMB_BITS) + { + *rp++ = out; + rn--; + + bits -= GMP_NUMB_BITS; + out = in >> (8 - bits); + } + } + if (rn > 0) + { + *rp++ = out; + if (--rn > 0) + mpn_zero (rp, rn); + } +} + +void +mpn_get_base256 (uint8_t *rp, size_t rn, + const mp_limb_t *xp, mp_size_t xn) +{ + unsigned bits; + mp_limb_t in; + for (bits = in = 0; xn > 0 && rn > 0; ) + { + if (bits >= 8) + { + rp[--rn] = in; + in >>= 8; + bits -= 8; + } + else + { + uint8_t old = in; + in = *xp++; + xn--; + rp[--rn] = old | (in << bits); + in >>= (8 - bits); + bits += GMP_NUMB_BITS - 8; + } + } + while (rn > 0) + { + rp[--rn] = in; + in >>= 8; + } +} + +void +mpn_get_base256_le (uint8_t *rp, size_t rn, + const mp_limb_t *xp, mp_size_t xn) +{ + unsigned bits; + mp_limb_t in; + for (bits = in = 0; xn > 0 && rn > 0; ) + { + if (bits >= 8) + { + *rp++ = in; + rn--; + in >>= 8; + bits -= 8; + } + else + { + uint8_t old = in; + in = *xp++; + xn--; + *rp++ = old | (in << bits); + rn--; + in >>= (8 - bits); + bits += GMP_NUMB_BITS - 8; + } + } + while (rn > 0) + { + *rp++ = in; + rn--; + in >>= 8; + } +} + +mp_limb_t * +gmp_alloc_limbs (mp_size_t n) +{ + + void *(*alloc_func)(size_t); + + assert (n > 0); + + mp_get_memory_functions (&alloc_func, NULL, NULL); + return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t)); +} + +void +gmp_free_limbs (mp_limb_t *p, mp_size_t n) +{ + void (*free_func)(void *, size_t); + assert (n > 0); + assert (p != 0); + mp_get_memory_functions (NULL, NULL, &free_func); + + free_func (p, (size_t) n * sizeof(mp_limb_t)); +} + +void * +gmp_alloc(size_t n) +{ + void *(*alloc_func)(size_t); + assert (n > 0); + + mp_get_memory_functions(&alloc_func, NULL, NULL); + + return alloc_func (n); +} + +void +gmp_free(void *p, size_t n) +{ + void (*free_func)(void *, size_t); + assert (n > 0); + assert (p != 0); + mp_get_memory_functions (NULL, NULL, &free_func); + + free_func (p, (size_t) n); +} diff --git a/gmp-glue.h b/gmp-glue.h new file mode 100644 index 0000000..7f42cc2 --- /dev/null +++ b/gmp-glue.h @@ -0,0 +1,172 @@ +/* gmp-glue.h + + Copyright (C) 2013 Niels Möller + Copyright (C) 2013 Red Hat + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_GMP_GLUE_H_INCLUDED +#define NETTLE_GMP_GLUE_H_INCLUDED + +#include "bignum.h" + +#ifdef mpz_limbs_read +#define GMP_HAVE_mpz_limbs_read 1 +#else +#define GMP_HAVE_mpz_limbs_read 0 +#endif + +/* Name mangling. */ +#if !GMP_HAVE_mpz_limbs_read +#define mpz_limbs_read _nettle_mpz_limbs_read +#define mpz_limbs_write _nettle_mpz_limbs_write +#define mpz_limbs_modify _nettle_mpz_limbs_modify +#define mpz_limbs_finish _nettle_mpz_limbs_finish +#define mpz_roinit_n _nettle_mpz_roinit_n +#endif + +#define cnd_swap _nettle_cnd_swap +#define mpz_limbs_cmp _nettle_mpz_limbs_cmp +#define mpz_limbs_read_n _nettle_mpz_limbs_read_n +#define mpz_limbs_copy _nettle_mpz_limbs_copy +#define mpz_set_n _nettle_mpz_set_n +#define mpn_set_base256 _nettle_mpn_set_base256 +#define mpn_set_base256_le _nettle_mpn_set_base256_le +#define mpn_get_base256 _nettle_mpn_get_base256 +#define mpn_get_base256_le _nettle_mpn_get_base256_le +#define gmp_alloc_limbs _nettle_gmp_alloc_limbs +#define gmp_free_limbs _nettle_gmp_free_limbs +#define gmp_free _nettle_gmp_free +#define gmp_alloc _nettle_gmp_alloc + +#define TMP_GMP_DECL(name, type) type *name; \ + size_t tmp_##name##_size +#define TMP_GMP_ALLOC(name, size) do { \ + tmp_##name##_size = (size); \ + (name) = gmp_alloc(sizeof (*name) * (size)); \ + } while (0) +#define TMP_GMP_FREE(name) (gmp_free(name, tmp_##name##_size)) + + +/* Use only in-place operations, so we can fall back to addmul_1/submul_1 */ +#ifdef mpn_cnd_add_n +# define cnd_add_n(cnd, rp, ap, n) mpn_cnd_add_n ((cnd), (rp), (rp), (ap), (n)) +# define cnd_sub_n(cnd, rp, ap, n) mpn_cnd_sub_n ((cnd), (rp), (rp), (ap), (n)) +#else +# define cnd_add_n(cnd, rp, ap, n) mpn_addmul_1 ((rp), (ap), (n), (cnd) != 0) +# define cnd_sub_n(cnd, rp, ap, n) mpn_submul_1 ((rp), (ap), (n), (cnd) != 0) +#endif + +#define NETTLE_OCTET_SIZE_TO_LIMB_SIZE(n) \ + (((n) * 8 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) + +/* Some functions for interfacing between mpz and mpn code. Signs of + the mpz numbers are generally ignored. */ + +#if !GMP_HAVE_mpz_limbs_read +/* Read access to mpz numbers. */ + +/* Return limb pointer, for read-only operations. Use mpz_size to get + the number of limbs. */ +const mp_limb_t * +mpz_limbs_read (const mpz_srcptr x); + +/* Write access to mpz numbers. */ + +/* Get a limb pointer for writing, previous contents may be + destroyed. */ +mp_limb_t * +mpz_limbs_write (mpz_ptr x, mp_size_t n); + +/* Get a limb pointer for writing, previous contents is intact. */ +mp_limb_t * +mpz_limbs_modify (mpz_ptr x, mp_size_t n); + +/* Update size. */ +void +mpz_limbs_finish (mpz_ptr x, mp_size_t n); + +/* Using an mpn number as an mpz. Can be used for read-only access + only. x must not be cleared or reallocated. */ +mpz_srcptr +mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs); + +#endif /* !GMP_HAVE_mpz_limbs_read */ + +void +cnd_swap (mp_limb_t cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n); + +/* Convenience functions */ +int +mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn); + +/* Get a pointer to an n limb area, for read-only operation. n must be + greater or equal to the current size, and the mpz is zero-padded if + needed. */ +const mp_limb_t * +mpz_limbs_read_n (mpz_ptr x, mp_size_t n); + +/* Copy limbs, with zero-padding. */ +/* FIXME: Reorder arguments, on the theory that the first argument of + an _mpz_* function should be an mpz_t? Or rename to _mpz_get_limbs, + with argument order consistent with mpz_get_*. */ +void +mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n); + +void +mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn); + +/* Like mpn_set_str, but always writes rn limbs. If input is larger, + higher bits are ignored. */ +void +mpn_set_base256 (mp_limb_t *rp, mp_size_t rn, + const uint8_t *xp, size_t xn); + +void +mpn_set_base256_le (mp_limb_t *rp, mp_size_t rn, + const uint8_t *xp, size_t xn); + +void +mpn_get_base256 (uint8_t *rp, size_t rn, + const mp_limb_t *xp, mp_size_t xn); + +void +mpn_get_base256_le (uint8_t *rp, size_t rn, + const mp_limb_t *xp, mp_size_t xn); + + +mp_limb_t * +gmp_alloc_limbs (mp_size_t n); + +void +gmp_free_limbs (mp_limb_t *p, mp_size_t n); + +void *gmp_alloc(size_t n); +void gmp_free(void *p, size_t n); + +#endif /* NETTLE_GMP_GLUE_H_INCLUDED */ diff --git a/gosthash94-meta.c b/gosthash94-meta.c new file mode 100644 index 0000000..42b0556 --- /dev/null +++ b/gosthash94-meta.c @@ -0,0 +1,41 @@ +/* gosthash94-meta.c + + Copyright (C) 2012 Nikos Mavrogiannopoulos, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nettle-meta.h" + +#include "gosthash94.h" + +const struct nettle_hash nettle_gosthash94 += _NETTLE_HASH(gosthash94, GOSTHASH94); diff --git a/gosthash94.c b/gosthash94.c new file mode 100644 index 0000000..e60c9ae --- /dev/null +++ b/gosthash94.c @@ -0,0 +1,592 @@ +/* gost.c - an implementation of GOST Hash Function + * based on the Russian Standard GOST R 34.11-94. + * See also RFC 4357. + * + * Copyright: 2009-2012 Aleksey Kravchenko + * + * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Ported to nettle by Nikos Mavrogiannopoulos. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "macros.h" +#include "nettle-write.h" +#include "gosthash94.h" + +/* pre-initialized GOST lookup tables based on rotated S-Box */ +static const uint32_t gosthash94_sbox[4][256] = { + { + 0x72000, 0x75000, 0x74800, 0x71000, 0x76800, + 0x74000, 0x70000, 0x77000, 0x73000, 0x75800, + 0x70800, 0x76000, 0x73800, 0x77800, 0x72800, + 0x71800, 0x5A000, 0x5D000, 0x5C800, 0x59000, + 0x5E800, 0x5C000, 0x58000, 0x5F000, 0x5B000, + 0x5D800, 0x58800, 0x5E000, 0x5B800, 0x5F800, + 0x5A800, 0x59800, 0x22000, 0x25000, 0x24800, + 0x21000, 0x26800, 0x24000, 0x20000, 0x27000, + 0x23000, 0x25800, 0x20800, 0x26000, 0x23800, + 0x27800, 0x22800, 0x21800, 0x62000, 0x65000, + 0x64800, 0x61000, 0x66800, 0x64000, 0x60000, + 0x67000, 0x63000, 0x65800, 0x60800, 0x66000, + 0x63800, 0x67800, 0x62800, 0x61800, 0x32000, + 0x35000, 0x34800, 0x31000, 0x36800, 0x34000, + 0x30000, 0x37000, 0x33000, 0x35800, 0x30800, + 0x36000, 0x33800, 0x37800, 0x32800, 0x31800, + 0x6A000, 0x6D000, 0x6C800, 0x69000, 0x6E800, + 0x6C000, 0x68000, 0x6F000, 0x6B000, 0x6D800, + 0x68800, 0x6E000, 0x6B800, 0x6F800, 0x6A800, + 0x69800, 0x7A000, 0x7D000, 0x7C800, 0x79000, + 0x7E800, 0x7C000, 0x78000, 0x7F000, 0x7B000, + 0x7D800, 0x78800, 0x7E000, 0x7B800, 0x7F800, + 0x7A800, 0x79800, 0x52000, 0x55000, 0x54800, + 0x51000, 0x56800, 0x54000, 0x50000, 0x57000, + 0x53000, 0x55800, 0x50800, 0x56000, 0x53800, + 0x57800, 0x52800, 0x51800, 0x12000, 0x15000, + 0x14800, 0x11000, 0x16800, 0x14000, 0x10000, + 0x17000, 0x13000, 0x15800, 0x10800, 0x16000, + 0x13800, 0x17800, 0x12800, 0x11800, 0x1A000, + 0x1D000, 0x1C800, 0x19000, 0x1E800, 0x1C000, + 0x18000, 0x1F000, 0x1B000, 0x1D800, 0x18800, + 0x1E000, 0x1B800, 0x1F800, 0x1A800, 0x19800, + 0x42000, 0x45000, 0x44800, 0x41000, 0x46800, + 0x44000, 0x40000, 0x47000, 0x43000, 0x45800, + 0x40800, 0x46000, 0x43800, 0x47800, 0x42800, + 0x41800, 0xA000, 0xD000, 0xC800, 0x9000, + 0xE800, 0xC000, 0x8000, 0xF000, 0xB000, + 0xD800, 0x8800, 0xE000, 0xB800, 0xF800, + 0xA800, 0x9800, 0x2000, 0x5000, 0x4800, + 0x1000, 0x6800, 0x4000, 0x0, 0x7000, + 0x3000, 0x5800, 0x800, 0x6000, 0x3800, + 0x7800, 0x2800, 0x1800, 0x3A000, 0x3D000, + 0x3C800, 0x39000, 0x3E800, 0x3C000, 0x38000, + 0x3F000, 0x3B000, 0x3D800, 0x38800, 0x3E000, + 0x3B800, 0x3F800, 0x3A800, 0x39800, 0x2A000, + 0x2D000, 0x2C800, 0x29000, 0x2E800, 0x2C000, + 0x28000, 0x2F000, 0x2B000, 0x2D800, 0x28800, + 0x2E000, 0x2B800, 0x2F800, 0x2A800, 0x29800, + 0x4A000, 0x4D000, 0x4C800, 0x49000, 0x4E800, + 0x4C000, 0x48000, 0x4F000, 0x4B000, 0x4D800, + 0x48800, 0x4E000, 0x4B800, 0x4F800, 0x4A800, + 0x49800 + }, { + 0x3A80000, 0x3C00000, 0x3880000, 0x3E80000, 0x3D00000, + 0x3980000, 0x3A00000, 0x3900000, 0x3F00000, 0x3F80000, + 0x3E00000, 0x3B80000, 0x3B00000, 0x3800000, 0x3C80000, + 0x3D80000, 0x6A80000, 0x6C00000, 0x6880000, 0x6E80000, + 0x6D00000, 0x6980000, 0x6A00000, 0x6900000, 0x6F00000, + 0x6F80000, 0x6E00000, 0x6B80000, 0x6B00000, 0x6800000, + 0x6C80000, 0x6D80000, 0x5280000, 0x5400000, 0x5080000, + 0x5680000, 0x5500000, 0x5180000, 0x5200000, 0x5100000, + 0x5700000, 0x5780000, 0x5600000, 0x5380000, 0x5300000, + 0x5000000, 0x5480000, 0x5580000, 0xA80000, 0xC00000, + 0x880000, 0xE80000, 0xD00000, 0x980000, 0xA00000, + 0x900000, 0xF00000, 0xF80000, 0xE00000, 0xB80000, + 0xB00000, 0x800000, 0xC80000, 0xD80000, 0x280000, + 0x400000, 0x80000, 0x680000, 0x500000, 0x180000, + 0x200000, 0x100000, 0x700000, 0x780000, 0x600000, + 0x380000, 0x300000, 0x0, 0x480000, 0x580000, + 0x4280000, 0x4400000, 0x4080000, 0x4680000, 0x4500000, + 0x4180000, 0x4200000, 0x4100000, 0x4700000, 0x4780000, + 0x4600000, 0x4380000, 0x4300000, 0x4000000, 0x4480000, + 0x4580000, 0x4A80000, 0x4C00000, 0x4880000, 0x4E80000, + 0x4D00000, 0x4980000, 0x4A00000, 0x4900000, 0x4F00000, + 0x4F80000, 0x4E00000, 0x4B80000, 0x4B00000, 0x4800000, + 0x4C80000, 0x4D80000, 0x7A80000, 0x7C00000, 0x7880000, + 0x7E80000, 0x7D00000, 0x7980000, 0x7A00000, 0x7900000, + 0x7F00000, 0x7F80000, 0x7E00000, 0x7B80000, 0x7B00000, + 0x7800000, 0x7C80000, 0x7D80000, 0x7280000, 0x7400000, + 0x7080000, 0x7680000, 0x7500000, 0x7180000, 0x7200000, + 0x7100000, 0x7700000, 0x7780000, 0x7600000, 0x7380000, + 0x7300000, 0x7000000, 0x7480000, 0x7580000, 0x2280000, + 0x2400000, 0x2080000, 0x2680000, 0x2500000, 0x2180000, + 0x2200000, 0x2100000, 0x2700000, 0x2780000, 0x2600000, + 0x2380000, 0x2300000, 0x2000000, 0x2480000, 0x2580000, + 0x3280000, 0x3400000, 0x3080000, 0x3680000, 0x3500000, + 0x3180000, 0x3200000, 0x3100000, 0x3700000, 0x3780000, + 0x3600000, 0x3380000, 0x3300000, 0x3000000, 0x3480000, + 0x3580000, 0x6280000, 0x6400000, 0x6080000, 0x6680000, + 0x6500000, 0x6180000, 0x6200000, 0x6100000, 0x6700000, + 0x6780000, 0x6600000, 0x6380000, 0x6300000, 0x6000000, + 0x6480000, 0x6580000, 0x5A80000, 0x5C00000, 0x5880000, + 0x5E80000, 0x5D00000, 0x5980000, 0x5A00000, 0x5900000, + 0x5F00000, 0x5F80000, 0x5E00000, 0x5B80000, 0x5B00000, + 0x5800000, 0x5C80000, 0x5D80000, 0x1280000, 0x1400000, + 0x1080000, 0x1680000, 0x1500000, 0x1180000, 0x1200000, + 0x1100000, 0x1700000, 0x1780000, 0x1600000, 0x1380000, + 0x1300000, 0x1000000, 0x1480000, 0x1580000, 0x2A80000, + 0x2C00000, 0x2880000, 0x2E80000, 0x2D00000, 0x2980000, + 0x2A00000, 0x2900000, 0x2F00000, 0x2F80000, 0x2E00000, + 0x2B80000, 0x2B00000, 0x2800000, 0x2C80000, 0x2D80000, + 0x1A80000, 0x1C00000, 0x1880000, 0x1E80000, 0x1D00000, + 0x1980000, 0x1A00000, 0x1900000, 0x1F00000, 0x1F80000, + 0x1E00000, 0x1B80000, 0x1B00000, 0x1800000, 0x1C80000, + 0x1D80000 + }, { + 0x30000002, 0x60000002, 0x38000002, 0x8000002, + 0x28000002, 0x78000002, 0x68000002, 0x40000002, + 0x20000002, 0x50000002, 0x48000002, 0x70000002, + 0x2, 0x18000002, 0x58000002, 0x10000002, + 0xB0000005, 0xE0000005, 0xB8000005, 0x88000005, + 0xA8000005, 0xF8000005, 0xE8000005, 0xC0000005, + 0xA0000005, 0xD0000005, 0xC8000005, 0xF0000005, + 0x80000005, 0x98000005, 0xD8000005, 0x90000005, + 0x30000005, 0x60000005, 0x38000005, 0x8000005, + 0x28000005, 0x78000005, 0x68000005, 0x40000005, + 0x20000005, 0x50000005, 0x48000005, 0x70000005, + 0x5, 0x18000005, 0x58000005, 0x10000005, + 0x30000000, 0x60000000, 0x38000000, 0x8000000, + 0x28000000, 0x78000000, 0x68000000, 0x40000000, + 0x20000000, 0x50000000, 0x48000000, 0x70000000, + 0x0, 0x18000000, 0x58000000, 0x10000000, + 0xB0000003, 0xE0000003, 0xB8000003, 0x88000003, + 0xA8000003, 0xF8000003, 0xE8000003, 0xC0000003, + 0xA0000003, 0xD0000003, 0xC8000003, 0xF0000003, + 0x80000003, 0x98000003, 0xD8000003, 0x90000003, + 0x30000001, 0x60000001, 0x38000001, 0x8000001, + 0x28000001, 0x78000001, 0x68000001, 0x40000001, + 0x20000001, 0x50000001, 0x48000001, 0x70000001, + 0x1, 0x18000001, 0x58000001, 0x10000001, + 0xB0000000, 0xE0000000, 0xB8000000, 0x88000000, + 0xA8000000, 0xF8000000, 0xE8000000, 0xC0000000, + 0xA0000000, 0xD0000000, 0xC8000000, 0xF0000000, + 0x80000000, 0x98000000, 0xD8000000, 0x90000000, + 0xB0000006, 0xE0000006, 0xB8000006, 0x88000006, + 0xA8000006, 0xF8000006, 0xE8000006, 0xC0000006, + 0xA0000006, 0xD0000006, 0xC8000006, 0xF0000006, + 0x80000006, 0x98000006, 0xD8000006, 0x90000006, + 0xB0000001, 0xE0000001, 0xB8000001, 0x88000001, + 0xA8000001, 0xF8000001, 0xE8000001, 0xC0000001, + 0xA0000001, 0xD0000001, 0xC8000001, 0xF0000001, + 0x80000001, 0x98000001, 0xD8000001, 0x90000001, + 0x30000003, 0x60000003, 0x38000003, 0x8000003, + 0x28000003, 0x78000003, 0x68000003, 0x40000003, + 0x20000003, 0x50000003, 0x48000003, 0x70000003, + 0x3, 0x18000003, 0x58000003, 0x10000003, + 0x30000004, 0x60000004, 0x38000004, 0x8000004, + 0x28000004, 0x78000004, 0x68000004, 0x40000004, + 0x20000004, 0x50000004, 0x48000004, 0x70000004, + 0x4, 0x18000004, 0x58000004, 0x10000004, + 0xB0000002, 0xE0000002, 0xB8000002, 0x88000002, + 0xA8000002, 0xF8000002, 0xE8000002, 0xC0000002, + 0xA0000002, 0xD0000002, 0xC8000002, 0xF0000002, + 0x80000002, 0x98000002, 0xD8000002, 0x90000002, + 0xB0000004, 0xE0000004, 0xB8000004, 0x88000004, + 0xA8000004, 0xF8000004, 0xE8000004, 0xC0000004, + 0xA0000004, 0xD0000004, 0xC8000004, 0xF0000004, + 0x80000004, 0x98000004, 0xD8000004, 0x90000004, + 0x30000006, 0x60000006, 0x38000006, 0x8000006, + 0x28000006, 0x78000006, 0x68000006, 0x40000006, + 0x20000006, 0x50000006, 0x48000006, 0x70000006, + 0x6, 0x18000006, 0x58000006, 0x10000006, + 0xB0000007, 0xE0000007, 0xB8000007, 0x88000007, + 0xA8000007, 0xF8000007, 0xE8000007, 0xC0000007, + 0xA0000007, 0xD0000007, 0xC8000007, 0xF0000007, + 0x80000007, 0x98000007, 0xD8000007, 0x90000007, + 0x30000007, 0x60000007, 0x38000007, 0x8000007, + 0x28000007, 0x78000007, 0x68000007, 0x40000007, + 0x20000007, 0x50000007, 0x48000007, 0x70000007, + 0x7, 0x18000007, 0x58000007, 0x10000007 + }, { + 0xE8, 0xD8, 0xA0, 0x88, 0x98, 0xF8, 0xA8, 0xC8, 0x80, 0xD0, + 0xF0, 0xB8, 0xB0, 0xC0, 0x90, 0xE0, 0x7E8, 0x7D8, 0x7A0, 0x788, + 0x798, 0x7F8, 0x7A8, 0x7C8, 0x780, 0x7D0, 0x7F0, 0x7B8, 0x7B0, 0x7C0, + 0x790, 0x7E0, 0x6E8, 0x6D8, 0x6A0, 0x688, 0x698, 0x6F8, 0x6A8, 0x6C8, + 0x680, 0x6D0, 0x6F0, 0x6B8, 0x6B0, 0x6C0, 0x690, 0x6E0, 0x68, 0x58, + 0x20, 0x8, 0x18, 0x78, 0x28, 0x48, 0x0, 0x50, 0x70, 0x38, + 0x30, 0x40, 0x10, 0x60, 0x2E8, 0x2D8, 0x2A0, 0x288, 0x298, 0x2F8, + 0x2A8, 0x2C8, 0x280, 0x2D0, 0x2F0, 0x2B8, 0x2B0, 0x2C0, 0x290, 0x2E0, + 0x3E8, 0x3D8, 0x3A0, 0x388, 0x398, 0x3F8, 0x3A8, 0x3C8, 0x380, 0x3D0, + 0x3F0, 0x3B8, 0x3B0, 0x3C0, 0x390, 0x3E0, 0x568, 0x558, 0x520, 0x508, + 0x518, 0x578, 0x528, 0x548, 0x500, 0x550, 0x570, 0x538, 0x530, 0x540, + 0x510, 0x560, 0x268, 0x258, 0x220, 0x208, 0x218, 0x278, 0x228, 0x248, + 0x200, 0x250, 0x270, 0x238, 0x230, 0x240, 0x210, 0x260, 0x4E8, 0x4D8, + 0x4A0, 0x488, 0x498, 0x4F8, 0x4A8, 0x4C8, 0x480, 0x4D0, 0x4F0, 0x4B8, + 0x4B0, 0x4C0, 0x490, 0x4E0, 0x168, 0x158, 0x120, 0x108, 0x118, 0x178, + 0x128, 0x148, 0x100, 0x150, 0x170, 0x138, 0x130, 0x140, 0x110, 0x160, + 0x1E8, 0x1D8, 0x1A0, 0x188, 0x198, 0x1F8, 0x1A8, 0x1C8, 0x180, 0x1D0, + 0x1F0, 0x1B8, 0x1B0, 0x1C0, 0x190, 0x1E0, 0x768, 0x758, 0x720, 0x708, + 0x718, 0x778, 0x728, 0x748, 0x700, 0x750, 0x770, 0x738, 0x730, 0x740, + 0x710, 0x760, 0x368, 0x358, 0x320, 0x308, 0x318, 0x378, 0x328, 0x348, + 0x300, 0x350, 0x370, 0x338, 0x330, 0x340, 0x310, 0x360, 0x5E8, 0x5D8, + 0x5A0, 0x588, 0x598, 0x5F8, 0x5A8, 0x5C8, 0x580, 0x5D0, 0x5F0, 0x5B8, + 0x5B0, 0x5C0, 0x590, 0x5E0, 0x468, 0x458, 0x420, 0x408, 0x418, 0x478, + 0x428, 0x448, 0x400, 0x450, 0x470, 0x438, 0x430, 0x440, 0x410, 0x460, + 0x668, 0x658, 0x620, 0x608, 0x618, 0x678, 0x628, 0x648, 0x600, 0x650, + 0x670, 0x638, 0x630, 0x640, 0x610, 0x660 + } +}; + +/** + * Initialize algorithm context before calculating hash + * with test parameters set. + * + * @param ctx context to initalize + */ +void +gosthash94_init (struct gosthash94_ctx *ctx) +{ + memset (ctx, 0, sizeof (struct gosthash94_ctx)); +} + +/* + * A macro that performs a full encryption round of GOST 28147-89. + * Temporary variables tmp assumed and variables r and l for left and right + * blocks. + */ +#define GOST_ENCRYPT_ROUND(key1, key2, sbox) \ + tmp = (key1) + r; \ + l ^= (sbox)[0][tmp & 0xff] ^ (sbox)[1][(tmp >> 8) & 0xff] ^ \ + (sbox)[2][(tmp >> 16) & 0xff] ^ (sbox)[3][tmp >> 24]; \ + tmp = (key2) + l; \ + r ^= (sbox)[0][tmp & 0xff] ^ (sbox)[1][(tmp >> 8) & 0xff] ^ \ + (sbox)[2][(tmp >> 16) & 0xff] ^ (sbox)[3][tmp >> 24]; + +/* encrypt a block with the given key */ +#define GOST_ENCRYPT(result, i, key, hash, sbox) \ + r = hash[i], l = hash[i + 1]; \ + GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \ + GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \ + GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \ + GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \ + GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \ + GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \ + GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \ + GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \ + GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \ + GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \ + GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \ + GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \ + GOST_ENCRYPT_ROUND(key[7], key[6], sbox) \ + GOST_ENCRYPT_ROUND(key[5], key[4], sbox) \ + GOST_ENCRYPT_ROUND(key[3], key[2], sbox) \ + GOST_ENCRYPT_ROUND(key[1], key[0], sbox) \ + result[i] = l, result[i + 1] = r; + +/** + * The core transformation. Process a 512-bit block. + * + * @param hash intermediate message hash + * @param block the message block to process + */ +static void +gost_block_compress (struct gosthash94_ctx *ctx, const uint32_t *block) +{ + unsigned i; + uint32_t key[8], u[8], v[8], w[8], s[8]; + uint32_t l, r, tmp; + + /* u := hash, v := <256-bit message block> */ + memcpy (u, ctx->hash, sizeof (u)); + memcpy (v, block, sizeof (v)); + + /* w := u xor v */ + w[0] = u[0] ^ v[0], w[1] = u[1] ^ v[1]; + w[2] = u[2] ^ v[2], w[3] = u[3] ^ v[3]; + w[4] = u[4] ^ v[4], w[5] = u[5] ^ v[5]; + w[6] = u[6] ^ v[6], w[7] = u[7] ^ v[7]; + + /* calculate keys, encrypt hash and store result to the s[] array */ + for (i = 0;; i += 2) + { + /* key generation: key_i := P(w) */ + key[0] = + (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | + ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24); + key[1] = + ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) | + ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16); + key[2] = + ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | + (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8); + key[3] = + ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | + ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000); + key[4] = + (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | + ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24); + key[5] = + ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) | + ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16); + key[6] = + ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | + (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8); + key[7] = + ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | + ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000); + + /* encryption: s_i := E_{key_i} (h_i) */ + GOST_ENCRYPT (s, i, key, ctx->hash, gosthash94_sbox); + + if (i == 0) + { + /* w:= A(u) ^ A^2(v) */ + w[0] = u[2] ^ v[4], w[1] = u[3] ^ v[5]; + w[2] = u[4] ^ v[6], w[3] = u[5] ^ v[7]; + w[4] = u[6] ^ (v[0] ^= v[2]); + w[5] = u[7] ^ (v[1] ^= v[3]); + w[6] = (u[0] ^= u[2]) ^ (v[2] ^= v[4]); + w[7] = (u[1] ^= u[3]) ^ (v[3] ^= v[5]); + } + else if ((i & 2) != 0) + { + if (i == 6) + break; + + /* w := A^2(u) xor A^4(v) xor C_3; u := A(u) xor C_3 */ + /* C_3=0xff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00 */ + u[2] ^= u[4] ^ 0x000000ff; + u[3] ^= u[5] ^ 0xff00ffff; + u[4] ^= 0xff00ff00; + u[5] ^= 0xff00ff00; + u[6] ^= 0x00ff00ff; + u[7] ^= 0x00ff00ff; + u[0] ^= 0x00ffff00; + u[1] ^= 0xff0000ff; + + w[0] = u[4] ^ v[0]; + w[2] = u[6] ^ v[2]; + w[4] = u[0] ^ (v[4] ^= v[6]); + w[6] = u[2] ^ (v[6] ^= v[0]); + w[1] = u[5] ^ v[1]; + w[3] = u[7] ^ v[3]; + w[5] = u[1] ^ (v[5] ^= v[7]); + w[7] = u[3] ^ (v[7] ^= v[1]); + } + else + { + /* i==4 here */ + /* w:= A( A^2(u) xor C_3 ) xor A^6(v) */ + w[0] = u[6] ^ v[4], w[1] = u[7] ^ v[5]; + w[2] = u[0] ^ v[6], w[3] = u[1] ^ v[7]; + w[4] = u[2] ^ (v[0] ^= v[2]); + w[5] = u[3] ^ (v[1] ^= v[3]); + w[6] = (u[4] ^= u[6]) ^ (v[2] ^= v[4]); + w[7] = (u[5] ^= u[7]) ^ (v[3] ^= v[5]); + } + } + + /* step hash function: x(block, hash) := psi^61(hash xor psi(block xor psi^12(S))) */ + + /* 12 rounds of the LFSR and xor in */ + u[0] = block[0] ^ s[6]; + u[1] = block[1] ^ s[7]; + u[2] = + block[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ (s[1] & + 0xffff) + ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[7] & + 0xffff0000) + ^ (s[7] >> 16); + u[3] = + block[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ (s[1] + << + 16) + ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[6] + ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ + (s[7] >> 16); + u[4] = + block[4] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^ + (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ + (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ (s[6] + >> 16) + ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16); + u[5] = + block[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^ + (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) + ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ (s[6] + >> + 16) + ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16); + u[6] = + block[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16) + ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] + ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16); + u[7] = + block[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ + (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ + (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ + (s[7] << 16) ^ (s[7] >> 16); + + /* 1 round of the LFSR (a mixing transformation) and xor with */ + v[0] = ctx->hash[0] ^ (u[1] << 16) ^ (u[0] >> 16); + v[1] = ctx->hash[1] ^ (u[2] << 16) ^ (u[1] >> 16); + v[2] = ctx->hash[2] ^ (u[3] << 16) ^ (u[2] >> 16); + v[3] = ctx->hash[3] ^ (u[4] << 16) ^ (u[3] >> 16); + v[4] = ctx->hash[4] ^ (u[5] << 16) ^ (u[4] >> 16); + v[5] = ctx->hash[5] ^ (u[6] << 16) ^ (u[5] >> 16); + v[6] = ctx->hash[6] ^ (u[7] << 16) ^ (u[6] >> 16); + v[7] = + ctx-> + hash[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[1] & 0xffff0000) + ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000) ^ (u[7] >> 16); + + /* 61 rounds of LFSR, mixing up hash */ + ctx->hash[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ + (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ + (v[3] >> 16) ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^ + (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff); + ctx->hash[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ + (v[1] & 0xffff) ^ v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ + (v[4] >> 16) ^ (v[5] << 16) ^ (v[6] << 16) ^ v[6] ^ + (v[7] & 0xffff0000) ^ (v[7] >> 16); + ctx->hash[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ + (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ + v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ + (v[7] & 0xffff) ^ (v[7] << 16) ^ (v[7] >> 16); + ctx->hash[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ + (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^ + (v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ + (v[5] << 16) ^ (v[6] << 16) ^ (v[7] & 0xffff) ^ (v[7] >> 16); + ctx->hash[4] = + (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ (v[3] << + 16) ^ + (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << + 16) ^ + (v[6] >> 16) ^ (v[7] << 16); + ctx->hash[5] = + (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ (v[1] >> 16) ^ + (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ (v[3] >> 16) ^ v[3] ^ + (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ + (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & + 0xffff0000); + ctx->hash[6] = + v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ (v[4] >> + 16) ^ + (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ + v[6] ^ (v[7] << 16) ^ v[7]; + ctx->hash[7] = + v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[2] << 16) ^ + (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ + (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7]; +} + +/** + * This function calculates hash value by 256-bit blocks. + * It updates 256-bit check sum as follows: + * *(uint256_t)(ctx->sum) += *(uint256_t*)block; + * and then updates intermediate hash value ctx->hash + * by calling gost_block_compress(). + * + * @param ctx algorithm context + * @param block the 256-bit message block to process + */ +static void +gost_compute_sum_and_hash (struct gosthash94_ctx *ctx, const uint8_t *block) +{ + uint32_t block_le[8]; + unsigned i, carry; + + /* compute the 256-bit sum */ + for (i = carry = 0; i < 8; i++, block += 4) + { + block_le[i] = LE_READ_UINT32(block); + ctx->sum[i] += carry; + carry = (ctx->sum[i] < carry); + ctx->sum[i] += block_le[i]; + carry += (ctx->sum[i] < block_le[i]); + } + + /* update message hash */ + gost_block_compress (ctx, block_le); +} + +/** + * Calculate message hash. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param ctx the algorithm context containing current hashing state + * @param msg message chunk + * @param size length of the message chunk + */ +void +gosthash94_update (struct gosthash94_ctx *ctx, + size_t length, const uint8_t *msg) +{ + unsigned index = (unsigned) ctx->length & 31; + ctx->length += length; + + /* fill partial block */ + if (index) + { + unsigned left = GOSTHASH94_BLOCK_SIZE - index; + memcpy (ctx->message + index, msg, (length < left ? length : left)); + if (length < left) + return; + + /* process partial block */ + gost_compute_sum_and_hash (ctx, ctx->message); + msg += left; + length -= left; + } + while (length >= GOSTHASH94_BLOCK_SIZE) + { + gost_compute_sum_and_hash (ctx, msg); + msg += GOSTHASH94_BLOCK_SIZE; + length -= GOSTHASH94_BLOCK_SIZE; + } + if (length) + { + /* save leftovers */ + memcpy (ctx->message, msg, length); + } +} + +/** + * Finish hashing and store message digest into given array. + * + * @param ctx the algorithm context containing current hashing state + * @param result calculated hash in binary form + */ +void +gosthash94_digest (struct gosthash94_ctx *ctx, + size_t length, uint8_t *result) +{ + unsigned index = ctx->length & 31; + uint32_t msg32[8]; + + assert(length <= GOSTHASH94_DIGEST_SIZE); + + /* pad the last block with zeroes and hash it */ + if (index > 0) + { + memset (ctx->message + index, 0, 32 - index); + gost_compute_sum_and_hash (ctx, ctx->message); + } + + /* hash the message length and the sum */ + msg32[0] = ctx->length << 3; + msg32[1] = ctx->length >> 29; + memset (msg32 + 2, 0, sizeof (uint32_t) * 6); + + gost_block_compress (ctx, msg32); + gost_block_compress (ctx, ctx->sum); + + /* convert hash state to result bytes */ + _nettle_write_le32(length, result, ctx->hash); + gosthash94_init (ctx); +} diff --git a/gosthash94.h b/gosthash94.h new file mode 100644 index 0000000..8e9d49f --- /dev/null +++ b/gosthash94.h @@ -0,0 +1,98 @@ +/* gosthash94.h + + The GOST R 34.11-94 hash function, described in RFC 5831. + + Copyright (C) 2012 Nikos Mavrogiannopoulos, Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Based on rhash gost.h. */ + +/* Copyright: 2009-2012 Aleksey Kravchenko + * + * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Ported to nettle by Nikos Mavrogiannopoulos. + */ + +#ifndef NETTLE_GOSTHASH94_H_INCLUDED +#define NETTLE_GOSTHASH94_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define gosthash94_init nettle_gosthash94_init +#define gosthash94_update nettle_gosthash94_update +#define gosthash94_digest nettle_gosthash94_digest + +#define GOSTHASH94_BLOCK_SIZE 32 +#define GOSTHASH94_DIGEST_SIZE 32 +/* For backwards compatibility */ +#define GOSTHASH94_DATA_SIZE GOSTHASH94_BLOCK_SIZE + +struct gosthash94_ctx +{ + uint32_t hash[8]; /* algorithm 256-bit state */ + uint32_t sum[8]; /* sum of processed message blocks */ + uint8_t message[GOSTHASH94_BLOCK_SIZE]; /* 256-bit buffer for leftovers */ + uint64_t length; /* number of processed bytes */ +}; + +void gosthash94_init(struct gosthash94_ctx *ctx); +void gosthash94_update(struct gosthash94_ctx *ctx, + size_t length, const uint8_t *msg); +void gosthash94_digest(struct gosthash94_ctx *ctx, + size_t length, uint8_t *result); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_GOSTHASH94_H_INCLUDED */ diff --git a/hkdf.c b/hkdf.c new file mode 100644 index 0000000..2d7336a --- /dev/null +++ b/hkdf.c @@ -0,0 +1,84 @@ +/* hkdf.c + + Copyright (C) 2017 Red Hat, Inc. + + Author: Nikos Mavrogiannopoulos + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. + */ + +/* Functions for the HKDF handling. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hkdf.h" + +/* hkdf_extract: Outputs a PRK of digest_size + */ +void +hkdf_extract(void *mac_ctx, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_size, + size_t secret_size, const uint8_t *secret, + uint8_t *dst) +{ + update(mac_ctx, secret_size, secret); + digest(mac_ctx, digest_size, dst); +} + +/* hkdf_expand: Outputs an arbitrary key of size specified by length + */ +void +hkdf_expand(void *mac_ctx, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_size, + size_t info_size, const uint8_t *info, + size_t length, uint8_t *dst) +{ + uint8_t i = 1; + + if (!length) + return; + + for (;; dst += digest_size, length -= digest_size, i++) + { + update(mac_ctx, info_size, info); + update(mac_ctx, 1, &i); + if (length <= digest_size) + break; + + digest(mac_ctx, digest_size, dst); + update(mac_ctx, digest_size, dst); + } + + digest(mac_ctx, length, dst); +} diff --git a/hkdf.h b/hkdf.h new file mode 100644 index 0000000..43b16ad --- /dev/null +++ b/hkdf.h @@ -0,0 +1,67 @@ +/* hkdf.h + + TLS PRF code (RFC-5246, RFC-2246). + + Copyright (C) 2017 Red Hat, Inc. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_HKDF_H_INCLUDED +#define NETTLE_HKDF_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Namespace mangling */ +#define hkdf_extract nettle_hkdf_extract +#define hkdf_expand nettle_hkdf_expand + +void +hkdf_extract(void *mac_ctx, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_size, + size_t secret_size, const uint8_t *secret, + uint8_t *dst); + +void +hkdf_expand(void *mac_ctx, + nettle_hash_update_func *update, + nettle_hash_digest_func *digest, + size_t digest_size, + size_t info_size, const uint8_t *info, + size_t length, uint8_t *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_HKDF_H_INCLUDED */ diff --git a/hmac-md5.c b/hmac-md5.c new file mode 100644 index 0000000..a27e64f --- /dev/null +++ b/hmac-md5.c @@ -0,0 +1,59 @@ +/* hmac-md5.c + + HMAC-MD5 message authentication code. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_md5_set_key(struct hmac_md5_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_md5, key_length, key); +} + +void +hmac_md5_update(struct hmac_md5_ctx *ctx, + size_t length, const uint8_t *data) +{ + md5_update(&ctx->state, length, data); +} + +void +hmac_md5_digest(struct hmac_md5_ctx *ctx, + size_t length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_md5, length, digest); +} diff --git a/hmac-ripemd160.c b/hmac-ripemd160.c new file mode 100644 index 0000000..24e2cbe --- /dev/null +++ b/hmac-ripemd160.c @@ -0,0 +1,59 @@ +/* hmac-ripemd160.c + + HMAC-RIPEMD160 message authentication code. + + Copyright (C) 2011 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_ripemd160, key_length, key); +} + +void +hmac_ripemd160_update(struct hmac_ripemd160_ctx *ctx, + size_t length, const uint8_t *data) +{ + ripemd160_update(&ctx->state, length, data); +} + +void +hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx, + size_t length, uint8_t *digest) +{ + HMAC_DIGEST(ctx, &nettle_ripemd160, length, digest); +} diff --git a/hmac-sha1.c b/hmac-sha1.c new file mode 100644 index 0000000..5e7188f --- /dev/null +++ b/hmac-sha1.c @@ -0,0 +1,59 @@ +/* hmac-sha1.c + + HMAC-SHA1 message authentication code. + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha1_set_key(struct hmac_sha1_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha1, key_length, key); +} + +void +hmac_sha1_update(struct hmac_sha1_ctx *ctx, + size_t length, const uint8_t *data) +{ + sha1_update(&ctx->state, length, data); +} + +void +hmac_sha1_digest(struct hmac_sha1_ctx *ctx, + size_t 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..c5bc875 --- /dev/null +++ b/hmac-sha224.c @@ -0,0 +1,52 @@ +/* hmac-sha224.c + + HMAC-SHA224 message authentication code. + + Copyright (C) 2003, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha224_set_key(struct hmac_sha224_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha224, key_length, key); +} + +void +hmac_sha224_digest(struct hmac_sha224_ctx *ctx, + size_t 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..af5cc0f --- /dev/null +++ b/hmac-sha256.c @@ -0,0 +1,59 @@ +/* hmac-sha256.c + + HMAC-SHA256 message authentication code. + + Copyright (C) 2003 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha256_set_key(struct hmac_sha256_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha256, key_length, key); +} + +void +hmac_sha256_update(struct hmac_sha256_ctx *ctx, + size_t length, const uint8_t *data) +{ + sha256_update(&ctx->state, length, data); +} + +void +hmac_sha256_digest(struct hmac_sha256_ctx *ctx, + size_t 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..30008b5 --- /dev/null +++ b/hmac-sha384.c @@ -0,0 +1,52 @@ +/* hmac-sha384.c + + HMAC-SHA384 message authentication code. + + Copyright (C) 2003, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha384_set_key(struct hmac_sha512_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha384, key_length, key); +} + +void +hmac_sha384_digest(struct hmac_sha512_ctx *ctx, + size_t 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..de64637 --- /dev/null +++ b/hmac-sha512.c @@ -0,0 +1,59 @@ +/* hmac-sha512.c + + HMAC-SHA512 message authentication code. + + Copyright (C) 2003, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "hmac.h" + +void +hmac_sha512_set_key(struct hmac_sha512_ctx *ctx, + size_t key_length, const uint8_t *key) +{ + HMAC_SET_KEY(ctx, &nettle_sha512, key_length, key); +} + +void +hmac_sha512_update(struct hmac_sha512_ctx *ctx, + size_t length, const uint8_t *data) +{ + sha512_update(&ctx->state, length, data); +} + +void +hmac_sha512_digest(struct hmac_sha512_ctx *ctx, + size_t 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..6ac5e11 --- /dev/null +++ b/hmac.c @@ -0,0 +1,117 @@ +/* hmac.c + + HMAC message authentication code (RFC-2104). + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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, + size_t 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, + size_t 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, + size_t 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..40a8e77 --- /dev/null +++ b/hmac.h @@ -0,0 +1,210 @@ +/* hmac.h + + HMAC message authentication code (RFC-2104). + + Copyright (C) 2001, 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_HMAC_H_INCLUDED +#define NETTLE_HMAC_H_INCLUDED + +#include "nettle-meta.h" + +#include "md5.h" +#include "ripemd160.h" +#include "sha1.h" +#include "sha2.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_ripemd160_set_key nettle_hmac_ripemd160_set_key +#define hmac_ripemd160_update nettle_hmac_ripemd160_update +#define hmac_ripemd160_digest nettle_hmac_ripemd160_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, + size_t 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, + size_t length, const uint8_t *data); + +void +hmac_digest(const void *outer, const void *inner, void *state, + const struct nettle_hash *hash, + size_t 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, + size_t key_length, const uint8_t *key); + +void +hmac_md5_update(struct hmac_md5_ctx *ctx, + size_t length, const uint8_t *data); + +void +hmac_md5_digest(struct hmac_md5_ctx *ctx, + size_t length, uint8_t *digest); + + +/* hmac-ripemd160 */ +struct hmac_ripemd160_ctx HMAC_CTX(struct ripemd160_ctx); + +void +hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx, + size_t key_length, const uint8_t *key); + +void +hmac_ripemd160_update(struct hmac_ripemd160_ctx *ctx, + size_t length, const uint8_t *data); + +void +hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx, + size_t 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, + size_t key_length, const uint8_t *key); + +void +hmac_sha1_update(struct hmac_sha1_ctx *ctx, + size_t length, const uint8_t *data); + +void +hmac_sha1_digest(struct hmac_sha1_ctx *ctx, + size_t 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, + size_t key_length, const uint8_t *key); + +void +hmac_sha256_update(struct hmac_sha256_ctx *ctx, + size_t length, const uint8_t *data); + +void +hmac_sha256_digest(struct hmac_sha256_ctx *ctx, + size_t length, uint8_t *digest); + +/* hmac-sha224 */ +#define hmac_sha224_ctx hmac_sha256_ctx + +void +hmac_sha224_set_key(struct hmac_sha224_ctx *ctx, + size_t key_length, const uint8_t *key); + +#define hmac_sha224_update nettle_hmac_sha256_update + +void +hmac_sha224_digest(struct hmac_sha224_ctx *ctx, + size_t 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, + size_t key_length, const uint8_t *key); + +void +hmac_sha512_update(struct hmac_sha512_ctx *ctx, + size_t length, const uint8_t *data); + +void +hmac_sha512_digest(struct hmac_sha512_ctx *ctx, + size_t length, uint8_t *digest); + +/* hmac-sha384 */ +#define hmac_sha384_ctx hmac_sha512_ctx + +void +hmac_sha384_set_key(struct hmac_sha512_ctx *ctx, + size_t key_length, const uint8_t *key); + +#define hmac_sha384_update nettle_hmac_sha512_update + +void +hmac_sha384_digest(struct hmac_sha512_ctx *ctx, + size_t length, uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_HMAC_H_INCLUDED */ diff --git a/hogweed.pc.in b/hogweed.pc.in new file mode 100644 index 0000000..97fb9d4 --- /dev/null +++ b/hogweed.pc.in @@ -0,0 +1,19 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +# Uses Requires.private and Libs.private, under the assumption that +# when using shared libraries, the ELF dependencies from libhogweed.so +# to nettle and gmp work. + +Name: Hogweed +Description: Nettle low-level cryptographic library (public-key algorithms) +URL: http://www.lysator.liu.se/~nisse/nettle +Version: @PACKAGE_VERSION@ +Requires: @IF_NOT_SHARED@ nettle +Requires.private: @IF_SHARED@ nettle +Libs: -L${libdir} -lhogweed @IF_NOT_SHARED@ @LIBS@ +Libs.private: @IF_SHARED@ @LIBS@ +Cflags: -I${includedir} + 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..5e3fd5c --- /dev/null +++ b/knuth-lfib.c @@ -0,0 +1,175 @@ +/* knuth-lfib.c + + The "lagged fibonacci" pseudorandomness generator, described in + Knuth, TAoCP, 3.6 + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* This file includes code copied verbatim from Knuth's TAoCP. + Technically, doing that probably requires asking for the author's + explicit permission. I'd expect such a request to be granted, but I + haven't asked, because I don't want to distract him from more + important and interesting work. */ + + + +/* 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, + size_t 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..df0b495 --- /dev/null +++ b/knuth-lfib.h @@ -0,0 +1,80 @@ +/* knuth-lfib.h + + The "lagged fibonacci" pseudorandomness generator, described in + Knuth, TAoCP, 3.6 + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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, + size_t n, uint32_t *a); + +/* Get an array of octets. */ +void +knuth_lfib_random(struct knuth_lfib_ctx *ctx, + size_t n, uint8_t *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_KNUTH_LFIB_H_INCLUDED */ diff --git a/libhogweed.map.in b/libhogweed.map.in new file mode 100644 index 0000000..eea6ed8 --- /dev/null +++ b/libhogweed.map.in @@ -0,0 +1,18 @@ +# libhogweed.map -- libhogweed linker version script. -*- ld-script -*- + +# +# The symbol version must be updated on every hogweed +# library major number change. That is taken care by +# auto-generating the file. + +HOGWEED_@LIBHOGWEED_MAJOR@ +{ + global: + nettle_*; + _nettle_*; + @HOGWEED_EXTRA_SYMBOLS@ + + local: + *; +}; + diff --git a/libnettle.map.in b/libnettle.map.in new file mode 100644 index 0000000..02455bc --- /dev/null +++ b/libnettle.map.in @@ -0,0 +1,17 @@ +# libnettle.map -- libnettle linker version script. -*- ld-script -*- + +# +# The symbol version must be updated on every nettle +# library major number change. That is taken care by +# auto-generating the file. + +NETTLE_@LIBNETTLE_MAJOR@ +{ + global: + nettle_*; + _nettle_*; + + local: + *; +}; + diff --git a/macros.h b/macros.h new file mode 100644 index 0000000..990d32e --- /dev/null +++ b/macros.h @@ -0,0 +1,245 @@ +/* macros.h + + Copyright (C) 2001, 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_UINT64(p) \ +( (((uint64_t) (p)[7]) << 56) \ + | (((uint64_t) (p)[6]) << 48) \ + | (((uint64_t) (p)[5]) << 40) \ + | (((uint64_t) (p)[4]) << 32) \ + | (((uint64_t) (p)[3]) << 24) \ + | (((uint64_t) (p)[2]) << 16) \ + | (((uint64_t) (p)[1]) << 8) \ + | ((uint64_t) (p)[0])) + +#define LE_WRITE_UINT64(p, i) \ +do { \ + (p)[7] = ((i) >> 56) & 0xff; \ + (p)[6] = ((i) >> 48) & 0xff; \ + (p)[5] = ((i) >> 40) & 0xff; \ + (p)[4] = ((i) >> 32) & 0xff; \ + (p)[3] = ((i) >> 24) & 0xff; \ + (p)[2] = ((i) >> 16) & 0xff; \ + (p)[1] = ((i) >> 8) & 0xff; \ + (p)[0] = (i) & 0xff; \ +} while (0) + +#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)) ) + +/* The masking of the right shift is needed to allow n == 0 (using + just 32 - n and 64 - n results in undefined behaviour). Most uses + of these macros use a constant and non-zero rotation count. */ +#define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31)))) + +#define ROTL64(n,x) (((x)<<(n)) | ((x)>>((-(n))&63))) + +/* Requires that size > 0 */ +#define INCREMENT(size, ctr) \ + do { \ + unsigned increment_i = (size) - 1; \ + if (++(ctr)[increment_i] == 0) \ + while (increment_i > 0 \ + && ++(ctr)[--increment_i] == 0 ) \ + ; \ + } while (0) + + +/* Helper macro for Merkle-Damgård hash functions. Assumes the context + structs includes the following fields: + + uint8_t block[...]; // Buffer holding one block + unsigned int index; // Index into block +*/ + +/* Currently used by sha512 (and sha384) only. */ +#define MD_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low) + +/* Takes the compression function f as argument. NOTE: also clobbers + length and data. */ +#define MD_UPDATE(ctx, length, data, f, incr) \ + do { \ + if ((ctx)->index) \ + { \ + /* Try to fill partial block */ \ + unsigned __md_left = sizeof((ctx)->block) - (ctx)->index; \ + if ((length) < __md_left) \ + { \ + memcpy((ctx)->block + (ctx)->index, (data), (length)); \ + (ctx)->index += (length); \ + goto __md_done; /* Finished */ \ + } \ + else \ + { \ + memcpy((ctx)->block + (ctx)->index, (data), __md_left); \ + \ + f((ctx), (ctx)->block); \ + (incr); \ + \ + (data) += __md_left; \ + (length) -= __md_left; \ + } \ + } \ + while ((length) >= sizeof((ctx)->block)) \ + { \ + f((ctx), (data)); \ + (incr); \ + \ + (data) += sizeof((ctx)->block); \ + (length) -= sizeof((ctx)->block); \ + } \ + memcpy ((ctx)->block, (data), (length)); \ + (ctx)->index = (length); \ + __md_done: \ + ; \ + } while (0) + +/* Pads the block to a block boundary with the bit pattern 1 0*, + leaving size octets for the length field at the end. If needed, + compresses the block and starts a new one. */ +#define MD_PAD(ctx, size, f) \ + do { \ + unsigned __md_i; \ + __md_i = (ctx)->index; \ + \ + /* Set the first char of padding to 0x80. This is safe since there \ + is always at least one byte free */ \ + \ + assert(__md_i < sizeof((ctx)->block)); \ + (ctx)->block[__md_i++] = 0x80; \ + \ + if (__md_i > (sizeof((ctx)->block) - (size))) \ + { /* No room for length in this block. Process it and \ + pad with another one */ \ + memset((ctx)->block + __md_i, 0, sizeof((ctx)->block) - __md_i); \ + \ + f((ctx), (ctx)->block); \ + __md_i = 0; \ + } \ + memset((ctx)->block + __md_i, 0, \ + sizeof((ctx)->block) - (size) - __md_i); \ + \ + } while (0) + +#endif /* NETTLE_MACROS_H_INCLUDED */ diff --git a/md2-meta.c b/md2-meta.c new file mode 100644 index 0000000..b46815f --- /dev/null +++ b/md2-meta.c @@ -0,0 +1,41 @@ +/* md2-meta.c + + Copyright (C) 2003 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..a0cb1b6 --- /dev/null +++ b/md2.c @@ -0,0 +1,139 @@ +/* md2.c + + The MD2 hash function, described in RFC 1319. + + Copyright (C) 2003 Niels Möller, Andreas Sigfridsson + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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_BLOCK_SIZE); + + for (i = 0, t = ctx->C[15]; + iX[2 * MD2_BLOCK_SIZE + i] + = ctx->X[i] ^ ctx->X[MD2_BLOCK_SIZE + i]; + t = (ctx->C[i] ^= S[data[i]^t]); + } + for (i = t = 0; + i< MD2_BLOCK_SIZE + 2; + t = (t + i) & 0xff, i++) + { + unsigned j; + for (j = 0; j < 3 * MD2_BLOCK_SIZE; j++) + t = (ctx->X[j] ^= S[t]); + } +} + +void +md2_init(struct md2_ctx *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +void +md2_update(struct md2_ctx *ctx, + size_t length, + const uint8_t *data) +{ + MD_UPDATE(ctx, length, data, md2_transform, (void)0); +} + +void +md2_digest(struct md2_ctx *ctx, + size_t length, + uint8_t *digest) +{ + unsigned left; + + assert(length <= MD2_DIGEST_SIZE); + + left = MD2_BLOCK_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..560b2cb --- /dev/null +++ b/md2.h @@ -0,0 +1,79 @@ +/* md2.h + + The MD2 hash function, described in RFC 1319. + + Copyright (C) 2003 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_BLOCK_SIZE 16 +/* For backwards compatibility */ +#define MD2_DATA_SIZE MD2_BLOCK_SIZE + +struct md2_ctx +{ + uint8_t C[MD2_BLOCK_SIZE]; + uint8_t X[3 * MD2_BLOCK_SIZE]; + uint8_t block[MD2_BLOCK_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ +}; + +void +md2_init(struct md2_ctx *ctx); + +void +md2_update(struct md2_ctx *ctx, + size_t length, + const uint8_t *data); + +void +md2_digest(struct md2_ctx *ctx, + size_t 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..b0b857f --- /dev/null +++ b/md4-meta.c @@ -0,0 +1,41 @@ +/* md4-meta.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..f6330d1 --- /dev/null +++ b/md4.c @@ -0,0 +1,197 @@ +/* md4.c + + The MD4 hash function, described in RFC 1320. + + Copyright (C) 2003 Niels Möller, Marcus Comstedt + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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" +#include "nettle-write.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_compress(struct md4_ctx *ctx, const uint8_t *block); + +/* FIXME: Could be an alias for md5_init */ +void +md4_init(struct md4_ctx *ctx) +{ + /* Same constants as for md5. */ + const uint32_t iv[_MD4_DIGEST_LENGTH] = + { + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, + }; + memcpy(ctx->state, iv, sizeof(ctx->state)); + + ctx->count = 0; + ctx->index = 0; +} + +void +md4_update(struct md4_ctx *ctx, + size_t length, + const uint8_t *data) +{ + MD_UPDATE(ctx, length, data, md4_compress, ctx->count++); +} + +void +md4_digest(struct md4_ctx *ctx, + size_t length, + uint8_t *digest) +{ + uint64_t bit_count; + uint32_t data[MD4_DATA_LENGTH]; + unsigned i; + + assert(length <= MD4_DIGEST_SIZE); + + MD_PAD(ctx, 8, md4_compress); + for (i = 0; i < MD4_DATA_LENGTH - 2; i++) + data[i] = LE_READ_UINT32(ctx->block + 4*i); + + /* There are 512 = 2^9 bits in one block + * Little-endian order => Least significant word first */ + bit_count = (ctx->count << 9) | (ctx->index << 3); + data[MD4_DATA_LENGTH-2] = bit_count; + data[MD4_DATA_LENGTH-1] = bit_count >> 32; + md4_transform(ctx->state, data); + + _nettle_write_le32(length, digest, ctx->state); + 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_compress(struct md4_ctx *ctx, const uint8_t *block) +{ + uint32_t data[MD4_DATA_LENGTH]; + unsigned i; + + /* Endian independent conversion */ + for (i = 0; i<16; i++, block += 4) + data[i] = LE_READ_UINT32(block); + + md4_transform(ctx->state, data); +} diff --git a/md4.h b/md4.h new file mode 100644 index 0000000..f199a80 --- /dev/null +++ b/md4.h @@ -0,0 +1,83 @@ +/* md4.h + + The MD4 hash function, described in RFC 1320. + + Copyright (C) 2003 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_BLOCK_SIZE 64 +/* For backwards compatibility */ +#define MD4_DATA_SIZE MD4_BLOCK_SIZE + +/* Digest is kept internally as 4 32-bit words. */ +#define _MD4_DIGEST_LENGTH 4 + +/* FIXME: Identical to md5_ctx */ +struct md4_ctx +{ + uint32_t state[_MD4_DIGEST_LENGTH]; + uint64_t count; /* Block count */ + uint8_t block[MD4_BLOCK_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ +}; + +void +md4_init(struct md4_ctx *ctx); + +void +md4_update(struct md4_ctx *ctx, + size_t length, + const uint8_t *data); + +void +md4_digest(struct md4_ctx *ctx, + size_t 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..d0d6176 --- /dev/null +++ b/md5-compat.c @@ -0,0 +1,56 @@ +/* md5-compat.c + + The md5 hash function, RFC 1321-style interface. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..fd30982 --- /dev/null +++ b/md5-compat.h @@ -0,0 +1,58 @@ +/* md5-compat.h + + The md5 hash function, RFC 1321-style interface. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..dab33e3 --- /dev/null +++ b/md5-compress.c @@ -0,0 +1,174 @@ +/* md5-compress.c + + The compression function for the md5 hash function. + + Copyright (C) 2001, 2005 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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..e4013ed --- /dev/null +++ b/md5-meta.c @@ -0,0 +1,41 @@ +/* md5-meta.c + + Copyright (C) 2002 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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..142b112 --- /dev/null +++ b/md5.c @@ -0,0 +1,93 @@ +/* md5.c + + The MD5 hash function, described in RFC 1321. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* 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" +#include "nettle-write.h" + +void +md5_init(struct md5_ctx *ctx) +{ + const uint32_t iv[_MD5_DIGEST_LENGTH] = + { + 0x67452301, + 0xefcdab89, + 0x98badcfe, + 0x10325476, + }; + memcpy(ctx->state, iv, sizeof(ctx->state)); + ctx->count = 0; + ctx->index = 0; +} + +#define COMPRESS(ctx, data) (_nettle_md5_compress((ctx)->state, (data))) + +void +md5_update(struct md5_ctx *ctx, + size_t length, + const uint8_t *data) +{ + MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++); +} + +void +md5_digest(struct md5_ctx *ctx, + size_t length, + uint8_t *digest) +{ + uint64_t bit_count; + + assert(length <= MD5_DIGEST_SIZE); + + MD_PAD(ctx, 8, COMPRESS); + + /* There are 512 = 2^9 bits in one block */ + bit_count = (ctx->count << 9) | (ctx->index << 3); + + LE_WRITE_UINT64(ctx->block + (MD5_BLOCK_SIZE - 8), bit_count); + _nettle_md5_compress(ctx->state, ctx->block); + + _nettle_write_le32(length, digest, ctx->state); + md5_init(ctx); +} diff --git a/md5.h b/md5.h new file mode 100644 index 0000000..040cf9d --- /dev/null +++ b/md5.h @@ -0,0 +1,86 @@ +/* md5.h + + The MD5 hash function, described in RFC 1321. + + Copyright (C) 2001 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_BLOCK_SIZE 64 +/* For backwards compatibility */ +#define MD5_DATA_SIZE MD5_BLOCK_SIZE + +/* Digest is kept internally as 4 32-bit words. */ +#define _MD5_DIGEST_LENGTH 4 + +struct md5_ctx +{ + uint32_t state[_MD5_DIGEST_LENGTH]; + uint64_t count; /* Block count */ + uint8_t block[MD5_BLOCK_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ +}; + +void +md5_init(struct md5_ctx *ctx); + +void +md5_update(struct md5_ctx *ctx, + size_t length, + const uint8_t *data); + +void +md5_digest(struct md5_ctx *ctx, + size_t 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/memeql-sec.c b/memeql-sec.c new file mode 100644 index 0000000..b19052e --- /dev/null +++ b/memeql-sec.c @@ -0,0 +1,51 @@ +/* memeql-sec.c + + Copyright (C) 2016 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "memops.h" + +int +memeql_sec (const void *a, const void *b, size_t n) +{ + volatile const unsigned char *ap = (const unsigned char *) a; + volatile const unsigned char *bp = (const unsigned char *) b; + + volatile unsigned char diff; + size_t i; + + for (i = diff = 0; i < n; i++) + diff |= (ap[i] ^ bp[i]); + + return diff == 0; +} diff --git a/memops.h b/memops.h new file mode 100644 index 0000000..815d547 --- /dev/null +++ b/memops.h @@ -0,0 +1,57 @@ +/* memops.h + + Copyright (C) 2016 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_MEMOPS_H_INCLUDED +#define NETTLE_MEMOPS_H_INCLUDED + +#include "memxor.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define cnd_memcpy nettle_cnd_memcpy +#define memeql_sec nettle_memeql_sec + +int +memeql_sec (const void *a, const void *b, size_t n); + +/* Side-channel silent conditional memcpy. cnd must be 0 (nop) or 1 + (copy). */ +void +cnd_memcpy(int cnd, volatile void *dst, const volatile void *src, size_t n); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MEMOPS_H_INCLUDED */ diff --git a/memxor-internal.h b/memxor-internal.h new file mode 100644 index 0000000..dbb5e99 --- /dev/null +++ b/memxor-internal.h @@ -0,0 +1,73 @@ +/* memxor-internal.h + + Copyright (C) 2010, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_MEMXOR_INTERNAL_H_INCLUDED +#define NETTLE_MEMXOR_INTERNAL_H_INCLUDED + +#include "nettle-types.h" + +/* The word_t type is intended to be the native word size. */ +#if defined(__x86_64__) || defined(__arch64__) +/* Including on M$ windows, where unsigned long is only 32 bits */ +typedef uint64_t word_t; +#else +typedef unsigned long int word_t; +#endif + +#define ALIGN_OFFSET(p) ((uintptr_t) (p) % sizeof(word_t)) + +#ifndef WORDS_BIGENDIAN +#define MERGE(w0, sh_1, w1, sh_2) \ + (((w0) >> (sh_1)) | ((w1) << (sh_2))) +#else +#define MERGE(w0, sh_1, w1, sh_2) \ + (((w0) << (sh_1)) | ((w1) >> (sh_2))) +#endif + +#ifndef WORDS_BIGENDIAN +#define READ_PARTIAL(r,p,n) do { \ + word_t _rp_x; \ + unsigned _rp_i; \ + for (_rp_i = (n), _rp_x = (p)[--_rp_i]; _rp_i > 0;) \ + _rp_x = (_rp_x << CHAR_BIT) | (p)[--_rp_i]; \ + (r) = _rp_x; \ + } while (0) +#else +#define READ_PARTIAL(r,p,n) do { \ + word_t _rp_x; \ + unsigned _rp_i; \ + for (_rp_x = (p)[0], _rp_i = 1; _rp_i < (n); _rp_i++) \ + _rp_x = (_rp_x << CHAR_BIT) | (p)[_rp_i]; \ + (r) = _rp_x; \ + } while (0) +#endif + +#endif /* NETTLE_MEMXOR_INTERNAL_H_INCLUDED */ diff --git a/memxor.c b/memxor.c new file mode 100644 index 0000000..36306ac --- /dev/null +++ b/memxor.c @@ -0,0 +1,161 @@ +/* memxor.c + + Copyright (C) 2010, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Implementation inspired by memcmp in glibc, contributed to the FSF + by Torbjorn Granlund. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "memxor.h" +#include "memxor-internal.h" + +#define WORD_T_THRESH 16 + +/* XOR word-aligned areas. n is the number of words, not bytes. */ +static void +memxor_common_alignment (word_t *dst, const word_t *src, size_t n) +{ + /* FIXME: Require n > 0? */ + /* FIXME: Unroll four times, like memcmp? Probably not worth the + effort. */ + + if (n & 1) + { + n--; + dst[n] ^= src[n]; + } + while (n >= 2) + { + n -= 2; + dst[n+1] ^= src[n+1]; + dst[n] ^= src[n]; + } +} + +/* XOR *un-aligned* src-area onto aligned dst area. n is number of + words, not bytes. Assumes we can read complete words at the start + and end of the src operand. */ +static void +memxor_different_alignment (word_t *dst, const unsigned char *src, size_t n) +{ + int shl, shr; + const word_t *src_word; + unsigned offset = ALIGN_OFFSET (src); + word_t s0, s1; + + assert (n > 0); + shl = CHAR_BIT * offset; + shr = CHAR_BIT * (sizeof(word_t) - offset); + + src_word = (const word_t *) ((uintptr_t) src & -sizeof(word_t)); + + /* Read top offset bytes, in native byte order. */ + READ_PARTIAL (s0, (unsigned char *) &src_word[n], offset); +#ifdef WORDS_BIGENDIAN + s0 <<= shr; /* FIXME: Eliminate this shift? */ +#endif + + /* Do n-1 regular iterations */ + if (n & 1) + s1 = s0; + else + { + n--; + s1 = src_word[n]; + dst[n] ^= MERGE (s1, shl, s0, shr); + } + + assert (n & 1); + while (n > 2) + { + n -= 2; + s0 = src_word[n+1]; + dst[n+1] ^= MERGE(s0, shl, s1, shr); + s1 = src_word[n]; /* FIXME: Overread on last iteration */ + dst[n] ^= MERGE(s1, shl, s0, shr); + } + assert (n == 1); + /* Read low wordsize - offset bytes */ + READ_PARTIAL (s0, src, sizeof(word_t) - offset); +#ifndef WORDS_BIGENDIAN + s0 <<= shl; /* FIXME: eliminate shift? */ +#endif /* !WORDS_BIGENDIAN */ + + dst[0] ^= MERGE(s0, shl, s1, shr); +} + +/* Performance, Intel SU1400 (x86_64): 0.25 cycles/byte aligned, 0.45 + cycles/byte unaligned. */ + +/* XOR LEN bytes starting at SRCADDR onto DESTADDR. Result undefined + if the source overlaps with the destination. Return DESTADDR. */ +void * +memxor(void *dst_in, const void *src_in, size_t n) +{ + unsigned char *dst = dst_in; + const unsigned char *src = src_in; + + if (n >= WORD_T_THRESH) + { + unsigned i; + unsigned offset; + size_t nwords; + /* There are at least some bytes to compare. No need to test + for N == 0 in this alignment loop. */ + for (i = ALIGN_OFFSET(dst + n); i > 0; i--) + { + n--; + dst[n] ^= src[n]; + } + offset = ALIGN_OFFSET(src + n); + nwords = n / sizeof (word_t); + n %= sizeof (word_t); + + if (offset) + memxor_different_alignment ((word_t *) (dst+n), src+n, nwords); + else + memxor_common_alignment ((word_t *) (dst+n), + (const word_t *) (src+n), nwords); + } + while (n > 0) + { + n--; + dst[n] ^= src[n]; + } + + return dst; +} diff --git a/memxor.h b/memxor.h new file mode 100644 index 0000000..b7bef09 --- /dev/null +++ b/memxor.h @@ -0,0 +1,25 @@ +/* memxor.h + * + */ + +#ifndef NETTLE_MEMXOR_H_INCLUDED +#define NETTLE_MEMXOR_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define memxor nettle_memxor +#define memxor3 nettle_memxor3 + +void *memxor(void *dst, const void *src, size_t n); +void *memxor3(void *dst, const void *a, const void *b, size_t n); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_MEMXOR_H_INCLUDED */ diff --git a/memxor3.c b/memxor3.c new file mode 100644 index 0000000..fe208bf --- /dev/null +++ b/memxor3.c @@ -0,0 +1,292 @@ +/* memxor3.c + + Copyright (C) 2010, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +/* Implementation inspired by memcmp in glibc, contributed to the FSF + by Torbjorn Granlund. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "memxor.h" +#include "memxor-internal.h" + +#define WORD_T_THRESH 16 + +/* XOR word-aligned areas. n is the number of words, not bytes. */ +static void +memxor3_common_alignment (word_t *dst, + const word_t *a, const word_t *b, size_t n) +{ + /* FIXME: Require n > 0? */ + if (n & 1) + { + n--; + dst[n] = a[n] ^ b[n]; + } + while (n > 0) + { + n -= 2; + dst[n+1] = a[n+1] ^ b[n+1]; + dst[n] = a[n] ^ b[n]; + } +} + +static void +memxor3_different_alignment_b (word_t *dst, + const word_t *a, const unsigned char *b, + unsigned offset, size_t n) +{ + int shl, shr; + const word_t *b_word; + + word_t s0, s1; + + assert (n > 0); + + shl = CHAR_BIT * offset; + shr = CHAR_BIT * (sizeof(word_t) - offset); + + b_word = (const word_t *) ((uintptr_t) b & -sizeof(word_t)); + + /* Read top offset bytes, in native byte order. */ + READ_PARTIAL (s0, (unsigned char *) &b_word[n], offset); +#ifdef WORDS_BIGENDIAN + s0 <<= shr; +#endif + + if (n & 1) + s1 = s0; + else + { + n--; + s1 = b_word[n]; + dst[n] = a[n] ^ MERGE (s1, shl, s0, shr); + } + + while (n > 2) + { + n -= 2; + s0 = b_word[n+1]; + dst[n+1] = a[n+1] ^ MERGE(s0, shl, s1, shr); + s1 = b_word[n]; + dst[n] = a[n] ^ MERGE(s1, shl, s0, shr); + } + assert (n == 1); + /* Read low wordsize - offset bytes */ + READ_PARTIAL (s0, b, sizeof(word_t) - offset); +#ifndef WORDS_BIGENDIAN + s0 <<= shl; +#endif /* !WORDS_BIGENDIAN */ + + dst[0] = a[0] ^ MERGE(s0, shl, s1, shr); +} + +static void +memxor3_different_alignment_ab (word_t *dst, + const unsigned char *a, const unsigned char *b, + unsigned offset, size_t n) +{ + int shl, shr; + const word_t *a_word; + const word_t *b_word; + + word_t s0, s1, t; + + assert (n > 0); + + shl = CHAR_BIT * offset; + shr = CHAR_BIT * (sizeof(word_t) - offset); + + a_word = (const word_t *) ((uintptr_t) a & -sizeof(word_t)); + b_word = (const word_t *) ((uintptr_t) b & -sizeof(word_t)); + + /* Read top offset bytes, in native byte order. */ + READ_PARTIAL (s0, (unsigned char *) &a_word[n], offset); + READ_PARTIAL (t, (unsigned char *) &b_word[n], offset); + s0 ^= t; +#ifdef WORDS_BIGENDIAN + s0 <<= shr; +#endif + + if (n & 1) + s1 = s0; + else + { + n--; + s1 = a_word[n] ^ b_word[n]; + dst[n] = MERGE (s1, shl, s0, shr); + } + + while (n > 2) + { + n -= 2; + s0 = a_word[n+1] ^ b_word[n+1]; + dst[n+1] = MERGE(s0, shl, s1, shr); + s1 = a_word[n] ^ b_word[n]; + dst[n] = MERGE(s1, shl, s0, shr); + } + assert (n == 1); + /* Read low wordsize - offset bytes */ + READ_PARTIAL (s0, a, sizeof(word_t) - offset); + READ_PARTIAL (t, b, sizeof(word_t) - offset); + s0 ^= t; +#ifndef WORDS_BIGENDIAN + s0 <<= shl; +#endif /* !WORDS_BIGENDIAN */ + + dst[0] = MERGE(s0, shl, s1, shr); +} + +static void +memxor3_different_alignment_all (word_t *dst, + const unsigned char *a, const unsigned char *b, + unsigned a_offset, unsigned b_offset, + size_t n) +{ + int al, ar, bl, br; + const word_t *a_word; + const word_t *b_word; + + word_t a0, a1, b0, b1; + + al = CHAR_BIT * a_offset; + ar = CHAR_BIT * (sizeof(word_t) - a_offset); + bl = CHAR_BIT * b_offset; + br = CHAR_BIT * (sizeof(word_t) - b_offset); + + a_word = (const word_t *) ((uintptr_t) a & -sizeof(word_t)); + b_word = (const word_t *) ((uintptr_t) b & -sizeof(word_t)); + + /* Read top offset bytes, in native byte order. */ + READ_PARTIAL (a0, (unsigned char *) &a_word[n], a_offset); + READ_PARTIAL (b0, (unsigned char *) &b_word[n], b_offset); +#ifdef WORDS_BIGENDIAN + a0 <<= ar; + b0 <<= br; +#endif + + if (n & 1) + { + a1 = a0; b1 = b0; + } + else + { + n--; + a1 = a_word[n]; + b1 = b_word[n]; + + dst[n] = MERGE (a1, al, a0, ar) ^ MERGE (b1, bl, b0, br); + } + while (n > 2) + { + n -= 2; + a0 = a_word[n+1]; b0 = b_word[n+1]; + dst[n+1] = MERGE(a0, al, a1, ar) ^ MERGE(b0, bl, b1, br); + a1 = a_word[n]; b1 = b_word[n]; + dst[n] = MERGE(a1, al, a0, ar) ^ MERGE(b1, bl, b0, br); + } + assert (n == 1); + /* Read low wordsize - offset bytes */ + READ_PARTIAL (a0, a, sizeof(word_t) - a_offset); + READ_PARTIAL (b0, b, sizeof(word_t) - b_offset); +#ifndef WORDS_BIGENDIAN + a0 <<= al; + b0 <<= bl; +#endif /* !WORDS_BIGENDIAN */ + + dst[0] = MERGE(a0, al, a1, ar) ^ MERGE(b0, bl, b1, br); +} + +/* Current implementation processes data in descending order, to + support overlapping operation with one of the sources overlapping + the start of the destination area. This feature is used only + internally by cbc decrypt, and it is not advertised or documented + to nettle users. */ +void * +memxor3(void *dst_in, const void *a_in, const void *b_in, size_t n) +{ + unsigned char *dst = dst_in; + const unsigned char *a = a_in; + const unsigned char *b = b_in; + + if (n >= WORD_T_THRESH) + { + unsigned i; + unsigned a_offset; + unsigned b_offset; + size_t nwords; + + for (i = ALIGN_OFFSET(dst + n); i > 0; i--) + { + n--; + dst[n] = a[n] ^ b[n]; + } + + a_offset = ALIGN_OFFSET(a + n); + b_offset = ALIGN_OFFSET(b + n); + + nwords = n / sizeof (word_t); + n %= sizeof (word_t); + + if (a_offset == b_offset) + { + if (!a_offset) + memxor3_common_alignment((word_t *) (dst + n), + (const word_t *) (a + n), + (const word_t *) (b + n), nwords); + else + memxor3_different_alignment_ab((word_t *) (dst + n), + a + n, b + n, a_offset, + nwords); + } + else if (!a_offset) + memxor3_different_alignment_b((word_t *) (dst + n), + (const word_t *) (a + n), b + n, + b_offset, nwords); + else if (!b_offset) + memxor3_different_alignment_b((word_t *) (dst + n), + (const word_t *) (b + n), a + n, + a_offset, nwords); + else + memxor3_different_alignment_all((word_t *) (dst + n), a + n, b + n, + a_offset, b_offset, nwords); + + } + while (n-- > 0) + dst[n] = a[n] ^ b[n]; + + return dst; +} diff --git a/mini-gmp.c b/mini-gmp.c new file mode 100644 index 0000000..d4d257c --- /dev/null +++ b/mini-gmp.c @@ -0,0 +1,4424 @@ +/* mini-gmp, a minimalistic implementation of a GNU GMP subset. + + Contributed to the GNU project by Niels Möller + +Copyright 1991-1997, 1999-2017 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * 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. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +/* NOTE: All functions in this file which are not declared in + mini-gmp.h are internal, and are not intended to be compatible + neither with GMP nor with future versions of mini-gmp. */ + +/* Much of the material copied from GMP files, including: gmp-impl.h, + longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c, + mpn/generic/lshift.c, mpn/generic/mul_1.c, + mpn/generic/mul_basecase.c, mpn/generic/rshift.c, + mpn/generic/sbpi1_div_qr.c, mpn/generic/sub_n.c, + mpn/generic/submul_1.c. */ + +#include +#include +#include +#include +#include +#include + +#include "mini-gmp.h" + + +/* Macros */ +#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) + +#define GMP_LIMB_MAX (~ (mp_limb_t) 0) +#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1)) + +#define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2)) +#define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1) + +#define GMP_ULONG_BITS (sizeof(unsigned long) * CHAR_BIT) +#define GMP_ULONG_HIGHBIT ((unsigned long) 1 << (GMP_ULONG_BITS - 1)) + +#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) +#define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1)) + +#define GMP_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define GMP_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define GMP_CMP(a,b) (((a) > (b)) - ((a) < (b))) + +/* Return non-zero if xp,xsize and yp,ysize overlap. + If xp+xsize<=yp there's no overlap, or if yp+ysize<=xp there's no + overlap. If both these are false, there's an overlap. */ +#define GMP_MPN_OVERLAP_P(xp, xsize, yp, ysize) \ + ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp)) + +#define gmp_assert_nocarry(x) do { \ + mp_limb_t __cy = (x); \ + assert (__cy == 0); \ + } while (0) + +#define gmp_clz(count, x) do { \ + mp_limb_t __clz_x = (x); \ + unsigned __clz_c; \ + for (__clz_c = 0; \ + (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \ + __clz_c += 8) \ + __clz_x <<= 8; \ + for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \ + __clz_x <<= 1; \ + (count) = __clz_c; \ + } while (0) + +#define gmp_ctz(count, x) do { \ + mp_limb_t __ctz_x = (x); \ + unsigned __ctz_c = 0; \ + gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \ + (count) = GMP_LIMB_BITS - 1 - __ctz_c; \ + } while (0) + +#define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + mp_limb_t __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) + +#define gmp_sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + mp_limb_t __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - ((al) < (bl)); \ + (sl) = __x; \ + } while (0) + +#define gmp_umul_ppmm(w1, w0, u, v) \ + do { \ + mp_limb_t __x0, __x1, __x2, __x3; \ + unsigned __ul, __vl, __uh, __vh; \ + mp_limb_t __u = (u), __v = (v); \ + \ + __ul = __u & GMP_LLIMB_MASK; \ + __uh = __u >> (GMP_LIMB_BITS / 2); \ + __vl = __v & GMP_LLIMB_MASK; \ + __vh = __v >> (GMP_LIMB_BITS / 2); \ + \ + __x0 = (mp_limb_t) __ul * __vl; \ + __x1 = (mp_limb_t) __ul * __vh; \ + __x2 = (mp_limb_t) __uh * __vl; \ + __x3 = (mp_limb_t) __uh * __vh; \ + \ + __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \ + (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \ + } while (0) + +#define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ + do { \ + mp_limb_t _qh, _ql, _r, _mask; \ + gmp_umul_ppmm (_qh, _ql, (nh), (di)); \ + gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \ + _r = (nl) - _qh * (d); \ + _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \ + _qh += _mask; \ + _r += _mask & (d); \ + if (_r >= (d)) \ + { \ + _r -= (d); \ + _qh++; \ + } \ + \ + (r) = _r; \ + (q) = _qh; \ + } while (0) + +#define gmp_udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \ + do { \ + mp_limb_t _q0, _t1, _t0, _mask; \ + gmp_umul_ppmm ((q), _q0, (n2), (dinv)); \ + gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \ + \ + /* Compute the two most significant limbs of n - q'd */ \ + (r1) = (n1) - (d1) * (q); \ + gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \ + gmp_umul_ppmm (_t1, _t0, (d0), (q)); \ + gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \ + (q)++; \ + \ + /* Conditionally adjust q and the remainders */ \ + _mask = - (mp_limb_t) ((r1) >= _q0); \ + (q) += _mask; \ + gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \ + if ((r1) >= (d1)) \ + { \ + if ((r1) > (d1) || (r0) >= (d0)) \ + { \ + (q)++; \ + gmp_sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \ + } \ + } \ + } while (0) + +/* Swap macros. */ +#define MP_LIMB_T_SWAP(x, y) \ + do { \ + mp_limb_t __mp_limb_t_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_limb_t_swap__tmp; \ + } while (0) +#define MP_SIZE_T_SWAP(x, y) \ + do { \ + mp_size_t __mp_size_t_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_size_t_swap__tmp; \ + } while (0) +#define MP_BITCNT_T_SWAP(x,y) \ + do { \ + mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_bitcnt_t_swap__tmp; \ + } while (0) +#define MP_PTR_SWAP(x, y) \ + do { \ + mp_ptr __mp_ptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_ptr_swap__tmp; \ + } while (0) +#define MP_SRCPTR_SWAP(x, y) \ + do { \ + mp_srcptr __mp_srcptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mp_srcptr_swap__tmp; \ + } while (0) + +#define MPN_PTR_SWAP(xp,xs, yp,ys) \ + do { \ + MP_PTR_SWAP (xp, yp); \ + MP_SIZE_T_SWAP (xs, ys); \ + } while(0) +#define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \ + do { \ + MP_SRCPTR_SWAP (xp, yp); \ + MP_SIZE_T_SWAP (xs, ys); \ + } while(0) + +#define MPZ_PTR_SWAP(x, y) \ + do { \ + mpz_ptr __mpz_ptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mpz_ptr_swap__tmp; \ + } while (0) +#define MPZ_SRCPTR_SWAP(x, y) \ + do { \ + mpz_srcptr __mpz_srcptr_swap__tmp = (x); \ + (x) = (y); \ + (y) = __mpz_srcptr_swap__tmp; \ + } while (0) + +const int mp_bits_per_limb = GMP_LIMB_BITS; + + +/* Memory allocation and other helper functions. */ +static void +gmp_die (const char *msg) +{ + fprintf (stderr, "%s\n", msg); + abort(); +} + +static void * +gmp_default_alloc (size_t size) +{ + void *p; + + assert (size > 0); + + p = malloc (size); + if (!p) + gmp_die("gmp_default_alloc: Virtual memory exhausted."); + + return p; +} + +static void * +gmp_default_realloc (void *old, size_t old_size, size_t new_size) +{ + void * p; + + p = realloc (old, new_size); + + if (!p) + gmp_die("gmp_default_realloc: Virtual memory exhausted."); + + return p; +} + +static void +gmp_default_free (void *p, size_t size) +{ + free (p); +} + +static void * (*gmp_allocate_func) (size_t) = gmp_default_alloc; +static void * (*gmp_reallocate_func) (void *, size_t, size_t) = gmp_default_realloc; +static void (*gmp_free_func) (void *, size_t) = gmp_default_free; + +void +mp_get_memory_functions (void *(**alloc_func) (size_t), + void *(**realloc_func) (void *, size_t, size_t), + void (**free_func) (void *, size_t)) +{ + if (alloc_func) + *alloc_func = gmp_allocate_func; + + if (realloc_func) + *realloc_func = gmp_reallocate_func; + + if (free_func) + *free_func = gmp_free_func; +} + +void +mp_set_memory_functions (void *(*alloc_func) (size_t), + void *(*realloc_func) (void *, size_t, size_t), + void (*free_func) (void *, size_t)) +{ + if (!alloc_func) + alloc_func = gmp_default_alloc; + if (!realloc_func) + realloc_func = gmp_default_realloc; + if (!free_func) + free_func = gmp_default_free; + + gmp_allocate_func = alloc_func; + gmp_reallocate_func = realloc_func; + gmp_free_func = free_func; +} + +#define gmp_xalloc(size) ((*gmp_allocate_func)((size))) +#define gmp_free(p) ((*gmp_free_func) ((p), 0)) + +static mp_ptr +gmp_xalloc_limbs (mp_size_t size) +{ + return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t)); +} + +static mp_ptr +gmp_xrealloc_limbs (mp_ptr old, mp_size_t size) +{ + assert (size > 0); + return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t)); +} + + +/* MPN interface */ + +void +mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + d[i] = s[i]; +} + +void +mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n) +{ + while (--n >= 0) + d[n] = s[n]; +} + +int +mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + while (--n >= 0) + { + if (ap[n] != bp[n]) + return ap[n] > bp[n] ? 1 : -1; + } + return 0; +} + +static int +mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) +{ + if (an != bn) + return an < bn ? -1 : 1; + else + return mpn_cmp (ap, bp, an); +} + +static mp_size_t +mpn_normalized_size (mp_srcptr xp, mp_size_t n) +{ + while (n > 0 && xp[n-1] == 0) + --n; + return n; +} + +int +mpn_zero_p(mp_srcptr rp, mp_size_t n) +{ + return mpn_normalized_size (rp, n) == 0; +} + +void +mpn_zero (mp_ptr rp, mp_size_t n) +{ + while (--n >= 0) + rp[n] = 0; +} + +mp_limb_t +mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) +{ + mp_size_t i; + + assert (n > 0); + i = 0; + do + { + mp_limb_t r = ap[i] + b; + /* Carry out */ + b = (r < b); + rp[i] = r; + } + while (++i < n); + + return b; +} + +mp_limb_t +mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + mp_size_t i; + mp_limb_t cy; + + for (i = 0, cy = 0; i < n; i++) + { + mp_limb_t a, b, r; + a = ap[i]; b = bp[i]; + r = a + cy; + cy = (r < cy); + r += b; + cy += (r < b); + rp[i] = r; + } + return cy; +} + +mp_limb_t +mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) +{ + mp_limb_t cy; + + assert (an >= bn); + + cy = mpn_add_n (rp, ap, bp, bn); + if (an > bn) + cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy); + return cy; +} + +mp_limb_t +mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) +{ + mp_size_t i; + + assert (n > 0); + + i = 0; + do + { + mp_limb_t a = ap[i]; + /* Carry out */ + mp_limb_t cy = a < b; + rp[i] = a - b; + b = cy; + } + while (++i < n); + + return b; +} + +mp_limb_t +mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + mp_size_t i; + mp_limb_t cy; + + for (i = 0, cy = 0; i < n; i++) + { + mp_limb_t a, b; + a = ap[i]; b = bp[i]; + b += cy; + cy = (b < cy); + cy += (a < b); + rp[i] = a - b; + } + return cy; +} + +mp_limb_t +mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn) +{ + mp_limb_t cy; + + assert (an >= bn); + + cy = mpn_sub_n (rp, ap, bp, bn); + if (an > bn) + cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy); + return cy; +} + +mp_limb_t +mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) +{ + mp_limb_t ul, cl, hpl, lpl; + + assert (n >= 1); + + cl = 0; + do + { + ul = *up++; + gmp_umul_ppmm (hpl, lpl, ul, vl); + + lpl += cl; + cl = (lpl < cl) + hpl; + + *rp++ = lpl; + } + while (--n != 0); + + return cl; +} + +mp_limb_t +mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) +{ + mp_limb_t ul, cl, hpl, lpl, rl; + + assert (n >= 1); + + cl = 0; + do + { + ul = *up++; + gmp_umul_ppmm (hpl, lpl, ul, vl); + + lpl += cl; + cl = (lpl < cl) + hpl; + + rl = *rp; + lpl = rl + lpl; + cl += lpl < rl; + *rp++ = lpl; + } + while (--n != 0); + + return cl; +} + +mp_limb_t +mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) +{ + mp_limb_t ul, cl, hpl, lpl, rl; + + assert (n >= 1); + + cl = 0; + do + { + ul = *up++; + gmp_umul_ppmm (hpl, lpl, ul, vl); + + lpl += cl; + cl = (lpl < cl) + hpl; + + rl = *rp; + lpl = rl - lpl; + cl += lpl > rl; + *rp++ = lpl; + } + while (--n != 0); + + return cl; +} + +mp_limb_t +mpn_mul (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn) +{ + assert (un >= vn); + assert (vn >= 1); + assert (!GMP_MPN_OVERLAP_P(rp, un + vn, up, un)); + assert (!GMP_MPN_OVERLAP_P(rp, un + vn, vp, vn)); + + /* We first multiply by the low order limb. This result can be + stored, not added, to rp. We also avoid a loop for zeroing this + way. */ + + rp[un] = mpn_mul_1 (rp, up, un, vp[0]); + + /* Now accumulate the product of up[] and the next higher limb from + vp[]. */ + + while (--vn >= 1) + { + rp += 1, vp += 1; + rp[un] = mpn_addmul_1 (rp, up, un, vp[0]); + } + return rp[un]; +} + +void +mpn_mul_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n) +{ + mpn_mul (rp, ap, n, bp, n); +} + +void +mpn_sqr (mp_ptr rp, mp_srcptr ap, mp_size_t n) +{ + mpn_mul (rp, ap, n, ap, n); +} + +mp_limb_t +mpn_lshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) +{ + mp_limb_t high_limb, low_limb; + unsigned int tnc; + mp_limb_t retval; + + assert (n >= 1); + assert (cnt >= 1); + assert (cnt < GMP_LIMB_BITS); + + up += n; + rp += n; + + tnc = GMP_LIMB_BITS - cnt; + low_limb = *--up; + retval = low_limb >> tnc; + high_limb = (low_limb << cnt); + + while (--n != 0) + { + low_limb = *--up; + *--rp = high_limb | (low_limb >> tnc); + high_limb = (low_limb << cnt); + } + *--rp = high_limb; + + return retval; +} + +mp_limb_t +mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) +{ + mp_limb_t high_limb, low_limb; + unsigned int tnc; + mp_limb_t retval; + + assert (n >= 1); + assert (cnt >= 1); + assert (cnt < GMP_LIMB_BITS); + + tnc = GMP_LIMB_BITS - cnt; + high_limb = *up++; + retval = (high_limb << tnc); + low_limb = high_limb >> cnt; + + while (--n != 0) + { + high_limb = *up++; + *rp++ = low_limb | (high_limb << tnc); + low_limb = high_limb >> cnt; + } + *rp = low_limb; + + return retval; +} + +static mp_bitcnt_t +mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un, + mp_limb_t ux) +{ + unsigned cnt; + + assert (ux == 0 || ux == GMP_LIMB_MAX); + assert (0 <= i && i <= un ); + + while (limb == 0) + { + i++; + if (i == un) + return (ux == 0 ? ~(mp_bitcnt_t) 0 : un * GMP_LIMB_BITS); + limb = ux ^ up[i]; + } + gmp_ctz (cnt, limb); + return (mp_bitcnt_t) i * GMP_LIMB_BITS + cnt; +} + +mp_bitcnt_t +mpn_scan1 (mp_srcptr ptr, mp_bitcnt_t bit) +{ + mp_size_t i; + i = bit / GMP_LIMB_BITS; + + return mpn_common_scan ( ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)), + i, ptr, i, 0); +} + +mp_bitcnt_t +mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit) +{ + mp_size_t i; + i = bit / GMP_LIMB_BITS; + + return mpn_common_scan (~ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)), + i, ptr, i, GMP_LIMB_MAX); +} + +void +mpn_com (mp_ptr rp, mp_srcptr up, mp_size_t n) +{ + while (--n >= 0) + *rp++ = ~ *up++; +} + +mp_limb_t +mpn_neg (mp_ptr rp, mp_srcptr up, mp_size_t n) +{ + while (*up == 0) + { + *rp = 0; + if (!--n) + return 0; + ++up; ++rp; + } + *rp = - *up; + mpn_com (++rp, ++up, --n); + return 1; +} + + +/* MPN division interface. */ + +/* The 3/2 inverse is defined as + + m = floor( (B^3-1) / (B u1 + u0)) - B +*/ +mp_limb_t +mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) +{ + mp_limb_t r, p, m, ql; + unsigned ul, uh, qh; + + assert (u1 >= GMP_LIMB_HIGHBIT); + + /* For notation, let b denote the half-limb base, so that B = b^2. + Split u1 = b uh + ul. */ + ul = u1 & GMP_LLIMB_MASK; + uh = u1 >> (GMP_LIMB_BITS / 2); + + /* Approximation of the high half of quotient. Differs from the 2/1 + inverse of the half limb uh, since we have already subtracted + u0. */ + qh = ~u1 / uh; + + /* Adjust to get a half-limb 3/2 inverse, i.e., we want + + qh' = floor( (b^3 - 1) / u) - b = floor ((b^3 - b u - 1) / u + = floor( (b (~u) + b-1) / u), + + and the remainder + + r = b (~u) + b-1 - qh (b uh + ul) + = b (~u - qh uh) + b-1 - qh ul + + Subtraction of qh ul may underflow, which implies adjustments. + But by normalization, 2 u >= B > qh ul, so we need to adjust by + at most 2. + */ + + r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK; + + p = (mp_limb_t) qh * ul; + /* Adjustment steps taken from udiv_qrnnd_c */ + if (r < p) + { + qh--; + r += u1; + if (r >= u1) /* i.e. we didn't get carry when adding to r */ + if (r < p) + { + qh--; + r += u1; + } + } + r -= p; + + /* Low half of the quotient is + + ql = floor ( (b r + b-1) / u1). + + This is a 3/2 division (on half-limbs), for which qh is a + suitable inverse. */ + + p = (r >> (GMP_LIMB_BITS / 2)) * qh + r; + /* Unlike full-limb 3/2, we can add 1 without overflow. For this to + work, it is essential that ql is a full mp_limb_t. */ + ql = (p >> (GMP_LIMB_BITS / 2)) + 1; + + /* By the 3/2 trick, we don't need the high half limb. */ + r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1; + + if (r >= (p << (GMP_LIMB_BITS / 2))) + { + ql--; + r += u1; + } + m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql; + if (r >= u1) + { + m++; + r -= u1; + } + + /* Now m is the 2/1 invers of u1. If u0 > 0, adjust it to become a + 3/2 inverse. */ + if (u0 > 0) + { + mp_limb_t th, tl; + r = ~r; + r += u0; + if (r < u0) + { + m--; + if (r >= u1) + { + m--; + r -= u1; + } + r -= u1; + } + gmp_umul_ppmm (th, tl, u0, m); + r += th; + if (r < th) + { + m--; + m -= ((r > u1) | ((r == u1) & (tl > u0))); + } + } + + return m; +} + +struct gmp_div_inverse +{ + /* Normalization shift count. */ + unsigned shift; + /* Normalized divisor (d0 unused for mpn_div_qr_1) */ + mp_limb_t d1, d0; + /* Inverse, for 2/1 or 3/2. */ + mp_limb_t di; +}; + +static void +mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d) +{ + unsigned shift; + + assert (d > 0); + gmp_clz (shift, d); + inv->shift = shift; + inv->d1 = d << shift; + inv->di = mpn_invert_limb (inv->d1); +} + +static void +mpn_div_qr_2_invert (struct gmp_div_inverse *inv, + mp_limb_t d1, mp_limb_t d0) +{ + unsigned shift; + + assert (d1 > 0); + gmp_clz (shift, d1); + inv->shift = shift; + if (shift > 0) + { + d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift)); + d0 <<= shift; + } + inv->d1 = d1; + inv->d0 = d0; + inv->di = mpn_invert_3by2 (d1, d0); +} + +static void +mpn_div_qr_invert (struct gmp_div_inverse *inv, + mp_srcptr dp, mp_size_t dn) +{ + assert (dn > 0); + + if (dn == 1) + mpn_div_qr_1_invert (inv, dp[0]); + else if (dn == 2) + mpn_div_qr_2_invert (inv, dp[1], dp[0]); + else + { + unsigned shift; + mp_limb_t d1, d0; + + d1 = dp[dn-1]; + d0 = dp[dn-2]; + assert (d1 > 0); + gmp_clz (shift, d1); + inv->shift = shift; + if (shift > 0) + { + d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift)); + d0 = (d0 << shift) | (dp[dn-3] >> (GMP_LIMB_BITS - shift)); + } + inv->d1 = d1; + inv->d0 = d0; + inv->di = mpn_invert_3by2 (d1, d0); + } +} + +/* Not matching current public gmp interface, rather corresponding to + the sbpi1_div_* functions. */ +static mp_limb_t +mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn, + const struct gmp_div_inverse *inv) +{ + mp_limb_t d, di; + mp_limb_t r; + mp_ptr tp = NULL; + + if (inv->shift > 0) + { + tp = gmp_xalloc_limbs (nn); + r = mpn_lshift (tp, np, nn, inv->shift); + np = tp; + } + else + r = 0; + + d = inv->d1; + di = inv->di; + while (--nn >= 0) + { + mp_limb_t q; + + gmp_udiv_qrnnd_preinv (q, r, r, np[nn], d, di); + if (qp) + qp[nn] = q; + } + if (inv->shift > 0) + gmp_free (tp); + + return r >> inv->shift; +} + +static mp_limb_t +mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d) +{ + assert (d > 0); + + /* Special case for powers of two. */ + if ((d & (d-1)) == 0) + { + mp_limb_t r = np[0] & (d-1); + if (qp) + { + if (d <= 1) + mpn_copyi (qp, np, nn); + else + { + unsigned shift; + gmp_ctz (shift, d); + mpn_rshift (qp, np, nn, shift); + } + } + return r; + } + else + { + struct gmp_div_inverse inv; + mpn_div_qr_1_invert (&inv, d); + return mpn_div_qr_1_preinv (qp, np, nn, &inv); + } +} + +static void +mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn, + const struct gmp_div_inverse *inv) +{ + unsigned shift; + mp_size_t i; + mp_limb_t d1, d0, di, r1, r0; + mp_ptr tp; + + assert (nn >= 2); + shift = inv->shift; + d1 = inv->d1; + d0 = inv->d0; + di = inv->di; + + if (shift > 0) + { + tp = gmp_xalloc_limbs (nn); + r1 = mpn_lshift (tp, np, nn, shift); + np = tp; + } + else + r1 = 0; + + r0 = np[nn - 1]; + + i = nn - 2; + do + { + mp_limb_t n0, q; + n0 = np[i]; + gmp_udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di); + + if (qp) + qp[i] = q; + } + while (--i >= 0); + + if (shift > 0) + { + assert ((r0 << (GMP_LIMB_BITS - shift)) == 0); + r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift)); + r1 >>= shift; + + gmp_free (tp); + } + + rp[1] = r1; + rp[0] = r0; +} + +#if 0 +static void +mpn_div_qr_2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn, + mp_limb_t d1, mp_limb_t d0) +{ + struct gmp_div_inverse inv; + assert (nn >= 2); + + mpn_div_qr_2_invert (&inv, d1, d0); + mpn_div_qr_2_preinv (qp, rp, np, nn, &inv); +} +#endif + +static void +mpn_div_qr_pi1 (mp_ptr qp, + mp_ptr np, mp_size_t nn, mp_limb_t n1, + mp_srcptr dp, mp_size_t dn, + mp_limb_t dinv) +{ + mp_size_t i; + + mp_limb_t d1, d0; + mp_limb_t cy, cy1; + mp_limb_t q; + + assert (dn > 2); + assert (nn >= dn); + + d1 = dp[dn - 1]; + d0 = dp[dn - 2]; + + assert ((d1 & GMP_LIMB_HIGHBIT) != 0); + /* Iteration variable is the index of the q limb. + * + * We divide + * by + */ + + i = nn - dn; + do + { + mp_limb_t n0 = np[dn-1+i]; + + if (n1 == d1 && n0 == d0) + { + q = GMP_LIMB_MAX; + mpn_submul_1 (np+i, dp, dn, q); + n1 = np[dn-1+i]; /* update n1, last loop's value will now be invalid */ + } + else + { + gmp_udiv_qr_3by2 (q, n1, n0, n1, n0, np[dn-2+i], d1, d0, dinv); + + cy = mpn_submul_1 (np + i, dp, dn-2, q); + + cy1 = n0 < cy; + n0 = n0 - cy; + cy = n1 < cy1; + n1 = n1 - cy1; + np[dn-2+i] = n0; + + if (cy != 0) + { + n1 += d1 + mpn_add_n (np + i, np + i, dp, dn - 1); + q--; + } + } + + if (qp) + qp[i] = q; + } + while (--i >= 0); + + np[dn - 1] = n1; +} + +static void +mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn, + mp_srcptr dp, mp_size_t dn, + const struct gmp_div_inverse *inv) +{ + assert (dn > 0); + assert (nn >= dn); + + if (dn == 1) + np[0] = mpn_div_qr_1_preinv (qp, np, nn, inv); + else if (dn == 2) + mpn_div_qr_2_preinv (qp, np, np, nn, inv); + else + { + mp_limb_t nh; + unsigned shift; + + assert (inv->d1 == dp[dn-1]); + assert (inv->d0 == dp[dn-2]); + assert ((inv->d1 & GMP_LIMB_HIGHBIT) != 0); + + shift = inv->shift; + if (shift > 0) + nh = mpn_lshift (np, np, nn, shift); + else + nh = 0; + + mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di); + + if (shift > 0) + gmp_assert_nocarry (mpn_rshift (np, np, dn, shift)); + } +} + +static void +mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn) +{ + struct gmp_div_inverse inv; + mp_ptr tp = NULL; + + assert (dn > 0); + assert (nn >= dn); + + mpn_div_qr_invert (&inv, dp, dn); + if (dn > 2 && inv.shift > 0) + { + tp = gmp_xalloc_limbs (dn); + gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift)); + dp = tp; + } + mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv); + if (tp) + gmp_free (tp); +} + + +/* MPN base conversion. */ +static unsigned +mpn_base_power_of_two_p (unsigned b) +{ + switch (b) + { + case 2: return 1; + case 4: return 2; + case 8: return 3; + case 16: return 4; + case 32: return 5; + case 64: return 6; + case 128: return 7; + case 256: return 8; + default: return 0; + } +} + +struct mpn_base_info +{ + /* bb is the largest power of the base which fits in one limb, and + exp is the corresponding exponent. */ + unsigned exp; + mp_limb_t bb; +}; + +static void +mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b) +{ + mp_limb_t m; + mp_limb_t p; + unsigned exp; + + m = GMP_LIMB_MAX / b; + for (exp = 1, p = b; p <= m; exp++) + p *= b; + + info->exp = exp; + info->bb = p; +} + +static mp_bitcnt_t +mpn_limb_size_in_base_2 (mp_limb_t u) +{ + unsigned shift; + + assert (u > 0); + gmp_clz (shift, u); + return GMP_LIMB_BITS - shift; +} + +static size_t +mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un) +{ + unsigned char mask; + size_t sn, j; + mp_size_t i; + unsigned shift; + + sn = ((un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]) + + bits - 1) / bits; + + mask = (1U << bits) - 1; + + for (i = 0, j = sn, shift = 0; j-- > 0;) + { + unsigned char digit = up[i] >> shift; + + shift += bits; + + if (shift >= GMP_LIMB_BITS && ++i < un) + { + shift -= GMP_LIMB_BITS; + digit |= up[i] << (bits - shift); + } + sp[j] = digit & mask; + } + return sn; +} + +/* We generate digits from the least significant end, and reverse at + the end. */ +static size_t +mpn_limb_get_str (unsigned char *sp, mp_limb_t w, + const struct gmp_div_inverse *binv) +{ + mp_size_t i; + for (i = 0; w > 0; i++) + { + mp_limb_t h, l, r; + + h = w >> (GMP_LIMB_BITS - binv->shift); + l = w << binv->shift; + + gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di); + assert ( (r << (GMP_LIMB_BITS - binv->shift)) == 0); + r >>= binv->shift; + + sp[i] = r; + } + return i; +} + +static size_t +mpn_get_str_other (unsigned char *sp, + int base, const struct mpn_base_info *info, + mp_ptr up, mp_size_t un) +{ + struct gmp_div_inverse binv; + size_t sn; + size_t i; + + mpn_div_qr_1_invert (&binv, base); + + sn = 0; + + if (un > 1) + { + struct gmp_div_inverse bbinv; + mpn_div_qr_1_invert (&bbinv, info->bb); + + do + { + mp_limb_t w; + size_t done; + w = mpn_div_qr_1_preinv (up, up, un, &bbinv); + un -= (up[un-1] == 0); + done = mpn_limb_get_str (sp + sn, w, &binv); + + for (sn += done; done < info->exp; done++) + sp[sn++] = 0; + } + while (un > 1); + } + sn += mpn_limb_get_str (sp + sn, up[0], &binv); + + /* Reverse order */ + for (i = 0; 2*i + 1 < sn; i++) + { + unsigned char t = sp[i]; + sp[i] = sp[sn - i - 1]; + sp[sn - i - 1] = t; + } + + return sn; +} + +size_t +mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un) +{ + unsigned bits; + + assert (un > 0); + assert (up[un-1] > 0); + + bits = mpn_base_power_of_two_p (base); + if (bits) + return mpn_get_str_bits (sp, bits, up, un); + else + { + struct mpn_base_info info; + + mpn_get_base_info (&info, base); + return mpn_get_str_other (sp, base, &info, up, un); + } +} + +static mp_size_t +mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn, + unsigned bits) +{ + mp_size_t rn; + size_t j; + unsigned shift; + + for (j = sn, rn = 0, shift = 0; j-- > 0; ) + { + if (shift == 0) + { + rp[rn++] = sp[j]; + shift += bits; + } + else + { + rp[rn-1] |= (mp_limb_t) sp[j] << shift; + shift += bits; + if (shift >= GMP_LIMB_BITS) + { + shift -= GMP_LIMB_BITS; + if (shift > 0) + rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift); + } + } + } + rn = mpn_normalized_size (rp, rn); + return rn; +} + +/* Result is usually normalized, except for all-zero input, in which + case a single zero limb is written at *RP, and 1 is returned. */ +static mp_size_t +mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn, + mp_limb_t b, const struct mpn_base_info *info) +{ + mp_size_t rn; + mp_limb_t w; + unsigned k; + size_t j; + + assert (sn > 0); + + k = 1 + (sn - 1) % info->exp; + + j = 0; + w = sp[j++]; + while (--k != 0) + w = w * b + sp[j++]; + + rp[0] = w; + + for (rn = 1; j < sn;) + { + mp_limb_t cy; + + w = sp[j++]; + for (k = 1; k < info->exp; k++) + w = w * b + sp[j++]; + + cy = mpn_mul_1 (rp, rp, rn, info->bb); + cy += mpn_add_1 (rp, rp, rn, w); + if (cy > 0) + rp[rn++] = cy; + } + assert (j == sn); + + return rn; +} + +mp_size_t +mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base) +{ + unsigned bits; + + if (sn == 0) + return 0; + + bits = mpn_base_power_of_two_p (base); + if (bits) + return mpn_set_str_bits (rp, sp, sn, bits); + else + { + struct mpn_base_info info; + + mpn_get_base_info (&info, base); + return mpn_set_str_other (rp, sp, sn, base, &info); + } +} + + +/* MPZ interface */ +void +mpz_init (mpz_t r) +{ + static const mp_limb_t dummy_limb = 0xc1a0; + + r->_mp_alloc = 0; + r->_mp_size = 0; + r->_mp_d = (mp_ptr) &dummy_limb; +} + +/* The utility of this function is a bit limited, since many functions + assigns the result variable using mpz_swap. */ +void +mpz_init2 (mpz_t r, mp_bitcnt_t bits) +{ + mp_size_t rn; + + bits -= (bits != 0); /* Round down, except if 0 */ + rn = 1 + bits / GMP_LIMB_BITS; + + r->_mp_alloc = rn; + r->_mp_size = 0; + r->_mp_d = gmp_xalloc_limbs (rn); +} + +void +mpz_clear (mpz_t r) +{ + if (r->_mp_alloc) + gmp_free (r->_mp_d); +} + +static mp_ptr +mpz_realloc (mpz_t r, mp_size_t size) +{ + size = GMP_MAX (size, 1); + + if (r->_mp_alloc) + r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size); + else + r->_mp_d = gmp_xalloc_limbs (size); + r->_mp_alloc = size; + + if (GMP_ABS (r->_mp_size) > size) + r->_mp_size = 0; + + return r->_mp_d; +} + +/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */ +#define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc \ + ? mpz_realloc(z,n) \ + : (z)->_mp_d) + +/* MPZ assignment and basic conversions. */ +void +mpz_set_si (mpz_t r, signed long int x) +{ + if (x >= 0) + mpz_set_ui (r, x); + else /* (x < 0) */ + { + r->_mp_size = -1; + MPZ_REALLOC (r, 1)[0] = GMP_NEG_CAST (unsigned long int, x); + } +} + +void +mpz_set_ui (mpz_t r, unsigned long int x) +{ + if (x > 0) + { + r->_mp_size = 1; + MPZ_REALLOC (r, 1)[0] = x; + } + else + r->_mp_size = 0; +} + +void +mpz_set (mpz_t r, const mpz_t x) +{ + /* Allow the NOP r == x */ + if (r != x) + { + mp_size_t n; + mp_ptr rp; + + n = GMP_ABS (x->_mp_size); + rp = MPZ_REALLOC (r, n); + + mpn_copyi (rp, x->_mp_d, n); + r->_mp_size = x->_mp_size; + } +} + +void +mpz_init_set_si (mpz_t r, signed long int x) +{ + mpz_init (r); + mpz_set_si (r, x); +} + +void +mpz_init_set_ui (mpz_t r, unsigned long int x) +{ + mpz_init (r); + mpz_set_ui (r, x); +} + +void +mpz_init_set (mpz_t r, const mpz_t x) +{ + mpz_init (r); + mpz_set (r, x); +} + +int +mpz_fits_slong_p (const mpz_t u) +{ + mp_size_t us = u->_mp_size; + + if (us == 1) + return u->_mp_d[0] < GMP_LIMB_HIGHBIT; + else if (us == -1) + return u->_mp_d[0] <= GMP_LIMB_HIGHBIT; + else + return (us == 0); +} + +int +mpz_fits_ulong_p (const mpz_t u) +{ + mp_size_t us = u->_mp_size; + + return (us == (us > 0)); +} + +long int +mpz_get_si (const mpz_t u) +{ + if (u->_mp_size < 0) + /* This expression is necessary to properly handle 0x80000000 */ + return -1 - (long) ((u->_mp_d[0] - 1) & ~GMP_LIMB_HIGHBIT); + else + return (long) (mpz_get_ui (u) & ~GMP_LIMB_HIGHBIT); +} + +unsigned long int +mpz_get_ui (const mpz_t u) +{ + return u->_mp_size == 0 ? 0 : u->_mp_d[0]; +} + +size_t +mpz_size (const mpz_t u) +{ + return GMP_ABS (u->_mp_size); +} + +mp_limb_t +mpz_getlimbn (const mpz_t u, mp_size_t n) +{ + if (n >= 0 && n < GMP_ABS (u->_mp_size)) + return u->_mp_d[n]; + else + return 0; +} + +void +mpz_realloc2 (mpz_t x, mp_bitcnt_t n) +{ + mpz_realloc (x, 1 + (n - (n != 0)) / GMP_LIMB_BITS); +} + +mp_srcptr +mpz_limbs_read (mpz_srcptr x) +{ + return x->_mp_d; +} + +mp_ptr +mpz_limbs_modify (mpz_t x, mp_size_t n) +{ + assert (n > 0); + return MPZ_REALLOC (x, n); +} + +mp_ptr +mpz_limbs_write (mpz_t x, mp_size_t n) +{ + return mpz_limbs_modify (x, n); +} + +void +mpz_limbs_finish (mpz_t x, mp_size_t xs) +{ + mp_size_t xn; + xn = mpn_normalized_size (x->_mp_d, GMP_ABS (xs)); + x->_mp_size = xs < 0 ? -xn : xn; +} + +mpz_srcptr +mpz_roinit_n (mpz_t x, mp_srcptr xp, mp_size_t xs) +{ + x->_mp_alloc = 0; + x->_mp_d = (mp_ptr) xp; + mpz_limbs_finish (x, xs); + return x; +} + + +/* Conversions and comparison to double. */ +void +mpz_set_d (mpz_t r, double x) +{ + int sign; + mp_ptr rp; + mp_size_t rn, i; + double B; + double Bi; + mp_limb_t f; + + /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is + zero or infinity. */ + if (x != x || x == x * 0.5) + { + r->_mp_size = 0; + return; + } + + sign = x < 0.0 ; + if (sign) + x = - x; + + if (x < 1.0) + { + r->_mp_size = 0; + return; + } + B = 2.0 * (double) GMP_LIMB_HIGHBIT; + Bi = 1.0 / B; + for (rn = 1; x >= B; rn++) + x *= Bi; + + rp = MPZ_REALLOC (r, rn); + + f = (mp_limb_t) x; + x -= f; + assert (x < 1.0); + i = rn-1; + rp[i] = f; + while (--i >= 0) + { + x = B * x; + f = (mp_limb_t) x; + x -= f; + assert (x < 1.0); + rp[i] = f; + } + + r->_mp_size = sign ? - rn : rn; +} + +void +mpz_init_set_d (mpz_t r, double x) +{ + mpz_init (r); + mpz_set_d (r, x); +} + +double +mpz_get_d (const mpz_t u) +{ + mp_size_t un; + double x; + double B = 2.0 * (double) GMP_LIMB_HIGHBIT; + + un = GMP_ABS (u->_mp_size); + + if (un == 0) + return 0.0; + + x = u->_mp_d[--un]; + while (un > 0) + x = B*x + u->_mp_d[--un]; + + if (u->_mp_size < 0) + x = -x; + + return x; +} + +int +mpz_cmpabs_d (const mpz_t x, double d) +{ + mp_size_t xn; + double B, Bi; + mp_size_t i; + + xn = x->_mp_size; + d = GMP_ABS (d); + + if (xn != 0) + { + xn = GMP_ABS (xn); + + B = 2.0 * (double) GMP_LIMB_HIGHBIT; + Bi = 1.0 / B; + + /* Scale d so it can be compared with the top limb. */ + for (i = 1; i < xn; i++) + d *= Bi; + + if (d >= B) + return -1; + + /* Compare floor(d) to top limb, subtract and cancel when equal. */ + for (i = xn; i-- > 0;) + { + mp_limb_t f, xl; + + f = (mp_limb_t) d; + xl = x->_mp_d[i]; + if (xl > f) + return 1; + else if (xl < f) + return -1; + d = B * (d - f); + } + } + return - (d > 0.0); +} + +int +mpz_cmp_d (const mpz_t x, double d) +{ + if (x->_mp_size < 0) + { + if (d >= 0.0) + return -1; + else + return -mpz_cmpabs_d (x, d); + } + else + { + if (d < 0.0) + return 1; + else + return mpz_cmpabs_d (x, d); + } +} + + +/* MPZ comparisons and the like. */ +int +mpz_sgn (const mpz_t u) +{ + return GMP_CMP (u->_mp_size, 0); +} + +int +mpz_cmp_si (const mpz_t u, long v) +{ + mp_size_t usize = u->_mp_size; + + if (usize < -1) + return -1; + else if (v >= 0) + return mpz_cmp_ui (u, v); + else if (usize >= 0) + return 1; + else /* usize == -1 */ + return GMP_CMP (GMP_NEG_CAST (mp_limb_t, v), u->_mp_d[0]); +} + +int +mpz_cmp_ui (const mpz_t u, unsigned long v) +{ + mp_size_t usize = u->_mp_size; + + if (usize > 1) + return 1; + else if (usize < 0) + return -1; + else + return GMP_CMP (mpz_get_ui (u), v); +} + +int +mpz_cmp (const mpz_t a, const mpz_t b) +{ + mp_size_t asize = a->_mp_size; + mp_size_t bsize = b->_mp_size; + + if (asize != bsize) + return (asize < bsize) ? -1 : 1; + else if (asize >= 0) + return mpn_cmp (a->_mp_d, b->_mp_d, asize); + else + return mpn_cmp (b->_mp_d, a->_mp_d, -asize); +} + +int +mpz_cmpabs_ui (const mpz_t u, unsigned long v) +{ + if (GMP_ABS (u->_mp_size) > 1) + return 1; + else + return GMP_CMP (mpz_get_ui (u), v); +} + +int +mpz_cmpabs (const mpz_t u, const mpz_t v) +{ + return mpn_cmp4 (u->_mp_d, GMP_ABS (u->_mp_size), + v->_mp_d, GMP_ABS (v->_mp_size)); +} + +void +mpz_abs (mpz_t r, const mpz_t u) +{ + mpz_set (r, u); + r->_mp_size = GMP_ABS (r->_mp_size); +} + +void +mpz_neg (mpz_t r, const mpz_t u) +{ + mpz_set (r, u); + r->_mp_size = -r->_mp_size; +} + +void +mpz_swap (mpz_t u, mpz_t v) +{ + MP_SIZE_T_SWAP (u->_mp_size, v->_mp_size); + MP_SIZE_T_SWAP (u->_mp_alloc, v->_mp_alloc); + MP_PTR_SWAP (u->_mp_d, v->_mp_d); +} + + +/* MPZ addition and subtraction */ + +/* Adds to the absolute value. Returns new size, but doesn't store it. */ +static mp_size_t +mpz_abs_add_ui (mpz_t r, const mpz_t a, unsigned long b) +{ + mp_size_t an; + mp_ptr rp; + mp_limb_t cy; + + an = GMP_ABS (a->_mp_size); + if (an == 0) + { + MPZ_REALLOC (r, 1)[0] = b; + return b > 0; + } + + rp = MPZ_REALLOC (r, an + 1); + + cy = mpn_add_1 (rp, a->_mp_d, an, b); + rp[an] = cy; + an += cy; + + return an; +} + +/* Subtract from the absolute value. Returns new size, (or -1 on underflow), + but doesn't store it. */ +static mp_size_t +mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b) +{ + mp_size_t an = GMP_ABS (a->_mp_size); + mp_ptr rp; + + if (an == 0) + { + MPZ_REALLOC (r, 1)[0] = b; + return -(b > 0); + } + rp = MPZ_REALLOC (r, an); + if (an == 1 && a->_mp_d[0] < b) + { + rp[0] = b - a->_mp_d[0]; + return -1; + } + else + { + gmp_assert_nocarry (mpn_sub_1 (rp, a->_mp_d, an, b)); + return mpn_normalized_size (rp, an); + } +} + +void +mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b) +{ + if (a->_mp_size >= 0) + r->_mp_size = mpz_abs_add_ui (r, a, b); + else + r->_mp_size = -mpz_abs_sub_ui (r, a, b); +} + +void +mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b) +{ + if (a->_mp_size < 0) + r->_mp_size = -mpz_abs_add_ui (r, a, b); + else + r->_mp_size = mpz_abs_sub_ui (r, a, b); +} + +void +mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b) +{ + if (b->_mp_size < 0) + r->_mp_size = mpz_abs_add_ui (r, b, a); + else + r->_mp_size = -mpz_abs_sub_ui (r, b, a); +} + +static mp_size_t +mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t an = GMP_ABS (a->_mp_size); + mp_size_t bn = GMP_ABS (b->_mp_size); + mp_ptr rp; + mp_limb_t cy; + + if (an < bn) + { + MPZ_SRCPTR_SWAP (a, b); + MP_SIZE_T_SWAP (an, bn); + } + + rp = MPZ_REALLOC (r, an + 1); + cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn); + + rp[an] = cy; + + return an + cy; +} + +static mp_size_t +mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t an = GMP_ABS (a->_mp_size); + mp_size_t bn = GMP_ABS (b->_mp_size); + int cmp; + mp_ptr rp; + + cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn); + if (cmp > 0) + { + rp = MPZ_REALLOC (r, an); + gmp_assert_nocarry (mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn)); + return mpn_normalized_size (rp, an); + } + else if (cmp < 0) + { + rp = MPZ_REALLOC (r, bn); + gmp_assert_nocarry (mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an)); + return -mpn_normalized_size (rp, bn); + } + else + return 0; +} + +void +mpz_add (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t rn; + + if ( (a->_mp_size ^ b->_mp_size) >= 0) + rn = mpz_abs_add (r, a, b); + else + rn = mpz_abs_sub (r, a, b); + + r->_mp_size = a->_mp_size >= 0 ? rn : - rn; +} + +void +mpz_sub (mpz_t r, const mpz_t a, const mpz_t b) +{ + mp_size_t rn; + + if ( (a->_mp_size ^ b->_mp_size) >= 0) + rn = mpz_abs_sub (r, a, b); + else + rn = mpz_abs_add (r, a, b); + + r->_mp_size = a->_mp_size >= 0 ? rn : - rn; +} + + +/* MPZ multiplication */ +void +mpz_mul_si (mpz_t r, const mpz_t u, long int v) +{ + if (v < 0) + { + mpz_mul_ui (r, u, GMP_NEG_CAST (unsigned long int, v)); + mpz_neg (r, r); + } + else + mpz_mul_ui (r, u, (unsigned long int) v); +} + +void +mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v) +{ + mp_size_t un, us; + mp_ptr tp; + mp_limb_t cy; + + us = u->_mp_size; + + if (us == 0 || v == 0) + { + r->_mp_size = 0; + return; + } + + un = GMP_ABS (us); + + tp = MPZ_REALLOC (r, un + 1); + cy = mpn_mul_1 (tp, u->_mp_d, un, v); + tp[un] = cy; + + un += (cy > 0); + r->_mp_size = (us < 0) ? - un : un; +} + +void +mpz_mul (mpz_t r, const mpz_t u, const mpz_t v) +{ + int sign; + mp_size_t un, vn, rn; + mpz_t t; + mp_ptr tp; + + un = u->_mp_size; + vn = v->_mp_size; + + if (un == 0 || vn == 0) + { + r->_mp_size = 0; + return; + } + + sign = (un ^ vn) < 0; + + un = GMP_ABS (un); + vn = GMP_ABS (vn); + + mpz_init2 (t, (un + vn) * GMP_LIMB_BITS); + + tp = t->_mp_d; + if (un >= vn) + mpn_mul (tp, u->_mp_d, un, v->_mp_d, vn); + else + mpn_mul (tp, v->_mp_d, vn, u->_mp_d, un); + + rn = un + vn; + rn -= tp[rn-1] == 0; + + t->_mp_size = sign ? - rn : rn; + mpz_swap (r, t); + mpz_clear (t); +} + +void +mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits) +{ + mp_size_t un, rn; + mp_size_t limbs; + unsigned shift; + mp_ptr rp; + + un = GMP_ABS (u->_mp_size); + if (un == 0) + { + r->_mp_size = 0; + return; + } + + limbs = bits / GMP_LIMB_BITS; + shift = bits % GMP_LIMB_BITS; + + rn = un + limbs + (shift > 0); + rp = MPZ_REALLOC (r, rn); + if (shift > 0) + { + mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift); + rp[rn-1] = cy; + rn -= (cy == 0); + } + else + mpn_copyd (rp + limbs, u->_mp_d, un); + + mpn_zero (rp, limbs); + + r->_mp_size = (u->_mp_size < 0) ? - rn : rn; +} + +void +mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) +{ + mpz_t t; + mpz_init (t); + mpz_mul_ui (t, u, v); + mpz_add (r, r, t); + mpz_clear (t); +} + +void +mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v) +{ + mpz_t t; + mpz_init (t); + mpz_mul_ui (t, u, v); + mpz_sub (r, r, t); + mpz_clear (t); +} + +void +mpz_addmul (mpz_t r, const mpz_t u, const mpz_t v) +{ + mpz_t t; + mpz_init (t); + mpz_mul (t, u, v); + mpz_add (r, r, t); + mpz_clear (t); +} + +void +mpz_submul (mpz_t r, const mpz_t u, const mpz_t v) +{ + mpz_t t; + mpz_init (t); + mpz_mul (t, u, v); + mpz_sub (r, r, t); + mpz_clear (t); +} + + +/* MPZ division */ +enum mpz_div_round_mode { GMP_DIV_FLOOR, GMP_DIV_CEIL, GMP_DIV_TRUNC }; + +/* Allows q or r to be zero. Returns 1 iff remainder is non-zero. */ +static int +mpz_div_qr (mpz_t q, mpz_t r, + const mpz_t n, const mpz_t d, enum mpz_div_round_mode mode) +{ + mp_size_t ns, ds, nn, dn, qs; + ns = n->_mp_size; + ds = d->_mp_size; + + if (ds == 0) + gmp_die("mpz_div_qr: Divide by zero."); + + if (ns == 0) + { + if (q) + q->_mp_size = 0; + if (r) + r->_mp_size = 0; + return 0; + } + + nn = GMP_ABS (ns); + dn = GMP_ABS (ds); + + qs = ds ^ ns; + + if (nn < dn) + { + if (mode == GMP_DIV_CEIL && qs >= 0) + { + /* q = 1, r = n - d */ + if (r) + mpz_sub (r, n, d); + if (q) + mpz_set_ui (q, 1); + } + else if (mode == GMP_DIV_FLOOR && qs < 0) + { + /* q = -1, r = n + d */ + if (r) + mpz_add (r, n, d); + if (q) + mpz_set_si (q, -1); + } + else + { + /* q = 0, r = d */ + if (r) + mpz_set (r, n); + if (q) + q->_mp_size = 0; + } + return 1; + } + else + { + mp_ptr np, qp; + mp_size_t qn, rn; + mpz_t tq, tr; + + mpz_init_set (tr, n); + np = tr->_mp_d; + + qn = nn - dn + 1; + + if (q) + { + mpz_init2 (tq, qn * GMP_LIMB_BITS); + qp = tq->_mp_d; + } + else + qp = NULL; + + mpn_div_qr (qp, np, nn, d->_mp_d, dn); + + if (qp) + { + qn -= (qp[qn-1] == 0); + + tq->_mp_size = qs < 0 ? -qn : qn; + } + rn = mpn_normalized_size (np, dn); + tr->_mp_size = ns < 0 ? - rn : rn; + + if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0) + { + if (q) + mpz_sub_ui (tq, tq, 1); + if (r) + mpz_add (tr, tr, d); + } + else if (mode == GMP_DIV_CEIL && qs >= 0 && rn != 0) + { + if (q) + mpz_add_ui (tq, tq, 1); + if (r) + mpz_sub (tr, tr, d); + } + + if (q) + { + mpz_swap (tq, q); + mpz_clear (tq); + } + if (r) + mpz_swap (tr, r); + + mpz_clear (tr); + + return rn != 0; + } +} + +void +mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, r, n, d, GMP_DIV_CEIL); +} + +void +mpz_fdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, r, n, d, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC); +} + +void +mpz_cdiv_q (mpz_t q, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, NULL, n, d, GMP_DIV_CEIL); +} + +void +mpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, NULL, n, d, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_q (mpz_t q, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC); +} + +void +mpz_cdiv_r (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, GMP_DIV_CEIL); +} + +void +mpz_fdiv_r (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_r (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, GMP_DIV_TRUNC); +} + +void +mpz_mod (mpz_t r, const mpz_t n, const mpz_t d) +{ + mpz_div_qr (NULL, r, n, d, d->_mp_size >= 0 ? GMP_DIV_FLOOR : GMP_DIV_CEIL); +} + +static void +mpz_div_q_2exp (mpz_t q, const mpz_t u, mp_bitcnt_t bit_index, + enum mpz_div_round_mode mode) +{ + mp_size_t un, qn; + mp_size_t limb_cnt; + mp_ptr qp; + int adjust; + + un = u->_mp_size; + if (un == 0) + { + q->_mp_size = 0; + return; + } + limb_cnt = bit_index / GMP_LIMB_BITS; + qn = GMP_ABS (un) - limb_cnt; + bit_index %= GMP_LIMB_BITS; + + if (mode == ((un > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* un != 0 here. */ + /* Note: Below, the final indexing at limb_cnt is valid because at + that point we have qn > 0. */ + adjust = (qn <= 0 + || !mpn_zero_p (u->_mp_d, limb_cnt) + || (u->_mp_d[limb_cnt] + & (((mp_limb_t) 1 << bit_index) - 1))); + else + adjust = 0; + + if (qn <= 0) + qn = 0; + else + { + qp = MPZ_REALLOC (q, qn); + + if (bit_index != 0) + { + mpn_rshift (qp, u->_mp_d + limb_cnt, qn, bit_index); + qn -= qp[qn - 1] == 0; + } + else + { + mpn_copyi (qp, u->_mp_d + limb_cnt, qn); + } + } + + q->_mp_size = qn; + + if (adjust) + mpz_add_ui (q, q, 1); + if (un < 0) + mpz_neg (q, q); +} + +static void +mpz_div_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bit_index, + enum mpz_div_round_mode mode) +{ + mp_size_t us, un, rn; + mp_ptr rp; + mp_limb_t mask; + + us = u->_mp_size; + if (us == 0 || bit_index == 0) + { + r->_mp_size = 0; + return; + } + rn = (bit_index + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + assert (rn > 0); + + rp = MPZ_REALLOC (r, rn); + un = GMP_ABS (us); + + mask = GMP_LIMB_MAX >> (rn * GMP_LIMB_BITS - bit_index); + + if (rn > un) + { + /* Quotient (with truncation) is zero, and remainder is + non-zero */ + if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */ + { + /* Have to negate and sign extend. */ + mp_size_t i; + + gmp_assert_nocarry (! mpn_neg (rp, u->_mp_d, un)); + for (i = un; i < rn - 1; i++) + rp[i] = GMP_LIMB_MAX; + + rp[rn-1] = mask; + us = -us; + } + else + { + /* Just copy */ + if (r != u) + mpn_copyi (rp, u->_mp_d, un); + + rn = un; + } + } + else + { + if (r != u) + mpn_copyi (rp, u->_mp_d, rn - 1); + + rp[rn-1] = u->_mp_d[rn-1] & mask; + + if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */ + { + /* If r != 0, compute 2^{bit_count} - r. */ + mpn_neg (rp, rp, rn); + + rp[rn-1] &= mask; + + /* us is not used for anything else, so we can modify it + here to indicate flipped sign. */ + us = -us; + } + } + rn = mpn_normalized_size (rp, rn); + r->_mp_size = us < 0 ? -rn : rn; +} + +void +mpz_cdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_q_2exp (r, u, cnt, GMP_DIV_CEIL); +} + +void +mpz_fdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_q_2exp (r, u, cnt, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_q_2exp (r, u, cnt, GMP_DIV_TRUNC); +} + +void +mpz_cdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_r_2exp (r, u, cnt, GMP_DIV_CEIL); +} + +void +mpz_fdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_r_2exp (r, u, cnt, GMP_DIV_FLOOR); +} + +void +mpz_tdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt) +{ + mpz_div_r_2exp (r, u, cnt, GMP_DIV_TRUNC); +} + +void +mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d) +{ + gmp_assert_nocarry (mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC)); +} + +int +mpz_divisible_p (const mpz_t n, const mpz_t d) +{ + return mpz_div_qr (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; +} + +int +mpz_congruent_p (const mpz_t a, const mpz_t b, const mpz_t m) +{ + mpz_t t; + int res; + + /* a == b (mod 0) iff a == b */ + if (mpz_sgn (m) == 0) + return (mpz_cmp (a, b) == 0); + + mpz_init (t); + mpz_sub (t, a, b); + res = mpz_divisible_p (t, m); + mpz_clear (t); + + return res; +} + +static unsigned long +mpz_div_qr_ui (mpz_t q, mpz_t r, + const mpz_t n, unsigned long d, enum mpz_div_round_mode mode) +{ + mp_size_t ns, qn; + mp_ptr qp; + mp_limb_t rl; + mp_size_t rs; + + ns = n->_mp_size; + if (ns == 0) + { + if (q) + q->_mp_size = 0; + if (r) + r->_mp_size = 0; + return 0; + } + + qn = GMP_ABS (ns); + if (q) + qp = MPZ_REALLOC (q, qn); + else + qp = NULL; + + rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d); + assert (rl < d); + + rs = rl > 0; + rs = (ns < 0) ? -rs : rs; + + if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0) + || (mode == GMP_DIV_CEIL && ns >= 0))) + { + if (q) + gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1)); + rl = d - rl; + rs = -rs; + } + + if (r) + { + MPZ_REALLOC (r, 1)[0] = rl; + r->_mp_size = rs; + } + if (q) + { + qn -= (qp[qn-1] == 0); + assert (qn == 0 || qp[qn-1] > 0); + + q->_mp_size = (ns < 0) ? - qn : qn; + } + + return rl; +} + +unsigned long +mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL); +} + +unsigned long +mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR); +} + +unsigned long +mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL); +} + +unsigned long +mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR); +} + +unsigned long +mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_cdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL); +} +unsigned long +mpz_fdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); +} +unsigned long +mpz_tdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_cdiv_ui (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL); +} + +unsigned long +mpz_fdiv_ui (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR); +} + +unsigned long +mpz_tdiv_ui (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC); +} + +unsigned long +mpz_mod_ui (mpz_t r, const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); +} + +void +mpz_divexact_ui (mpz_t q, const mpz_t n, unsigned long d) +{ + gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC)); +} + +int +mpz_divisible_ui_p (const mpz_t n, unsigned long d) +{ + return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; +} + + +/* GCD */ +static mp_limb_t +mpn_gcd_11 (mp_limb_t u, mp_limb_t v) +{ + unsigned shift; + + assert ( (u | v) > 0); + + if (u == 0) + return v; + else if (v == 0) + return u; + + gmp_ctz (shift, u | v); + + u >>= shift; + v >>= shift; + + if ( (u & 1) == 0) + MP_LIMB_T_SWAP (u, v); + + while ( (v & 1) == 0) + v >>= 1; + + while (u != v) + { + if (u > v) + { + u -= v; + do + u >>= 1; + while ( (u & 1) == 0); + } + else + { + v -= u; + do + v >>= 1; + while ( (v & 1) == 0); + } + } + return u << shift; +} + +unsigned long +mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) +{ + mp_size_t un; + + if (v == 0) + { + if (g) + mpz_abs (g, u); + } + else + { + un = GMP_ABS (u->_mp_size); + if (un != 0) + v = mpn_gcd_11 (mpn_div_qr_1 (NULL, u->_mp_d, un, v), v); + + if (g) + mpz_set_ui (g, v); + } + + return v; +} + +static mp_bitcnt_t +mpz_make_odd (mpz_t r) +{ + mp_bitcnt_t shift; + + assert (r->_mp_size > 0); + /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ + shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0); + mpz_tdiv_q_2exp (r, r, shift); + + return shift; +} + +void +mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v) +{ + mpz_t tu, tv; + mp_bitcnt_t uz, vz, gz; + + if (u->_mp_size == 0) + { + mpz_abs (g, v); + return; + } + if (v->_mp_size == 0) + { + mpz_abs (g, u); + return; + } + + mpz_init (tu); + mpz_init (tv); + + mpz_abs (tu, u); + uz = mpz_make_odd (tu); + mpz_abs (tv, v); + vz = mpz_make_odd (tv); + gz = GMP_MIN (uz, vz); + + if (tu->_mp_size < tv->_mp_size) + mpz_swap (tu, tv); + + mpz_tdiv_r (tu, tu, tv); + if (tu->_mp_size == 0) + { + mpz_swap (g, tv); + } + else + for (;;) + { + int c; + + mpz_make_odd (tu); + c = mpz_cmp (tu, tv); + if (c == 0) + { + mpz_swap (g, tu); + break; + } + if (c < 0) + mpz_swap (tu, tv); + + if (tv->_mp_size == 1) + { + mp_limb_t vl = tv->_mp_d[0]; + mp_limb_t ul = mpz_tdiv_ui (tu, vl); + mpz_set_ui (g, mpn_gcd_11 (ul, vl)); + break; + } + mpz_sub (tu, tu, tv); + } + mpz_clear (tu); + mpz_clear (tv); + mpz_mul_2exp (g, g, gz); +} + +void +mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) +{ + mpz_t tu, tv, s0, s1, t0, t1; + mp_bitcnt_t uz, vz, gz; + mp_bitcnt_t power; + + if (u->_mp_size == 0) + { + /* g = 0 u + sgn(v) v */ + signed long sign = mpz_sgn (v); + mpz_abs (g, v); + if (s) + mpz_set_ui (s, 0); + if (t) + mpz_set_si (t, sign); + return; + } + + if (v->_mp_size == 0) + { + /* g = sgn(u) u + 0 v */ + signed long sign = mpz_sgn (u); + mpz_abs (g, u); + if (s) + mpz_set_si (s, sign); + if (t) + mpz_set_ui (t, 0); + return; + } + + mpz_init (tu); + mpz_init (tv); + mpz_init (s0); + mpz_init (s1); + mpz_init (t0); + mpz_init (t1); + + mpz_abs (tu, u); + uz = mpz_make_odd (tu); + mpz_abs (tv, v); + vz = mpz_make_odd (tv); + gz = GMP_MIN (uz, vz); + + uz -= gz; + vz -= gz; + + /* Cofactors corresponding to odd gcd. gz handled later. */ + if (tu->_mp_size < tv->_mp_size) + { + mpz_swap (tu, tv); + MPZ_SRCPTR_SWAP (u, v); + MPZ_PTR_SWAP (s, t); + MP_BITCNT_T_SWAP (uz, vz); + } + + /* Maintain + * + * u = t0 tu + t1 tv + * v = s0 tu + s1 tv + * + * where u and v denote the inputs with common factors of two + * eliminated, and det (s0, t0; s1, t1) = 2^p. Then + * + * 2^p tu = s1 u - t1 v + * 2^p tv = -s0 u + t0 v + */ + + /* After initial division, tu = q tv + tu', we have + * + * u = 2^uz (tu' + q tv) + * v = 2^vz tv + * + * or + * + * t0 = 2^uz, t1 = 2^uz q + * s0 = 0, s1 = 2^vz + */ + + mpz_setbit (t0, uz); + mpz_tdiv_qr (t1, tu, tu, tv); + mpz_mul_2exp (t1, t1, uz); + + mpz_setbit (s1, vz); + power = uz + vz; + + if (tu->_mp_size > 0) + { + mp_bitcnt_t shift; + shift = mpz_make_odd (tu); + mpz_mul_2exp (t0, t0, shift); + mpz_mul_2exp (s0, s0, shift); + power += shift; + + for (;;) + { + int c; + c = mpz_cmp (tu, tv); + if (c == 0) + break; + + if (c < 0) + { + /* tv = tv' + tu + * + * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv' + * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */ + + mpz_sub (tv, tv, tu); + mpz_add (t0, t0, t1); + mpz_add (s0, s0, s1); + + shift = mpz_make_odd (tv); + mpz_mul_2exp (t1, t1, shift); + mpz_mul_2exp (s1, s1, shift); + } + else + { + mpz_sub (tu, tu, tv); + mpz_add (t1, t0, t1); + mpz_add (s1, s0, s1); + + shift = mpz_make_odd (tu); + mpz_mul_2exp (t0, t0, shift); + mpz_mul_2exp (s0, s0, shift); + } + power += shift; + } + } + + /* Now tv = odd part of gcd, and -s0 and t0 are corresponding + cofactors. */ + + mpz_mul_2exp (tv, tv, gz); + mpz_neg (s0, s0); + + /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To + adjust cofactors, we need u / g and v / g */ + + mpz_divexact (s1, v, tv); + mpz_abs (s1, s1); + mpz_divexact (t1, u, tv); + mpz_abs (t1, t1); + + while (power-- > 0) + { + /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */ + if (mpz_odd_p (s0) || mpz_odd_p (t0)) + { + mpz_sub (s0, s0, s1); + mpz_add (t0, t0, t1); + } + mpz_divexact_ui (s0, s0, 2); + mpz_divexact_ui (t0, t0, 2); + } + + /* Arrange so that |s| < |u| / 2g */ + mpz_add (s1, s0, s1); + if (mpz_cmpabs (s0, s1) > 0) + { + mpz_swap (s0, s1); + mpz_sub (t0, t0, t1); + } + if (u->_mp_size < 0) + mpz_neg (s0, s0); + if (v->_mp_size < 0) + mpz_neg (t0, t0); + + mpz_swap (g, tv); + if (s) + mpz_swap (s, s0); + if (t) + mpz_swap (t, t0); + + mpz_clear (tu); + mpz_clear (tv); + mpz_clear (s0); + mpz_clear (s1); + mpz_clear (t0); + mpz_clear (t1); +} + +void +mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v) +{ + mpz_t g; + + if (u->_mp_size == 0 || v->_mp_size == 0) + { + r->_mp_size = 0; + return; + } + + mpz_init (g); + + mpz_gcd (g, u, v); + mpz_divexact (g, u, g); + mpz_mul (r, g, v); + + mpz_clear (g); + mpz_abs (r, r); +} + +void +mpz_lcm_ui (mpz_t r, const mpz_t u, unsigned long v) +{ + if (v == 0 || u->_mp_size == 0) + { + r->_mp_size = 0; + return; + } + + v /= mpz_gcd_ui (NULL, u, v); + mpz_mul_ui (r, u, v); + + mpz_abs (r, r); +} + +int +mpz_invert (mpz_t r, const mpz_t u, const mpz_t m) +{ + mpz_t g, tr; + int invertible; + + if (u->_mp_size == 0 || mpz_cmpabs_ui (m, 1) <= 0) + return 0; + + mpz_init (g); + mpz_init (tr); + + mpz_gcdext (g, tr, NULL, u, m); + invertible = (mpz_cmp_ui (g, 1) == 0); + + if (invertible) + { + if (tr->_mp_size < 0) + { + if (m->_mp_size >= 0) + mpz_add (tr, tr, m); + else + mpz_sub (tr, tr, m); + } + mpz_swap (r, tr); + } + + mpz_clear (g); + mpz_clear (tr); + return invertible; +} + + +/* Higher level operations (sqrt, pow and root) */ + +void +mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e) +{ + unsigned long bit; + mpz_t tr; + mpz_init_set_ui (tr, 1); + + bit = GMP_ULONG_HIGHBIT; + do + { + mpz_mul (tr, tr, tr); + if (e & bit) + mpz_mul (tr, tr, b); + bit >>= 1; + } + while (bit > 0); + + mpz_swap (r, tr); + mpz_clear (tr); +} + +void +mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e) +{ + mpz_t b; + mpz_pow_ui (r, mpz_roinit_n (b, &blimb, 1), e); +} + +void +mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) +{ + mpz_t tr; + mpz_t base; + mp_size_t en, mn; + mp_srcptr mp; + struct gmp_div_inverse minv; + unsigned shift; + mp_ptr tp = NULL; + + en = GMP_ABS (e->_mp_size); + mn = GMP_ABS (m->_mp_size); + if (mn == 0) + gmp_die ("mpz_powm: Zero modulo."); + + if (en == 0) + { + mpz_set_ui (r, 1); + return; + } + + mp = m->_mp_d; + mpn_div_qr_invert (&minv, mp, mn); + shift = minv.shift; + + if (shift > 0) + { + /* To avoid shifts, we do all our reductions, except the final + one, using a *normalized* m. */ + minv.shift = 0; + + tp = gmp_xalloc_limbs (mn); + gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift)); + mp = tp; + } + + mpz_init (base); + + if (e->_mp_size < 0) + { + if (!mpz_invert (base, b, m)) + gmp_die ("mpz_powm: Negative exponent and non-invertible base."); + } + else + { + mp_size_t bn; + mpz_abs (base, b); + + bn = base->_mp_size; + if (bn >= mn) + { + mpn_div_qr_preinv (NULL, base->_mp_d, base->_mp_size, mp, mn, &minv); + bn = mn; + } + + /* We have reduced the absolute value. Now take care of the + sign. Note that we get zero represented non-canonically as + m. */ + if (b->_mp_size < 0) + { + mp_ptr bp = MPZ_REALLOC (base, mn); + gmp_assert_nocarry (mpn_sub (bp, mp, mn, bp, bn)); + bn = mn; + } + base->_mp_size = mpn_normalized_size (base->_mp_d, bn); + } + mpz_init_set_ui (tr, 1); + + while (--en >= 0) + { + mp_limb_t w = e->_mp_d[en]; + mp_limb_t bit; + + bit = GMP_LIMB_HIGHBIT; + do + { + mpz_mul (tr, tr, tr); + if (w & bit) + mpz_mul (tr, tr, base); + if (tr->_mp_size > mn) + { + mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv); + tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); + } + bit >>= 1; + } + while (bit > 0); + } + + /* Final reduction */ + if (tr->_mp_size >= mn) + { + minv.shift = shift; + mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv); + tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); + } + if (tp) + gmp_free (tp); + + mpz_swap (r, tr); + mpz_clear (tr); + mpz_clear (base); +} + +void +mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) +{ + mpz_t e; + mpz_powm (r, b, mpz_roinit_n (e, &elimb, 1), m); +} + +/* x=trunc(y^(1/z)), r=y-x^z */ +void +mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z) +{ + int sgn; + mpz_t t, u; + + sgn = y->_mp_size < 0; + if ((~z & sgn) != 0) + gmp_die ("mpz_rootrem: Negative argument, with even root."); + if (z == 0) + gmp_die ("mpz_rootrem: Zeroth root."); + + if (mpz_cmpabs_ui (y, 1) <= 0) { + if (x) + mpz_set (x, y); + if (r) + r->_mp_size = 0; + return; + } + + mpz_init (u); + mpz_init (t); + mpz_setbit (t, mpz_sizeinbase (y, 2) / z + 1); + + if (z == 2) /* simplify sqrt loop: z-1 == 1 */ + do { + mpz_swap (u, t); /* u = x */ + mpz_tdiv_q (t, y, u); /* t = y/x */ + mpz_add (t, t, u); /* t = y/x + x */ + mpz_tdiv_q_2exp (t, t, 1); /* x'= (y/x + x)/2 */ + } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */ + else /* z != 2 */ { + mpz_t v; + + mpz_init (v); + if (sgn) + mpz_neg (t, t); + + do { + mpz_swap (u, t); /* u = x */ + mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */ + mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */ + mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */ + mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */ + mpz_tdiv_q_ui (t, t, z); /* x'=(y/x^(z-1) + x*(z-1))/z */ + } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */ + + mpz_clear (v); + } + + if (r) { + mpz_pow_ui (t, u, z); + mpz_sub (r, y, t); + } + if (x) + mpz_swap (x, u); + mpz_clear (u); + mpz_clear (t); +} + +int +mpz_root (mpz_t x, const mpz_t y, unsigned long z) +{ + int res; + mpz_t r; + + mpz_init (r); + mpz_rootrem (x, r, y, z); + res = r->_mp_size == 0; + mpz_clear (r); + + return res; +} + +/* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */ +void +mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u) +{ + mpz_rootrem (s, r, u, 2); +} + +void +mpz_sqrt (mpz_t s, const mpz_t u) +{ + mpz_rootrem (s, NULL, u, 2); +} + +int +mpz_perfect_square_p (const mpz_t u) +{ + if (u->_mp_size <= 0) + return (u->_mp_size == 0); + else + return mpz_root (NULL, u, 2); +} + +int +mpn_perfect_square_p (mp_srcptr p, mp_size_t n) +{ + mpz_t t; + + assert (n > 0); + assert (p [n-1] != 0); + return mpz_root (NULL, mpz_roinit_n (t, p, n), 2); +} + +mp_size_t +mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr p, mp_size_t n) +{ + mpz_t s, r, u; + mp_size_t res; + + assert (n > 0); + assert (p [n-1] != 0); + + mpz_init (r); + mpz_init (s); + mpz_rootrem (s, r, mpz_roinit_n (u, p, n), 2); + + assert (s->_mp_size == (n+1)/2); + mpn_copyd (sp, s->_mp_d, s->_mp_size); + mpz_clear (s); + res = r->_mp_size; + if (rp) + mpn_copyd (rp, r->_mp_d, res); + mpz_clear (r); + return res; +} + +/* Combinatorics */ + +void +mpz_fac_ui (mpz_t x, unsigned long n) +{ + mpz_set_ui (x, n + (n == 0)); + while (n > 2) + mpz_mul_ui (x, x, --n); +} + +void +mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k) +{ + mpz_t t; + + mpz_set_ui (r, k <= n); + + if (k > (n >> 1)) + k = (k <= n) ? n - k : 0; + + mpz_init (t); + mpz_fac_ui (t, k); + + for (; k > 0; k--) + mpz_mul_ui (r, r, n--); + + mpz_divexact (r, r, t); + mpz_clear (t); +} + + +/* Primality testing */ +static int +gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y, + const mpz_t q, mp_bitcnt_t k) +{ + assert (k > 0); + + /* Caller must initialize y to the base. */ + mpz_powm (y, y, q, n); + + if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0) + return 1; + + while (--k > 0) + { + mpz_powm_ui (y, y, 2, n); + if (mpz_cmp (y, nm1) == 0) + return 1; + /* y == 1 means that the previous y was a non-trivial square root + of 1 (mod n). y == 0 means that n is a power of the base. + In either case, n is not prime. */ + if (mpz_cmp_ui (y, 1) <= 0) + return 0; + } + return 0; +} + +/* This product is 0xc0cfd797, and fits in 32 bits. */ +#define GMP_PRIME_PRODUCT \ + (3UL*5UL*7UL*11UL*13UL*17UL*19UL*23UL*29UL) + +/* Bit (p+1)/2 is set, for each odd prime <= 61 */ +#define GMP_PRIME_MASK 0xc96996dcUL + +int +mpz_probab_prime_p (const mpz_t n, int reps) +{ + mpz_t nm1; + mpz_t q; + mpz_t y; + mp_bitcnt_t k; + int is_prime; + int j; + + /* Note that we use the absolute value of n only, for compatibility + with the real GMP. */ + if (mpz_even_p (n)) + return (mpz_cmpabs_ui (n, 2) == 0) ? 2 : 0; + + /* Above test excludes n == 0 */ + assert (n->_mp_size != 0); + + if (mpz_cmpabs_ui (n, 64) < 0) + return (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1)) & 2; + + if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1) + return 0; + + /* All prime factors are >= 31. */ + if (mpz_cmpabs_ui (n, 31*31) < 0) + return 2; + + /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] = + j^2 + j + 41 using Euler's polynomial. We potentially stop early, + if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps > + 30 (a[30] == 971 > 31*31 == 961). */ + + mpz_init (nm1); + mpz_init (q); + mpz_init (y); + + /* Find q and k, where q is odd and n = 1 + 2**k * q. */ + nm1->_mp_size = mpz_abs_sub_ui (nm1, n, 1); + k = mpz_scan1 (nm1, 0); + mpz_tdiv_q_2exp (q, nm1, k); + + for (j = 0, is_prime = 1; is_prime & (j < reps); j++) + { + mpz_set_ui (y, (unsigned long) j*j+j+41); + if (mpz_cmp (y, nm1) >= 0) + { + /* Don't try any further bases. This "early" break does not affect + the result for any reasonable reps value (<=5000 was tested) */ + assert (j >= 30); + break; + } + is_prime = gmp_millerrabin (n, nm1, y, q, k); + } + mpz_clear (nm1); + mpz_clear (q); + mpz_clear (y); + + return is_prime; +} + + +/* Logical operations and bit manipulation. */ + +/* Numbers are treated as if represented in two's complement (and + infinitely sign extended). For a negative values we get the two's + complement from -x = ~x + 1, where ~ is bitwise complement. + Negation transforms + + xxxx10...0 + + into + + yyyy10...0 + + where yyyy is the bitwise complement of xxxx. So least significant + bits, up to and including the first one bit, are unchanged, and + the more significant bits are all complemented. + + To change a bit from zero to one in a negative number, subtract the + corresponding power of two from the absolute value. This can never + underflow. To change a bit from one to zero, add the corresponding + power of two, and this might overflow. E.g., if x = -001111, the + two's complement is 110001. Clearing the least significant bit, we + get two's complement 110000, and -010000. */ + +int +mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index) +{ + mp_size_t limb_index; + unsigned shift; + mp_size_t ds; + mp_size_t dn; + mp_limb_t w; + int bit; + + ds = d->_mp_size; + dn = GMP_ABS (ds); + limb_index = bit_index / GMP_LIMB_BITS; + if (limb_index >= dn) + return ds < 0; + + shift = bit_index % GMP_LIMB_BITS; + w = d->_mp_d[limb_index]; + bit = (w >> shift) & 1; + + if (ds < 0) + { + /* d < 0. Check if any of the bits below is set: If so, our bit + must be complemented. */ + if (shift > 0 && (w << (GMP_LIMB_BITS - shift)) > 0) + return bit ^ 1; + while (--limb_index >= 0) + if (d->_mp_d[limb_index] > 0) + return bit ^ 1; + } + return bit; +} + +static void +mpz_abs_add_bit (mpz_t d, mp_bitcnt_t bit_index) +{ + mp_size_t dn, limb_index; + mp_limb_t bit; + mp_ptr dp; + + dn = GMP_ABS (d->_mp_size); + + limb_index = bit_index / GMP_LIMB_BITS; + bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS); + + if (limb_index >= dn) + { + mp_size_t i; + /* The bit should be set outside of the end of the number. + We have to increase the size of the number. */ + dp = MPZ_REALLOC (d, limb_index + 1); + + dp[limb_index] = bit; + for (i = dn; i < limb_index; i++) + dp[i] = 0; + dn = limb_index + 1; + } + else + { + mp_limb_t cy; + + dp = d->_mp_d; + + cy = mpn_add_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit); + if (cy > 0) + { + dp = MPZ_REALLOC (d, dn + 1); + dp[dn++] = cy; + } + } + + d->_mp_size = (d->_mp_size < 0) ? - dn : dn; +} + +static void +mpz_abs_sub_bit (mpz_t d, mp_bitcnt_t bit_index) +{ + mp_size_t dn, limb_index; + mp_ptr dp; + mp_limb_t bit; + + dn = GMP_ABS (d->_mp_size); + dp = d->_mp_d; + + limb_index = bit_index / GMP_LIMB_BITS; + bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS); + + assert (limb_index < dn); + + gmp_assert_nocarry (mpn_sub_1 (dp + limb_index, dp + limb_index, + dn - limb_index, bit)); + dn = mpn_normalized_size (dp, dn); + d->_mp_size = (d->_mp_size < 0) ? - dn : dn; +} + +void +mpz_setbit (mpz_t d, mp_bitcnt_t bit_index) +{ + if (!mpz_tstbit (d, bit_index)) + { + if (d->_mp_size >= 0) + mpz_abs_add_bit (d, bit_index); + else + mpz_abs_sub_bit (d, bit_index); + } +} + +void +mpz_clrbit (mpz_t d, mp_bitcnt_t bit_index) +{ + if (mpz_tstbit (d, bit_index)) + { + if (d->_mp_size >= 0) + mpz_abs_sub_bit (d, bit_index); + else + mpz_abs_add_bit (d, bit_index); + } +} + +void +mpz_combit (mpz_t d, mp_bitcnt_t bit_index) +{ + if (mpz_tstbit (d, bit_index) ^ (d->_mp_size < 0)) + mpz_abs_sub_bit (d, bit_index); + else + mpz_abs_add_bit (d, bit_index); +} + +void +mpz_com (mpz_t r, const mpz_t u) +{ + mpz_neg (r, u); + mpz_sub_ui (r, r, 1); +} + +void +mpz_and (mpz_t r, const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, rn, i; + mp_ptr up, vp, rp; + + mp_limb_t ux, vx, rx; + mp_limb_t uc, vc, rc; + mp_limb_t ul, vl, rl; + + un = GMP_ABS (u->_mp_size); + vn = GMP_ABS (v->_mp_size); + if (un < vn) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (un, vn); + } + if (vn == 0) + { + r->_mp_size = 0; + return; + } + + uc = u->_mp_size < 0; + vc = v->_mp_size < 0; + rc = uc & vc; + + ux = -uc; + vx = -vc; + rx = -rc; + + /* If the smaller input is positive, higher limbs don't matter. */ + rn = vx ? un : vn; + + rp = MPZ_REALLOC (r, rn + (mp_size_t) rc); + + up = u->_mp_d; + vp = v->_mp_d; + + i = 0; + do + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + vl = (vp[i] ^ vx) + vc; + vc = vl < vc; + + rl = ( (ul & vl) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + while (++i < vn); + assert (vc == 0); + + for (; i < rn; i++) + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + rl = ( (ul & vx) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + if (rc) + rp[rn++] = rc; + else + rn = mpn_normalized_size (rp, rn); + + r->_mp_size = rx ? -rn : rn; +} + +void +mpz_ior (mpz_t r, const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, rn, i; + mp_ptr up, vp, rp; + + mp_limb_t ux, vx, rx; + mp_limb_t uc, vc, rc; + mp_limb_t ul, vl, rl; + + un = GMP_ABS (u->_mp_size); + vn = GMP_ABS (v->_mp_size); + if (un < vn) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (un, vn); + } + if (vn == 0) + { + mpz_set (r, u); + return; + } + + uc = u->_mp_size < 0; + vc = v->_mp_size < 0; + rc = uc | vc; + + ux = -uc; + vx = -vc; + rx = -rc; + + /* If the smaller input is negative, by sign extension higher limbs + don't matter. */ + rn = vx ? vn : un; + + rp = MPZ_REALLOC (r, rn + (mp_size_t) rc); + + up = u->_mp_d; + vp = v->_mp_d; + + i = 0; + do + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + vl = (vp[i] ^ vx) + vc; + vc = vl < vc; + + rl = ( (ul | vl) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + while (++i < vn); + assert (vc == 0); + + for (; i < rn; i++) + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + rl = ( (ul | vx) ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + if (rc) + rp[rn++] = rc; + else + rn = mpn_normalized_size (rp, rn); + + r->_mp_size = rx ? -rn : rn; +} + +void +mpz_xor (mpz_t r, const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, i; + mp_ptr up, vp, rp; + + mp_limb_t ux, vx, rx; + mp_limb_t uc, vc, rc; + mp_limb_t ul, vl, rl; + + un = GMP_ABS (u->_mp_size); + vn = GMP_ABS (v->_mp_size); + if (un < vn) + { + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (un, vn); + } + if (vn == 0) + { + mpz_set (r, u); + return; + } + + uc = u->_mp_size < 0; + vc = v->_mp_size < 0; + rc = uc ^ vc; + + ux = -uc; + vx = -vc; + rx = -rc; + + rp = MPZ_REALLOC (r, un + (mp_size_t) rc); + + up = u->_mp_d; + vp = v->_mp_d; + + i = 0; + do + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + vl = (vp[i] ^ vx) + vc; + vc = vl < vc; + + rl = (ul ^ vl ^ rx) + rc; + rc = rl < rc; + rp[i] = rl; + } + while (++i < vn); + assert (vc == 0); + + for (; i < un; i++) + { + ul = (up[i] ^ ux) + uc; + uc = ul < uc; + + rl = (ul ^ ux) + rc; + rc = rl < rc; + rp[i] = rl; + } + if (rc) + rp[un++] = rc; + else + un = mpn_normalized_size (rp, un); + + r->_mp_size = rx ? -un : un; +} + +static unsigned +gmp_popcount_limb (mp_limb_t x) +{ + unsigned c; + + /* Do 16 bits at a time, to avoid limb-sized constants. */ + for (c = 0; x > 0; x >>= 16) + { + unsigned w = ((x >> 1) & 0x5555) + (x & 0x5555); + w = ((w >> 2) & 0x3333) + (w & 0x3333); + w = ((w >> 4) & 0x0f0f) + (w & 0x0f0f); + w = (w >> 8) + (w & 0x00ff); + c += w; + } + return c; +} + +mp_bitcnt_t +mpn_popcount (mp_srcptr p, mp_size_t n) +{ + mp_size_t i; + mp_bitcnt_t c; + + for (c = 0, i = 0; i < n; i++) + c += gmp_popcount_limb (p[i]); + + return c; +} + +mp_bitcnt_t +mpz_popcount (const mpz_t u) +{ + mp_size_t un; + + un = u->_mp_size; + + if (un < 0) + return ~(mp_bitcnt_t) 0; + + return mpn_popcount (u->_mp_d, un); +} + +mp_bitcnt_t +mpz_hamdist (const mpz_t u, const mpz_t v) +{ + mp_size_t un, vn, i; + mp_limb_t uc, vc, ul, vl, comp; + mp_srcptr up, vp; + mp_bitcnt_t c; + + un = u->_mp_size; + vn = v->_mp_size; + + if ( (un ^ vn) < 0) + return ~(mp_bitcnt_t) 0; + + comp = - (uc = vc = (un < 0)); + if (uc) + { + assert (vn < 0); + un = -un; + vn = -vn; + } + + up = u->_mp_d; + vp = v->_mp_d; + + if (un < vn) + MPN_SRCPTR_SWAP (up, un, vp, vn); + + for (i = 0, c = 0; i < vn; i++) + { + ul = (up[i] ^ comp) + uc; + uc = ul < uc; + + vl = (vp[i] ^ comp) + vc; + vc = vl < vc; + + c += gmp_popcount_limb (ul ^ vl); + } + assert (vc == 0); + + for (; i < un; i++) + { + ul = (up[i] ^ comp) + uc; + uc = ul < uc; + + c += gmp_popcount_limb (ul ^ comp); + } + + return c; +} + +mp_bitcnt_t +mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit) +{ + mp_ptr up; + mp_size_t us, un, i; + mp_limb_t limb, ux; + + us = u->_mp_size; + un = GMP_ABS (us); + i = starting_bit / GMP_LIMB_BITS; + + /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit + for u<0. Notice this test picks up any u==0 too. */ + if (i >= un) + return (us >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit); + + up = u->_mp_d; + ux = 0; + limb = up[i]; + + if (starting_bit != 0) + { + if (us < 0) + { + ux = mpn_zero_p (up, i); + limb = ~ limb + ux; + ux = - (mp_limb_t) (limb >= ux); + } + + /* Mask to 0 all bits before starting_bit, thus ignoring them. */ + limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS)); + } + + return mpn_common_scan (limb, i, up, un, ux); +} + +mp_bitcnt_t +mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit) +{ + mp_ptr up; + mp_size_t us, un, i; + mp_limb_t limb, ux; + + us = u->_mp_size; + ux = - (mp_limb_t) (us >= 0); + un = GMP_ABS (us); + i = starting_bit / GMP_LIMB_BITS; + + /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for + u<0. Notice this test picks up all cases of u==0 too. */ + if (i >= un) + return (ux ? starting_bit : ~(mp_bitcnt_t) 0); + + up = u->_mp_d; + limb = up[i] ^ ux; + + if (ux == 0) + limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */ + + /* Mask all bits before starting_bit, thus ignoring them. */ + limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS)); + + return mpn_common_scan (limb, i, up, un, ux); +} + + +/* MPZ base conversion. */ + +size_t +mpz_sizeinbase (const mpz_t u, int base) +{ + mp_size_t un; + mp_srcptr up; + mp_ptr tp; + mp_bitcnt_t bits; + struct gmp_div_inverse bi; + size_t ndigits; + + assert (base >= 2); + assert (base <= 62); + + un = GMP_ABS (u->_mp_size); + if (un == 0) + return 1; + + up = u->_mp_d; + + bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]); + switch (base) + { + case 2: + return bits; + case 4: + return (bits + 1) / 2; + case 8: + return (bits + 2) / 3; + case 16: + return (bits + 3) / 4; + case 32: + return (bits + 4) / 5; + /* FIXME: Do something more clever for the common case of base + 10. */ + } + + tp = gmp_xalloc_limbs (un); + mpn_copyi (tp, up, un); + mpn_div_qr_1_invert (&bi, base); + + ndigits = 0; + do + { + ndigits++; + mpn_div_qr_1_preinv (tp, tp, un, &bi); + un -= (tp[un-1] == 0); + } + while (un > 0); + + gmp_free (tp); + return ndigits; +} + +char * +mpz_get_str (char *sp, int base, const mpz_t u) +{ + unsigned bits; + const char *digits; + mp_size_t un; + size_t i, sn; + + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + if (base > 1) + { + if (base <= 36) + digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + else if (base > 62) + return NULL; + } + else if (base >= -1) + base = 10; + else + { + base = -base; + if (base > 36) + return NULL; + } + + sn = 1 + mpz_sizeinbase (u, base); + if (!sp) + sp = (char *) gmp_xalloc (1 + sn); + + un = GMP_ABS (u->_mp_size); + + if (un == 0) + { + sp[0] = '0'; + sp[1] = '\0'; + return sp; + } + + i = 0; + + if (u->_mp_size < 0) + sp[i++] = '-'; + + bits = mpn_base_power_of_two_p (base); + + if (bits) + /* Not modified in this case. */ + sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un); + else + { + struct mpn_base_info info; + mp_ptr tp; + + mpn_get_base_info (&info, base); + tp = gmp_xalloc_limbs (un); + mpn_copyi (tp, u->_mp_d, un); + + sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un); + gmp_free (tp); + } + + for (; i < sn; i++) + sp[i] = digits[(unsigned char) sp[i]]; + + sp[sn] = '\0'; + return sp; +} + +int +mpz_set_str (mpz_t r, const char *sp, int base) +{ + unsigned bits, value_of_a; + mp_size_t rn, alloc; + mp_ptr rp; + size_t dn; + int sign; + unsigned char *dp; + + assert (base == 0 || (base >= 2 && base <= 62)); + + while (isspace( (unsigned char) *sp)) + sp++; + + sign = (*sp == '-'); + sp += sign; + + if (base == 0) + { + if (sp[0] == '0') + { + if (sp[1] == 'x' || sp[1] == 'X') + { + base = 16; + sp += 2; + } + else if (sp[1] == 'b' || sp[1] == 'B') + { + base = 2; + sp += 2; + } + else + base = 8; + } + else + base = 10; + } + + if (!*sp) + { + r->_mp_size = 0; + return -1; + } + dp = (unsigned char *) gmp_xalloc (strlen (sp)); + + value_of_a = (base > 36) ? 36 : 10; + for (dn = 0; *sp; sp++) + { + unsigned digit; + + if (isspace ((unsigned char) *sp)) + continue; + else if (*sp >= '0' && *sp <= '9') + digit = *sp - '0'; + else if (*sp >= 'a' && *sp <= 'z') + digit = *sp - 'a' + value_of_a; + else if (*sp >= 'A' && *sp <= 'Z') + digit = *sp - 'A' + 10; + else + digit = base; /* fail */ + + if (digit >= (unsigned) base) + { + gmp_free (dp); + r->_mp_size = 0; + return -1; + } + + dp[dn++] = digit; + } + + if (!dn) + { + gmp_free (dp); + r->_mp_size = 0; + return -1; + } + bits = mpn_base_power_of_two_p (base); + + if (bits > 0) + { + alloc = (dn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + rp = MPZ_REALLOC (r, alloc); + rn = mpn_set_str_bits (rp, dp, dn, bits); + } + else + { + struct mpn_base_info info; + mpn_get_base_info (&info, base); + alloc = (dn + info.exp - 1) / info.exp; + rp = MPZ_REALLOC (r, alloc); + rn = mpn_set_str_other (rp, dp, dn, base, &info); + /* Normalization, needed for all-zero input. */ + assert (rn > 0); + rn -= rp[rn-1] == 0; + } + assert (rn <= alloc); + gmp_free (dp); + + r->_mp_size = sign ? - rn : rn; + + return 0; +} + +int +mpz_init_set_str (mpz_t r, const char *sp, int base) +{ + mpz_init (r); + return mpz_set_str (r, sp, base); +} + +size_t +mpz_out_str (FILE *stream, int base, const mpz_t x) +{ + char *str; + size_t len; + + str = mpz_get_str (NULL, base, x); + len = strlen (str); + len = fwrite (str, 1, len, stream); + gmp_free (str); + return len; +} + + +static int +gmp_detect_endian (void) +{ + static const int i = 2; + const unsigned char *p = (const unsigned char *) &i; + return 1 - *p; +} + +/* Import and export. Does not support nails. */ +void +mpz_import (mpz_t r, size_t count, int order, size_t size, int endian, + size_t nails, const void *src) +{ + const unsigned char *p; + ptrdiff_t word_step; + mp_ptr rp; + mp_size_t rn; + + /* The current (partial) limb. */ + mp_limb_t limb; + /* The number of bytes already copied to this limb (starting from + the low end). */ + size_t bytes; + /* The index where the limb should be stored, when completed. */ + mp_size_t i; + + if (nails != 0) + gmp_die ("mpz_import: Nails not supported."); + + assert (order == 1 || order == -1); + assert (endian >= -1 && endian <= 1); + + if (endian == 0) + endian = gmp_detect_endian (); + + p = (unsigned char *) src; + + word_step = (order != endian) ? 2 * size : 0; + + /* Process bytes from the least significant end, so point p at the + least significant word. */ + if (order == 1) + { + p += size * (count - 1); + word_step = - word_step; + } + + /* And at least significant byte of that word. */ + if (endian == 1) + p += (size - 1); + + rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t); + rp = MPZ_REALLOC (r, rn); + + for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step) + { + size_t j; + for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) + { + limb |= (mp_limb_t) *p << (bytes++ * CHAR_BIT); + if (bytes == sizeof(mp_limb_t)) + { + rp[i++] = limb; + bytes = 0; + limb = 0; + } + } + } + assert (i + (bytes > 0) == rn); + if (limb != 0) + rp[i++] = limb; + else + i = mpn_normalized_size (rp, i); + + r->_mp_size = i; +} + +void * +mpz_export (void *r, size_t *countp, int order, size_t size, int endian, + size_t nails, const mpz_t u) +{ + size_t count; + mp_size_t un; + + if (nails != 0) + gmp_die ("mpz_import: Nails not supported."); + + assert (order == 1 || order == -1); + assert (endian >= -1 && endian <= 1); + assert (size > 0 || u->_mp_size == 0); + + un = u->_mp_size; + count = 0; + if (un != 0) + { + size_t k; + unsigned char *p; + ptrdiff_t word_step; + /* The current (partial) limb. */ + mp_limb_t limb; + /* The number of bytes left to to in this limb. */ + size_t bytes; + /* The index where the limb was read. */ + mp_size_t i; + + un = GMP_ABS (un); + + /* Count bytes in top limb. */ + limb = u->_mp_d[un-1]; + assert (limb != 0); + + k = 0; + do { + k++; limb >>= CHAR_BIT; + } while (limb != 0); + + count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; + + if (!r) + r = gmp_xalloc (count * size); + + if (endian == 0) + endian = gmp_detect_endian (); + + p = (unsigned char *) r; + + word_step = (order != endian) ? 2 * size : 0; + + /* Process bytes from the least significant end, so point p at the + least significant word. */ + if (order == 1) + { + p += size * (count - 1); + word_step = - word_step; + } + + /* And at least significant byte of that word. */ + if (endian == 1) + p += (size - 1); + + for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step) + { + size_t j; + for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) + { + if (bytes == 0) + { + if (i < un) + limb = u->_mp_d[i++]; + bytes = sizeof (mp_limb_t); + } + *p = limb; + limb >>= CHAR_BIT; + bytes--; + } + } + assert (i == un); + assert (k == count); + } + + if (countp) + *countp = count; + + return r; +} diff --git a/mini-gmp.h b/mini-gmp.h new file mode 100644 index 0000000..bb5c637 --- /dev/null +++ b/mini-gmp.h @@ -0,0 +1,298 @@ +/* mini-gmp, a minimalistic implementation of a GNU GMP subset. + +Copyright 2011-2015 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * 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. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +/* About mini-gmp: This is a minimal implementation of a subset of the + GMP interface. It is intended for inclusion into applications which + have modest bignums needs, as a fallback when the real GMP library + is not installed. + + This file defines the public interface. */ + +#ifndef __MINI_GMP_H__ +#define __MINI_GMP_H__ + +/* For size_t */ +#include + +#if defined (__cplusplus) +extern "C" { +#endif + +void mp_set_memory_functions (void *(*) (size_t), + void *(*) (void *, size_t, size_t), + void (*) (void *, size_t)); + +void mp_get_memory_functions (void *(**) (size_t), + void *(**) (void *, size_t, size_t), + void (**) (void *, size_t)); + +typedef unsigned long mp_limb_t; +typedef long mp_size_t; +typedef unsigned long mp_bitcnt_t; + +typedef mp_limb_t *mp_ptr; +typedef const mp_limb_t *mp_srcptr; + +typedef struct +{ + int _mp_alloc; /* Number of *limbs* allocated and pointed + to by the _mp_d field. */ + int _mp_size; /* abs(_mp_size) is the number of limbs the + last field points to. If _mp_size is + negative this is a negative number. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpz_struct; + +typedef __mpz_struct mpz_t[1]; + +typedef __mpz_struct *mpz_ptr; +typedef const __mpz_struct *mpz_srcptr; + +extern const int mp_bits_per_limb; + +void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t); +void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t); +void mpn_zero (mp_ptr, mp_size_t); + +int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t); +int mpn_zero_p (mp_srcptr, mp_size_t); + +mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); + +mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); + +mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); +mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); + +mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); +void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); +int mpn_perfect_square_p (mp_srcptr, mp_size_t); +mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); + +mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); +mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); + +mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t); +mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t); + +void mpn_com (mp_ptr, mp_srcptr, mp_size_t); +mp_limb_t mpn_neg (mp_ptr, mp_srcptr, mp_size_t); + +mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t); + +mp_limb_t mpn_invert_3by2 (mp_limb_t, mp_limb_t); +#define mpn_invert_limb(x) mpn_invert_3by2 ((x), 0) + +size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t); +mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int); + +void mpz_init (mpz_t); +void mpz_init2 (mpz_t, mp_bitcnt_t); +void mpz_clear (mpz_t); + +#define mpz_odd_p(z) (((z)->_mp_size != 0) & (int) (z)->_mp_d[0]) +#define mpz_even_p(z) (! mpz_odd_p (z)) + +int mpz_sgn (const mpz_t); +int mpz_cmp_si (const mpz_t, long); +int mpz_cmp_ui (const mpz_t, unsigned long); +int mpz_cmp (const mpz_t, const mpz_t); +int mpz_cmpabs_ui (const mpz_t, unsigned long); +int mpz_cmpabs (const mpz_t, const mpz_t); +int mpz_cmp_d (const mpz_t, double); +int mpz_cmpabs_d (const mpz_t, double); + +void mpz_abs (mpz_t, const mpz_t); +void mpz_neg (mpz_t, const mpz_t); +void mpz_swap (mpz_t, mpz_t); + +void mpz_add_ui (mpz_t, const mpz_t, unsigned long); +void mpz_add (mpz_t, const mpz_t, const mpz_t); +void mpz_sub_ui (mpz_t, const mpz_t, unsigned long); +void mpz_ui_sub (mpz_t, unsigned long, const mpz_t); +void mpz_sub (mpz_t, const mpz_t, const mpz_t); + +void mpz_mul_si (mpz_t, const mpz_t, long int); +void mpz_mul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_mul (mpz_t, const mpz_t, const mpz_t); +void mpz_mul_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_addmul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_addmul (mpz_t, const mpz_t, const mpz_t); +void mpz_submul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_submul (mpz_t, const mpz_t, const mpz_t); + +void mpz_cdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_fdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_tdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_cdiv_q (mpz_t, const mpz_t, const mpz_t); +void mpz_fdiv_q (mpz_t, const mpz_t, const mpz_t); +void mpz_tdiv_q (mpz_t, const mpz_t, const mpz_t); +void mpz_cdiv_r (mpz_t, const mpz_t, const mpz_t); +void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t); +void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t); + +void mpz_cdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_fdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_tdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_cdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_fdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); +void mpz_tdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t); + +void mpz_mod (mpz_t, const mpz_t, const mpz_t); + +void mpz_divexact (mpz_t, const mpz_t, const mpz_t); + +int mpz_divisible_p (const mpz_t, const mpz_t); +int mpz_congruent_p (const mpz_t, const mpz_t, const mpz_t); + +unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); +unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); +unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); +unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_cdiv_r_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_fdiv_r_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_tdiv_r_ui (mpz_t, const mpz_t, unsigned long); +unsigned long mpz_cdiv_ui (const mpz_t, unsigned long); +unsigned long mpz_fdiv_ui (const mpz_t, unsigned long); +unsigned long mpz_tdiv_ui (const mpz_t, unsigned long); + +unsigned long mpz_mod_ui (mpz_t, const mpz_t, unsigned long); + +void mpz_divexact_ui (mpz_t, const mpz_t, unsigned long); + +int mpz_divisible_ui_p (const mpz_t, unsigned long); + +unsigned long mpz_gcd_ui (mpz_t, const mpz_t, unsigned long); +void mpz_gcd (mpz_t, const mpz_t, const mpz_t); +void mpz_gcdext (mpz_t, mpz_t, mpz_t, const mpz_t, const mpz_t); +void mpz_lcm_ui (mpz_t, const mpz_t, unsigned long); +void mpz_lcm (mpz_t, const mpz_t, const mpz_t); +int mpz_invert (mpz_t, const mpz_t, const mpz_t); + +void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t); +void mpz_sqrt (mpz_t, const mpz_t); +int mpz_perfect_square_p (const mpz_t); + +void mpz_pow_ui (mpz_t, const mpz_t, unsigned long); +void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long); +void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t); +void mpz_powm_ui (mpz_t, const mpz_t, unsigned long, const mpz_t); + +void mpz_rootrem (mpz_t, mpz_t, const mpz_t, unsigned long); +int mpz_root (mpz_t, const mpz_t, unsigned long); + +void mpz_fac_ui (mpz_t, unsigned long); +void mpz_bin_uiui (mpz_t, unsigned long, unsigned long); + +int mpz_probab_prime_p (const mpz_t, int); + +int mpz_tstbit (const mpz_t, mp_bitcnt_t); +void mpz_setbit (mpz_t, mp_bitcnt_t); +void mpz_clrbit (mpz_t, mp_bitcnt_t); +void mpz_combit (mpz_t, mp_bitcnt_t); + +void mpz_com (mpz_t, const mpz_t); +void mpz_and (mpz_t, const mpz_t, const mpz_t); +void mpz_ior (mpz_t, const mpz_t, const mpz_t); +void mpz_xor (mpz_t, const mpz_t, const mpz_t); + +mp_bitcnt_t mpz_popcount (const mpz_t); +mp_bitcnt_t mpz_hamdist (const mpz_t, const mpz_t); +mp_bitcnt_t mpz_scan0 (const mpz_t, mp_bitcnt_t); +mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t); + +int mpz_fits_slong_p (const mpz_t); +int mpz_fits_ulong_p (const mpz_t); +long int mpz_get_si (const mpz_t); +unsigned long int mpz_get_ui (const mpz_t); +double mpz_get_d (const mpz_t); +size_t mpz_size (const mpz_t); +mp_limb_t mpz_getlimbn (const mpz_t, mp_size_t); + +void mpz_realloc2 (mpz_t, mp_bitcnt_t); +mp_srcptr mpz_limbs_read (mpz_srcptr); +mp_ptr mpz_limbs_modify (mpz_t, mp_size_t); +mp_ptr mpz_limbs_write (mpz_t, mp_size_t); +void mpz_limbs_finish (mpz_t, mp_size_t); +mpz_srcptr mpz_roinit_n (mpz_t, mp_srcptr, mp_size_t); + +#define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }} + +void mpz_set_si (mpz_t, signed long int); +void mpz_set_ui (mpz_t, unsigned long int); +void mpz_set (mpz_t, const mpz_t); +void mpz_set_d (mpz_t, double); + +void mpz_init_set_si (mpz_t, signed long int); +void mpz_init_set_ui (mpz_t, unsigned long int); +void mpz_init_set (mpz_t, const mpz_t); +void mpz_init_set_d (mpz_t, double); + +size_t mpz_sizeinbase (const mpz_t, int); +char *mpz_get_str (char *, int, const mpz_t); +int mpz_set_str (mpz_t, const char *, int); +int mpz_init_set_str (mpz_t, const char *, int); + +/* This long list taken from gmp.h. */ +/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4, + defines EOF but not FILE. */ +#if defined (FILE) \ + || defined (H_STDIO) \ + || defined (_H_STDIO) /* AIX */ \ + || defined (_STDIO_H) /* glibc, Sun, SCO */ \ + || defined (_STDIO_H_) /* BSD, OSF */ \ + || defined (__STDIO_H) /* Borland */ \ + || defined (__STDIO_H__) /* IRIX */ \ + || defined (_STDIO_INCLUDED) /* HPUX */ \ + || defined (__dj_include_stdio_h_) /* DJGPP */ \ + || defined (_FILE_DEFINED) /* Microsoft */ \ + || defined (__STDIO__) /* Apple MPW MrC */ \ + || defined (_MSL_STDIO_H) /* Metrowerks */ \ + || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ + || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ + || defined (__STDIO_LOADED) /* VMS */ +size_t mpz_out_str (FILE *, int, const mpz_t); +#endif + +void mpz_import (mpz_t, size_t, int, size_t, int, size_t, const void *); +void *mpz_export (void *, size_t *, int, size_t, int, size_t, const mpz_t); + +#if defined (__cplusplus) +} +#endif +#endif /* __MINI_GMP_H__ */ diff --git a/nettle-internal.c b/nettle-internal.c new file mode 100644 index 0000000..2a80947 --- /dev/null +++ b/nettle-internal.c @@ -0,0 +1,151 @@ +/* nettle-internal.c + + Things that are used only by the testsuite and benchmark, and + not included in the library. + + Copyright (C) 2002, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "nettle-internal.h" +#include "arcfour.h" +#include "blowfish.h" +#include "des.h" +#include "chacha.h" +#include "salsa20.h" + +/* Wrapper functions discarding the return value. Needed for the + ciphers with weak keys. */ +static void +des_set_key_wrapper (void *ctx, const uint8_t *key) +{ + des_set_key (ctx, key); +} + +static void +des3_set_key_wrapper (void *ctx, const uint8_t *key) +{ + des3_set_key (ctx, key); +} + +static void +blowfish128_set_key_wrapper (void *ctx, const uint8_t *key) +{ + blowfish128_set_key (ctx, key); +} + +const struct nettle_cipher +nettle_des = { + "des", sizeof(struct des_ctx), + DES_BLOCK_SIZE, DES_KEY_SIZE, + des_set_key_wrapper, + des_set_key_wrapper, + (nettle_cipher_func *) des_encrypt, + (nettle_cipher_func *) des_decrypt +}; + +const struct nettle_cipher +nettle_des3 = { + "des3", sizeof(struct des3_ctx), + DES3_BLOCK_SIZE, DES3_KEY_SIZE, + des3_set_key_wrapper, + des3_set_key_wrapper, + (nettle_cipher_func *) des3_encrypt, + (nettle_cipher_func *) des3_decrypt +}; + +const struct nettle_cipher +nettle_blowfish128 = + { "blowfish128", sizeof(struct blowfish_ctx), + BLOWFISH_BLOCK_SIZE, BLOWFISH128_KEY_SIZE, + blowfish128_set_key_wrapper, + blowfish128_set_key_wrapper, + (nettle_cipher_func *) blowfish_encrypt, + (nettle_cipher_func *) blowfish_decrypt + }; + +const struct nettle_aead +nettle_arcfour128 = { + "arcfour128", sizeof(struct arcfour_ctx), + 1, ARCFOUR128_KEY_SIZE, 0, 0, + (nettle_set_key_func *) arcfour128_set_key, + (nettle_set_key_func *) arcfour128_set_key, + NULL, NULL, + (nettle_crypt_func *) arcfour_crypt, + (nettle_crypt_func *) arcfour_crypt, + NULL, +}; + +const struct nettle_aead +nettle_chacha = { + "chacha", sizeof(struct chacha_ctx), + CHACHA_BLOCK_SIZE, CHACHA_KEY_SIZE, + CHACHA_NONCE_SIZE, 0, + (nettle_set_key_func *) chacha_set_key, + (nettle_set_key_func *) chacha_set_key, + (nettle_set_key_func *) chacha_set_nonce, + NULL, + (nettle_crypt_func *) chacha_crypt, + (nettle_crypt_func *) chacha_crypt, + NULL, +}; + +const struct nettle_aead +nettle_salsa20 = { + "salsa20", sizeof(struct salsa20_ctx), + SALSA20_BLOCK_SIZE, SALSA20_256_KEY_SIZE, + SALSA20_NONCE_SIZE, 0, + (nettle_set_key_func *) salsa20_256_set_key, + (nettle_set_key_func *) salsa20_256_set_key, + (nettle_set_key_func *) salsa20_set_nonce, + NULL, + (nettle_crypt_func *) salsa20_crypt, + (nettle_crypt_func *) salsa20_crypt, + NULL, +}; + +const struct nettle_aead +nettle_salsa20r12 = { + "salsa20r12", sizeof(struct salsa20_ctx), + SALSA20_BLOCK_SIZE, SALSA20_256_KEY_SIZE, + SALSA20_NONCE_SIZE, 0, + (nettle_set_key_func*) salsa20_256_set_key, + (nettle_set_key_func*) salsa20_256_set_key, + (nettle_set_key_func*) salsa20_set_nonce, + NULL, + (nettle_crypt_func *) salsa20r12_crypt, + (nettle_crypt_func *) salsa20r12_crypt, + NULL, +}; diff --git a/nettle-internal.h b/nettle-internal.h new file mode 100644 index 0000000..0b0d25c --- /dev/null +++ b/nettle-internal.h @@ -0,0 +1,94 @@ +/* nettle-internal.h + + Things that are used only by the testsuite and benchmark, and + not included in the library. + + Copyright (C) 2002, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_HASH_BLOCK_SIZE 128 +#define NETTLE_MAX_HASH_DIGEST_SIZE 64 +#define NETTLE_MAX_HASH_CONTEXT_SIZE (sizeof(struct sha3_224_ctx)) +#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; + +extern const struct nettle_cipher nettle_unified_aes128; +extern const struct nettle_cipher nettle_unified_aes192; +extern const struct nettle_cipher nettle_unified_aes256; + +/* Stream ciphers treated as aead algorithms with no authentication. */ +extern const struct nettle_aead nettle_arcfour128; +extern const struct nettle_aead nettle_chacha; +extern const struct nettle_aead nettle_salsa20; +extern const struct nettle_aead nettle_salsa20r12; + +/* Glue to openssl, for comparative benchmarking. Code in + * examples/nettle-openssl.c. */ +extern void nettle_openssl_init(void); +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_blowfish128; +extern const struct nettle_cipher nettle_openssl_des; +extern const struct nettle_cipher nettle_openssl_cast128; +extern const struct nettle_aead nettle_openssl_arcfour128; + +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-lookup-hash.c b/nettle-lookup-hash.c new file mode 100644 index 0000000..98cd4ae --- /dev/null +++ b/nettle-lookup-hash.c @@ -0,0 +1,51 @@ +/* nettle-lookup-hash.c + + Copyright (C) 2016 Niels Möller. + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "nettle-meta.h" + +#undef nettle_hashes + +const struct nettle_hash * +nettle_lookup_hash (const char *name) +{ + unsigned i; + for (i = 0; nettle_hashes[i]; i++) + if (!strcmp (name, nettle_hashes[i]->name)) + return nettle_hashes[i]; + return NULL; +} diff --git a/nettle-meta-aeads.c b/nettle-meta-aeads.c new file mode 100644 index 0000000..51866b6 --- /dev/null +++ b/nettle-meta-aeads.c @@ -0,0 +1,57 @@ +/* nettle-meta-aeads.c + + Copyright (C) 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#undef nettle_aeads + +const struct nettle_aead * const nettle_aeads[] = { + &nettle_gcm_aes128, + &nettle_gcm_aes192, + &nettle_gcm_aes256, + &nettle_gcm_camellia128, + &nettle_gcm_camellia256, + &nettle_eax_aes128, + &nettle_chacha_poly1305, + NULL +}; + +const struct nettle_aead * const * +nettle_get_aeads (void) +{ + return nettle_aeads; +} diff --git a/nettle-meta-armors.c b/nettle-meta-armors.c new file mode 100644 index 0000000..b8a81bc --- /dev/null +++ b/nettle-meta-armors.c @@ -0,0 +1,52 @@ +/* nettle-meta-armors.c + + Copyright (C) 2011 Daniel Kahn Gillmor + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "nettle-meta.h" + +#undef nettle_armors + +const struct nettle_armor * const nettle_armors[] = { + &nettle_base64, + &nettle_base64url, + &nettle_base16, + NULL +}; + +const struct nettle_armor * const * +nettle_get_armors (void) +{ + return nettle_armors; +} diff --git a/nettle-meta-ciphers.c b/nettle-meta-ciphers.c new file mode 100644 index 0000000..ef905d8 --- /dev/null +++ b/nettle-meta-ciphers.c @@ -0,0 +1,66 @@ +/* nettle-meta-ciphers.c + + Copyright (C) 2011 Daniel Kahn Gillmor + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "nettle-meta.h" + +#undef nettle_ciphers + +const struct nettle_cipher * const nettle_ciphers[] = { + &nettle_aes128, + &nettle_aes192, + &nettle_aes256, + &nettle_camellia128, + &nettle_camellia192, + &nettle_camellia256, + &nettle_cast128, + &nettle_serpent128, + &nettle_serpent192, + &nettle_serpent256, + &nettle_twofish128, + &nettle_twofish192, + &nettle_twofish256, + &nettle_arctwo40, + &nettle_arctwo64, + &nettle_arctwo128, + &nettle_arctwo_gutmann128, + NULL +}; + +const struct nettle_cipher * const * +nettle_get_ciphers (void) +{ + return nettle_ciphers; +} diff --git a/nettle-meta-hashes.c b/nettle-meta-hashes.c new file mode 100644 index 0000000..5df6f79 --- /dev/null +++ b/nettle-meta-hashes.c @@ -0,0 +1,63 @@ +/* nettle-meta-hashes.c + + Copyright (C) 2011 Daniel Kahn Gillmor + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "nettle-meta.h" + +#undef nettle_hashes + +const struct nettle_hash * const nettle_hashes[] = { + &nettle_md2, + &nettle_md4, + &nettle_md5, + &nettle_ripemd160, + &nettle_sha1, + &nettle_sha224, + &nettle_sha256, + &nettle_sha384, + &nettle_sha512, + &nettle_sha3_224, + &nettle_sha3_256, + &nettle_sha3_384, + &nettle_sha3_512, + NULL +}; + +const struct nettle_hash * const * +nettle_get_hashes (void) +{ + return nettle_hashes; +} diff --git a/nettle-meta.h b/nettle-meta.h new file mode 100644 index 0000000..0d16a2b --- /dev/null +++ b/nettle-meta.h @@ -0,0 +1,277 @@ +/* nettle-meta.h + + Information about algorithms. + + Copyright (C) 2002, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#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_cipher_func *encrypt; + nettle_cipher_func *decrypt; +}; + +/* FIXME: Rename with leading underscore, but keep current name (and + size!) for now, for ABI compatibility with nettle-3.1, soname + libnettle.so.6. */ +/* null-terminated list of ciphers implemented by this version of nettle */ +extern const struct nettle_cipher * const nettle_ciphers[]; + +const struct nettle_cipher * const * +#ifdef __GNUC__ +__attribute__((pure)) +#endif +nettle_get_ciphers (void); + +#define nettle_ciphers (nettle_get_ciphers()) + +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_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##_BLOCK_SIZE, \ + (nettle_hash_init_func *) name##_init, \ + (nettle_hash_update_func *) name##_update, \ + (nettle_hash_digest_func *) name##_digest \ +} + +/* FIXME: Rename with leading underscore, but keep current name (and + size!) for now, for ABI compatibility with nettle-3.1, soname + libnettle.so.6. */ +/* null-terminated list of digests implemented by this version of nettle */ +extern const struct nettle_hash * const nettle_hashes[]; + +const struct nettle_hash * const * +#ifdef __GNUC__ +__attribute__((pure)) +#endif +nettle_get_hashes (void); + +#define nettle_hashes (nettle_get_hashes()) + +const struct nettle_hash * +nettle_lookup_hash (const char *name); + +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_gosthash94; +extern const struct nettle_hash nettle_ripemd160; +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; +extern const struct nettle_hash nettle_sha512_224; +extern const struct nettle_hash nettle_sha512_256; +extern const struct nettle_hash nettle_sha3_224; +extern const struct nettle_hash nettle_sha3_256; +extern const struct nettle_hash nettle_sha3_384; +extern const struct nettle_hash nettle_sha3_512; + +struct nettle_aead +{ + const char *name; + + unsigned context_size; + /* Block size for encrypt and decrypt. */ + unsigned block_size; + unsigned key_size; + unsigned nonce_size; + unsigned digest_size; + + nettle_set_key_func *set_encrypt_key; + nettle_set_key_func *set_decrypt_key; + nettle_set_key_func *set_nonce; + nettle_hash_update_func *update; + nettle_crypt_func *encrypt; + nettle_crypt_func *decrypt; + /* FIXME: Drop length argument? */ + nettle_hash_digest_func *digest; +}; + +/* FIXME: Rename with leading underscore, but keep current name (and + size!) for now, for ABI compatibility with nettle-3.1, soname + libnettle.so.6. */ +/* null-terminated list of aead constructions implemented by this + version of nettle */ +extern const struct nettle_aead * const nettle_aeads[]; + +const struct nettle_aead * const * +#ifdef __GNUC__ +__attribute__((pure)) +#endif +nettle_get_aeads (void); + +#define nettle_aeads (nettle_get_aeads()) + +extern const struct nettle_aead nettle_gcm_aes128; +extern const struct nettle_aead nettle_gcm_aes192; +extern const struct nettle_aead nettle_gcm_aes256; +extern const struct nettle_aead nettle_gcm_camellia128; +extern const struct nettle_aead nettle_gcm_camellia256; +extern const struct nettle_aead nettle_eax_aes128; +extern const struct nettle_aead nettle_chacha_poly1305; + +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, \ +} + +/* FIXME: Rename with leading underscore, but keep current name (and + size!) for now, for ABI compatibility with nettle-3.1, soname + libnettle.so.6. */ +/* null-terminated list of armor schemes implemented by this version of nettle */ +extern const struct nettle_armor * const nettle_armors[]; + +const struct nettle_armor * const * +#ifdef __GNUC__ +__attribute__((pure)) +#endif +nettle_get_armors (void); + +#define nettle_armors (nettle_get_armors()) + +extern const struct nettle_armor nettle_base64; +extern const struct nettle_armor nettle_base64url; +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..84c375d --- /dev/null +++ b/nettle-types.h @@ -0,0 +1,110 @@ +/* nettle-types.h + + Copyright (C) 2005, 2014 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_TYPES_H +#define NETTLE_TYPES_H + +/* For size_t */ +#include + +/* Pretend these types always exists. Nettle doesn't use them. */ +#define _STDINT_HAVE_INT_FAST32_T 1 +#include "nettle-stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* An aligned 16-byte block. */ +union nettle_block16 +{ + uint8_t b[16]; + unsigned long w[16 / sizeof(unsigned long)]; +}; + +/* Randomness. Used by key generation and dsa signature creation. */ +typedef void nettle_random_func(void *ctx, + size_t length, uint8_t *dst); + +/* Progress report function, mainly for key generation. */ +typedef void nettle_progress_func(void *ctx, int c); + +/* Realloc function, used by struct nettle_buffer. */ +typedef void *nettle_realloc_func(void *ctx, void *p, size_t length); + +/* Ciphers */ +typedef void nettle_set_key_func(void *ctx, const uint8_t *key); + +/* For block ciphers, const context. */ +typedef void nettle_cipher_func(const void *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + + +/* Uses a void * for cipher contexts. Used for crypt operations where + the internal state changes during the encryption. */ +typedef void nettle_crypt_func(void *ctx, + size_t 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, + size_t length, + const uint8_t *src); +typedef void nettle_hash_digest_func(void *ctx, + size_t length, uint8_t *dst); + +/* ASCII armor codecs. NOTE: Experimental and subject to change. */ + +typedef size_t nettle_armor_length_func(size_t length); +typedef void nettle_armor_init_func(void *ctx); + +typedef size_t nettle_armor_encode_update_func(void *ctx, + char *dst, + size_t src_length, + const uint8_t *src); + +typedef size_t nettle_armor_encode_final_func(void *ctx, char *dst); + +typedef int nettle_armor_decode_update_func(void *ctx, + size_t *dst_length, + uint8_t *dst, + size_t src_length, + const char *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..6ca9963 --- /dev/null +++ b/nettle-write.h @@ -0,0 +1,58 @@ +/* nettle-write.h + + Internal functions to write out word-sized data to byte arrays. + + Copyright (C) 2010 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * 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. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_WRITE_H_INCLUDED +#define NETTLE_WRITE_H_INCLUDED + +/* For size_t */ +#include + +#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. */ + +/* FIXME: Use a macro shortcut to memcpy for native endianness. */ +void +_nettle_write_be32(size_t length, uint8_t *dst, + const uint32_t *src); +void +_nettle_write_le32(size_t length, uint8_t *dst, + const uint32_t *src); + +void +_nettle_write_le64(size_t length, uint8_t *dst, + const uint64_t *src); + +#endif /* NETTLE_WRITE_H_INCLUDED */ diff --git a/nettle.html b/nettle.html new file mode 100644 index 0000000..321470d --- /dev/null +++ b/nettle.html @@ -0,0 +1,6805 @@ + + + + + +Nettle: a low-level cryptographic library + + + + + + + + + + + + + + + + + +

Nettle: a low-level cryptographic library

+ + + + + + + +

Table of Contents

+ +
+ + +
+ + + +
+

+Next: , Previous: , Up: (dir)   [Contents][Index]

+
+ +

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 3.4), a +low-level cryptographic library. +

+

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

+
+

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. +

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

1 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. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

2 Copyright

+ +

Nettle is dual licenced under the GNU General Public License version 2 +or later, and the GNU Lesser General Public License version 3 or later. +When using Nettle, you must comply fully with all conditions of at least +one of these licenses. A few of the individual files are licensed under +more permissive terms, or in the public domain. 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 exceptions to the +above licensing: +

+
+
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. +

+
+
ARCFOUR
+

The implementation of the ARCFOUR (also known as RC4) cipher is written +by Niels Möller. +

+
+
ARCTWO
+

The implementation of the ARCTWO (also known as RC2) cipher is written +by Nikos Mavroyanopoulos and modified by Werner Koch and Simon +Josefsson. +

+
+
BLOWFISH
+

The implementation of the BLOWFISH cipher is written by Werner Koch, +copyright owned by the Free Software Foundation. Also hacked by Simon +Josefsson and Niels Möller. +

+
+
CAMELLIA
+

The C implementation is by Nippon Telegraph and Telephone Corporation +(NTT), heavily modified by Niels Möller. Assembler for x86 and x86_64 +by Niels Möller. +

+
+
CAST128
+

The implementation of the CAST128 cipher is written by Steve Reid. +Released into the public domain. +

+
+
CHACHA
+

Implemented by Joachim Strömbergson, based on the implementation of +SALSA20 (see below). Assembly for x86_64 by Niels Möller. +

+
+
DES
+

The implementation of the DES cipher is written by Dana L. How, and +released under the LGPL, version 2 or later. +

+
+
GOSTHASH94
+

The C implementation of the GOST94 message digest is written by +Aleksey Kravchenko and was ported from the rhash library by Nikos +Mavrogiannopoulos. It is released under the MIT license. +

+
+
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. +

+
+
PBKDF2
+

The C implementation of PBKDF2 is based on earlier work for Shishi and +GnuTLS by Simon Josefsson. +

+
+
RIPEMD160
+

The implementation of RIPEMD160 message digest is based on the code in +libgcrypt, copyright owned by the Free Software Foundation. Ported to +Nettle by Andres Mejia. +

+
+
SALSA20
+

The C implementation of SALSA20 is based on D. J. Bernstein’s reference +implementation (in the public domain), adapted to Nettle by Simon +Josefsson, and heavily modified by Niels Möller. Assembly for x86_64 and +ARM by Niels Möller. +

+
+
SERPENT
+

The implementation of the SERPENT cipher is based on the code in libgcrypt, +copyright owned by the Free Software Foundation. Adapted to Nettle by +Simon Josefsson and heavily modified by Niels Möller. Assembly for +x86_64 by Niels Möller. +

+
+
POLY1305
+

Based on the implementation by Andrew M. (floodyberry), modified by +Nikos Mavrogiannopoulos and Niels Möller. Assembly for x86_64 by Niels +Möller. +

+
+
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, x86_64 and ARM by +Niels Möller, released under the LGPL. +

+
+
SHA2
+

Written by Niels Möller, using Peter Gutmann’s SHA1 code as a model. +

+
+
SHA3
+

Written by Niels Möller. +

+
+
TWOFISH
+

The implementation of the TWOFISH cipher is written by Ruud de Rooij. +

+
+
UMAC
+

Written by Niels Möller. +

+
+
RSA
+

Written by Niels Möller. Uses the GMP library for bignum operations. +

+
+
DSA
+

Written by Niels Möller. Uses the GMP library for bignum operations. +

+
+
ECDSA
+

Written by Niels Möller. Uses the GMP library for bignum operations. +Development of Nettle’s ECC support was funded by the .SE Internet Fund. +

+
+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

3 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 size_t, 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 usually of the same length. +When they differ, e.g., for ccm_encrypt_message, the length +argument specifies the size of the destination area. Source and +destination pointers may be equal, so that you can process strings in +place, but source and destination areas 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. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

4 Example

+ +

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

+
+
#include <stdio.h>
+#include <stdlib.h>
+
+#include <nettle/sha1.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 +

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

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

5 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. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

6 Reference

+ +

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

+ + + + + + + + + + + + + + +
+ +
+

+Next: , Previous: , Up: Reference   [Contents][Index]

+
+ + +

6.1 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 functions +for new applications are SHA2 (with main variants SHA256 and SHA512). At +the time of this writing (Autumn 2015), SHA3 has recently been +standardized, and the new SHA3 and other top SHA3 candidates may also be +reasonable alternatives. +

+ + + + + + +
+ + + +

6.1.1 Recommended hash functions

+ +

The following hash functions have no known weaknesses, and are suitable +for new applications. The SHA2 family of hash functions were specified +by NIST, intended as a replacement for SHA1. +

+ +

6.1.1.1 SHA256

+ +

SHA256 is a member of the SHA2 family. It outputs hash values of 256 +bits, or 32 octets. Nettle defines SHA256 in <nettle/sha2.h>. +

+
+
Context struct: struct sha256_ctx
+
+ +
+
Constant: SHA256_DIGEST_SIZE
+

The size of a SHA256 digest, i.e. 32. +

+ +
+
Constant: SHA256_BLOCK_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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha256_digest (struct sha256_ctx *ctx, size_t 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. +

+ +

Earlier versions of nettle defined SHA256 in the header file +<nettle/sha.h>, which is now deprecated, but kept for +compatibility. +

+ +

6.1.1.2 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/sha2.h> (and in <nettle/sha.h>, for backwards +compatibility). +

+
+
Context struct: struct sha224_ctx
+
+ +
+
Constant: SHA224_DIGEST_SIZE
+

The size of a SHA224 digest, i.e. 28. +

+ +
+
Constant: SHA224_BLOCK_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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha224_digest (struct sha224_ctx *ctx, size_t 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. +

+ + +

6.1.1.3 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/sha2.h> (and in +<nettle/sha.h>, for backwards compatibility). +

+
+
Context struct: struct sha512_ctx
+
+ +
+
Constant: SHA512_DIGEST_SIZE
+

The size of a SHA512 digest, i.e. 64. +

+ +
+
Constant: SHA512_BLOCK_SIZE
+

The internal block size of SHA512, 128. 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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha512_digest (struct sha512_ctx *ctx, size_t 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. +

+ + +

6.1.1.4 SHA384 and other variants of SHA512

+ +

Several variants of SHA512 have been defined, with a different initial +state, and with the output truncated to shorter length than 512 bits. +Naming is a bit confused, these algorithms are called SHA512-224, +SHA512-256 and SHA384, for output sizes of 224, 256 and 384 bits, +respectively. Nettle defines these in <nettle/sha2.h> (and in +<nettle/sha.h>, for backwards compatibility). +

+
+
Context struct: struct sha512_224_ctx
+
Context struct: struct sha512_256_ctx
+
Context struct: struct sha384_ctx
+

These context structs are all the same as sha512_ctx. They are defined as +simple preprocessor aliases, which may cause some problems if used as +identifiers for other purposes. So avoid doing that. +

+ +
+
Constant: SHA512_224_DIGEST_SIZE
+
Constant: SHA512_256_DIGEST_SIZE
+
Constant: SHA384_DIGEST_SIZE
+

The digest size for each variant, i.e., 28, 32, and 48, respectively. +

+ +
+
Constant: SHA512_224_BLOCK_SIZE
+
Constant: SHA512_256_BLOCK_SIZE
+
Constant: SHA384_BLOCK_SIZE
+

The internal block size, same as SHA512_BLOCK_SIZE, i.e., 128. Useful for +some special constructions, in particular HMAC-SHA384. +

+ +
+
Function: void sha512_224_init (struct sha512_224_ctx *ctx)
+
Function: void sha512_256_init (struct sha512_256_ctx *ctx)
+
Function: void sha384_init (struct sha384_ctx *ctx)
+

Initialize the context struct. +

+ +
+
Function: void sha512_224_update (struct sha512_224_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void sha512_256_update (struct sha512_256_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void sha384_update (struct sha384_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. These are all aliases for sha512_update, which does +the same thing. +

+ +
+
Function: void sha512_224_digest (struct sha512_224_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void sha512_256_digest (struct sha512_256_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void sha384_digest (struct sha384_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it to +digest. length may be smaller than the specified digest +size, in which case only the first length octets of the digest are +written. +

+

These function also reset the context in the same way as the +corresponding init function. +

+ + +

6.1.1.5 SHA3-224

+ + +

The SHA3 hash functions were specified by NIST in response to weaknesses +in SHA1, and doubts about SHA2 hash functions which structurally are +very similar to SHA1. SHA3 is a result of a competition, where the +winner, also known as Keccak, was designed by Guido Bertoni, Joan +Daemen, Michaël Peeters and Gilles Van Assche. It is structurally very +different from all widely used earlier hash functions. Like SHA2, there +are several variants, with output sizes of 224, 256, 384 and 512 bits +(28, 32, 48 and 64 octets, respectively). In August 2015, it was +formally standardized by NIST, as FIPS 202, +http://dx.doi.org/10.6028/NIST.FIPS.202. +

+

Note that the SHA3 implementation in earlier versions of Nettle was +based on the specification at the time Keccak was announced as the +winner of the competition, which is incompatible with the final standard +and hence with current versions of Nettle. The nette/sha3.h +defines a preprocessor symbol NETTLE_SHA3_FIPS202 to indicate +conformance with the standard. +

+
+
Constant: NETTLE_SHA3_FIPS202
+

Defined to 1 in Nettle versions supporting FIPS 202. Undefined in +earlier versions. +

+ +

Nettle defines SHA3-224 in <nettle/sha3.h>. +

+
+
Context struct: struct sha3_224_ctx
+
+ +
+
Constant: SHA3_224_DIGEST_SIZE
+

The size of a SHA3_224 digest, i.e., 28. +

+ +
+
Constant: SHA3_224_BLOCK_SIZE
+

The internal block size of SHA3_224. +

+ +
+
Function: void sha3_224_init (struct sha3_224_ctx *ctx)
+

Initialize the SHA3-224 state. +

+ +
+
Function: void sha3_224_update (struct sha3_224_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha3_224_digest (struct sha3_224_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA3_224_DIGEST_SIZE, in which case only the first length +octets of the digest are written. +

+

This function also resets the context. +

+ + +

6.1.1.6 SHA3-256

+ +

This is SHA3 with 256-bit output size, and possibly the most useful +of the SHA3 hash functions. +

+

Nettle defines SHA3-256 in <nettle/sha3.h>. +

+
+
Context struct: struct sha3_256_ctx
+
+ +
+
Constant: SHA3_256_DIGEST_SIZE
+

The size of a SHA3_256 digest, i.e., 32. +

+ +
+
Constant: SHA3_256_BLOCK_SIZE
+

The internal block size of SHA3_256. +

+ +
+
Function: void sha3_256_init (struct sha3_256_ctx *ctx)
+

Initialize the SHA3-256 state. +

+ +
+
Function: void sha3_256_update (struct sha3_256_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha3_256_digest (struct sha3_256_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA3_256_DIGEST_SIZE, in which case only the first length +octets of the digest are written. +

+

This function also resets the context. +

+ + +

6.1.1.7 SHA3-384

+ +

This is SHA3 with 384-bit output size. +

+

Nettle defines SHA3-384 in <nettle/sha3.h>. +

+
+
Context struct: struct sha3_384_ctx
+
+ +
+
Constant: SHA3_384_DIGEST_SIZE
+

The size of a SHA3_384 digest, i.e., 48. +

+ +
+
Constant: SHA3_384_BLOCK_SIZE
+

The internal block size of SHA3_384. +

+ +
+
Function: void sha3_384_init (struct sha3_384_ctx *ctx)
+

Initialize the SHA3-384 state. +

+ +
+
Function: void sha3_384_update (struct sha3_384_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha3_384_digest (struct sha3_384_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA3_384_DIGEST_SIZE, in which case only the first length +octets of the digest are written. +

+

This function also resets the context. +

+ + +

6.1.1.8 SHA3-512

+ +

This is SHA3 with 512-bit output size. +

+

Nettle defines SHA3-512 in <nettle/sha3.h>. +

+
+
Context struct: struct sha3_512_ctx
+
+ +
+
Constant: SHA3_512_DIGEST_SIZE
+

The size of a SHA3_512 digest, i.e. 64. +

+ +
+
Constant: SHA3_512_BLOCK_SIZE
+

The internal block size of SHA3_512. +

+ +
+
Function: void sha3_512_init (struct sha3_512_ctx *ctx)
+

Initialize the SHA3-512 state. +

+ +
+
Function: void sha3_512_update (struct sha3_512_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha3_512_digest (struct sha3_512_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +SHA3_512_DIGEST_SIZE, in which case only the first length +octets of the digest are written. +

+

This function also resets the context. +

+ +
+ + + +

6.1.2 Legacy hash functions

+ +

The hash functions in this section all have some known weaknesses, and +should be avoided for new applications. These hash functions are mainly +useful for compatibility with old applications and protocols. Some are +still considered safe as building blocks for particular constructions, +e.g., there seems to be no known attacks against HMAC-SHA1 or even +HMAC-MD5. In some important cases, use of a “legacy” hash function +does not in itself make the application insecure; if a known weakness is +relevant depends on how the hash function is used, and on the threat +model. +

+ +

6.1.2.1 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>. +

+
+
Context struct: struct md5_ctx
+
+ +
+
Constant: MD5_DIGEST_SIZE
+

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

+ +
+
Constant: MD5_BLOCK_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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void md5_digest (struct md5_ctx *ctx, size_t 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. +

+ +

6.1.2.2 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>. +

+
+
Context struct: struct md2_ctx
+
+ +
+
Constant: MD2_DIGEST_SIZE
+

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

+ +
+
Constant: MD2_BLOCK_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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void md2_digest (struct md2_ctx *ctx, size_t 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. +

+ + +

6.1.2.3 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. +

+
+
Context struct: struct md4_ctx
+
+ +
+
Constant: MD4_DIGEST_SIZE
+

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

+ +
+
Constant: MD4_BLOCK_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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void md4_digest (struct md4_ctx *ctx, size_t 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. +

+ + +

6.1.2.4 RIPEMD160

+ +

RIPEMD160 is a hash function designed by Hans Dobbertin, Antoon +Bosselaers, and Bart Preneel, as a strengthened version of RIPEMD +(which, like MD4 and MD5, fails the collision-resistance requirement). +It produces message digests of 160 bits, or 20 octets. Nettle defined +RIPEMD160 in nettle/ripemd160.h. +

+
+
Context struct: struct ripemd160_ctx
+
+ +
+
Constant: RIPEMD160_DIGEST_SIZE
+

The size of a RIPEMD160 digest, i.e. 20. +

+ +
+
Constant: RIPEMD160_BLOCK_SIZE
+

The internal block size of RIPEMD160. +

+ +
+
Function: void ripemd160_init (struct ripemd160_ctx *ctx)
+

Initialize the RIPEMD160 state. +

+ +
+
Function: void ripemd160_update (struct ripemd160_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void ripemd160_digest (struct ripemd160_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +RIPEMD160_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 +ripemd160_init. +

+ + +

6.1.2.5 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/sha1.h> (and +in <nettle/sha.h>, for backwards compatibility). +

+
+
Context struct: struct sha1_ctx
+
+ +
+
Constant: SHA1_DIGEST_SIZE
+

The size of a SHA1 digest, i.e. 20. +

+ +
+
Constant: SHA1_BLOCK_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, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void sha1_digest (struct sha1_ctx *ctx, size_t 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. +

+ + + +

6.1.2.6 GOSTHASH94

+ +

The GOST94 or GOST R 34.11-94 hash algorithm is a Soviet-era algorithm +used in Russian government standards (see RFC 4357). +It outputs message digests of 256 bits, or 32 octets. +Nettle defines GOSTHASH94 in <nettle/gosthash94.h>. +

+
+
Context struct: struct gosthash94_ctx
+
+ +
+
Constant: GOSTHASH94_DIGEST_SIZE
+

The size of a GOSTHASH94 digest, i.e. 32. +

+ +
+
Constant: GOSTHASH94_BLOCK_SIZE
+

The internal block size of GOSTHASH94, i.e., 32. +

+ +
+
Function: void gosthash94_init (struct gosthash94_ctx *ctx)
+

Initialize the GOSTHASH94 state. +

+ +
+
Function: void gosthash94_update (struct gosthash94_ctx *ctx, size_t length, const uint8_t *data)
+

Hash some more data. +

+ +
+
Function: void gosthash94_digest (struct gosthash94_ctx *ctx, size_t length, uint8_t *digest)
+

Performs final processing and extracts the message digest, writing it +to digest. length may be smaller than +GOSTHASH94_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 +gosthash94_init. +

+ +
+ + + +

6.1.3 The struct nettle_hash abstraction

+ + + + +

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). +

+
+
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_ripemd160
+
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: struct nettle_hash nettle_sha3_256
+
Constant Struct: struct nettle_hash nettle_gosthash94
+

These are all the hash functions that Nettle implements. +

+ +

Nettle also exports a list of all these hashes. +

+
+
Function: const struct nettle_hash **nettle_get_hashes(void)
+

Returns a NULL-terminated list of pointers to supported hash functions. +This list can be used to dynamically enumerate or search the supported +algorithms. +

+ +
+
Macro: nettle_hashes
+

A macro expanding to a call to nettle_get_hashes, so that one could +write, e.g., nettle_hashes[0]->name for the name of the first +hash function on the list. In earlier versions, this was not a macro but +the actual array of pointers. However, referring directly to the array +makes the array size leak into the ABI in some cases. +

+ +
+ +
+

+Next: , Previous: , Up: Reference   [Contents][Index]

+
+ +

6.2 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. +

+ +

6.2.1 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 three possible 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>, and there is one +context struct for each key size. (Earlier versions of Nettle used a +single context struct, struct aes_ctx, for all key sizes. This +interface kept for backwards compatibility). +

+
+
Context struct: struct aes128_ctx
+
Context struct: struct aes192_ctx
+
Context struct: struct aes256_ctx
+
+ +
+
Context struct: struct aes_ctx
+

Alternative struct, for the old AES interface. +

+ +
+
Constant: AES_BLOCK_SIZE
+

The AES block-size, 16. +

+ +
+
Constant: AES128_KEY_SIZE
+
Constant: AES192_KEY_SIZE
+
Constant: AES256_KEY_SIZE
+
Constant: AES_MIN_KEY_SIZE
+
Constant: AES_MAX_KEY_SIZE
+
+ +
+
Constant: AES_KEY_SIZE
+

Default AES key size, 32. +

+ +
+
Function: void aes128_set_encrypt_key (struct aes128_ctx *ctx, const uint8_t *key)
+
Function: void aes128_set_decrypt_key (struct aes128_ctx *ctx, const uint8_t *key)
+
Function: void aes192_set_encrypt_key (struct aes192_ctx *ctx, const uint8_t *key)
+
Function: void aes192_set_decrypt_key (struct aes192_ctx *ctx, const uint8_t *key)
+
Function: void aes256_set_encrypt_key (struct aes256_ctx *ctx, const uint8_t *key)
+
Function: void aes256_set_decrypt_key (struct aes256_ctx *ctx, const uint8_t *key)
+
Function: void aes_set_encrypt_key (struct aes_ctx *ctx, size_t length, const uint8_t *key)
+
Function: void aes_set_decrypt_key (struct aes_ctx *ctx, size_t length, const uint8_t *key)
+

Initialize the cipher, for encryption or decryption, respectively. +

+ +
+
Function: void aes128_invert_key (struct aes128_ctx *dst, const struct aes128_ctx *src)
+
Function: void aes192_invert_key (struct aes192_ctx *dst, const struct aes192_ctx *src)
+
Function: void aes256_invert_key (struct aes256_ctx *dst, const struct aes256_ctx *src)
+
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. These functions are mainly useful for applications +which needs to both encrypt and decrypt using the same key, +because calling, e.g., aes128_set_encrypt_key and +aes128_invert_key, is more efficient than calling +aes128_set_encrypt_key and aes128_set_decrypt_key. +

+ +
+
Function: void aes128_encrypt (struct aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void aes192_encrypt (struct aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void aes256_encrypt (struct aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void aes_encrypt (struct aes_ctx *ctx, size_t length, uint8_t *dst, const 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 aes128_decrypt (struct aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void aes192_decrypt (struct aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void aes256_decrypt (struct aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void aes_decrypt (struct aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to the encryption functions above. +

+ + +

6.2.2 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,
+                       size_t 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>. +

+
+
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, size_t 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, size_t length, uint8_t *dst, const 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. +

+ + +

6.2.3 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. +

+
+
Context struct: struct arctwo_ctx
+
+ +
+
Constant: ARCTWO_BLOCK_SIZE
+

The ARCTWO 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, size_t length, const uint8_t *key, unsigned ekb)
+
Function: void arctwo_set_key (struct arctwo_ctx *ctx, size_t length, const uint8_t *key)
+
Function: void arctwo_set_key_gutmann (struct arctwo_ctx *ctx, size_t 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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to arctwo_encrypt +

+ + +

6.2.4 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>. +

+
+
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, size_t 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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to blowfish_encrypt +

+ + +

6.2.5 Camellia

+ +

Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph +and Telephone Corporation, described in RFC3713. It is +recommended by some Japanese and European authorities as an alternative +to AES, and it is one of the selected algorithms in the New European +Schemes for Signatures, Integrity and Encryption (NESSIE) project. 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. The variants with 192 and 256 bit keys are identical, except +for the key setup. Nettle defines Camellia in +<nettle/camellia.h>, and there is one context struct for each key +size. (Earlier versions of Nettle used a single context struct, +struct camellia_ctx, for all key sizes. This interface kept for +backwards compatibility). +

+
+
Context struct: struct camellia128_ctx
+
Context struct: struct camellia192_ctx
+
Context struct: struct camellia256_ctx
+

Contexts structs. Actually, camellia192_ctx is an alias for +camellia256_ctx. +

+ +
+
Context struct: struct camellia_ctx
+

Alternative struct, for the old Camellia interface. +

+ +
+
Constant: CAMELLIA_BLOCK_SIZE
+

The CAMELLIA block-size, 16. +

+ +
+
Constant: CAMELLIA128_KEY_SIZE
+
Constant: CAMELLIA192_KEY_SIZE
+
Constant: CAMELLIA256_KEY_SIZE
+
Constant: CAMELLIA_MIN_KEY_SIZE
+
Constant: CAMELLIA_MAX_KEY_SIZE
+
+ +
+
Constant: CAMELLIA_KEY_SIZE
+

Default CAMELLIA key size, 32. +

+ +
+
Function: void camellia128_set_encrypt_key (struct camellia128_ctx *ctx, const uint8_t *key)
+
Function: void camellia128_set_decrypt_key (struct camellia128_ctx *ctx, const uint8_t *key)
+
Function: void camellia192_set_encrypt_key (struct camellia192_ctx *ctx, const uint8_t *key)
+
Function: void camellia192_set_decrypt_key (struct camellia192_ctx *ctx, const uint8_t *key)
+
Function: void camellia256_set_encrypt_key (struct camellia256_ctx *ctx, const uint8_t *key)
+
Function: void camellia256_set_decrypt_key (struct camellia256_ctx *ctx, const uint8_t *key)
+
Function: void camellia_set_encrypt_key (struct camellia_ctx *ctx, size_t length, const uint8_t *key)
+
Function: void camellia_set_decrypt_key (struct camellia_ctx *ctx, size_t length, const uint8_t *key)
+

Initialize the cipher, for encryption or decryption, respectively. +

+ +
+
Function: void camellia128_invert_key (struct camellia128_ctx *dst, const struct camellia128_ctx *src)
+
Function: void camellia192_invert_key (struct camellia192_ctx *dst, const struct camellia192_ctx *src)
+
Function: void camellia256_invert_key (struct camellia256_ctx *dst, const struct camellia256_ctx *src)
+
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. These functions are mainly useful for applications +which needs to both encrypt and decrypt using the same key. +

+ +
+
Function: void camellia128_crypt (struct camellia128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void camellia192_crypt (struct camellia192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void camellia256_crypt (struct camellia256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void camellia_crypt (struct camellia_ctx *ctx, size_t length, uint8_t *dst, const 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. +

+ + +

6.2.6 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>. +

+
+
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, size_t 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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to cast128_encrypt +

+ + +

6.2.7 ChaCha

+ +

ChaCha is a variant of the stream cipher Salsa20, also designed by D. J. +Bernstein. For more information on Salsa20, see below. Nettle defines +ChaCha in <nettle/chacha.h>. +

+
+
Context struct: struct chacha_ctx
+
+ +
+
Constant: CHACHA_KEY_SIZE
+

ChaCha key size, 32. +

+ +
+
Constant: CHACHA_BLOCK_SIZE
+

ChaCha block size, 64. +

+ +
+
Constant: CHACHA_NONCE_SIZE
+

Size of the nonce, 8. +

+ +
+
Function: void chacha_set_key (struct chacha_ctx *ctx, const uint8_t *key)
+

Initialize the cipher. The same function is used for both encryption and +decryption. Before using the cipher, +you must also call chacha_set_nonce, see below. +

+ +
+
Function: void chacha_set_nonce (struct chacha_ctx *ctx, const uint8_t *nonce)
+

Sets the nonce. It is always of size CHACHA_NONCE_SIZE, 8 +octets. This function also initializes the block counter, setting it to +zero. +

+ +
+
Function: void chacha_crypt (struct chacha_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message, using ChaCha. When a +message is encrypted using a sequence of calls to chacha_crypt, +all but the last call must use a length that is a multiple of +CHACHA_BLOCK_SIZE. +

+ + +

6.2.8 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>. +

+
+
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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to des_encrypt +

+ +
+
Function: int des_check_parity (size_t 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 (size_t 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. +

+ + +

6.2.9 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>. +

+
+
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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to des_encrypt +

+ + +

6.2.10 Salsa20

+

Salsa20 is a fairly recent stream cipher designed by D. J. Bernstein. It +is built on the observation that a cryptographic hash function can be +used for encryption: Form the hash input from the secret key and a +counter, xor the hash output and the first block of the plaintext, then +increment the counter to process the next block (similar to CTR mode, see +see CTR). Bernstein defined an encryption algorithm, Snuffle, +in this way to ridicule United States export restrictions which treated hash +functions as nice and harmless, but ciphers as dangerous munitions. +

+

Salsa20 uses the same idea, but with a new specialized hash function to +mix key, block counter, and a couple of constants. It’s also designed +for speed; on x86_64, it is currently the fastest cipher offered by +nettle. It uses a block size of 512 bits (64 octets) and there are two +specified key sizes, 128 and 256 bits (16 and 32 octets). +

+

Caution: The hash function used in Salsa20 is not +directly applicable for use as a general hash function. It’s not +collision resistant if arbitrary inputs are allowed, and furthermore, +the input and output is of fixed size. +

+

When using Salsa20 to process a message, one specifies both a key and a +nonce, the latter playing a similar rôle to the initialization +vector (IV) used with CBC or CTR mode. One +can use the same key for several messages, provided one uses a unique +random iv for each message. The iv is 64 bits (8 +octets). The block counter is initialized to zero for each message, and +is also 64 bits (8 octets). Nettle defines Salsa20 in +<nettle/salsa20.h>. +

+
+
Context struct: struct salsa20_ctx
+
+ +
+
Constant: SALSA20_128_KEY_SIZE
+
Constant: SALSA20_256_KEY_SIZE
+

The two supported key sizes, 16 and 32 octets. +

+ +
+
Constant: SALSA20_KEY_SIZE
+

Recommended key size, 32. +

+ +
+
Constant: SALSA20_BLOCK_SIZE
+

Salsa20 block size, 64. +

+ +
+
Constant: SALSA20_NONCE_SIZE
+

Size of the nonce, 8. +

+ +
+
Function: void salsa20_128_set_key (struct salsa20_ctx *ctx, const uint8_t *key)
+
Function: void salsa20_256_set_key (struct salsa20_ctx *ctx, const uint8_t *key)
+
Function: void salsa20_set_key (struct salsa20_ctx *ctx, size_t length, const uint8_t *key)
+

Initialize the cipher. The same function is used for both encryption and +decryption. salsa20_128_set_key and salsa20_128_set_key +use a fix key size each, 16 and 32 octets, respectively. The function +salsa20_set_key is provided for backwards compatibility, and the +length argument must be either 16 or 32. Before using the cipher, +you must also call salsa20_set_nonce, see below. +

+ +
+
Function: void salsa20_set_nonce (struct salsa20_ctx *ctx, const uint8_t *nonce)
+

Sets the nonce. It is always of size SALSA20_NONCE_SIZE, 8 +octets. This function also initializes the block counter, setting it to +zero. +

+ +
+
Function: void salsa20_crypt (struct salsa20_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message, using salsa20. When a +message is encrypted using a sequence of calls to salsa20_crypt, +all but the last call must use a length that is a multiple of +SALSA20_BLOCK_SIZE. +

+ +

The full salsa20 cipher uses 20 rounds of mixing. Variants of Salsa20 +with fewer rounds are possible, and the 12-round variant is specified by +eSTREAM, see http://www.ecrypt.eu.org/stream/finallist.html. +Nettle calls this variant salsa20r12. It uses the same context +struct and key setup as the full salsa20 cipher, but a separate function +for encryption and decryption. +

+
+
Function: void salsa20r12_crypt (struct salsa20_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message, using salsa20 reduced to 12 +rounds. +

+ + +

6.2.11 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>. +

+
+
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, size_t 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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to serpent_encrypt +

+ + + +

6.2.12 TWOFISH

+

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

+
+
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, size_t 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, size_t length, uint8_t *dst, const 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, size_t length, uint8_t *dst, const uint8_t *src)
+

Analogous to twofish_encrypt +

+ + +

6.2.13 The struct nettle_cipher abstraction

+ + + + +

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

+
+
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_cipher_func *. The first +argument to these functions is a const 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
+

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

+ +

Nettle also exports a list of all these ciphers without weak keys or +other oddities. +

+
+
Function: const struct nettle_cipher **nettle_get_ciphers(void)
+

Returns a NULL-terminated list of pointers to supported block ciphers. +This list can be used to dynamically enumerate or search the supported +algorithms. +

+ +
+
Macro: nettle_ciphers
+

A macro expanding to a call to nettle_get_ciphers. In earlier versions, +this was not a macro but the actual array of pointers. +

+ +
+ + + +

6.3 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 several other modes of operation: +Cipher Block Chaining (CBC), Counter mode (CTR), Cipher +Feedback (CFB) and a couple of AEAD modes +(see Authenticated encryption). CBC is widely used, but +there are a few subtle issues of information leakage, see, e.g., +SSH CBC +vulnerability. Today, CTR is usually preferred over CBC. +

+

Modes like CBC, CTR and CFB provide no +message authentication, and should always be used together with a +MAC (see Keyed hash functions) or signature to authenticate +the message. +

+ + + + + + +
+ +
+

+Next: , Previous: , Up: Cipher modes   [Contents][Index]

+
+ +

6.3.1 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 (const void *ctx, nettle_cipher_func *f, size_t block_size, uint8_t *iv, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void cbc_decrypt (const void *ctx, nettle_cipher_func *f, size_t block_size, uint8_t *iv, size_t 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 a large message can be processed by a sequence of +calls to cbc_encrypt. The function f is of type +

+

void f (void *ctx, size_t 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 to +

+
{
+   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. +

+
+ +
+

+Next: , Previous: , Up: Cipher modes   [Contents][Index]

+
+ +

6.3.2 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 rôle 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 (const void *ctx, nettle_cipher_func *f, size_t block_size, uint8_t *ctr, size_t 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 to +

+
{
+   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. +

+ +
+ +
+

+Previous: , Up: Cipher modes   [Contents][Index]

+
+ +

6.3.3 Cipher Feedback mode

+ + + + +

Cipher Feedback mode (CFB) being a close relative to both +CBC mode and CTR mode borrows some characteristics +from stream ciphers. +

+

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, IV is +the initialization vector, then the n plaintext blocks 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-1) = E_k(C_(n - 2)) XOR M_(n-1)
+C_n = E_k(C_(n - 1)) [1..m] XOR M_n
+
+ +

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

+
+
Function: void cfb_encrypt (const void *ctx, nettle_cipher_func *f, size_t block_size, uint8_t *iv, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void cfb_decrypt (const void *ctx, nettle_cipher_func *f, size_t block_size, uint8_t *iv, size_t length, uint8_t *dst, const uint8_t *src)
+
+

Applies the encryption or decryption function f in CFB +mode. The final ciphertext block processed is copied into iv +before returning, so that a large message can be processed by a sequence +of calls to cfb_encrypt. Note that for CFB mode +internally uses encryption only function 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 +cfb_encrypt, 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: CFB_CTX (context_type, block_size)
+

Expands to +

+
{
+   context_type ctx;
+   uint8_t iv[block_size];
+}
+
+
+ +
+
Macro: CFB_SET_IV(ctx, iv)
+

First argument is a pointer to a context struct as defined by +CFB_CTX, and the second is a pointer to an initialization vector +that is copied into that context. +

+ +
+
Macro: CFB_ENCRYPT (ctx, f, length, dst, src)
+

A simpler way to invoke cfb_encrypt. The first argument is a +pointer to a context struct as defined by CFB_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. +

+ +
+
Macro: CFB_DECRYPT (ctx, f, length, dst, src)
+

A simpler way to invoke cfb_decrypt. The first argument is a +pointer to a context struct as defined by CFB_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. +

+ +
+ +
+

+Next: , Previous: , Up: Reference   [Contents][Index]

+
+ + +

6.4 Authenticated encryption with associated data

+ + + +

Since there are some subtle design choices to be made when combining a +block cipher mode with out authentication with a MAC. In +recent years, several constructions that combine encryption and +authentication have been defined. These constructions typically also +have an additional input, the “associated data”, which is +authenticated but not included with the message. A simple example is an +implicit message number which is available at both sender and receiver, +and which needs authentication in order to detect deletions or replay of +messages. This family of building blocks are therefore called +AEAD, Authenticated encryption with associated data. +

+

The aim is to provide building blocks that it is easier for designers of +protocols and applications to use correctly. There is also some +potential for improved performance, if encryption and authentication can +be done in a single step, although that potential is not realized for +the constructions currently supported by Nettle. +

+

For encryption, the inputs are: +

+
    +
  • The key, which can be used for many messages. +
  • A nonce, which must be unique for each message using the same key. +
  • Additional associated data to be authenticated, but not included in the +message. +
  • The cleartext message to be encrypted. +
+ +

The outputs are: +

+
    +
  • The ciphertext, of the same size as the cleartext. +
  • A digest or “authentication tag”. +
+ +

Decryption works the same, but with cleartext and ciphertext +interchanged. All currently supported AEAD algorithms always +use the encryption function of the underlying block cipher, for both +encryption and decryption. +

+

Usually, the authentication tag should be appended at the end of the +ciphertext, producing an encrypted message which is slightly longer than +the cleartext. However, Nettle’s low level AEAD functions +produce the authentication tag as a separate output for both encryption +and decryption. +

+

Both associated data and the message data (cleartext or ciphertext) can +be processed incrementally. In general, all associated data must be +processed before the message data, and all calls but the last one must +use a length that is a multiple of the block size, although some +AEAD may implement more liberal conventions. The CCM +mode is a bit special in that it requires the message lengths up front, +other AEAD constructions don’t have this restriction. +

+

The supported AEAD constructions are Galois/Counter mode +(GCM), EAX, ChaCha-Poly1305, and Counter with +CBC-MAC (CCM). There are some weaknesses +in GCM authentication, see +http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/comments/CWC-GCM/Ferguson2.pdf. +CCM and EAX use the same building blocks, but the +EAX design is cleaner and avoids a couple of inconveniences of +CCM. Therefore, EAX seems like a good conservative +choice. The more recent ChaCha-Poly1305 may also be an attractive but +more adventurous alternative, in particular if performance is important. +

+ + + + + + + + +
+ + + +

6.4.1 EAX

+ +

The EAX mode is an AEAD mode whichcombines +CTR mode encryption, See CTR, with a message authentication +based on CBC, See CBC. The implementation in Nettle is +restricted to ciphers with a block size of 128 bits (16 octets). +EAX was defined as a reaction to the CCM mode, +See CCM, which uses the same primitives but has some undesirable and +inelegant properties. +

+

EAX supports arbitrary nonce size; it’s even possible to use +an empty nonce in case only a single message is encrypted for each key. +

+

Nettle’s support for EAX consists of a low-level general +interface, some convenience macros, and specific functions for +EAX using AES-128 as the underlying cipher. These +interfaces are defined in <nettle/eax.h> +

+ +

6.4.1.1 General EAX interface

+ +
+
Context struct: struct eax_key
+

EAX state which depends only on the key, but not on the nonce +or the message. +

+ +
+
Context struct: struct eax_ctx
+

Holds state corresponding to a particular message. +

+ +
+
Constant: EAX_BLOCK_SIZE
+

EAX’s block size, 16. +

+ +
+
Constant: EAX_DIGEST_SIZE
+

Size of the EAX digest, also 16. +

+ +
+
Function: void eax_set_key (struct eax_key *key, const void *cipher, nettle_cipher_func *f)
+

Initializes key. cipher gives a context struct for the +underlying cipher, which must have been previously initialized for +encryption, and f is the encryption function. +

+ +
+
Function: void eax_set_nonce (struct eax_ctx *eax, const struct eax_key *key, const void *cipher, nettle_cipher_func *f, size_t nonce_length, const uint8_t *nonce)
+

Initializes ctx for processing a new message, using the given +nonce. +

+ +
+
Function: void eax_update (struct eax_ctx *eax, const struct eax_key *key, const void *cipher, nettle_cipher_func *f, size_t data_length, const uint8_t *data)
+

Process associated data for authentication. All but the last call for +each message must use a length that is a multiple of the block +size. Unlike many other AEAD constructions, for EAX +it’s not necessary to complete the processing of all associated data +before encrypting or decrypting the message data. +

+ +
+
Function: void eax_encrypt (struct eax_ctx *eax, const struct eax_key *key, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void eax_decrypt (struct eax_ctx *eax, const struct eax_key *key, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message. cipher is the context +struct for the underlying cipher and f is the encryption function. +All but the last call for each message must use a length that is +a multiple of the block size. +

+ +
+
Function: void eax_digest (struct eax_ctx *eax, const struct eax_key *key, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *digest);
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. If length is +smaller than EAX_DIGEST_SIZE, only the first length octets +of the digest are written. +

+ + + +

6.4.1.2 EAX helper macros

+ +

The following macros are defined. +

+
+
Macro: EAX_CTX (context_type)
+

This defines an all-in-one context struct, including the context of the +underlying cipher and all EAX state. It expands +to +

+
{
+   struct eax_key key;
+   struct eax_ctx eax;
+   context_type cipher;
+}
+
+
+ +

For all these macros, ctx, is a context struct as defined by +EAX_CTX, and encrypt is the encryption function of the +underlying cipher. +

+
+
Macro: EAX_SET_KEY (ctx, set_key, encrypt, key)
+

set_key is the function for setting the encryption key for the +underlying cipher, and key is the key. +

+ +
+
Macro: EAX_SET_NONCE (ctx, encrypt, length, nonce)
+

Sets the nonce to be used for the message. +

+ +
+
Macro: EAX_UPDATE (ctx, encrypt, length, data)
+

Process associated data for authentication. +

+ +
+
Macro: EAX_ENCRYPT (ctx, encrypt, length, dst, src)
+
Macro: EAX_DECRYPT (ctx, encrypt, length, dst, src)
+

Process message data for encryption or decryption. +

+ +
+
Macro: EAX_DIGEST (ctx, encrypt, length, digest)
+

Extract te authentication tag for the message. +

+ + + +

6.4.1.3 EAX-AES128 interface

+ +

The following functions implement EAX using AES-128 +as the underlying cipher. +

+
+
Context struct: struct eax_aes128_ctx
+

The context struct, defined using EAX_CTX. +

+ +
+
Function: void eax_aes128_set_key (struct eax_aes128_ctx *ctx, const uint8_t *key)
+

Initializes ctx using the given key. +

+ +
+
Function: void eax_aes128_set_nonce (struct eax_aes128_ctx *ctx, size_t length, const uint8_t *iv)
+

Initializes the per-message state, using the given nonce. +

+ +
+
Function: void eax_aes128_update (struct eax_aes128_ctx *ctx, size_t length, const uint8_t *data)
+

Process associated data for authentication. All but the last call for +each message must use a length that is a multiple of the block +size. +

+ +
+
Function: void eax_aes128_encrypt (struct eax_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void eax_aes128_decrypt (struct eax_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message. All but the last call for +each message must use a length that is a multiple of the block +size. +

+ +
+
Function: void eax_aes128_digest (struct eax_aes128_ctx *ctx, size_t length, uint8_t *digest);
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. If length is +smaller than EAX_DIGEST_SIZE, only the first length octets +of the digest are written. +

+ +
+ +
+

+Next: , Previous: , Up: Authenticated encryption   [Contents][Index]

+
+ +

6.4.2 Galois counter mode

+ + + + +

Galois counter mode is an AEAD constructions combining counter +mode with message authentication based on universal hashing. The main +objective of the design is to provide high performance for hardware +implementations, where other popular MAC algorithms +(see Keyed hash functions) become a bottleneck for high-speed +hardware implementations. It was proposed by David A. McGrew and John +Viega in 2005, and recommended by NIST in 2007, +NIST Special Publication 800-38D. It is constructed on top of a block +cipher which must have a block size of 128 bits. +

+

The authentication in GCM has some known weaknesses, see +http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/comments/CWC-GCM/Ferguson2.pdf. +In particular, don’t use GCM with short authentication tags. +

+

Nettle’s support for GCM consists of a low-level general +interface, some convenience macros, and specific functions for +GCM using AES or Camellia as the underlying cipher. +These interfaces are defined in <nettle/gcm.h> +

+ +

6.4.2.1 General GCM interface

+ +
+
Context struct: struct gcm_key
+

Message independent hash sub-key, and related tables. +

+ +
+
Context struct: struct gcm_ctx
+

Holds state corresponding to a particular message. +

+ +
+
Constant: GCM_BLOCK_SIZE
+

GCM’s block size, 16. +

+ +
+
Constant: GCM_DIGEST_SIZE
+

Size of the GCM digest, also 16. +

+ +
+
Constant: GCM_IV_SIZE
+

Recommended size of the IV, 12. Arbitrary sizes are allowed. +

+ +
+
Function: void gcm_set_key (struct gcm_key *key, const void *cipher, nettle_cipher_func *f)
+

Initializes key. cipher gives a context struct for the +underlying cipher, which must have been previously initialized for +encryption, and f is the encryption function. +

+ +
+
Function: void gcm_set_iv (struct gcm_ctx *ctx, const struct gcm_key *key, size_t length, const uint8_t *iv)
+

Initializes ctx using the given IV. The key +argument is actually needed only if length differs from +GCM_IV_SIZE. +

+ +
+
Function: void gcm_update (struct gcm_ctx *ctx, const struct gcm_key *key, size_t length, const uint8_t *data)
+

Provides associated data to be authenticated. If used, must be called +before gcm_encrypt or gcm_decrypt. All but the last call +for each message must use a length that is a multiple of the +block size. +

+ +
+
Function: void gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_decrypt (struct gcm_ctx *ctx, const struct gcm_key *key, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message. cipher is the context +struct for the underlying cipher and f is the encryption function. +All but the last call for each message must use a length that is +a multiple of the block size. +

+ +
+
Function: void gcm_digest (struct gcm_ctx *ctx, const struct gcm_key *key, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *digest)
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. It’s strongly recommended +that length is GCM_DIGEST_SIZE, but if you provide a smaller +value, only the first length octets of the digest are written. +

+ +

To encrypt a message using GCM, first initialize a context for +the underlying block cipher with a key to use for encryption. Then call +the above functions in the following order: gcm_set_key, +gcm_set_iv, gcm_update, gcm_encrypt, +gcm_digest. The decryption procedure is analogous, just calling +gcm_decrypt instead of gcm_encrypt (note that +GCM decryption still uses the encryption function of the +underlying block cipher). To process a new message, using the same key, +call gcm_set_iv with a new iv. +

+ +

6.4.2.2 GCM helper macros

+ +

The following macros are defined. +

+
+
Macro: GCM_CTX (context_type)
+

This defines an all-in-one context struct, including the context of the +underlying cipher, the hash sub-key, and the per-message state. It expands +to +

+
{
+   struct gcm_key key; 
+   struct gcm_ctx gcm;
+   context_type cipher;
+}
+
+
+ +

Example use: +

+
struct gcm_aes128_ctx GCM_CTX(struct aes128_ctx);
+
+ +

The following macros operate on context structs of this form. +

+
+
Macro: GCM_SET_KEY (ctx, set_key, encrypt, key)
+

First argument, ctx, is a context struct as defined +by GCM_CTX. set_key and encrypt are functions for +setting the encryption key and for encrypting data using the underlying +cipher. +

+ +
+
Macro: GCM_SET_IV (ctx, length, data)
+

First argument is a context struct as defined by +GCM_CTX. length and data give the initialization +vector (IV). +

+ +
+
Macro: GCM_UPDATE (ctx, length, data)
+

Simpler way to call gcm_update. First argument is a context +struct as defined by GCM_CTX +

+ +
+
Macro: GCM_ENCRYPT (ctx, encrypt, length, dst, src)
+
Macro: GCM_DECRYPT (ctx, encrypt, length, dst, src)
+
Macro: GCM_DIGEST (ctx, encrypt, length, digest)
+

Simpler way to call gcm_encrypt, gcm_decrypt or +gcm_digest. First argument is a context struct as defined by +GCM_CTX. Second argument, encrypt, is the encryption +function of the underlying cipher. +

+ + +

6.4.2.3 GCM-AES interface

+ +

The following functions implement the common case of GCM using +AES as the underlying cipher. The variants with a specific +AES flavor are recommended, while the fucntinos using +struct gcm_aes_ctx are kept for compatibility with older versiosn +of Nettle. +

+
+
Context struct: struct gcm_aes128_ctx
+
Context struct: struct gcm_aes192_ctx
+
Context struct: struct gcm_aes256_ctx
+

Context structs, defined using GCM_CTX. +

+ +
+
Context struct: struct gcm_aes_ctx
+

Alternative context struct, usign the old AES interface. +

+ +
+
Function: void gcm_aes128_set_key (struct gcm_aes128_ctx *ctx, const uint8_t *key)
+
Function: void gcm_aes192_set_key (struct gcm_aes192_ctx *ctx, const uint8_t *key)
+
Function: void gcm_aes256_set_key (struct gcm_aes256_ctx *ctx, const uint8_t *key)
+

Initializes ctx using the given key. +

+ +
+
Function: void gcm_aes_set_key (struct gcm_aes_ctx *ctx, size_t length, const uint8_t *key)
+

Corresponding function, using the old AES interface. All valid +AES key sizes can be used. +

+ +
+
Function: void gcm_aes128_set_iv (struct gcm_aes128_ctx *ctx, size_t length, const uint8_t *iv)
+
Function: void gcm_aes192_set_iv (struct gcm_aes192_ctx *ctx, size_t length, const uint8_t *iv)
+
Function: void gcm_aes256_set_iv (struct gcm_aes256_ctx *ctx, size_t length, const uint8_t *iv)
+
Function: void gcm_aes_set_iv (struct gcm_aes_ctx *ctx, size_t length, const uint8_t *iv)
+

Initializes the per-message state, using the given IV. +

+ +
+
Function: void gcm_aes128_update (struct gcm_aes128_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void gcm_aes192_update (struct gcm_aes192_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void gcm_aes256_update (struct gcm_aes256_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void gcm_aes_update (struct gcm_aes_ctx *ctx, size_t length, const uint8_t *data)
+

Provides associated data to be authenticated. If used, must be called +before gcm_aes_encrypt or gcm_aes_decrypt. All but the +last call for each message must use a length that is a multiple +of the block size. +

+ +
+
Function: void gcm_aes128_encrypt (struct gcm_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes192_encrypt (struct gcm_aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes256_encrypt (struct gcm_aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes_encrypt (struct gcm_aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes128_decrypt (struct gcm_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes192_decrypt (struct gcm_aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes256_decrypt (struct gcm_aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_aes_decrypt (struct gcm_aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message. All but the last call for +each message must use a length that is a multiple of the block +size. +

+ +
+
Function: void gcm_aes128_digest (struct gcm_aes128_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void gcm_aes192_digest (struct gcm_aes192_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void gcm_aes256_digest (struct gcm_aes256_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void gcm_aes_digest (struct gcm_aes_ctx *ctx, size_t length, uint8_t *digest)
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. It’s strongly recommended +that length is GCM_DIGEST_SIZE, but if you provide a smaller +value, only the first length octets of the digest are written. +

+ + +

6.4.2.4 GCM-Camellia interface

+ +

The following functions implement the case of GCM using +Camellia as the underlying cipher. +

+
+
Context struct: struct gcm_camellia128_ctx
+
Context struct: struct gcm_camellia256_ctx
+

Context structs, defined using GCM_CTX. +

+ +
+
Function: void gcm_camellia128_set_key (struct gcm_camellia128_ctx *ctx, const uint8_t *key)
+
Function: void gcm_camellia256_set_key (struct gcm_camellia256_ctx *ctx, const uint8_t *key)
+

Initializes ctx using the given key. +

+ +
+
Function: void gcm_camellia128_set_iv (struct gcm_camellia128_ctx *ctx, size_t length, const uint8_t *iv)
+
Function: void gcm_camellia256_set_iv (struct gcm_camellia256_ctx *ctx, size_t length, const uint8_t *iv)
+

Initializes the per-message state, using the given IV. +

+ +
+
Function: void gcm_camellia128_update (struct gcm_camellia128_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void gcm_camellia256_update (struct gcm_camellia256_ctx *ctx, size_t length, const uint8_t *data)
+

Provides associated data to be authenticated. If used, must be called +before gcm_camellia_encrypt or gcm_camellia_decrypt. All but the +last call for each message must use a length that is a multiple +of the block size. +

+ +
+
Function: void gcm_camellia128_encrypt (struct gcm_camellia128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_camellia256_encrypt (struct gcm_camellia256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_camellia128_decrypt (struct gcm_camellia128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void gcm_camellia256_decrypt (struct gcm_camellia256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message. All but the last call for +each message must use a length that is a multiple of the block +size. +

+ +
+
Function: void gcm_camellia128_digest (struct gcm_camellia128_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void gcm_camellia192_digest (struct gcm_camellia192_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void gcm_camellia256_digest (struct gcm_camellia256_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void gcm_camellia_digest (struct gcm_camellia_ctx *ctx, size_t length, uint8_t *digest)
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. It’s strongly recommended +that length is GCM_DIGEST_SIZE, but if you provide a smaller +value, only the first length octets of the digest are written. +

+ +
+ +
+

+Next: , Previous: , Up: Authenticated encryption   [Contents][Index]

+
+ +

6.4.3 Counter with CBC-MAC mode

+ + + + +

CCM mode is a combination of counter mode with message +authentication based on cipher block chaining, the same building blocks +as EAX, see EAX. It is constructed on top of a block cipher +which must have a block size of 128 bits. CCM mode is +recommended by NIST in +NIST Special Publication 800-38C. Nettle’s support for CCM consists of +a low-level general interface, a message encryption and authentication +interface, and specific functions for CCM using AES as the underlying +block cipher. These interfaces are defined in <nettle/ccm.h>. +

+

In CCM, the length of the message must be known before +processing. The maximum message size depends on the size of the nonce, +since the message size is encoded in a field which must fit in a single +block, together with the nonce and a flag byte. E.g., with a nonce size +of 12 octets, there are three octets left for encoding the message +length, the maximum message length is 2^24 - 1 octets. +

+

CCM mode encryption operates as follows: +

    +
  • The nonce and message length are concatenated to create +B_0 = flags | nonce | mlength + +
  • The authenticated data and plaintext is formatted into the string +B = L(adata) | adata | padding | plaintext | padding with +padding being the shortest string of zero bytes such that the +length of the string is a multiple of the block size, and +L(adata) is an encoding of the length of adata. + +
  • The string B is separated into blocks B_1 ... +B_n +
  • The authentication tag T is calculated as +T=0, for i=0 to n, do T = E_k(B_i XOR T) + +
  • An initial counter is then initialized from the nonce to create +IC = flags | nonce | padding, where padding is the +shortest string of zero bytes such that IC is exactly one block +in length. + +
  • The authentication tag is encrypted using using CTR mode: +MAC = E_k(IC) XOR T + +
  • The plaintext is then encrypted using CTR mode with an +initial counter of IC+1. +
+ +

CCM mode decryption operates similarly, except that the +ciphertext and MAC are first decrypted using CTR mode to +retreive the plaintext and authentication tag. The authentication tag +can then be recalucated from the authenticated data and plantext, and +compared to the value in the message to check for authenticity. +

+ +

6.4.3.1 General CCM interface

+ +

For all of the functions in the CCM interface, cipher is +the context struct for the underlying cipher and f is the +encryption function. The cipher’s encryption key must be set before +calling any of the CCM functions. The cipher’s decryption +function and key are never used. +

+
+
Context struct: struct ccm_ctx
+

Holds state corresponding to a particular message. +

+ +
+
Constant: CCM_BLOCK_SIZE
+

CCM’s block size, 16. +

+ +
+
Constant: CCM_DIGEST_SIZE
+

Size of the CCM digest, 16. +

+ +
+
Constant: CCM_MIN_NONCE_SIZE
+
Constant: CCM_MAX_NONCE_SIZE
+

The the minimum and maximum sizes for an CCM nonce, 7 and 14, +respectively. +

+ +
+
Macro: CCM_MAX_MSG_SIZE (nonce_size)
+

The largest allowed plaintext length, when using CCM with a +nonce of the given size. +

+ +
+
Function: void ccm_set_nonce (struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, size_t noncelen, const uint8_t *nonce, size_t authlen, size_t msglen, size_t taglen)
+

Initializes ctx using the given nonce and the sizes of the +authenticated data, message, and MAC to be processed. +

+ +
+
Function: void ccm_update (struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, size_t length, const uint8_t *data)
+

Provides associated data to be authenticated. Must be called after +ccm_set_nonce, and before ccm_encrypt, ccm_decrypt, or +ccm_digest. +

+ +
+
Function: void ccm_encrypt (struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_decrypt (struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the message data. Must be called after +ccm_set_nonce and before ccm_digest. All but the last call +for each message must use a length that is a multiple of the +block size. +

+ +
+
Function: void ccm_digest (struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, size_t length, uint8_t *digest)
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. length is usually +equal to the taglen parameter supplied to ccm_set_nonce, +but if you provide a smaller value, only the first length octets +of the digest are written. +

+ +

To encrypt a message using the general CCM interface, set the +message nonce and length using ccm_set_nonce and then call +ccm_update to generate the digest of any authenticated data. +After all of the authenticated data has been digested use +ccm_encrypt to encrypt the plaintext. Finally, use +ccm_digest to return the encrypted MAC. +

+

To decrypt a message, use ccm_set_nonce and ccm_update the +same as you would for encryption, and then call ccm_decrypt to +decrypt the ciphertext. After decrypting the ciphertext +ccm_digest will return the encrypted MAC which should +be identical to the MAC in the received message. +

+ +

6.4.3.2 CCM message interface

+ +

The CCM message fuctions provides a simple interface that will +perform authentication and message encryption in a single function call. +The length of the cleartext is given by mlength and the length of +the ciphertext is given by clength, always exactly tlength +bytes longer than the corresponding plaintext. The length argument +passed to a function is always the size for the result, clength +for the encryption functions, and mlength for the decryption +functions. +

+
+
Function: void ccm_encrypt_message (void *cipher, nettle_cipher_func *f, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src)
+

Computes the message digest from the adata and src +parameters, encrypts the plaintext from src, appends the encrypted +MAC to ciphertext and outputs it to dst. +

+ +
+
Function: int ccm_decrypt_message (void *cipher, nettle_cipher_func *f, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src)
+

Decrypts the ciphertext from src, outputs the plaintext to +dst, recalculates the MAC from adata and the +plaintext, and compares it to the final tlength bytes of +src. If the values of the received and calculated MACs +are equal, this will return 1 indicating a valid and authenticated +message. Otherwise, this function will return zero. +

+ + +

6.4.3.3 CCM-AES interface

+ +

The AES CCM functions provide an API for using +CCM mode with the AES block ciphers. The parameters +all have the same meaning as the general and message interfaces, except +that the cipher, f, and ctx parameters are replaced +with an AES context structure, and a set-key function must be +called before using any of the other functions in this interface. +

+
+
Context struct: struct ccm_aes128_ctx
+

Holds state corresponding to a particular message encrypted using the +AES-128 block cipher. +

+ +
+
Context struct: struct ccm_aes192_ctx
+

Holds state corresponding to a particular message encrypted using the +AES-192 block cipher. +

+ +
+
Context struct: struct ccm_aes256_ctx
+

Holds state corresponding to a particular message encrypted using the +AES-256 block cipher. +

+ +
+
Function: void ccm_aes128_set_key (struct ccm_aes128_ctx *ctx, const uint8_t *key)
+
Function: void ccm_aes192_set_key (struct ccm_aes192_ctx *ctx, const uint8_t *key)
+
Function: void ccm_aes256_set_key (struct ccm_aes256_ctx *ctx, const uint8_t *key)
+

Initializes the encryption key for the AES block cipher. One of these +functions must be called before any of the other functions in the +AES CCM interface. +

+ +
+
Function: void ccm_aes128_set_nonce (struct ccm_aes128_ctx *ctx, size_t noncelen, const uint8_t *nonce, size_t authlen, size_t msglen, size_t taglen)
+
Function: void ccm_aes192_set_nonce (struct ccm_aes192_ctx *ctx, size_t noncelen, const uint8_t *nonce, size_t authlen, size_t msglen, size_t taglen)
+
Function: void ccm_aes256_set_nonce (struct ccm_aes256_ctx *ctx, size_t noncelen, const uint8_t *nonce, size_t authlen, size_t msglen, size_t taglen)
+

These are identical to ccm_set_nonce, except that cipher, +f, and ctx are replaced with a context structure. +

+ +
+
Function: void ccm_aes128_update (struct ccm_aes128_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void ccm_aes192_update (struct ccm_aes192_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void ccm_aes256_update (struct ccm_aes256_ctx *ctx, size_t length, const uint8_t *data)
+

These are identical to ccm_set_update, except that cipher, +f, and ctx are replaced with a context structure. +

+ +
+
Function: void ccm_aes128_encrypt (struct ccm_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes192_encrypt (struct ccm_aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes256_encrypt (struct ccm_aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes128_decrypt (struct ccm_aes128_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes192_decrypt (struct ccm_aes192_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes256_decrypt (struct ccm_aes256_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

These are identical to ccm_set_encrypt and ccm_set_decrypt, except +that cipher, f, and ctx are replaced with a context structure. +

+ +
+
Function: void ccm_aes128_digest (struct ccm_aes128_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void ccm_aes192_digest (struct ccm_aes192_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void ccm_aes256_digest (struct ccm_aes256_ctx *ctx, size_t length, uint8_t *digest)
+

These are identical to ccm_set_digest, except that cipher, +f, and ctx are replaced with a context structure. +

+ +
+
Function: void ccm_aes128_encrypt_message (struct ccm_aes128_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes192_encrypt_message (struct ccm_aes192_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src)
+
Function: void ccm_aes256_encrypt_message (struct ccm_aes256_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src)
+
Function: int ccm_aes128_decrypt_message (struct ccm_aes128_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src)
+
Function: int ccm_aes192_decrypt_message (struct ccm_aes192_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src)
+
Function: int ccm_aes192_decrypt_message (struct ccm_aes256_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src)
+

These are identical to ccm_encrypt_message and ccm_decrypt_message +except that cipher and f are replaced with a context structure. +

+ +
+ + + +

6.4.4 ChaCha-Poly1305

+ +

ChaCha-Poly1305 is a combination of the ChaCha stream cipher and the +poly1305 message authentication code (see Poly1305). It originates +from the NaCl cryptographic library by D. J. Bernstein et al, which +defines a similar construction but with Salsa20 instead of ChaCha. +

+

Nettle’s implementation ChaCha-Poly1305 should be considered +experimental. At the time of this writing, there is no +authoritative specification for ChaCha-Poly1305, and a couple of +different incompatible variants. Nettle implements it using the original +definition of ChaCha, with 64 bits (8 octets) each for the nonce and the +block counter. Some protocols prefer to use nonces of 12 bytes, and it’s +a small change to ChaCha to use the upper 32 bits of the block counter +as a nonce, instead limiting message size to 2^32 blocks or 256 +GBytes, but that variant is currently not supported. +

+

For ChaCha-Poly1305, the ChaCha cipher is initialized with a key, of 256 +bits, and a per-message nonce. The first block of the key stream +(counter all zero) is set aside for the authentication subkeys. Of this +64-octet block, the first 16 octets specify the poly1305 evaluation +point, and the next 16 bytes specify the value to add in for the final +digest. The final 32 bytes of this block are unused. Note that unlike +poly1305-aes, the evaluation point depends on the nonce. This is +preferable, because it leaks less information in case the attacker for +some reason is lucky enough to forge a valid authentication tag, and +observe (from the receiver’s behaviour) that the forgery succeeded. +

+

The ChaCha key stream, starting with counter value 1, is then used to +encrypt the message. For authentication, poly1305 is applied to the +concatenation of the associated data, the cryptotext, and the lengths of +the associated data and the message, each a 64-bit number (eight octets, +little-endian). Nettle defines ChaCha-Poly1305 in +<nettle/chacha-poly1305.h>. +

+
+
Constant: CHACHA_POLY1305_BLOCK_SIZE
+

Same as the ChaCha block size, 64. +

+ +
+
Constant: CHACHA_POLY1305_KEY_SIZE
+

ChaCha-Poly1305 key size, 32. +

+ +
+
Constant: CHACHA_POLY1305_NONCE_SIZE
+

Same as the ChaCha nonce size, 16. +

+ +
+
Constant: CHACHA_POLY1305_DIGEST_SIZE
+

Digest size, 16. +

+ +
+
Context struct: struct chacha_poly1305_ctx
+
+ +
+
Function: void chacha_poly1305_set_key (struct chacha_poly1305_ctx *ctx, const uint8_t *key)
+

Initializes ctx using the given key. Before using the context, you +must also call chacha_poly1305_set_nonce, see below. +

+ +
+
Function: void chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx, const uint8_t *nonce)
+

Initializes the per-message state, using the given nonce. +

+ +
+
Function: void chacha_poly1305_update (struct chacha_poly1305_ctx *ctx, size_t length, const uint8_t *data)
+

Process associated data for authentication. +

+ +
+
Function: void chacha_poly1305_encrypt (struct chacha_poly1305_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+
Function: void chacha_poly1305_decrypt (struct chacha_poly1305_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src)
+

Encrypts or decrypts the data of a message. All but the last call for +each message must use a length that is a multiple of the block +size. +

+ +
+
Function: void chacha_poly1305_digest (struct chacha_poly1305_ctx *ctx, size_t length, uint8_t *digest)
+

Extracts the message digest (also known “authentication tag”). This is +the final operation when processing a message. If length is +smaller than CHACHA_POLY1305_DIGEST_SIZE, only the first +length octets of the digest are written. +

+ +
+ + + +

6.4.5 The struct nettle_aead abstraction

+ + + + +

Nettle includes a struct including information about the supported hash +functions. It is defined in <nettle/nettle-meta.h>. +

+
+
Meta struct: struct nettle_aead name context_size block_size key_size nonce_size digest_size set_encrypt_key set_decrypt_key set_nonce update encrypt decrypt digest
+

The last seven attributes are function pointers. +

+ +
+
Constant Struct: struct nettle_aead nettle_gcm_aes128
+
Constant Struct: struct nettle_aead nettle_gcm_aes192
+
Constant Struct: struct nettle_aead nettle_gcm_aes256
+
Constant Struct: struct nettle_aead nettle_gcm_camellia128
+
Constant Struct: struct nettle_aead nettle_gcm_camellia256
+
Constant Struct: struct nettle_aead nettle_eax_aes128
+
Constant Struct: struct nettle_aead nettle_chacha_poly1305
+

These are most of the AEAD constructions that Nettle +implements. Note that CCM is missing; it requirement that the +message size is specified in advance makes it incompatible with the +nettle_aead abstraction. +

+ +

Nettle also exports a list of all these constructions. +

+
+
Function: const struct nettle_aead **nettle_get_aeads(void)
+

Returns a NULL-terminated list of pointers to supported algorithms.This +list can be used to dynamically enumerate or search the supported +algorithms. +

+ +
+
Macro: nettle_aeads
+

A macro expanding to a call to nettle_get_aeads. In earlier versions, +this was not a macro but the actual array of pointers. +

+ +
+ + + +

6.5 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. +

+ + + + + + +
+ +
+

+Next: , Previous: , Up: Keyed hash functions   [Contents][Index]

+
+ + +

6.5.1 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-RIPEMD160 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, size_t 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, size_t 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, size_t 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 to +

+
{
+   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. +

+ +

6.5.2 Concrete HMAC functions

+

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

+ +

6.5.2.1 HMAC-MD5

+ +
+
Context struct: struct hmac_md5_ctx
+
+ +
+
Function: void hmac_md5_set_key (struct hmac_md5_ctx *ctx, size_t key_length, const uint8_t *key)
+

Initializes the context with the key. +

+ +
+
Function: void hmac_md5_update (struct hmac_md5_ctx *ctx, size_t length, const uint8_t *data)
+

Process some more data. +

+ +
+
Function: void hmac_md5_digest (struct hmac_md5_ctx *ctx, size_t 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. +

+ + +

6.5.2.2 HMAC-RIPEMD160

+ +
+
Context struct: struct hmac_ripemd160_ctx
+
+ +
+
Function: void hmac_ripemd160_set_key (struct hmac_ripemd160_ctx *ctx, size_t key_length, const uint8_t *key)
+

Initializes the context with the key. +

+ +
+
Function: void hmac_ripemd160_update (struct hmac_ripemd160_ctx *ctx, size_t length, const uint8_t *data)
+

Process some more data. +

+ +
+
Function: void hmac_ripemd160_digest (struct hmac_ripemd160_ctx *ctx, size_t length, uint8_t *digest)
+

Extracts the MAC, writing it to digest. length may be smaller than +RIPEMD160_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. +

+ + +

6.5.2.3 HMAC-SHA1

+ +
+
Context struct: struct hmac_sha1_ctx
+
+ +
+
Function: void hmac_sha1_set_key (struct hmac_sha1_ctx *ctx, size_t key_length, const uint8_t *key)
+

Initializes the context with the key. +

+ +
+
Function: void hmac_sha1_update (struct hmac_sha1_ctx *ctx, size_t length, const uint8_t *data)
+

Process some more data. +

+ +
+
Function: void hmac_sha1_digest (struct hmac_sha1_ctx *ctx, size_t 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. +

+ + + +

6.5.2.4 HMAC-SHA256

+ +
+
Context struct: struct hmac_sha256_ctx
+
+ +
+
Function: void hmac_sha256_set_key (struct hmac_sha256_ctx *ctx, size_t key_length, const uint8_t *key)
+

Initializes the context with the key. +

+ +
+
Function: void hmac_sha256_update (struct hmac_sha256_ctx *ctx, size_t length, const uint8_t *data)
+

Process some more data. +

+ +
+
Function: void hmac_sha256_digest (struct hmac_sha256_ctx *ctx, size_t 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. +

+ + + +

6.5.2.5 HMAC-SHA512

+ +
+
Context struct: struct hmac_sha512_ctx
+
+ +
+
Function: void hmac_sha512_set_key (struct hmac_sha512_ctx *ctx, size_t key_length, const uint8_t *key)
+

Initializes the context with the key. +

+ +
+
Function: void hmac_sha512_update (struct hmac_sha512_ctx *ctx, size_t length, const uint8_t *data)
+

Process some more data. +

+ +
+
Function: void hmac_sha512_digest (struct hmac_sha512_ctx *ctx, size_t 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. +

+ +
+ +
+

+Next: , Previous: , Up: Keyed hash functions   [Contents][Index]

+
+ + +

6.5.3 UMAC

+ + +

UMAC is a message authentication code based on universal +hashing, and designed for high performance on modern processors (in +contrast to GCM, See GCM, which is designed primarily for hardware +performance). On processors with good integer multiplication +performance, it can be 10 times faster than SHA256 and SHA512. +UMAC is specified in RFC 4418. +

+

The secret key is always 128 bits (16 octets). The key is used as an +encryption key for the AES block cipher. This cipher is used +in counter mode to generate various internal subkeys needed in +UMAC. Messages are of arbitrary size, and for each message, +UMAC also needs a unique nonce. Nonce values must not be +reused for two messages with the same key, but they need not be kept +secret. +

+

The nonce must be at least one octet, and at most 16; nonces shorter +than 16 octets are zero-padded. Nettle’s implementation of +UMAC increments the nonce automatically for each message, so +explicitly setting the nonce for each message is optional. This +auto-increment uses network byte order and it takes the length of the +nonce into account. E.g., if the initial nonce is “abc” (3 octets), +this value is zero-padded to 16 octets for the first message. For the +next message, the nonce is incremented to “abd”, and this incremented +value is zero-padded to 16 octets. +

+

UMAC is defined in four variants, for different output sizes: +32 bits (4 octets), 64 bits (8 octets), 96 bits (12 octets) and 128 bits +(16 octets), corresponding to different trade-offs between speed and +security. Using a shorter output size sometimes (but not always!) gives +the same result as using a longer output size and truncating the result. +So it is important to use the right variant. For consistency with other +hash and MAC functions, Nettle’s _digest functions for +UMAC accept a length parameter so that the output can be +truncated to any desired size, but it is recommended to stick to the +specified output size and select the umac variant +corresponding to the desired size. +

+

The internal block size of UMAC is 1024 octets, and it also +generates more than 1024 bytes of subkeys. This makes the size of the +context struct quite a bit larger than other hash functions and +MAC algorithms in Nettle. +

+

Nettle defines UMAC in <nettle/umac.h>. +

+
+
Context struct: struct umac32_ctx
+
Context struct: struct umac64_ctx
+
Context struct: struct umac96_ctx
+
Context struct: struct umac128_ctx
+

Each UMAC variant uses its own context struct. +

+ +
+
Constant: UMAC_KEY_SIZE
+

The UMAC key size, 16. +

+
+
Constant: UMAC_MIN_NONCE_SIZE
+
Constant: UMAC_MAX_NONCE_SIZE
+

The the minimum and maximum sizes for an UMAC nonce, 1 and 16, +respectively. +

+
+
Constant: UMAC32_DIGEST_SIZE
+

The size of an UMAC32 digest, 4. +

+
+
Constant: UMAC64_DIGEST_SIZE
+

The size of an UMAC64 digest, 8. +

+
+
Constant: UMAC96_DIGEST_SIZE
+

The size of an UMAC96 digest, 12. +

+
+
Constant: UMAC128_DIGEST_SIZE
+

The size of an UMAC128 digest, 16. +

+
+
Constant: UMAC_BLOCK_SIZE
+

The internal block size of UMAC. +

+ +
+
Function: void umac32_set_key (struct umac32_ctx *ctx, const uint8_t *key)
+
Function: void umac64_set_key (struct umac64_ctx *ctx, const uint8_t *key)
+
Function: void umac96_set_key (struct umac96_ctx *ctx, const uint8_t *key)
+
Function: void umac128_set_key (struct umac128_ctx *ctx, const uint8_t *key)
+

These functions initialize the UMAC context struct. They also +initialize the nonce to zero (with length 16, for auto-increment). +

+ +
+
Function: void umac32_set_nonce (struct umac32_ctx *ctx, size_t length, const uint8_t *nonce)
+
Function: void umac64_set_nonce (struct umac64_ctx *ctx, size_t length, const uint8_t *nonce)
+
Function: void umac96_set_nonce (struct umac96_ctx *ctx, size_t length, const uint8_t *nonce)
+
Function: void umac128_set_nonce (struct umac128_ctx *ctx, size_t length, const uint8_t *nonce)
+

Sets the nonce to be used for the next message. In general, nonces +should be set before processing of the message. This is not strictly +required for UMAC (the nonce only affects the final processing +generating the digest), but it is nevertheless recommended that this +function is called before the first _update call for the +message. +

+ +
+
Function: void umac32_update (struct umac32_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void umac64_update (struct umac64_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void umac96_update (struct umac96_ctx *ctx, size_t length, const uint8_t *data)
+
Function: void umac128_update (struct umac128_ctx *ctx, size_t length, const uint8_t *data)
+

These functions are called zero or more times to process the message. +

+ +
+
Function: void umac32_digest (struct umac32_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void umac64_digest (struct umac64_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void umac96_digest (struct umac96_ctx *ctx, size_t length, uint8_t *digest)
+
Function: void umac128_digest (struct umac128_ctx *ctx, size_t length, uint8_t *digest)
+

Extracts the MAC of the message, writing it to digest. +length is usually equal to the specified output size, but if you +provide a smaller value, only the first length octets of the +MAC are written. These functions reset the context for +processing of a new message with the same key. The nonce is incremented +as described above, the new value is used unless you call the +_set_nonce function explicitly for each message. +

+ +
+ +
+

+Previous: , Up: Keyed hash functions   [Contents][Index]

+
+ +

6.5.4 Poly1305

+ +

Poly1305-AES is a message authentication code designed by D. J. +Bernstein. It treats the message as a polynomial modulo the prime number +2^130 - 5. +

+

The key, 256 bits, consists of two parts, where the first half is an +AES-128 key, and the second half specifies the point where the +polynomial is evaluated. Of the latter half, 22 bits are set to zero, to +enable high-performance implementation, leaving 106 bits for specifying +an evaluation point r. For each message, one must also provide a +128-bit nonce. The nonce is encrypted using the AES key, and +that’s the only thing AES is used for. +

+

The message is split into 128-bit chunks (with final chunk possibly +being shorter), each read as a little-endian integer. Each chunk has a +one-bit appended at the high end. The resulting integers are treated as +polynomial coefficients modulo 2^130 - 5, and the polynomial is +evaluated at the point r. Finally, this value is reduced modulo +2^128, and added (also modulo 2^128) to the encrypted +nonce, to produce an 128-bit authenticator for the message. See +http://cr.yp.to/mac/poly1305-20050329.pdf for further details. +

+

Clearly, variants using a different cipher than AES could be +defined. Another variant is the ChaCha-Poly1305 AEAD +construction (see ChaCha-Poly1305). Nettle defines +Poly1305-AES in nettle/poly1305.h. +

+
+
Constant: POLY1305_AES_KEY_SIZE
+

Key size, 32 octets. +

+ +
+
Constant: POLY1305_AES_DIGEST_SIZE
+

Size of the digest or “authenticator”, 16 octets. +

+ +
+
Constant: POLY1305_AES_NONCE_SIZE
+

Nonce size, 16 octets. +

+ +
+
Context struct: struct poly1305_aes_ctx
+

The poly1305-aes context struct. +

+ +
+
Function: void poly1305_aes_set_key (struct poly1305_aes_ctx *ctx, const uint8_t *key)
+

Initialize the context struct. Also sets the nonce to zero. +

+ +
+
Function: void poly1305_aes_set_nonce (struct poly1305_aes_ctx *ctx, const uint8_t *nonce)
+

Sets the nonce. Calling this function is optional, since the nonce is +incremented automatically for each message. +

+ +
+
Function: void poly1305_aes_update (struct poly1305_aes_ctx *ctx, size_t length, const uint8_t *data)
+

Process more data. +

+ +
+
Function: void poly1305_aes_digest (struct poly1305_aes_ctx *ctx, size_t length, uint8_t *digest)
+

Extracts the digest. If length is smaller than +POLY1305_AES_DIGEST_SIZE, only the first length octets are +written. Also increments the nonce, and prepares the context for +processing a new message. +

+ + +
+ + + +

6.6 Key derivation Functions

+ + +

A key derivation function (KDF) is a function that from +a given symmetric key derives other symmetric keys. A sub-class of KDFs +is the password-based key derivation functions (PBKDFs), +which take as input a password or passphrase, and its purpose is +typically to strengthen it and protect against certain pre-computation +attacks by using salting and expensive computation. +

+ +

6.6.1 HKDF: HMAC-based Extract-and-Expand

+ + +

HKDF is a key derivation function used as a building block of +higher-level protocols like TLS 1.3. It is a derivation function +based on HMAC described in RFC 5869, +and is split into two logical modules, called ’extract’ and ’expand’. +The extract module takes an initial secret and a random +salt to "extract" a fixed-length pseudorandom key (PRK). The second stage +takes as input the previous PRK and some informational data (e.g., +text) and expands them into multiple keys. +

+

Nettle’s HKDF functions are defined in +<nettle/hkdf.h>. There are two abstract functions for the extract +and expand operations that operate on any HMAC implemented via the nettle_hash_update_func, +and nettle_hash_digest_func interfaces. +

+
+
Function: void hkdf_extract (void *mac_ctx, nettle_hash_update_func *update, nettle_hash_digest_func *digest, size_t digest_size,size_t secret_size, const uint8_t *secret, uint8_t *dst)
+

Extract a Pseudorandom Key (PRK) from a secret and a salt according +to HKDF. The HMAC must have been initialized, with its key being the +salt for the Extract operation. This function will call the +update and digest functions passing the mac_ctx +context parameter as an argument in order to compute digest of size +digest_size. Inputs are the secret secret of length +secret_length. The output length is fixed to digest_size octets, +thus the output buffer dst must have room for at least digest_size octets. +

+ +
+
Function: void hkdf_expand (void *mac_ctx, nettle_hash_update_func *update, nettle_hash_digest_func *digest, size_t digest_size, size_t info_size, const uint8_t *info, size_t length, uint8_t *dst)
+

Expand a Pseudorandom Key (PRK) to an arbitrary size according to HKDF. +The HMAC must have been initialized, with its key being the +PRK from the Extract operation. This function will call the +update and digest functions passing the mac_ctx +context parameter as an argument in order to compute digest of size +digest_size. Inputs are the info info of length +info_length, and the desired derived output length length. +The output buffer is dst which must have room for at least length octets. +

+ + + +

6.6.2 PBKDF2

+ + + + +

The most well known PBKDF is the PKCS #5 PBKDF2 described in +RFC 2898 which uses a pseudo-random function such as +HMAC-SHA1. +

+

Nettle’s PBKDF2 functions are defined in +<nettle/pbkdf2.h>. There is an abstract function that operate on +any PRF implemented via the nettle_hash_update_func, +nettle_hash_digest_func interfaces. There is also helper macros +and concrete functions PBKDF2-HMAC-SHA1 and PBKDF2-HMAC-SHA256. First, +the abstract function: +

+
+
Function: void pbkdf2 (void *mac_ctx, nettle_hash_update_func *update, nettle_hash_digest_func *digest, size_t digest_size, unsigned iterations, size_t salt_length, const uint8_t *salt, size_t length, uint8_t *dst)
+

Derive symmetric key from a password according to PKCS #5 PBKDF2. The +PRF is assumed to have been initialized and this function will call the +update and digest functions passing the mac_ctx +context parameter as an argument in order to compute digest of size +digest_size. Inputs are the salt salt of length +salt_length, the iteration counter iterations (> 0), and the +desired derived output length length. The output buffer is +dst which must have room for at least length octets. +

+ +

Like for CBC and HMAC, there is a macro to help use the function +correctly. +

+
+
Macro: PBKDF2 (ctx, update, digest, digest_size, iterations, salt_length, salt, length, dst)
+

ctx is a pointer to a context struct passed to the update +and digest functions (of the types nettle_hash_update_func +and nettle_hash_digest_func respectively) to implement the +underlying PRF with digest size of digest_size. Inputs are the +salt salt of length salt_length, the iteration counter +iterations (> 0), and the desired derived output length +length. The output buffer is dst which must have room for +at least length octets. +

+ + +

6.6.3 Concrete PBKDF2 functions

+

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

+ +

6.6.3.1 PBKDF2-HMAC-SHA1

+ +
+
Function: void pbkdf2_hmac_sha1 (size_t key_length, const uint8_t *key, unsigned iterations, size_t salt_length, const uint8_t *salt, size_t length, uint8_t *dst)
+

PBKDF2 with HMAC-SHA1. Derive length bytes of key into buffer +dst using the password key of length key_length and +salt salt of length salt_length, with iteration counter +iterations (> 0). The output buffer is dst which must have +room for at least length octets. +

+ + +

6.6.3.2 PBKDF2-HMAC-SHA256

+ +
+
Function: void pbkdf2_hmac_sha256 (size_t key_length, const uint8_t *key, unsigned iterations, size_t salt_length, const uint8_t *salt, size_t length, uint8_t *dst)
+

PBKDF2 with HMAC-SHA256. Derive length bytes of key into buffer +dst using the password key of length key_length and +salt salt of length salt_length, with iteration counter +iterations (> 0). The output buffer is dst which must have +room for at least length octets. +

+ +
+ +
+

+Next: , Previous: , Up: Reference   [Contents][Index]

+
+ +

6.7 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”. +

+ + + + + + + +
+ + + +

6.7.1 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 2000 +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 2000 bits, +p and q are about 1000 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. +

+

The RSA algorithm can also be used for encryption. RSA encryption uses +the public key (n,e) to compute the ciphertext m^e mod n. +The PKCS#1 padding scheme will use at least 8 random and non-zero +octets, using m of the form [00 02 padding 00 plaintext]. +It is required that m < n, and therefor the plaintext must be +smaller than the octet size of the modulo n, with some margin. +

+

To decrypt the message, one needs the private key to compute m = +c^e mod n followed by checking and removing the padding. +

+ +

6.7.1.1 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 +See GMP Allocation in GMP Manual. +

+

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. +

+ +

For each operation using the private key, there are two variants, e.g., +rsa_sha256_sign and rsa_sha256_sign_tr. The former +function is older, and it should be avoided, because it provides no +defenses against side-channel attacks. The latter function use +randomized RSA blinding, which defends against timing attacks +using chosen-ciphertext, and it also checks the correctness of the +private key computation using the public key, which defends against +software or hardware errors which could leak the private key. +

+

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. +

+

Creating an RSA signature is done with one of the following +functions: +

+
+
Function: int rsa_md5_sign_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, struct md5_ctx *hash, mpz_t signature)
+
Function: int rsa_sha1_sign_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, struct sha1_ctx *hash, mpz_t signature)
+
Function: int rsa_sha256_sign_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, struct sha256_ctx *hash, mpz_t signature)
+
Function: int rsa_sha512_sign_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, 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. The random_ctx and random pointers +are used to generate the RSA blinding. Returns one on success, +or zero on failure. Signing fails if an error in the computation was +detected, or 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_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, const uint8_t *digest, mpz_t signature)
+
Function: int rsa_sha1_sign_digest_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, const uint8_t *digest, mpz_t signature)
+
Function: int rsa_sha256_sign_digest_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, const uint8_t *digest, mpz_t signature)
+
Function: int rsa_sha512_sign_digest_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, 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, SHA256_DIGEST_SIZE, or +SHA512_DIGEST_SIZErespectively. 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_pkcs1_sign_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, size_t length, const uint8_t *digest_info, mpz_t signature)
+

Similar to the above _sign_digest_tr functions, but the input is not the +plain hash digest, but a PKCS#1 “DigestInfo”, an ASN.1 DER-encoding +of the digest together with an object identifier for the used hash +algorithm. +

+ +
+
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; otherwise analoguous to +the above signing functions. digest should point to a digest of +size MD5_DIGEST_SIZE, SHA1_DIGEST_SIZE, +SHA256_DIGEST_SIZE, or SHA512_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_pkcs1_sign(const struct rsa_private_key *key, size_t length, const uint8_t *digest_info, mpz_t s)
+

Similar to the above _sign_digest functions, but the input is not the +plain hash digest, but a PKCS#1 “DigestInfo”, an ASN.1 DER-encoding +of the digest together with an object identifier for the used hash +algorithm. +

+ +

Verifying an RSA signature is done with one of the following functions: +

+
+
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, SHA256_DIGEST_SIZE, or +SHA512_DIGEST_SIZE respectively. +

+ +
+
Function: int rsa_pkcs1_verify(const struct rsa_public_key *key, size_t length, const uint8_t *digest_info, const mpz_t signature)
+

Similar to the above _verify_digest functions, but the input is not the +plain hash digest, but a PKCS#1 “DigestInfo”, and ASN.1 DER-encoding +of the digest together with an object identifier for the used hash +algorithm. +

+ +

While the above functions for the RSA signature operations use the +PKCS#1 padding scheme, Nettle also provides the variants based on +the PSS padding scheme, specified in RFC 3447. These variants +take advantage of a randomly choosen salt value, which could enhance the +security by causing output to be different for equivalent inputs. +However, assuming the same security level as inverting the RSA +algorithm, a longer salt value does not always mean a better security +http://www.iacr.org/archive/eurocrypt2002/23320268/coron.pdf. +The typical choices of the length are between 0 and the digest size of +the underlying hash function. +

+

Creating an RSA signature with the PSS padding scheme is done with one +of the following functions: +

+
+
Function: int rsa_pss_sha256_sign_digest_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, size_t salt_length, const uint8_t *salt, const uint8_t *digest, mpz_t signature)
+
Function: int rsa_pss_sha384_sign_digest_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, size_t salt_length, const uint8_t *salt, const uint8_t *digest, mpz_t signature)
+
Function: int rsa_pss_sha512_sign_digest_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, size_t salt_length, const uint8_t *salt, const uint8_t *digest, mpz_t signature)
+

Creates a signature using the PSS padding scheme. salt should +point to a salt string of size salt_length. digest should +point to a digest of size SHA256_DIGEST_SIZE, +SHA384_DIGEST_SIZE, or SHA512_DIGEST_SIZErespectively. The +signature is stored in signature (which must have been +mpz_init:ed earlier). +Returns one on success, or zero on failure. +

+ +

Verifying an RSA signature with the PSS padding scheme is done with one +of the following functions: +

+
+
Function: int rsa_pss_sha256_verify_digest (const struct rsa_public_key *key, size_t salt_length, const uint8_t *digest, const mpz_t signature)
+
Function: int rsa_pss_sha384_verify_digest (const struct rsa_public_key *key, size_t salt_length, const uint8_t *digest, const mpz_t signature)
+
Function: int rsa_pss_sha512_verify_digest (const struct rsa_public_key *key, size_t salt_length, 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 SHA256_DIGEST_SIZE, +SHA384_DIGEST_SIZE, or SHA512_DIGEST_SIZE respectively. +

+ +

The following function is used to encrypt a clear text message using RSA. +

+
Function: int rsa_encrypt (const struct rsa_public_key *key, void *random_ctx, nettle_random_func *random, size_t length, const uint8_t *cleartext, mpz_t ciphertext)
+

Returns 1 on success, 0 on failure. If the message is too long then this +will lead to a failure. +

+

The following function is used to decrypt a cipher text message using RSA. +

+
Function: int rsa_decrypt (const struct rsa_private_key *key, size_t *length, uint8_t *cleartext, const mpz_t ciphertext)
+

Returns 1 on success, 0 on failure. Causes of failure include decryption +failing or the resulting message being to large. The message buffer +pointed to by cleartext must be of size *length. After +decryption, *length will be updated with the size of the +message. +

+

There is also a timing resistant version of decryption that utilizes +randomized RSA blinding. +

+
Function: int rsa_decrypt_tr (const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, size_t *length, uint8_t *message, const mpz_t ciphertext)
+

Returns 1 on success, 0 on failure. +

+ +

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: int rsa_compute_root_tr(const struct rsa_public_key *pub, const struct rsa_private_key *key, void *random_ctx, nettle_random_func *random, mpz_t x, const mpz_t m)
+

Computes x = m^d. Returns one on success, or zero if a failure in +the computation was detected. +

+ +
+
Function: void rsa_compute_root (struct rsa_private_key *key, mpz_t x, const mpz_t m)
+

Computes x = m^d. +

+ +

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 +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. +

+ +
+ +
+

+Next: , Previous: , Up: Public-key algorithms   [Contents][Index]

+
+ +

6.7.2 DSA

+ +

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 issued in 2009, and it adds support for +larger hash functions than sha1. +

+

For DSA, the underlying mathematical problem is the +computation of discrete 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 chosen 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. +

+ +

6.7.2.1 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 in GMP Manual. Nettle’s DSA interface is defined +in <nettle/dsa.h>. +

+

A DSA group is represented using the following struct. +

+
+
Context struct: dsa_params p q g
+

Parameters of the DSA group. +

+ +
+
Function: void dsa_params_init (struct dsa_params *params)
+

Calls mpz_init on all numbers in the struct. +

+ +
+
Function: void dsa_params_clear (struct dsa_params *paramsparams)
+

Calls mpz_clear on all numbers in the struct. +

+ +
+
Function: int dsa_generate_params (struct dsa_params *params, void *random_ctx, nettle_random_func *random, void *progress_ctx, nettle_progress_func *progress, unsigned p_bits, unsigned q_bits)
+

Generates paramaters of a new group. The params struct 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. 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 too small, or too close to p_bits. +

+ +

Signatures are represented using the structure below. +

+
+
Context struct: dsa_signature r s
+
+ +
+
Function: void dsa_signature_init (struct dsa_signature *signature)
+
Function: void dsa_signature_clear (struct dsa_signature *signature)
+

You must call dsa_signature_init before creating or using a +signature, and call dsa_signature_clear when you are finished +with it. +

+ +

Keys are represented as bignums, of type mpz_t. A public keys +represent a group element, and is of the same size as p, while a +private key is an exponent, of the same size as q. +

+
+
Function: int dsa_sign (const struct dsa_params *params, const mpz_t x, void *random_ctx, nettle_random_func *random, size_t digest_size, const uint8_t *digest, struct dsa_signature *signature)
+

Creates a signature from the given hash digest, using the private key +x. 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 +can fail only if the key is invalid, so that inversion modulo q +fails. +

+ +
+
Function: int dsa_verify (const struct dsa_params *params, const mpz_t y, size_t digest_size, const uint8_t *digest, const struct dsa_signature *signature)
+

Verifies a signature, using the public key y. Returns 1 if the signature +is valid, otherwise 0. +

+ +

To generate a keypair, first generate a DSA group using +dsa_generate_params. A keypair in this group is then created +using +

+
+
Function: void dsa_generate_keypair (const struct dsa_params *params, mpz_t pub, mpz_t key, void *random_ctx, nettle_random_func *random)
+

Generates a new keypair, using the group params. The public key is +stored in pub, and the private key in key. Both variables +must be initialized using mpz_init before this call. +

+

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. +

+ + +

6.7.2.2 Old, deprecated, DSA interface

+ +

Versions before nettle-3.0 used a different interface for DSA +signatures, where the group parameters and the public key was packed +together as struct dsa_public_key. Most of this interface is kept +for backwards compatibility, and declared in nettle/dsa-compat.h. +Below is the old documentation. The old and new interface use distinct +names and don’t confict, with one exception: The key generation +function. The nettle/dsa-compat.h redefines +dsa_generate_keypair as an alias for +dsa_compat_generate_keypair, compatible with the old interface +and documented below. +

+

The old 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. +

+
+
Context struct: dsa_public_key p q g y
+

The public parameters described above. +

+ +
+
Context struct: dsa_private_key x
+

The private key x. +

+ +

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

+
+
Function: void dsa_public_key_init (struct dsa_public_key *pub)
+
Function: void dsa_private_key_init (struct dsa_private_key *key)
+

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 +

+
+
Function: void dsa_public_key_clear (struct dsa_public_key *pub)
+
Function: void dsa_private_key_clear (struct dsa_private_key *key)
+

Calls mpz_clear on all numbers in the key struct. +

+ +

Signatures are represented using struct dsa_signature, described +earlier. +

+

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. +

+
+
Function: 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)
+

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 +

+
+
Function: 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)
+

Verifies a signature. Returns 1 if the signature is valid, otherwise 0. +

+ +

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

+
+
Function: int dsa_compat_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)
+

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. See dsa_generate_keypair for details. +

+ +
+ +
+

+Previous: , Up: Public-key algorithms   [Contents][Index]

+
+ +

6.7.3 Elliptic curves

+ +

For cryptographic purposes, an elliptic curve is a mathematical group of +points, and computing logarithms in this group is computationally +difficult problem. Nettle uses additive notation for elliptic curve +groups. If P and Q are two points, and k is an +integer, the point sum, P + Q, and the multiple k P can be +computed efficiently, but given only two points P and Q, +finding an integer k such that Q = k P is the elliptic +curve discrete logarithm problem. +

+

Nettle supports standard curves which are all of the form y^2 = +x^3 - 3 x + b (mod p), i.e., the points have coordinates (x,y), +both considered as integers modulo a specified prime p. Curves +are represented as a struct ecc_curve. It also supports +curve25519, which uses a different form of curve. Supported curves are +declared in <nettle/ecc-curve.h>, e.g., call +nettle_get_secp_256r1 for a standardized curve using the 256-bit +prime p = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 1. The contents +of these structs is not visible to nettle users. The “bitsize of the +curve” is used as a shorthand for the bitsize of the curve’s prime +p, e.g., 256 bits for the SECP 256R1 curve. +

+ + + + + + +
+ +
+

+Next: , Up: Elliptic curves   [Contents][Index]

+
+ +

6.7.3.1 Side-channel silence

+ + +

Nettle’s implementation of the elliptic curve operations is intended to +be side-channel silent. The side-channel attacks considered are: +

+
    +
  • Timing attacks +If the timing of operations depends on secret values, an attacker +interacting with your system can measure the response time, and infer +information about your secrets, e.g., a private signature key. + +
  • Attacks using memory caches +Assume you have some secret data on a multi-user system, and that this +data is properly protected so that other users get no direct access to +it. If you have a process operating on the secret data, and this process +does memory accesses depending on the data, e.g, an internal lookup +table in some cryptographic algorithm, an attacker running a separate +process on the same system may use behavior of internal CPU caches to +get information about your secrets. This type of attack can even cross +virtual machine boundaries. +
+ +

Nettle’s ECC implementation is designed to be side-channel silent, +and not leak any information to these attacks. Timing and memory +accesses depend only on the size of the input data and its location in +memory, not on the actual data bits. This implies a performance penalty +in several of the building blocks. +

+
+ + + +

6.7.3.2 ECDSA

+ +

ECDSA is a variant of the DSA digital signature scheme (see DSA), +which works over an elliptic curve group rather than over a (subgroup +of) integers modulo p. Like DSA, creating a signature requires a unique +random nonce (repeating the nonce with two different messages reveals +the private key, and any leak or bias in the generation of the nonce +also leaks information about the key). +

+

Unlike DSA, signatures are in general not tied to any particular hash +function or even hash size. Any hash function can be used, and the hash +value is truncated or padded as needed to get a size matching the curve +being used. It is recommended to use a strong cryptographic hash +function with digest size close to the bit size of the curve, e.g., +SHA256 is a reasonable choice when using ECDSA signature over the curve +secp256r1. A protocol or application using ECDSA has to specify which +curve and which hash function to use, or provide some mechanism for +negotiating. +

+

Nettle defines ECDSA in <nettle/ecdsa.h>. We first need +to define the data types used to represent public and private keys. +

+
+
struct: struct ecc_point
+

Represents a point on an elliptic curve. In particular, it is used to +represent an ECDSA public key. +

+ +
+
Function: void ecc_point_init (struct ecc_point *p, const struct ecc_curve *ecc)
+

Initializes p to represent points on the given curve ecc. +Allocates storage for the coordinates, using the same allocation +functions as GMP. +

+ +
+
Function: void ecc_point_clear (struct ecc_point *p)
+

Deallocate storage. +

+ +
+
Function: int ecc_point_set (struct ecc_point *p, const mpz_t x, const mpz_t y)
+

Check that the given coordinates represent a point on the curve. If so, +the coordinates are copied and converted to internal representation, and +the function returns 1. Otherwise, it returns 0. Currently, the +infinity point (or zero point, with additive notation) is not allowed. +

+ +
+
Function: void ecc_point_get (const struct ecc_point *p, mpz_t x, mpz_t y)
+

Extracts the coordinate of the point p. The output parameters +x or y may be NULL if the caller doesn’t want that +coordinate. +

+ +
+
struct: struct ecc_scalar
+

Represents an integer in the range 0 < x < group order, where the +“group order” refers to the order of an ECC group. In particular, it +is used to represent an ECDSA private key. +

+ +
+
Function: void ecc_scalar_init (struct ecc_scalar *s, const struct ecc_curve *ecc)
+

Initializes s to represent a scalar suitable for the given curve +ecc. Allocates storage using the same allocation functions as GMP. +

+ +
+
Function: void ecc_scalar_clear (struct ecc_scalar *s)
+

Deallocate storage. +

+ +
+
Function: int ecc_scalar_set (struct ecc_scalar *s, const mpz_t z)
+

Check that z is in the correct range. If so, copies the value to +s and returns 1, otherwise returns 0. +

+ +
+
Function: void ecc_scalar_get (const struct ecc_scalar *s, mpz_t z)
+

Extracts the scalar, in GMP mpz_t representation. +

+ +

To create and verify ECDSA signatures, the following functions are used. +

+
+
Function: void ecdsa_sign (const struct ecc_scalar *key, void *random_ctx, nettle_random_func *random, size_t digest_length, const uint8_t *digest, struct dsa_signature *signature)
+

Uses the private key key to create a signature on digest. +random_ctx and random is a randomness generator. +random(random_ctx, length, dst) should generate length +random octets and store them at dst. The signature is stored in +signature, in the same was as for plain DSA. +

+ +
+
Function: int ecdsa_verify (const struct ecc_point *pub, size_t length, const uint8_t *digest, const struct dsa_signature *signature)
+

Uses the public key pub to verify that signature is a valid +signature for the message digest digest (of length octets). +Returns 1 if the signature is valid, otherwise 0. +

+ +

Finally, generating a new ECDSA key pair: +

+
+
Function: void ecdsa_generate_keypair (struct ecc_point *pub, struct ecc_scalar *key, void *random_ctx, nettle_random_func *random);
+

pub and key is where the resulting key pair is stored. The +structs should be initialized, for the desired ECC curve, 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. +

+ +
+ +
+

+Previous: , Up: Elliptic curves   [Contents][Index]

+
+ +

6.7.3.3 Curve25519

+ + + +

Curve25519 is an elliptic curve of Montgomery type, y^2 = x^3 + +486662 x^2 + x (mod p), with p = 2^255 - 19. Montgomery curves +have the advantage of simple and efficient point addition based on the +x-coordinate only. This particular curve was proposed by D. J. Bernstein +in 2006, for fast Diffie-Hellman key exchange, and is also described in +RFC 7748. The group generator is defined by x = 9 (there +are actually two points with x = 9, differing by the sign of the +y-coordinate, but that doesn’t matter for the curve25519 operations +which work with the x-coordinate only). +

+

The curve25519 functions are defined as operations on octet strings, +representing 255-bit scalars or x-coordinates, in little-endian byte +order. The most significant input bit, i.e, the most significant bit of +the last octet, is always ignored. +

+

For scalars, in addition, the least significant three bits are ignored, +and treated as zero, and the second most significant bit is ignored too, +and treated as one. Then the scalar input string always represents 8 +times a number in the range 2^251 <= s < 2^252. +

+

Of all the possible input strings, only about half correspond to +x-coordinates of points on curve25519, i.e., a value x for which +the the curve equation can be solved for y. The other half +correspond to points on a related “twist curve”. The function +curve25519_mul uses a Montgomery ladder for the scalar +multiplication, as suggested in the curve25519 literature, and required +by RFC 7748. The output is therefore well defined for +all possible inputs, no matter if the input string represents a +valid point on the curve or not. +

+

Note that the curve25519 implementation in earlier versions of Nettle +deviates slightly from RFC 7748, in that bit 255 of the x +coordinate of the point input to curve25519_mul was not ignored. The +nette/curve25519.h defines a preprocessor symbol +NETTLE_CURVE25519_RFC7748 to indicate conformance with the +standard. +

+

Nettle defines Curve 25519 in <nettle/curve25519.h>. +

+
+
Constant: NETTLE_CURVE25519_RFC7748
+

Defined to 1 in Nettle versions conforming to RFC 7748. Undefined in +earlier versions. +

+ +
+
Constant: CURVE25519_SIZE
+

The size of the strings representing curve25519 points and scalars, 32. +

+ +
+
Function: void curve25519_mul_g (uint8_t *q, const uint8_t *n)
+

Computes Q = N G, where G is the group generator and +N is an integer. The input argument n and the output +argument q use a little-endian representation of the scalar and +the x-coordinate, respectively. They are both of size +CURVE25519_SIZE. +

+

This function is intended to be compatible with the function +crypto_scalar_mult_base in the NaCl library. +

+ +
+
Function: void curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
+

Computes Q = N P, where P is an input point and N +is an integer. The input arguments n and p and the output +argument q use a little-endian representation of the scalar and +the x-coordinates, respectively. They are all of size +CURVE25519_SIZE. +

+

This function is intended to be compatible with the function +crypto_scalar_mult in the NaCl library. +

+ + +

6.7.3.4 EdDSA

+ + +

EdDSA is a signature scheme proposed by D. J. Bernstein et al. in 2011. +It is defined using a “Twisted Edwards curve”, of the form -x^2 ++ y^2 = 1 + d x^2 y^2. The specific signature scheme Ed25519 uses a +curve which is equivalent to curve25519: The two groups used differ only +by a simple change of coordinates, so that the discrete logarithm +problem is of equal difficulty in both groups. +

+

Unlike other signature schemes in Nettle, the input to the EdDSA sign +and verify functions is the possibly large message itself, not a hash +digest. EdDSA is a variant of Schnorr signatures, where the message is +hashed together with other data during the signature process, providing +resilience to hash-collisions: A successful attack finding collisions in +the hash function does not automatically translate into an attack to +forge signatures. EdDSA also avoids the use of a randomness source by +generating the needed signature nonce from a hash of the private key and +the message, which means that the message is actually hashed twice when +creating a signature. If signing huge messages, it is possible to hash +the message first and pass the short message digest as input to the sign +and verify functions, however, the resilience to hash collision is then +lost. +

+
+
Constant: ED25519_KEY_SIZE
+

The size of a private or public Ed25519 key, 32 octets. +

+ +
+
Constant: ED25519_SIGNATURE_SIZE
+

The size of an Ed25519 signature, 64 octets. +

+ +
+
Function: void ed25519_sha512_public_key (uint8_t *pub, const uint8_t *priv)
+

Computes the public key corresponding to the given private key. Both +input and output are of size ED25519_KEY_SIZE. +

+ +
+
Function: void ed25519_sha512_sign (const uint8_t *pub, const uint8_t *priv, size_t length, const uint8_t *msg, uint8_t *signature)
+

Signs a message using the provided key pair. +

+ +
+
Function: int ed25519_sha512_verify (const uint8_t *pub, size_t length, const uint8_t *msg, const uint8_t *signature)
+

Verifies a message using the provided public key. Returns 1 if the +signature is valid, otherwise 0. +

+ +
+ +
+

+Next: , Previous: , Up: Reference   [Contents][Index]

+
+ +

6.8 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. +

+ +

6.8.1 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>. +

+
+
Context struct: struct yarrow256_ctx
+
+ +
+
Context struct: struct yarrow_source
+

Information about a single source. +

+ +
+
Constant: YARROW256_SEED_FILE_SIZE
+

Recommended 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, size_t 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, size_t 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, size_t 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. +

+ +
+ +
+

+Next: , Previous: , Up: Reference   [Contents][Index]

+
+ +

6.9 ASCII encoding

+ +

Encryption will transform your data from text into binary format, and that +may be a problem if, for example, you want to send the data as if it was +plain text in an email, or store it along with descriptive text in a +file. You may then use an encoding from binary to text: each binary byte +is translated into a number of bytes of plain text. +

+

A base-N encoding of data is one representation of data that only uses N +different symbols (instead of the 256 possible values of a byte). +

+

The base64 encoding will always use alphanumeric (upper and lower case) +characters and the ’+’, ’/’ and ’=’ symbols to represent the data. Four +output characters are generated for each three bytes of input. In case +the length of the input is not a multiple of three, padding characters +are added at the end. There’s also a “URL safe” variant, which is +useful for encoding binary data into URLs and filenames. See RFC +4648. +

+

The base16 encoding, also known as “hexadecimal”, uses the decimal +digits and the letters from A to F. Two hexadecimal digits are generated +for each input byte. +

+

Nettle supports both base64 and base16 encoding and decoding. +

+

Encoding and decoding uses a context struct to maintain its state (with +the exception of base16 encoding, which doesn’t need any). To encode or +decode the data, first initialize the context, then call the update +function as many times as necessary, and complete the operation by +calling the final function. +

+

The following functions can be used to perform base64 encoding and decoding. +They are defined in <nettle/base64.h>. +

+
+
Context struct: struct base64_encode_ctx
+
+ +
+
Function: void base64_encode_init (struct base64_encode_ctx *ctx)
+
Function: void base64url_encode_init (struct base64_encode_ctx *ctx)
+

Initializes a base64 context. This is necessary before starting an +encoding session. base64_encode_init selects the standard base64 +alphabet, while base64url_encode_init selects the URL safe +alphabet. +

+ + +
+
Function: size_t base64_encode_single (struct base64_encode_ctx *ctx, uint8_t *dst, uint8_t src)
+

Encodes a single byte. Returns amount of output (always 1 or 2). +

+ +
+
Macro: BASE64_ENCODE_LENGTH (length)
+

The maximum number of output bytes when passing length input bytes +to base64_encode_update. +

+ +
+
Function: size_t base64_encode_update (struct base64_encode_ctx *ctx, uint8_t *dst, size_t length, const uint8_t *src)
+

After ctx is initialized, this function may be called to encode length +bytes from src. The result will be placed in dst, and the return value +will be the number of bytes generated. Note that dst must be at least of size +BASE64_ENCODE_LENGTH(length). +

+ +
+
Constant: BASE64_ENCODE_FINAL_LENGTH
+

The maximum amount of output from base64_encode_final. +

+ +
+
Function: size_t base64_encode_final (struct base64_encode_ctx *ctx, uint8_t *dst)
+

After calling base64_encode_update one or more times, this function +should be called to generate the final output bytes, including any +needed paddding. The return value is the number of output bytes +generated. +

+ +
+
Context struct: struct base64_decode_ctx
+
+ +
+
Function: void base64_decode_init (struct base64_decode_ctx *ctx)
+
Function: void base64url_decode_init (struct base64_decode_ctx *ctx)
+

Initializes a base64 decoding context. This is necessary before starting +a decoding session. base64_decode_init selects the standard +base64 alphabet, while base64url_decode_init selects the URL safe +alphabet. +

+ +
+
Function: int base64_decode_single (struct base64_decode_ctx *ctx, uint8_t *dst, uint8_t src)
+

Decodes a single byte (src) and stores the result in dst. +Returns amount of output (0 or 1), or -1 on errors. +

+ +
+
Macro: BASE64_DECODE_LENGTH (length)
+

The maximum number of output bytes when passing length input bytes +to base64_decode_update. +

+ +
+
Function: void base64_decode_update (struct base64_decode_ctx *ctx, size_t *dst_length, uint8_t *dst, size_t src_length, const uint8_t *src)
+

After ctx is initialized, this function may be called to decode +src_length bytes from src. dst should point to an area +of size at least BASE64_DECODE_LENGTH(src_length). The amount of data +generated is returned in *dst_length. Returns 1 on success +and 0 on error. +

+ +
+
Function: int base64_decode_final (struct base64_decode_ctx *ctx)
+

Check that final padding is correct. Returns 1 on success, and 0 on +error. +

+ +

Similarly to the base64 functions, the following functions perform base16 encoding, +and are defined in <nettle/base16.h>. Note that there is no encoding context +necessary for doing base16 encoding. +

+
+
Function: void base16_encode_single (uint8_t *dst, uint8_t src)
+

Encodes a single byte. Always stores two digits in dst[0] and dst[1]. +

+ +
+
Macro: BASE16_ENCODE_LENGTH (length)
+

The number of output bytes when passing length input bytes to +base16_encode_update. +

+ +
+
Function: void base16_encode_update (uint8_t *dst, size_t length, const uint8_t *src)
+

Always stores BASE16_ENCODE_LENGTH(length) digits in dst. +

+ +
+
Context struct: struct base16_decode_ctx
+
+ +
+
Function: void base16_decode_init (struct base16_decode_ctx *ctx)
+

Initializes a base16 decoding context. This is necessary before starting a decoding +session. +

+ +
+
Function: int base16_decode_single (struct base16_decode_ctx *ctx, uint8_t *dst, uint8_t src)
+

Decodes a single byte from src into dst. Returns amount of output (0 or 1), or -1 on errors. +

+ +
+
Macro: BASE16_DECODE_LENGTH (length)
+

The maximum number of output bytes when passing length input bytes +to base16_decode_update. +

+ +
+
Function: int base16_decode_update (struct base16_decode_ctx *ctx, size_t *dst_length, uint8_t *dst, size_t src_length, const uint8_t *src)
+

After ctx is initialized, this function may be called to decode +src_length bytes from src. dst should point to an area +of size at least BASE16_DECODE_LENGTH(src_length). The amount of data +generated is returned in *dst_length. Returns 1 on success +and 0 on error. +

+ +
+
Function: int base16_decode_final (struct base16_decode_ctx *ctx)
+

Checks that the end of data is correct (i.e., an even number of +hexadecimal digits have been seen). Returns 1 on success, and 0 on +error. +

+ +
+ + + +

6.10 Miscellaneous functions

+ +
+
Function: void * memxor (void *dst, const void *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. +

+ +
+
Function: void * memxor3 (void *dst, const void *a, const void *b, size_t n)
+

Like memxor, but takes two source areas and separate +destination area. +

+ +
+
Function: int memeql_sec (const void *a, const void *b, size_t n)
+

Side-channel silent comparison of the n bytes at a and +b. I.e., instructions executed and memory accesses are identical +no matter where the areas differ, see Side-channel silence. Return +non-zero if the areas are equal, and zero if they differ. +

+ +

These functions are declared in <nettle/memops.h>. For +compatibility with earlier versions of Nettle, memxor and +memxor3 are also declared in <nettle/memxor.h>. +

+
+ +
+

+Previous: , Up: Reference   [Contents][Index]

+
+ +

6.11 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. +

+
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

7 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. +

+ +
+ +
+

+Next: , Previous: , Up: Top   [Contents][Index]

+
+ +

8 Installation

+ +

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

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

to install it under the default prefix, /usr/local. Using GNU +make is strongly recommended. By default, both static and shared +libraries are built and installed. +

+

To get a list of configure options, use ./configure --help. Some +of the more interesting are: +

+
+
--enable-fat
+

Include multiple versions of certain functions in the library, and +select the ones to use at run-time, depending on available processor +features. Supported for ARM and x86_64. +

+
+
--enable-mini-gmp
+

Use the smaller and slower “mini-gmp” implementation of the bignum +functions needed for public-key cryptography, instead of the real GNU +GMP library. This option is intended primarily for smaller embedded +systems. Note that builds using mini-gmp are not binary compatible +with regular builds of Nettle, and more likely to leak side-channel +information. +

+
+
--disable-shared
+

Omit building the shared libraries. +

+
+
--disable-dependency-tracking
+

Disable the automatic dependency tracking. You will likely need this +option to be able to build with BSD make. +

+
+
+ +
+ +
+

+Previous: , Up: Top   [Contents][Index]

+
+ +

Function and Concept Index

+ +
Jump to:   A +   +B +   +C +   +D +   +E +   +G +   +H +   +K +   +M +   +N +   +O +   +P +   +R +   +S +   +T +   +U +   +Y +   +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index Entry  Section

A
AEAD: Authenticated encryption
aes128_decrypt: Cipher functions
aes128_encrypt: Cipher functions
aes128_invert_key: Cipher functions
aes128_set_decrypt_key: Cipher functions
aes128_set_encrypt_key: Cipher functions
aes192_decrypt: Cipher functions
aes192_encrypt: Cipher functions
aes192_invert_key: Cipher functions
aes192_set_decrypt_key: Cipher functions
aes192_set_encrypt_key: Cipher functions
aes256_decrypt: Cipher functions
aes256_encrypt: Cipher functions
aes256_invert_key: Cipher functions
aes256_set_decrypt_key: Cipher functions
aes256_set_encrypt_key: Cipher functions
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
Authenticated encryption: Authenticated encryption

B
base16_decode_final: ASCII encoding
base16_decode_init: ASCII encoding
BASE16_DECODE_LENGTH: ASCII encoding
base16_decode_single: ASCII encoding
base16_decode_update: ASCII encoding
BASE16_ENCODE_LENGTH: ASCII encoding
base16_encode_single: ASCII encoding
base16_encode_update: ASCII encoding
base64url_decode_init: ASCII encoding
base64url_encode_init: ASCII encoding
base64_decode_final: ASCII encoding
base64_decode_init: ASCII encoding
BASE64_DECODE_LENGTH: ASCII encoding
base64_decode_single: ASCII encoding
base64_decode_update: ASCII encoding
base64_encode_final: ASCII encoding
base64_encode_init: ASCII encoding
BASE64_ENCODE_LENGTH: ASCII encoding
base64_encode_single: ASCII encoding
base64_encode_update: ASCII encoding
Block Cipher: Cipher functions
blowfish_decrypt: Cipher functions
blowfish_encrypt: Cipher functions
blowfish_set_key: Cipher functions

C
camellia128_crypt: Cipher functions
camellia128_invert_key: Cipher functions
camellia128_set_decrypt_key: Cipher functions
camellia128_set_encrypt_key: Cipher functions
camellia192_crypt: Cipher functions
camellia192_invert_key: Cipher functions
camellia192_set_decrypt_key: Cipher functions
camellia192_set_encrypt_key: Cipher functions
camellia256_crypt: Cipher functions
camellia256_invert_key: Cipher functions
camellia256_set_decrypt_key: Cipher functions
camellia256_set_encrypt_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: CBC
CBC_CTX: CBC
cbc_decrypt: CBC
CBC_DECRYPT: CBC
cbc_encrypt: CBC
CBC_ENCRYPT: CBC
CBC_SET_IV: CBC
CCM Mode: CCM
ccm_aes128_decrypt: CCM
ccm_aes128_decrypt_message: CCM
ccm_aes128_digest: CCM
ccm_aes128_encrypt: CCM
ccm_aes128_encrypt_message: CCM
ccm_aes128_set_key: CCM
ccm_aes128_set_nonce: CCM
ccm_aes128_update: CCM
ccm_aes192_decrypt: CCM
ccm_aes192_decrypt_message: CCM
ccm_aes192_decrypt_message: CCM
ccm_aes192_digest: CCM
ccm_aes192_encrypt: CCM
ccm_aes192_encrypt_message: CCM
ccm_aes192_set_key: CCM
ccm_aes192_set_nonce: CCM
ccm_aes192_update: CCM
ccm_aes256_decrypt: CCM
ccm_aes256_digest: CCM
ccm_aes256_encrypt: CCM
ccm_aes256_encrypt_message: CCM
ccm_aes256_set_key: CCM
ccm_aes256_set_nonce: CCM
ccm_aes256_update: CCM
ccm_decrypt: CCM
ccm_decrypt_message: CCM
ccm_digest: CCM
ccm_encrypt: CCM
ccm_encrypt_message: CCM
CCM_MAX_MSG_SIZE: CCM
ccm_set_nonce: CCM
ccm_update: CCM
CFB Mode: CFB
CFB_CTX: CFB
cfb_decrypt: CFB
CFB_DECRYPT: CFB
cfb_encrypt: CFB
CFB_ENCRYPT: CFB
CFB_SET_IV(ctx,: CFB
chacha_crypt: Cipher functions
chacha_poly1305_decrypt: ChaCha-Poly1305
chacha_poly1305_digest: ChaCha-Poly1305
chacha_poly1305_encrypt: ChaCha-Poly1305
chacha_poly1305_set_key: ChaCha-Poly1305
chacha_poly1305_set_nonce: ChaCha-Poly1305
chacha_poly1305_update: ChaCha-Poly1305
chacha_set_key: Cipher functions
chacha_set_nonce: Cipher functions
Cipher: Cipher functions
Cipher Block Chaining: CBC
Cipher Feedback Mode: CFB
Collision-resistant: Hash functions
Conditional entropy: Randomness
Counter Mode: CTR
Counter with CBC-MAC Mode: CCM
CTR Mode: CTR
ctr_crypt: CTR
CTR_CRYPT: CTR
CTR_CTX: CTR
CTR_SET_COUNTER: CTR
Curve 25519: Curve 25519
curve25519_mul: Curve 25519
curve25519_mul_g: Curve 25519

D
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_compat_generate_keypair: DSA
dsa_generate_keypair: DSA
dsa_generate_params: DSA
dsa_params_clear: DSA
dsa_params_init: 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_sign: DSA
dsa_signature_clear: DSA
dsa_signature_init: DSA
dsa_verify: DSA

E
eax_aes128_decrypt: EAX
eax_aes128_digest: EAX
eax_aes128_encrypt: EAX
eax_aes128_set_key: EAX
eax_aes128_set_nonce: EAX
eax_aes128_update: EAX
EAX_CTX: EAX
eax_decrypt: EAX
EAX_DECRYPT: EAX
eax_digest: EAX
EAX_DIGEST: EAX
eax_encrypt: EAX
EAX_ENCRYPT: EAX
eax_set_key: EAX
EAX_SET_KEY: EAX
eax_set_nonce: EAX
EAX_SET_NONCE: EAX
eax_update: EAX
EAX_UPDATE: EAX
ecc_point_clear: ECDSA
ecc_point_get: ECDSA
ecc_point_init: ECDSA
ecc_point_set: ECDSA
ecc_scalar_clear: ECDSA
ecc_scalar_get: ECDSA
ecc_scalar_init: ECDSA
ecc_scalar_set: ECDSA
ecdsa_generate_keypair: ECDSA
ecdsa_sign: ECDSA
ecdsa_verify: ECDSA
ed25519_sha512_public_key: Curve 25519
ed25519_sha512_sign: Curve 25519
ed25519_sha512_verify: Curve 25519
eddsa: Curve 25519
Entropy: Randomness

G
Galois Counter Mode: GCM
GCM: GCM
gcm_aes128_decrypt: GCM
gcm_aes128_digest: GCM
gcm_aes128_encrypt: GCM
gcm_aes128_set_iv: GCM
gcm_aes128_set_key: GCM
gcm_aes128_update: GCM
gcm_aes192_decrypt: GCM
gcm_aes192_digest: GCM
gcm_aes192_encrypt: GCM
gcm_aes192_set_iv: GCM
gcm_aes192_set_key: GCM
gcm_aes192_update: GCM
gcm_aes256_decrypt: GCM
gcm_aes256_digest: GCM
gcm_aes256_encrypt: GCM
gcm_aes256_set_iv: GCM
gcm_aes256_set_key: GCM
gcm_aes256_update: GCM
gcm_aes_decrypt: GCM
gcm_aes_digest: GCM
gcm_aes_encrypt: GCM
gcm_aes_set_iv: GCM
gcm_aes_set_key: GCM
gcm_aes_update: GCM
gcm_camellia128_decrypt: GCM
gcm_camellia128_digest: GCM
gcm_camellia128_encrypt: GCM
gcm_camellia128_set_iv: GCM
gcm_camellia128_set_key: GCM
gcm_camellia128_update: GCM
gcm_camellia192_digest: GCM
gcm_camellia256_decrypt: GCM
gcm_camellia256_digest: GCM
gcm_camellia256_encrypt: GCM
gcm_camellia256_set_iv: GCM
gcm_camellia256_set_key: GCM
gcm_camellia256_update: GCM
gcm_camellia_digest: GCM
GCM_CTX: GCM
gcm_decrypt: GCM
GCM_DECRYPT: GCM
gcm_digest: GCM
GCM_DIGEST: GCM
gcm_encrypt: GCM
GCM_ENCRYPT: GCM
gcm_set_iv: GCM
GCM_SET_IV: GCM
gcm_set_key: GCM
GCM_SET_KEY: GCM
gcm_update: GCM
GCM_UPDATE: GCM
gosthash94_digest: Legacy hash functions
gosthash94_init: Legacy hash functions
gosthash94_update: Legacy hash functions

H
Hash function: Hash functions
HKDF: Key derivation functions
hkdf_expand: Key derivation functions
hkdf_extract: Key derivation functions
HMAC: HMAC
HMAC_CTX: HMAC
hmac_digest: HMAC
HMAC_DIGEST: HMAC
hmac_md5_digest: HMAC
hmac_md5_set_key: HMAC
hmac_md5_update: HMAC
hmac_ripemd160_digest: HMAC
hmac_ripemd160_set_key: HMAC
hmac_ripemd160_update: HMAC
hmac_set_key: HMAC
HMAC_SET_KEY: HMAC
hmac_sha1_digest: HMAC
hmac_sha1_set_key: HMAC
hmac_sha1_update: HMAC
hmac_sha256_digest: HMAC
hmac_sha256_set_key: HMAC
hmac_sha256_update: HMAC
hmac_sha512_digest: HMAC
hmac_sha512_set_key: HMAC
hmac_sha512_update: HMAC
hmac_update: HMAC

K
KDF: Key derivation functions
Key Derivation Function: Key derivation functions
Keyed Hash Function: Keyed hash functions

M
MAC: Keyed hash functions
md2_digest: Legacy hash functions
md2_init: Legacy hash functions
md2_update: Legacy hash functions
md4_digest: Legacy hash functions
md4_init: Legacy hash functions
md4_update: Legacy hash functions
md5_digest: Legacy hash functions
md5_init: Legacy hash functions
md5_update: Legacy hash functions
memeql_sec: Miscellaneous functions
memxor: Miscellaneous functions
memxor3: Miscellaneous functions
Message Authentication Code: Keyed hash functions

N
nettle_aead: nettle_aead abstraction
nettle_aeads: nettle_aead abstraction
nettle_aeads: nettle_aead abstraction
nettle_cipher: Cipher functions
nettle_ciphers: Cipher functions
nettle_ciphers: Cipher functions
nettle_get_aeads: nettle_aead abstraction
nettle_get_ciphers: Cipher functions
nettle_get_hashes: nettle_hash abstraction
nettle_hash: nettle_hash abstraction
nettle_hashes: nettle_hash abstraction
nettle_hashes: nettle_hash abstraction

O
One-way: Hash functions
One-way function: Public-key algorithms

P
Password Based Key Derivation Function: Key derivation functions
PBKDF: Key derivation functions
pbkdf2: Key derivation functions
PBKDF2: Key derivation functions
pbkdf2_hmac_sha1: Key derivation functions
pbkdf2_hmac_sha256: Key derivation functions
PKCS #5: Key derivation functions
poly1305_aes_digest: Poly1305
poly1305_aes_set_key: Poly1305
poly1305_aes_set_nonce: Poly1305
poly1305_aes_update: Poly1305
Public Key Cryptography: Public-key algorithms

R
Randomness: Randomness
ripemd160_digest: Legacy hash functions
ripemd160_init: Legacy hash functions
ripemd160_update: Legacy hash functions
rsa_compute_root: RSA
rsa_compute_root_tr(const: RSA
rsa_decrypt: RSA
rsa_decrypt_tr: RSA
rsa_encrypt: RSA
rsa_generate_keypair: RSA
rsa_md5_sign: RSA
rsa_md5_sign_digest: RSA
rsa_md5_sign_digest_tr(const: RSA
rsa_md5_sign_tr(const: RSA
rsa_md5_verify: RSA
rsa_md5_verify_digest: RSA
rsa_pkcs1_sign(const: RSA
rsa_pkcs1_sign_tr(const: RSA
rsa_pkcs1_verify(const: RSA
rsa_private_key_clear: RSA
rsa_private_key_init: RSA
rsa_private_key_prepare: RSA
rsa_pss_sha256_sign_digest_tr(const: RSA
rsa_pss_sha256_verify_digest: RSA
rsa_pss_sha384_sign_digest_tr(const: RSA
rsa_pss_sha384_verify_digest: RSA
rsa_pss_sha512_sign_digest_tr(const: RSA
rsa_pss_sha512_verify_digest: 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_sign_digest_tr(const: RSA
rsa_sha1_sign_tr(const: RSA
rsa_sha1_verify: RSA
rsa_sha1_verify_digest: RSA
rsa_sha256_sign: RSA
rsa_sha256_sign_digest: RSA
rsa_sha256_sign_digest_tr(const: RSA
rsa_sha256_sign_tr(const: RSA
rsa_sha256_verify: RSA
rsa_sha256_verify_digest: RSA
rsa_sha512_sign: RSA
rsa_sha512_sign_digest: RSA
rsa_sha512_sign_digest_tr(const: RSA
rsa_sha512_sign_tr(const: RSA
rsa_sha512_verify: RSA
rsa_sha512_verify_digest: RSA

S
salsa20r12_crypt: Cipher functions
salsa20_128_set_key: Cipher functions
salsa20_256_set_key: Cipher functions
salsa20_crypt: Cipher functions
salsa20_set_key: Cipher functions
salsa20_set_nonce: Cipher functions
serpent_decrypt: Cipher functions
serpent_encrypt: Cipher functions
serpent_set_key: Cipher functions
sha1_digest: Legacy hash functions
sha1_init: Legacy hash functions
sha1_update: Legacy hash functions
sha224_digest: Recommended hash functions
sha224_init: Recommended hash functions
sha224_update: Recommended hash functions
sha256_digest: Recommended hash functions
sha256_init: Recommended hash functions
sha256_update: Recommended hash functions
SHA3: Recommended hash functions
sha384_digest: Recommended hash functions
sha384_init: Recommended hash functions
sha384_update: Recommended hash functions
sha3_224_digest: Recommended hash functions
sha3_224_init: Recommended hash functions
sha3_224_update: Recommended hash functions
sha3_256_digest: Recommended hash functions
sha3_256_init: Recommended hash functions
sha3_256_update: Recommended hash functions
sha3_384_digest: Recommended hash functions
sha3_384_init: Recommended hash functions
sha3_384_update: Recommended hash functions
sha3_512_digest: Recommended hash functions
sha3_512_init: Recommended hash functions
sha3_512_update: Recommended hash functions
sha512_224_digest: Recommended hash functions
sha512_224_init: Recommended hash functions
sha512_224_update: Recommended hash functions
sha512_256_digest: Recommended hash functions
sha512_256_init: Recommended hash functions
sha512_256_update: Recommended hash functions
sha512_digest: Recommended hash functions
sha512_init: Recommended hash functions
sha512_update: Recommended hash functions
Side-channel attack: Side-channel silence
Stream Cipher: Cipher functions
struct: nettle_hash abstraction
struct: Cipher functions
struct: nettle_aead abstraction

T
twofish_decrypt: Cipher functions
twofish_encrypt: Cipher functions
twofish_set_key: Cipher functions

U
UMAC: UMAC
umac128_digest: UMAC
umac128_set_key: UMAC
umac128_set_nonce: UMAC
umac128_update: UMAC
umac32_digest: UMAC
umac32_set_key: UMAC
umac32_set_nonce: UMAC
umac32_update: UMAC
umac64_digest: UMAC
umac64_set_key: UMAC
umac64_set_nonce: UMAC
umac64_update: UMAC
umac96_digest: UMAC
umac96_set_key: UMAC
umac96_set_nonce: UMAC
umac96_update: UMAC

Y
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

+
Jump to:   A +   +B +   +C +   +D +   +E +   +G +   +H +   +K +   +M +   +N +   +O +   +P +   +R +   +S +   +T +   +U +   +Y +   +
+ +
+ +
+

+   [Contents][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..c055050 --- /dev/null +++ b/nettle.info @@ -0,0 +1,5782 @@ +This is nettle.info, produced by makeinfo version 6.3 from +nettle.texinfo. + +This manual is for the Nettle library (version 3.4), a low-level +cryptographic library. + + Originally written 2001 by Niels Möller, updated 2017. + + 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 3.4), a low-level +cryptographic library. + + Originally written 2001 by Niels Möller, updated 2017. + + 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 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. + + — The Detailed Node Listing — + +Reference + +* Hash functions:: +* Cipher functions:: +* Cipher modes:: +* Keyed hash functions:: +* Key derivation functions:: +* Public-key algorithms:: +* Randomness:: +* ASCII encoding:: +* Miscellaneous functions:: +* Compatibility functions:: + +Hash functions + +* Recommended hash functions:: +* Legacy hash functions:: +* nettle_hash abstraction:: + +Cipher modes + +* CBC:: +* CTR:: +* CFB:: +* GCM:: +* CCM:: + +Keyed Hash Functions + +* HMAC:: +* UMAC:: + +Public-key algorithms + +* RSA:: The RSA public key algorithm. +* DSA:: The DSA digital signature algorithm. +* Elliptic curves:: Elliptic curves and ECDSA + +Elliptic curves + +* Side-channel silence:: +* ECDSA:: +* Curve 25519:: + + + +File: nettle.info, Node: Introduction, Next: Copyright, Prev: Top, Up: Top + +1 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 + +2 Copyright +*********** + +Nettle is dual licenced under the GNU General Public License version 2 +or later, and the GNU Lesser General Public License version 3 or later. +When using Nettle, you must comply fully with all conditions of at least +one of these licenses. A few of the individual files are licensed under +more permissive terms, or in the public domain. 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 exceptions to +the above licensing: + +_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. + +_ARCFOUR_ + The implementation of the ARCFOUR (also known as RC4) cipher is + written by Niels Möller. + +_ARCTWO_ + The implementation of the ARCTWO (also known as RC2) cipher is + written by Nikos Mavroyanopoulos and modified by Werner Koch and + Simon Josefsson. + +_BLOWFISH_ + The implementation of the BLOWFISH cipher is written by Werner + Koch, copyright owned by the Free Software Foundation. Also hacked + by Simon Josefsson and Niels Möller. + +_CAMELLIA_ + The C implementation is by Nippon Telegraph and Telephone + Corporation (NTT), heavily modified by Niels Möller. Assembler for + x86 and x86_64 by Niels Möller. + +_CAST128_ + The implementation of the CAST128 cipher is written by Steve Reid. + Released into the public domain. + +_CHACHA_ + Implemented by Joachim Strömbergson, based on the implementation of + SALSA20 (see below). Assembly for x86_64 by Niels Möller. + +_DES_ + The implementation of the DES cipher is written by Dana L. How, and + released under the LGPL, version 2 or later. + +_GOSTHASH94_ + The C implementation of the GOST94 message digest is written by + Aleksey Kravchenko and was ported from the rhash library by Nikos + Mavrogiannopoulos. It is released under the MIT license. + +_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. + +_PBKDF2_ + The C implementation of PBKDF2 is based on earlier work for Shishi + and GnuTLS by Simon Josefsson. + +_RIPEMD160_ + The implementation of RIPEMD160 message digest is based on the code + in libgcrypt, copyright owned by the Free Software Foundation. + Ported to Nettle by Andres Mejia. + +_SALSA20_ + The C implementation of SALSA20 is based on D. J. Bernstein’s + reference implementation (in the public domain), adapted to Nettle + by Simon Josefsson, and heavily modified by Niels Möller. Assembly + for x86_64 and ARM by Niels Möller. + +_SERPENT_ + The implementation of the SERPENT cipher is based on the code in + libgcrypt, copyright owned by the Free Software Foundation. + Adapted to Nettle by Simon Josefsson and heavily modified by Niels + Möller. Assembly for x86_64 by Niels Möller. + +_POLY1305_ + Based on the implementation by Andrew M. (floodyberry), modified by + Nikos Mavrogiannopoulos and Niels Möller. Assembly for x86_64 by + Niels Möller. + +_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, x86_64 and ARM + by Niels Möller, released under the LGPL. + +_SHA2_ + Written by Niels Möller, using Peter Gutmann’s SHA1 code as a + model. + +_SHA3_ + Written by Niels Möller. + +_TWOFISH_ + The implementation of the TWOFISH cipher is written by Ruud de + Rooij. + +_UMAC_ + Written by Niels Möller. + +_RSA_ + Written by Niels Möller. Uses the GMP library for bignum + operations. + +_DSA_ + Written by Niels Möller. Uses the GMP library for bignum + operations. + +_ECDSA_ + Written by Niels Möller. Uses the GMP library for bignum + operations. Development of Nettle’s ECC support was funded by the + .SE Internet Fund. + + +File: nettle.info, Node: Conventions, Next: Example, Prev: Copyright, Up: Top + +3 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 ‘size_t’, 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 usually of the same length. When they differ, +e.g., for ‘ccm_encrypt_message’, the length argument specifies the size +of the destination area. Source and destination pointers may be equal, +so that you can process strings in place, but source and destination +areas _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 + +4 Example +********* + +A simple example program that reads a file from standard input and +writes its SHA1 check-sum 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 sha256_ctx + + -- Constant: SHA256_DIGEST_SIZE + The size of a SHA256 digest, i.e. 32. + + -- Constant: SHA256_BLOCK_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, size_t LENGTH, + const uint8_t *DATA) + Hash some more data. + + -- Function: void sha256_digest (struct sha256_ctx *CTX, size_t 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’. + + Earlier versions of nettle defined SHA256 in the header file +‘’, which is now deprecated, but kept for compatibility. + +6.1.1.2 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 ‘’ (and in ‘’, for backwards +compatibility). + + -- Context struct: struct sha224_ctx + + -- Constant: SHA224_DIGEST_SIZE + The size of a SHA224 digest, i.e. 28. + + -- Constant: SHA224_BLOCK_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, size_t LENGTH, + const uint8_t *DATA) + Hash some more data. + + -- Function: void sha224_digest (struct sha224_ctx *CTX, size_t 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’. + +6.1.1.3 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 ‘’ (and in +‘’, for backwards compatibility). + + -- Context struct: struct sha512_ctx + + -- Constant: SHA512_DIGEST_SIZE + The size of a SHA512 digest, i.e. 64. + + -- Constant: SHA512_BLOCK_SIZE + The internal block size of SHA512, 128. 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, size_t LENGTH, + const uint8_t *DATA) + Hash some more data. + + -- Function: void sha512_digest (struct sha512_ctx *CTX, size_t 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’. + +6.1.1.4 SHA384 and other variants of SHA512 +........................................... + +Several variants of SHA512 have been defined, with a different initial +state, and with the output truncated to shorter length than 512 bits. +Naming is a bit confused, these algorithms are called SHA512-224, +SHA512-256 and SHA384, for output sizes of 224, 256 and 384 bits, +respectively. Nettle defines these in ‘’ (and in +‘’, for backwards compatibility). + + -- Context struct: struct sha512_224_ctx + -- Context struct: struct sha512_256_ctx + -- Context struct: struct sha384_ctx + These context structs are all the same as sha512_ctx. They are + defined as simple preprocessor aliases, which may cause some + problems if used as identifiers for other purposes. So avoid doing + that. + + -- Constant: SHA512_224_DIGEST_SIZE + -- Constant: SHA512_256_DIGEST_SIZE + -- Constant: SHA384_DIGEST_SIZE + The digest size for each variant, i.e., 28, 32, and 48, + respectively. + + -- Constant: SHA512_224_BLOCK_SIZE + -- Constant: SHA512_256_BLOCK_SIZE + -- Constant: SHA384_BLOCK_SIZE + The internal block size, same as SHA512_BLOCK_SIZE, i.e., 128. + Useful for some special constructions, in particular HMAC-SHA384. + + -- Function: void sha512_224_init (struct sha512_224_ctx *CTX) + -- Function: void sha512_256_init (struct sha512_256_ctx *CTX) + -- Function: void sha384_init (struct sha384_ctx *CTX) + Initialize the context struct. + + -- Function: void sha512_224_update (struct sha512_224_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void sha512_256_update (struct sha512_256_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void sha384_update (struct sha384_ctx *CTX, size_t LENGTH, + const uint8_t *DATA) + Hash some more data. These are all aliases for sha512_update, + which does the same thing. + + -- Function: void sha512_224_digest (struct sha512_224_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void sha512_256_digest (struct sha512_256_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void sha384_digest (struct sha384_ctx *CTX, size_t LENGTH, + uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than the specified digest + size, in which case only the first LENGTH octets of the digest are + written. + + These function also reset the context in the same way as the + corresponding init function. + +6.1.1.5 SHA3-224 +................ + +The SHA3 hash functions were specified by NIST in response to weaknesses +in SHA1, and doubts about SHA2 hash functions which structurally are +very similar to SHA1. SHA3 is a result of a competition, where the +winner, also known as Keccak, was designed by Guido Bertoni, Joan +Daemen, Michaël Peeters and Gilles Van Assche. It is structurally very +different from all widely used earlier hash functions. Like SHA2, there +are several variants, with output sizes of 224, 256, 384 and 512 bits +(28, 32, 48 and 64 octets, respectively). In August 2015, it was +formally standardized by NIST, as FIPS 202, +. + + Note that the SHA3 implementation in earlier versions of Nettle was +based on the specification at the time Keccak was announced as the +winner of the competition, which is incompatible with the final standard +and hence with current versions of Nettle. The ‘nette/sha3.h’ defines a +preprocessor symbol ‘NETTLE_SHA3_FIPS202’ to indicate conformance with +the standard. + + -- Constant: NETTLE_SHA3_FIPS202 + Defined to 1 in Nettle versions supporting FIPS 202. Undefined in + earlier versions. + + Nettle defines SHA3-224 in ‘’. + + -- Context struct: struct sha3_224_ctx + + -- Constant: SHA3_224_DIGEST_SIZE + The size of a SHA3_224 digest, i.e., 28. + + -- Constant: SHA3_224_BLOCK_SIZE + The internal block size of SHA3_224. + + -- Function: void sha3_224_init (struct sha3_224_ctx *CTX) + Initialize the SHA3-224 state. + + -- Function: void sha3_224_update (struct sha3_224_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Hash some more data. + + -- Function: void sha3_224_digest (struct sha3_224_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than ‘SHA3_224_DIGEST_SIZE’, + in which case only the first LENGTH octets of the digest are + written. + + This function also resets the context. + +6.1.1.6 SHA3-256 +................ + +This is SHA3 with 256-bit output size, and possibly the most useful of +the SHA3 hash functions. + + Nettle defines SHA3-256 in ‘’. + + -- Context struct: struct sha3_256_ctx + + -- Constant: SHA3_256_DIGEST_SIZE + The size of a SHA3_256 digest, i.e., 32. + + -- Constant: SHA3_256_BLOCK_SIZE + The internal block size of SHA3_256. + + -- Function: void sha3_256_init (struct sha3_256_ctx *CTX) + Initialize the SHA3-256 state. + + -- Function: void sha3_256_update (struct sha3_256_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Hash some more data. + + -- Function: void sha3_256_digest (struct sha3_256_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than ‘SHA3_256_DIGEST_SIZE’, + in which case only the first LENGTH octets of the digest are + written. + + This function also resets the context. + +6.1.1.7 SHA3-384 +................ + +This is SHA3 with 384-bit output size. + + Nettle defines SHA3-384 in ‘’. + + -- Context struct: struct sha3_384_ctx + + -- Constant: SHA3_384_DIGEST_SIZE + The size of a SHA3_384 digest, i.e., 48. + + -- Constant: SHA3_384_BLOCK_SIZE + The internal block size of SHA3_384. + + -- Function: void sha3_384_init (struct sha3_384_ctx *CTX) + Initialize the SHA3-384 state. + + -- Function: void sha3_384_update (struct sha3_384_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Hash some more data. + + -- Function: void sha3_384_digest (struct sha3_384_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than ‘SHA3_384_DIGEST_SIZE’, + in which case only the first LENGTH octets of the digest are + written. + + This function also resets the context. + +6.1.1.8 SHA3-512 +................ + +This is SHA3 with 512-bit output size. + + Nettle defines SHA3-512 in ‘’. + + -- Context struct: struct sha3_512_ctx + + -- Constant: SHA3_512_DIGEST_SIZE + The size of a SHA3_512 digest, i.e. 64. + + -- Constant: SHA3_512_BLOCK_SIZE + The internal block size of SHA3_512. + + -- Function: void sha3_512_init (struct sha3_512_ctx *CTX) + Initialize the SHA3-512 state. + + -- Function: void sha3_512_update (struct sha3_512_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Hash some more data. + + -- Function: void sha3_512_digest (struct sha3_512_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than ‘SHA3_512_DIGEST_SIZE’, + in which case only the first LENGTH octets of the digest are + written. + + This function also resets the context. + + +File: nettle.info, Node: Legacy hash functions, Next: nettle_hash abstraction, Prev: Recommended hash functions, Up: Hash functions + +6.1.2 Legacy hash functions +--------------------------- + +The hash functions in this section all have some known weaknesses, and +should be avoided for new applications. These hash functions are mainly +useful for compatibility with old applications and protocols. Some are +still considered safe as building blocks for particular constructions, +e.g., there seems to be no known attacks against HMAC-SHA1 or even +HMAC-MD5. In some important cases, use of a “legacy” hash function does +not in itself make the application insecure; if a known weakness is +relevant depends on how the hash function is used, and on the threat +model. + +6.1.2.1 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 ‘’. + + -- Context struct: struct md5_ctx + + -- Constant: MD5_DIGEST_SIZE + The size of an MD5 digest, i.e. 16. + + -- Constant: MD5_BLOCK_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, size_t LENGTH, const + uint8_t *DATA) + Hash some more data. + + -- Function: void md5_digest (struct md5_ctx *CTX, size_t 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. + +6.1.2.2 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_BLOCK_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, size_t LENGTH, const + uint8_t *DATA) + Hash some more data. + + -- Function: void md2_digest (struct md2_ctx *CTX, size_t 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’. + +6.1.2.3 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_BLOCK_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, size_t LENGTH, const + uint8_t *DATA) + Hash some more data. + + -- Function: void md4_digest (struct md4_ctx *CTX, size_t 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’. + +6.1.2.4 RIPEMD160 +................. + +RIPEMD160 is a hash function designed by Hans Dobbertin, Antoon +Bosselaers, and Bart Preneel, as a strengthened version of RIPEMD +(which, like MD4 and MD5, fails the collision-resistance requirement). +It produces message digests of 160 bits, or 20 octets. Nettle defined +RIPEMD160 in ‘nettle/ripemd160.h’. + + -- Context struct: struct ripemd160_ctx + + -- Constant: RIPEMD160_DIGEST_SIZE + The size of a RIPEMD160 digest, i.e. 20. + + -- Constant: RIPEMD160_BLOCK_SIZE + The internal block size of RIPEMD160. + + -- Function: void ripemd160_init (struct ripemd160_ctx *CTX) + Initialize the RIPEMD160 state. + + -- Function: void ripemd160_update (struct ripemd160_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Hash some more data. + + -- Function: void ripemd160_digest (struct ripemd160_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than ‘RIPEMD160_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 + ‘ripemd160_init’. + +6.1.2.5 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 ‘’ (and in +‘’, for backwards compatibility). + + -- Context struct: struct sha1_ctx + + -- Constant: SHA1_DIGEST_SIZE + The size of a SHA1 digest, i.e. 20. + + -- Constant: SHA1_BLOCK_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, size_t LENGTH, + const uint8_t *DATA) + Hash some more data. + + -- Function: void sha1_digest (struct sha1_ctx *CTX, size_t 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’. + +6.1.2.6 GOSTHASH94 +.................. + +The GOST94 or GOST R 34.11-94 hash algorithm is a Soviet-era algorithm +used in Russian government standards (see ‘RFC 4357’). It outputs +message digests of 256 bits, or 32 octets. Nettle defines GOSTHASH94 in +‘’. + + -- Context struct: struct gosthash94_ctx + + -- Constant: GOSTHASH94_DIGEST_SIZE + The size of a GOSTHASH94 digest, i.e. 32. + + -- Constant: GOSTHASH94_BLOCK_SIZE + The internal block size of GOSTHASH94, i.e., 32. + + -- Function: void gosthash94_init (struct gosthash94_ctx *CTX) + Initialize the GOSTHASH94 state. + + -- Function: void gosthash94_update (struct gosthash94_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Hash some more data. + + -- Function: void gosthash94_digest (struct gosthash94_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Performs final processing and extracts the message digest, writing + it to DIGEST. LENGTH may be smaller than ‘GOSTHASH94_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 + ‘gosthash94_init’. + + +File: nettle.info, Node: nettle_hash abstraction, Prev: Legacy hash functions, Up: Hash functions + +6.1.3 The ‘struct nettle_hash’ abstraction +------------------------------------------ + +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_ripemd160 + -- 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: struct nettle_hash nettle_sha3_256 + -- Constant Struct: struct nettle_hash nettle_gosthash94 + These are all the hash functions that Nettle implements. + + Nettle also exports a list of all these hashes. + + -- Function: const struct nettle_hash **nettle_get_hashes(void) + Returns a NULL-terminated list of pointers to supported hash + functions. This list can be used to dynamically enumerate or + search the supported algorithms. + + -- Macro: nettle_hashes + A macro expanding to a call to nettle_get_hashes, so that one could + write, e.g., ‘nettle_hashes[0]->name’ for the name of the first + hash function on the list. In earlier versions, this was not a + macro but the actual array of pointers. However, referring + directly to the array makes the array size leak into the ABI in + some cases. + + +File: nettle.info, Node: Cipher functions, Next: Cipher modes, Prev: Hash functions, Up: Reference + +6.2 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. + +6.2.1 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 three possible 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 ‘’, and there +is one context struct for each key size. (Earlier versions of Nettle +used a single context struct, ‘struct aes_ctx’, for all key sizes. This +interface kept for backwards compatibility). + + -- Context struct: struct aes128_ctx + -- Context struct: struct aes192_ctx + -- Context struct: struct aes256_ctx + + -- Context struct: struct aes_ctx + Alternative struct, for the old AES interface. + + -- Constant: AES_BLOCK_SIZE + The AES block-size, 16. + + -- Constant: AES128_KEY_SIZE + -- Constant: AES192_KEY_SIZE + -- Constant: AES256_KEY_SIZE + -- Constant: AES_MIN_KEY_SIZE + -- Constant: AES_MAX_KEY_SIZE + + -- Constant: AES_KEY_SIZE + Default AES key size, 32. + + -- Function: void aes128_set_encrypt_key (struct aes128_ctx *CTX, const + uint8_t *KEY) + -- Function: void aes128_set_decrypt_key (struct aes128_ctx *CTX, const + uint8_t *KEY) + -- Function: void aes192_set_encrypt_key (struct aes192_ctx *CTX, const + uint8_t *KEY) + -- Function: void aes192_set_decrypt_key (struct aes192_ctx *CTX, const + uint8_t *KEY) + -- Function: void aes256_set_encrypt_key (struct aes256_ctx *CTX, const + uint8_t *KEY) + -- Function: void aes256_set_decrypt_key (struct aes256_ctx *CTX, const + uint8_t *KEY) + -- Function: void aes_set_encrypt_key (struct aes_ctx *CTX, size_t + LENGTH, const uint8_t *KEY) + -- Function: void aes_set_decrypt_key (struct aes_ctx *CTX, size_t + LENGTH, const uint8_t *KEY) + Initialize the cipher, for encryption or decryption, respectively. + + -- Function: void aes128_invert_key (struct aes128_ctx *DST, const + struct aes128_ctx *SRC) + -- Function: void aes192_invert_key (struct aes192_ctx *DST, const + struct aes192_ctx *SRC) + -- Function: void aes256_invert_key (struct aes256_ctx *DST, const + struct aes256_ctx *SRC) + -- 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. These functions are mainly useful for applications which + needs to both encrypt and decrypt using the _same_ key, because + calling, e.g., ‘aes128_set_encrypt_key’ and ‘aes128_invert_key’, is + more efficient than calling ‘aes128_set_encrypt_key’ and + ‘aes128_set_decrypt_key’. + + -- Function: void aes128_encrypt (struct aes128_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void aes192_encrypt (struct aes192_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void aes256_encrypt (struct aes256_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void aes_encrypt (struct aes_ctx *CTX, size_t LENGTH, + uint8_t *DST, const 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 aes128_decrypt (struct aes128_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void aes192_decrypt (struct aes192_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void aes256_decrypt (struct aes256_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void aes_decrypt (struct aes_ctx *CTX, size_t LENGTH, + uint8_t *DST, const uint8_t *SRC) + Analogous to the encryption functions above. + +6.2.2 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, + size_t 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, size_t + 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, size_t + LENGTH, uint8_t *DST, const 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. + +6.2.3 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 ARCTWO 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, size_t + LENGTH, const uint8_t *KEY, unsigned EKB) + -- Function: void arctwo_set_key (struct arctwo_ctx *CTX, size_t + LENGTH, const uint8_t *KEY) + -- Function: void arctwo_set_key_gutmann (struct arctwo_ctx *CTX, + size_t 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, size_t + LENGTH, uint8_t *DST, const 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, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Analogous to ‘arctwo_encrypt’ + +6.2.4 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, size_t + 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, size_t + LENGTH, uint8_t *DST, const 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, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Analogous to ‘blowfish_encrypt’ + +6.2.5 Camellia +-------------- + +Camellia is a block cipher developed by Mitsubishi and Nippon Telegraph +and Telephone Corporation, described in ‘RFC3713’. It is recommended by +some Japanese and European authorities as an alternative to AES, and it +is one of the selected algorithms in the New European Schemes for +Signatures, Integrity and Encryption (NESSIE) project. 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. The variants with 192 and 256 bit keys are identical, +except for the key setup. Nettle defines Camellia in +‘’, and there is one context struct for each key +size. (Earlier versions of Nettle used a single context struct, ‘struct +camellia_ctx’, for all key sizes. This interface kept for backwards +compatibility). + + -- Context struct: struct camellia128_ctx + -- Context struct: struct camellia192_ctx + -- Context struct: struct camellia256_ctx + Contexts structs. Actually, ‘camellia192_ctx’ is an alias for + ‘camellia256_ctx’. + + -- Context struct: struct camellia_ctx + Alternative struct, for the old Camellia interface. + + -- Constant: CAMELLIA_BLOCK_SIZE + The CAMELLIA block-size, 16. + + -- Constant: CAMELLIA128_KEY_SIZE + -- Constant: CAMELLIA192_KEY_SIZE + -- Constant: CAMELLIA256_KEY_SIZE + -- Constant: CAMELLIA_MIN_KEY_SIZE + -- Constant: CAMELLIA_MAX_KEY_SIZE + + -- Constant: CAMELLIA_KEY_SIZE + Default CAMELLIA key size, 32. + + -- Function: void camellia128_set_encrypt_key (struct camellia128_ctx + *CTX, const uint8_t *KEY) + -- Function: void camellia128_set_decrypt_key (struct camellia128_ctx + *CTX, const uint8_t *KEY) + -- Function: void camellia192_set_encrypt_key (struct camellia192_ctx + *CTX, const uint8_t *KEY) + -- Function: void camellia192_set_decrypt_key (struct camellia192_ctx + *CTX, const uint8_t *KEY) + -- Function: void camellia256_set_encrypt_key (struct camellia256_ctx + *CTX, const uint8_t *KEY) + -- Function: void camellia256_set_decrypt_key (struct camellia256_ctx + *CTX, const uint8_t *KEY) + -- Function: void camellia_set_encrypt_key (struct camellia_ctx *CTX, + size_t LENGTH, const uint8_t *KEY) + -- Function: void camellia_set_decrypt_key (struct camellia_ctx *CTX, + size_t LENGTH, const uint8_t *KEY) + Initialize the cipher, for encryption or decryption, respectively. + + -- Function: void camellia128_invert_key (struct camellia128_ctx *DST, + const struct camellia128_ctx *SRC) + -- Function: void camellia192_invert_key (struct camellia192_ctx *DST, + const struct camellia192_ctx *SRC) + -- Function: void camellia256_invert_key (struct camellia256_ctx *DST, + const struct camellia256_ctx *SRC) + -- 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. These functions are mainly useful for applications which + needs to both encrypt and decrypt using the _same_ key. + + -- Function: void camellia128_crypt (struct camellia128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void camellia192_crypt (struct camellia192_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void camellia256_crypt (struct camellia256_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void camellia_crypt (struct camellia_ctx *CTX, size_t + LENGTH, uint8_t *DST, const 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. + +6.2.6 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, size_t + 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, size_t + LENGTH, uint8_t *DST, const 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, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Analogous to ‘cast128_encrypt’ + +6.2.7 ChaCha +------------ + +ChaCha is a variant of the stream cipher Salsa20, also designed by D. J. +Bernstein. For more information on Salsa20, see below. Nettle defines +ChaCha in ‘’. + + -- Context struct: struct chacha_ctx + + -- Constant: CHACHA_KEY_SIZE + ChaCha key size, 32. + + -- Constant: CHACHA_BLOCK_SIZE + ChaCha block size, 64. + + -- Constant: CHACHA_NONCE_SIZE + Size of the nonce, 8. + + -- Function: void chacha_set_key (struct chacha_ctx *CTX, const uint8_t + *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. Before using the cipher, you _must_ + also call ‘chacha_set_nonce’, see below. + + -- Function: void chacha_set_nonce (struct chacha_ctx *CTX, const + uint8_t *NONCE) + Sets the nonce. It is always of size ‘CHACHA_NONCE_SIZE’, 8 + octets. This function also initializes the block counter, setting + it to zero. + + -- Function: void chacha_crypt (struct chacha_ctx *CTX, size_t LENGTH, + uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message, using ChaCha. When a + message is encrypted using a sequence of calls to ‘chacha_crypt’, + all but the last call _must_ use a length that is a multiple of + ‘CHACHA_BLOCK_SIZE’. + +6.2.8 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, size_t LENGTH, + uint8_t *DST, const 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, size_t LENGTH, + uint8_t *DST, const uint8_t *SRC) + Analogous to ‘des_encrypt’ + + -- Function: int des_check_parity (size_t 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 (size_t 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. + +6.2.9 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, size_t LENGTH, + uint8_t *DST, const 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, size_t LENGTH, + uint8_t *DST, const uint8_t *SRC) + Analogous to ‘des_encrypt’ + +6.2.10 Salsa20 +-------------- + +Salsa20 is a fairly recent stream cipher designed by D. J. Bernstein. +It is built on the observation that a cryptographic hash function can be +used for encryption: Form the hash input from the secret key and a +counter, xor the hash output and the first block of the plaintext, then +increment the counter to process the next block (similar to CTR mode, +see *note CTR::). Bernstein defined an encryption algorithm, Snuffle, +in this way to ridicule United States export restrictions which treated +hash functions as nice and harmless, but ciphers as dangerous munitions. + + Salsa20 uses the same idea, but with a new specialized hash function +to mix key, block counter, and a couple of constants. It’s also +designed for speed; on x86_64, it is currently the fastest cipher +offered by nettle. It uses a block size of 512 bits (64 octets) and +there are two specified key sizes, 128 and 256 bits (16 and 32 octets). + + *Caution:* The hash function used in Salsa20 is _not_ directly +applicable for use as a general hash function. It’s _not_ collision +resistant if arbitrary inputs are allowed, and furthermore, the input +and output is of fixed size. + + When using Salsa20 to process a message, one specifies both a key and +a “nonce”, the latter playing a similar rôle to the initialization +vector (IV) used with CBC or CTR mode. One can use the same key for +several messages, provided one uses a unique random iv for each message. +The iv is 64 bits (8 octets). The block counter is initialized to zero +for each message, and is also 64 bits (8 octets). Nettle defines +Salsa20 in ‘’. + + -- Context struct: struct salsa20_ctx + + -- Constant: SALSA20_128_KEY_SIZE + -- Constant: SALSA20_256_KEY_SIZE + The two supported key sizes, 16 and 32 octets. + + -- Constant: SALSA20_KEY_SIZE + Recommended key size, 32. + + -- Constant: SALSA20_BLOCK_SIZE + Salsa20 block size, 64. + + -- Constant: SALSA20_NONCE_SIZE + Size of the nonce, 8. + + -- Function: void salsa20_128_set_key (struct salsa20_ctx *CTX, const + uint8_t *KEY) + -- Function: void salsa20_256_set_key (struct salsa20_ctx *CTX, const + uint8_t *KEY) + -- Function: void salsa20_set_key (struct salsa20_ctx *CTX, size_t + LENGTH, const uint8_t *KEY) + Initialize the cipher. The same function is used for both + encryption and decryption. ‘salsa20_128_set_key’ and + ‘salsa20_128_set_key’ use a fix key size each, 16 and 32 octets, + respectively. The function ‘salsa20_set_key’ is provided for + backwards compatibility, and the LENGTH argument must be either 16 + or 32. Before using the cipher, you _must_ also call + ‘salsa20_set_nonce’, see below. + + -- Function: void salsa20_set_nonce (struct salsa20_ctx *CTX, const + uint8_t *NONCE) + Sets the nonce. It is always of size ‘SALSA20_NONCE_SIZE’, 8 + octets. This function also initializes the block counter, setting + it to zero. + + -- Function: void salsa20_crypt (struct salsa20_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message, using salsa20. When a + message is encrypted using a sequence of calls to ‘salsa20_crypt’, + all but the last call _must_ use a length that is a multiple of + ‘SALSA20_BLOCK_SIZE’. + + The full salsa20 cipher uses 20 rounds of mixing. Variants of +Salsa20 with fewer rounds are possible, and the 12-round variant is +specified by eSTREAM, see +. Nettle calls this +variant ‘salsa20r12’. It uses the same context struct and key setup as +the full salsa20 cipher, but a separate function for encryption and +decryption. + + -- Function: void salsa20r12_crypt (struct salsa20_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message, using salsa20 reduced + to 12 rounds. + +6.2.11 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, size_t + 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, size_t + LENGTH, uint8_t *DST, const 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, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Analogous to ‘serpent_encrypt’ + +6.2.12 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, size_t + 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, size_t + LENGTH, uint8_t *DST, const 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, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Analogous to ‘twofish_encrypt’ + +6.2.13 The ‘struct nettle_cipher’ abstraction +--------------------------------------------- + +Nettle includes a struct including information about some of the more +regular cipher functions. It 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_cipher_func *’. The first + argument to these functions is a ‘const 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 + Nettle includes such structs for all the _regular_ ciphers, i.e. + ones without weak keys or other oddities. + + Nettle also exports a list of all these ciphers without weak keys or +other oddities. + + -- Function: const struct nettle_cipher **nettle_get_ciphers(void) + Returns a NULL-terminated list of pointers to supported block + ciphers. This list can be used to dynamically enumerate or search + the supported algorithms. + + -- Macro: nettle_ciphers + A macro expanding to a call to nettle_get_ciphers. In earlier + versions, this was not a macro but the actual array of pointers. + + +File: nettle.info, Node: Cipher modes, Next: Authenticated encryption, Prev: Cipher functions, Up: Reference + +6.3 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 several other modes of operation: Cipher +Block Chaining (CBC), Counter mode (CTR), Cipher Feedback (CFB) and a +couple of AEAD modes (*note Authenticated encryption::). CBC is widely +used, but there are a few subtle issues of information leakage, see, +e.g., SSH CBC vulnerability (http://www.kb.cert.org/vuls/id/958563). +Today, CTR is usually preferred over CBC. + + Modes like CBC, CTR and CFB provide _no_ message authentication, and +should always be used together with a MAC (*note Keyed hash functions::) +or signature to authenticate the message. + +* Menu: + +* CBC:: +* CTR:: +* CFB:: + + +File: nettle.info, Node: CBC, Next: CTR, Prev: Cipher modes, Up: Cipher modes + +6.3.1 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 (const void *CTX, nettle_cipher_func *F, + size_t BLOCK_SIZE, uint8_t *IV, size_t LENGTH, uint8_t *DST, + const uint8_t *SRC) + -- Function: void cbc_decrypt (const void *CTX, nettle_cipher_func *F, + size_t BLOCK_SIZE, uint8_t *IV, size_t 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 a large message can be processed by a sequence + of calls to ‘cbc_encrypt’. The function F is of type + + ‘void f (void *CTX, size_t 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 to + { + 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. + + +File: nettle.info, Node: CTR, Next: CFB, Prev: CBC, Up: Cipher modes + +6.3.2 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 rôle +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 (const void *CTX, nettle_cipher_func *F, + size_t BLOCK_SIZE, uint8_t *CTR, size_t 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 to + { + 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: CFB, Prev: CTR, Up: Cipher modes + +6.3.3 Cipher Feedback mode +-------------------------- + +Cipher Feedback mode (CFB) being a close relative to both CBC mode and +CTR mode borrows some characteristics from stream ciphers. + + 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, ‘IV’ is the +initialization vector, then the ‘n’ plaintext blocks 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-1) = E_k(C_(n - 2)) XOR M_(n-1) + C_n = E_k(C_(n - 1)) [1..m] XOR M_n + + Nettle’s includes two functions for applying a block cipher in Cipher +Feedback (CFB) mode, one for encryption and one for decryption. These +functions uses ‘void *’ to pass cipher contexts around. + + -- Function: void cfb_encrypt (const void *CTX, nettle_cipher_func *F, + size_t BLOCK_SIZE, uint8_t *IV, size_t LENGTH, uint8_t *DST, + const uint8_t *SRC) + -- Function: void cfb_decrypt (const void *CTX, nettle_cipher_func *F, + size_t BLOCK_SIZE, uint8_t *IV, size_t LENGTH, uint8_t *DST, + const uint8_t *SRC) + + Applies the encryption or decryption function F in CFB mode. The + final ciphertext block processed is copied into IV before + returning, so that a large message can be processed by a sequence + of calls to ‘cfb_encrypt’. Note that for CFB mode internally uses + encryption only function 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 + ‘cfb_encrypt’, 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: CFB_CTX (CONTEXT_TYPE, BLOCK_SIZE) + Expands to + { + context_type ctx; + uint8_t iv[block_size]; + } + + -- Macro: CFB_SET_IV(CTX, IV) + First argument is a pointer to a context struct as defined by + ‘CFB_CTX’, and the second is a pointer to an initialization vector + that is copied into that context. + + -- Macro: CFB_ENCRYPT (CTX, F, LENGTH, DST, SRC) + A simpler way to invoke ‘cfb_encrypt’. The first argument is a + pointer to a context struct as defined by ‘CFB_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. + + -- Macro: CFB_DECRYPT (CTX, F, LENGTH, DST, SRC) + A simpler way to invoke ‘cfb_decrypt’. The first argument is a + pointer to a context struct as defined by ‘CFB_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: Authenticated encryption, Next: Keyed hash functions, Prev: Cipher modes, Up: Reference + +6.4 Authenticated encryption with associated data +================================================= + +Since there are some subtle design choices to be made when combining a +block cipher mode with out authentication with a MAC. In recent years, +several constructions that combine encryption and authentication have +been defined. These constructions typically also have an additional +input, the “associated data”, which is authenticated but not included +with the message. A simple example is an implicit message number which +is available at both sender and receiver, and which needs authentication +in order to detect deletions or replay of messages. This family of +building blocks are therefore called AEAD, Authenticated encryption with +associated data. + + The aim is to provide building blocks that it is easier for designers +of protocols and applications to use correctly. There is also some +potential for improved performance, if encryption and authentication can +be done in a single step, although that potential is not realized for +the constructions currently supported by Nettle. + + For encryption, the inputs are: + + • The key, which can be used for many messages. + • A nonce, which must be unique for each message using the same key. + • Additional associated data to be authenticated, but not included in + the message. + • The cleartext message to be encrypted. + + The outputs are: + + • The ciphertext, of the same size as the cleartext. + • A digest or “authentication tag”. + + Decryption works the same, but with cleartext and ciphertext +interchanged. All currently supported AEAD algorithms always use the +encryption function of the underlying block cipher, for both encryption +and decryption. + + Usually, the authentication tag should be appended at the end of the +ciphertext, producing an encrypted message which is slightly longer than +the cleartext. However, Nettle’s low level AEAD functions produce the +authentication tag as a separate output for both encryption and +decryption. + + Both associated data and the message data (cleartext or ciphertext) +can be processed incrementally. In general, all associated data must be +processed before the message data, and all calls but the last one must +use a length that is a multiple of the block size, although some AEAD +may implement more liberal conventions. The CCM mode is a bit special +in that it requires the message lengths up front, other AEAD +constructions don’t have this restriction. + + The supported AEAD constructions are Galois/Counter mode (GCM), EAX, +ChaCha-Poly1305, and Counter with CBC-MAC (CCM). There are some +weaknesses in GCM authentication, see +. +CCM and EAX use the same building blocks, but the EAX design is cleaner +and avoids a couple of inconveniences of CCM. Therefore, EAX seems like +a good conservative choice. The more recent ChaCha-Poly1305 may also be +an attractive but more adventurous alternative, in particular if +performance is important. + +* Menu: + +* EAX:: +* GCM:: +* CCM:: +* ChaCha-Poly1305:: +* nettle_aead abstraction:: + + +File: nettle.info, Node: EAX, Next: GCM, Prev: Authenticated encryption, Up: Authenticated encryption + +6.4.1 EAX +--------- + +The EAX mode is an AEAD mode whichcombines CTR mode encryption, *Note +CTR::, with a message authentication based on CBC, *Note CBC::. The +implementation in Nettle is restricted to ciphers with a block size of +128 bits (16 octets). EAX was defined as a reaction to the CCM mode, +*Note CCM::, which uses the same primitives but has some undesirable and +inelegant properties. + + EAX supports arbitrary nonce size; it’s even possible to use an empty +nonce in case only a single message is encrypted for each key. + + Nettle’s support for EAX consists of a low-level general interface, +some convenience macros, and specific functions for EAX using AES-128 as +the underlying cipher. These interfaces are defined in ‘’ + +6.4.1.1 General EAX interface +............................. + + -- Context struct: struct eax_key + EAX state which depends only on the key, but not on the nonce or + the message. + + -- Context struct: struct eax_ctx + Holds state corresponding to a particular message. + + -- Constant: EAX_BLOCK_SIZE + EAX’s block size, 16. + + -- Constant: EAX_DIGEST_SIZE + Size of the EAX digest, also 16. + + -- Function: void eax_set_key (struct eax_key *KEY, const void *CIPHER, + nettle_cipher_func *F) + Initializes KEY. CIPHER gives a context struct for the underlying + cipher, which must have been previously initialized for encryption, + and F is the encryption function. + + -- Function: void eax_set_nonce (struct eax_ctx *EAX, const struct + eax_key *KEY, const void *CIPHER, nettle_cipher_func *F, + size_t NONCE_LENGTH, const uint8_t *NONCE) + Initializes CTX for processing a new message, using the given + nonce. + + -- Function: void eax_update (struct eax_ctx *EAX, const struct eax_key + *KEY, const void *CIPHER, nettle_cipher_func *F, size_t + DATA_LENGTH, const uint8_t *DATA) + Process associated data for authentication. All but the last call + for each message _must_ use a length that is a multiple of the + block size. Unlike many other AEAD constructions, for EAX it’s not + necessary to complete the processing of all associated data before + encrypting or decrypting the message data. + + -- Function: void eax_encrypt (struct eax_ctx *EAX, const struct + eax_key *KEY, const void *CIPHER, nettle_cipher_func *F, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void eax_decrypt (struct eax_ctx *EAX, const struct + eax_key *KEY, const void *CIPHER, nettle_cipher_func *F, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message. CIPHER is the context + struct for the underlying cipher and F is the encryption function. + All but the last call for each message _must_ use a length that is + a multiple of the block size. + + -- Function: void eax_digest (struct eax_ctx *EAX, const struct eax_key + *KEY, const void *CIPHER, nettle_cipher_func *F, size_t + LENGTH, uint8_t *DIGEST); + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. If LENGTH + is smaller than ‘EAX_DIGEST_SIZE’, only the first LENGTH octets of + the digest are written. + +6.4.1.2 EAX helper macros +......................... + +The following macros are defined. + + -- Macro: EAX_CTX (CONTEXT_TYPE) + This defines an all-in-one context struct, including the context of + the underlying cipher and all EAX state. It expands to + { + struct eax_key key; + struct eax_ctx eax; + context_type cipher; + } + + For all these macros, CTX, is a context struct as defined by +‘EAX_CTX’, and ENCRYPT is the encryption function of the underlying +cipher. + + -- Macro: EAX_SET_KEY (CTX, SET_KEY, ENCRYPT, KEY) + SET_KEY is the function for setting the encryption key for the + underlying cipher, and KEY is the key. + + -- Macro: EAX_SET_NONCE (CTX, ENCRYPT, LENGTH, NONCE) + Sets the nonce to be used for the message. + + -- Macro: EAX_UPDATE (CTX, ENCRYPT, LENGTH, DATA) + Process associated data for authentication. + + -- Macro: EAX_ENCRYPT (CTX, ENCRYPT, LENGTH, DST, SRC) + -- Macro: EAX_DECRYPT (CTX, ENCRYPT, LENGTH, DST, SRC) + Process message data for encryption or decryption. + + -- Macro: EAX_DIGEST (CTX, ENCRYPT, LENGTH, DIGEST) + Extract te authentication tag for the message. + +6.4.1.3 EAX-AES128 interface +............................ + +The following functions implement EAX using AES-128 as the underlying +cipher. + + -- Context struct: struct eax_aes128_ctx + The context struct, defined using ‘EAX_CTX’. + + -- Function: void eax_aes128_set_key (struct eax_aes128_ctx *CTX, const + uint8_t *KEY) + Initializes CTX using the given key. + + -- Function: void eax_aes128_set_nonce (struct eax_aes128_ctx *CTX, + size_t LENGTH, const uint8_t *IV) + Initializes the per-message state, using the given nonce. + + -- Function: void eax_aes128_update (struct eax_aes128_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Process associated data for authentication. All but the last call + for each message _must_ use a length that is a multiple of the + block size. + + -- Function: void eax_aes128_encrypt (struct eax_aes128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void eax_aes128_decrypt (struct eax_aes128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message. All but the last call + for each message _must_ use a length that is a multiple of the + block size. + + -- Function: void eax_aes128_digest (struct eax_aes128_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST); + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. If LENGTH + is smaller than ‘EAX_DIGEST_SIZE’, only the first LENGTH octets of + the digest are written. + + +File: nettle.info, Node: GCM, Next: CCM, Prev: EAX, Up: Authenticated encryption + +6.4.2 Galois counter mode +------------------------- + +Galois counter mode is an AEAD constructions combining counter mode with +message authentication based on universal hashing. The main objective +of the design is to provide high performance for hardware +implementations, where other popular MAC algorithms (*note Keyed hash +functions::) become a bottleneck for high-speed hardware +implementations. It was proposed by David A. McGrew and John Viega in +2005, and recommended by NIST in 2007, NIST Special Publication 800-38D +(http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf). It +is constructed on top of a block cipher which must have a block size of +128 bits. + + The authentication in GCM has some known weaknesses, see +. +In particular, don’t use GCM with short authentication tags. + + Nettle’s support for GCM consists of a low-level general interface, +some convenience macros, and specific functions for GCM using AES or +Camellia as the underlying cipher. These interfaces are defined in +‘’ + +6.4.2.1 General GCM interface +............................. + + -- Context struct: struct gcm_key + Message independent hash sub-key, and related tables. + + -- Context struct: struct gcm_ctx + Holds state corresponding to a particular message. + + -- Constant: GCM_BLOCK_SIZE + GCM’s block size, 16. + + -- Constant: GCM_DIGEST_SIZE + Size of the GCM digest, also 16. + + -- Constant: GCM_IV_SIZE + Recommended size of the IV, 12. Arbitrary sizes are allowed. + + -- Function: void gcm_set_key (struct gcm_key *KEY, const void *CIPHER, + nettle_cipher_func *F) + Initializes KEY. CIPHER gives a context struct for the underlying + cipher, which must have been previously initialized for encryption, + and F is the encryption function. + + -- Function: void gcm_set_iv (struct gcm_ctx *CTX, const struct gcm_key + *KEY, size_t LENGTH, const uint8_t *IV) + Initializes CTX using the given IV. The KEY argument is actually + needed only if LENGTH differs from ‘GCM_IV_SIZE’. + + -- Function: void gcm_update (struct gcm_ctx *CTX, const struct gcm_key + *KEY, size_t LENGTH, const uint8_t *DATA) + Provides associated data to be authenticated. If used, must be + called before ‘gcm_encrypt’ or ‘gcm_decrypt’. All but the last + call for each message _must_ use a length that is a multiple of the + block size. + + -- Function: void gcm_encrypt (struct gcm_ctx *CTX, const struct + gcm_key *KEY, const void *CIPHER, nettle_cipher_func *F, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_decrypt (struct gcm_ctx *CTX, const struct + gcm_key *KEY, const void *CIPHER, nettle_cipher_func *F, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message. CIPHER is the context + struct for the underlying cipher and F is the encryption function. + All but the last call for each message _must_ use a length that is + a multiple of the block size. + + -- Function: void gcm_digest (struct gcm_ctx *CTX, const struct gcm_key + *KEY, const void *CIPHER, nettle_cipher_func *F, size_t + LENGTH, uint8_t *DIGEST) + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. It’s + strongly recommended that LENGTH is ‘GCM_DIGEST_SIZE’, but if you + provide a smaller value, only the first LENGTH octets of the digest + are written. + + To encrypt a message using GCM, first initialize a context for the +underlying block cipher with a key to use for encryption. Then call the +above functions in the following order: ‘gcm_set_key’, ‘gcm_set_iv’, +‘gcm_update’, ‘gcm_encrypt’, ‘gcm_digest’. The decryption procedure is +analogous, just calling ‘gcm_decrypt’ instead of ‘gcm_encrypt’ (note +that GCM decryption still uses the encryption function of the underlying +block cipher). To process a new message, using the same key, call +‘gcm_set_iv’ with a new iv. + +6.4.2.2 GCM helper macros +......................... + +The following macros are defined. + + -- Macro: GCM_CTX (CONTEXT_TYPE) + This defines an all-in-one context struct, including the context of + the underlying cipher, the hash sub-key, and the per-message state. + It expands to + { + struct gcm_key key; + struct gcm_ctx gcm; + context_type cipher; + } + + Example use: + struct gcm_aes128_ctx GCM_CTX(struct aes128_ctx); + + The following macros operate on context structs of this form. + + -- Macro: GCM_SET_KEY (CTX, SET_KEY, ENCRYPT, KEY) + First argument, CTX, is a context struct as defined by ‘GCM_CTX’. + SET_KEY and ENCRYPT are functions for setting the encryption key + and for encrypting data using the underlying cipher. + + -- Macro: GCM_SET_IV (CTX, LENGTH, DATA) + First argument is a context struct as defined by ‘GCM_CTX’. LENGTH + and DATA give the initialization vector (IV). + + -- Macro: GCM_UPDATE (CTX, LENGTH, DATA) + Simpler way to call ‘gcm_update’. First argument is a context + struct as defined by ‘GCM_CTX’ + + -- Macro: GCM_ENCRYPT (CTX, ENCRYPT, LENGTH, DST, SRC) + -- Macro: GCM_DECRYPT (CTX, ENCRYPT, LENGTH, DST, SRC) + -- Macro: GCM_DIGEST (CTX, ENCRYPT, LENGTH, DIGEST) + Simpler way to call ‘gcm_encrypt’, ‘gcm_decrypt’ or ‘gcm_digest’. + First argument is a context struct as defined by ‘GCM_CTX’. Second + argument, ENCRYPT, is the encryption function of the underlying + cipher. + +6.4.2.3 GCM-AES interface +......................... + +The following functions implement the common case of GCM using AES as +the underlying cipher. The variants with a specific AES flavor are +recommended, while the fucntinos using ‘struct gcm_aes_ctx’ are kept for +compatibility with older versiosn of Nettle. + + -- Context struct: struct gcm_aes128_ctx + -- Context struct: struct gcm_aes192_ctx + -- Context struct: struct gcm_aes256_ctx + Context structs, defined using ‘GCM_CTX’. + + -- Context struct: struct gcm_aes_ctx + Alternative context struct, usign the old AES interface. + + -- Function: void gcm_aes128_set_key (struct gcm_aes128_ctx *CTX, const + uint8_t *KEY) + -- Function: void gcm_aes192_set_key (struct gcm_aes192_ctx *CTX, const + uint8_t *KEY) + -- Function: void gcm_aes256_set_key (struct gcm_aes256_ctx *CTX, const + uint8_t *KEY) + Initializes CTX using the given key. + + -- Function: void gcm_aes_set_key (struct gcm_aes_ctx *CTX, size_t + LENGTH, const uint8_t *KEY) + Corresponding function, using the old AES interface. All valid AES + key sizes can be used. + + -- Function: void gcm_aes128_set_iv (struct gcm_aes128_ctx *CTX, size_t + LENGTH, const uint8_t *IV) + -- Function: void gcm_aes192_set_iv (struct gcm_aes192_ctx *CTX, size_t + LENGTH, const uint8_t *IV) + -- Function: void gcm_aes256_set_iv (struct gcm_aes256_ctx *CTX, size_t + LENGTH, const uint8_t *IV) + -- Function: void gcm_aes_set_iv (struct gcm_aes_ctx *CTX, size_t + LENGTH, const uint8_t *IV) + Initializes the per-message state, using the given IV. + + -- Function: void gcm_aes128_update (struct gcm_aes128_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void gcm_aes192_update (struct gcm_aes192_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void gcm_aes256_update (struct gcm_aes256_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void gcm_aes_update (struct gcm_aes_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Provides associated data to be authenticated. If used, must be + called before ‘gcm_aes_encrypt’ or ‘gcm_aes_decrypt’. All but the + last call for each message _must_ use a length that is a multiple + of the block size. + + -- Function: void gcm_aes128_encrypt (struct gcm_aes128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes192_encrypt (struct gcm_aes192_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes256_encrypt (struct gcm_aes256_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes_encrypt (struct gcm_aes_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes128_decrypt (struct gcm_aes128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes192_decrypt (struct gcm_aes192_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes256_decrypt (struct gcm_aes256_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_aes_decrypt (struct gcm_aes_ctx *CTX, size_t + LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message. All but the last call + for each message _must_ use a length that is a multiple of the + block size. + + -- Function: void gcm_aes128_digest (struct gcm_aes128_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void gcm_aes192_digest (struct gcm_aes192_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void gcm_aes256_digest (struct gcm_aes256_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void gcm_aes_digest (struct gcm_aes_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. It’s + strongly recommended that LENGTH is ‘GCM_DIGEST_SIZE’, but if you + provide a smaller value, only the first LENGTH octets of the digest + are written. + +6.4.2.4 GCM-Camellia interface +.............................. + +The following functions implement the case of GCM using Camellia as the +underlying cipher. + + -- Context struct: struct gcm_camellia128_ctx + -- Context struct: struct gcm_camellia256_ctx + Context structs, defined using ‘GCM_CTX’. + + -- Function: void gcm_camellia128_set_key (struct gcm_camellia128_ctx + *CTX, const uint8_t *KEY) + -- Function: void gcm_camellia256_set_key (struct gcm_camellia256_ctx + *CTX, const uint8_t *KEY) + Initializes CTX using the given key. + + -- Function: void gcm_camellia128_set_iv (struct gcm_camellia128_ctx + *CTX, size_t LENGTH, const uint8_t *IV) + -- Function: void gcm_camellia256_set_iv (struct gcm_camellia256_ctx + *CTX, size_t LENGTH, const uint8_t *IV) + Initializes the per-message state, using the given IV. + + -- Function: void gcm_camellia128_update (struct gcm_camellia128_ctx + *CTX, size_t LENGTH, const uint8_t *DATA) + -- Function: void gcm_camellia256_update (struct gcm_camellia256_ctx + *CTX, size_t LENGTH, const uint8_t *DATA) + Provides associated data to be authenticated. If used, must be + called before ‘gcm_camellia_encrypt’ or ‘gcm_camellia_decrypt’. + All but the last call for each message _must_ use a length that is + a multiple of the block size. + + -- Function: void gcm_camellia128_encrypt (struct gcm_camellia128_ctx + *CTX, size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_camellia256_encrypt (struct gcm_camellia256_ctx + *CTX, size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_camellia128_decrypt (struct gcm_camellia128_ctx + *CTX, size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void gcm_camellia256_decrypt (struct gcm_camellia256_ctx + *CTX, size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message. All but the last call + for each message _must_ use a length that is a multiple of the + block size. + + -- Function: void gcm_camellia128_digest (struct gcm_camellia128_ctx + *CTX, size_t LENGTH, uint8_t *DIGEST) + -- Function: void gcm_camellia192_digest (struct gcm_camellia192_ctx + *CTX, size_t LENGTH, uint8_t *DIGEST) + -- Function: void gcm_camellia256_digest (struct gcm_camellia256_ctx + *CTX, size_t LENGTH, uint8_t *DIGEST) + -- Function: void gcm_camellia_digest (struct gcm_camellia_ctx *CTX, + size_t LENGTH, uint8_t *DIGEST) + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. It’s + strongly recommended that LENGTH is ‘GCM_DIGEST_SIZE’, but if you + provide a smaller value, only the first LENGTH octets of the digest + are written. + + +File: nettle.info, Node: CCM, Next: ChaCha-Poly1305, Prev: GCM, Up: Authenticated encryption + +6.4.3 Counter with CBC-MAC mode +------------------------------- + +CCM mode is a combination of counter mode with message authentication +based on cipher block chaining, the same building blocks as EAX, *note +EAX::. It is constructed on top of a block cipher which must have a +block size of 128 bits. CCM mode is recommended by NIST in NIST Special +Publication 800-38C +(http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf). +Nettle’s support for CCM consists of a low-level general interface, a +message encryption and authentication interface, and specific functions +for CCM using AES as the underlying block cipher. These interfaces are +defined in ‘’. + + In CCM, the length of the message must be known before processing. +The maximum message size depends on the size of the nonce, since the +message size is encoded in a field which must fit in a single block, +together with the nonce and a flag byte. E.g., with a nonce size of 12 +octets, there are three octets left for encoding the message length, the +maximum message length is 2^24 - 1 octets. + + CCM mode encryption operates as follows: + • The nonce and message length are concatenated to create ‘B_0 = + flags | nonce | mlength’ + + • The authenticated data and plaintext is formatted into the string + ‘B = L(adata) | adata | padding | plaintext | padding’ with + ‘padding’ being the shortest string of zero bytes such that the + length of the string is a multiple of the block size, and + ‘L(adata)’ is an encoding of the length of ‘adata’. + + • The string ‘B’ is separated into blocks ‘B_1’ ... ‘B_n’ + • The authentication tag ‘T’ is calculated as ‘T=0, for i=0 to n, do + T = E_k(B_i XOR T)’ + + • An initial counter is then initialized from the nonce to create ‘IC + = flags | nonce | padding’, where ‘padding’ is the shortest string + of zero bytes such that ‘IC’ is exactly one block in length. + + • The authentication tag is encrypted using using CTR mode: ‘MAC = + E_k(IC) XOR T’ + + • The plaintext is then encrypted using CTR mode with an initial + counter of ‘IC+1’. + + CCM mode decryption operates similarly, except that the ciphertext +and MAC are first decrypted using CTR mode to retreive the plaintext and +authentication tag. The authentication tag can then be recalucated from +the authenticated data and plantext, and compared to the value in the +message to check for authenticity. + +6.4.3.1 General CCM interface +............................. + +For all of the functions in the CCM interface, CIPHER is the context +struct for the underlying cipher and F is the encryption function. The +cipher’s encryption key must be set before calling any of the CCM +functions. The cipher’s decryption function and key are never used. + + -- Context struct: struct ccm_ctx + Holds state corresponding to a particular message. + + -- Constant: CCM_BLOCK_SIZE + CCM’s block size, 16. + + -- Constant: CCM_DIGEST_SIZE + Size of the CCM digest, 16. + + -- Constant: CCM_MIN_NONCE_SIZE + -- Constant: CCM_MAX_NONCE_SIZE + The the minimum and maximum sizes for an CCM nonce, 7 and 14, + respectively. + + -- Macro: CCM_MAX_MSG_SIZE (NONCE_SIZE) + The largest allowed plaintext length, when using CCM with a nonce + of the given size. + + -- Function: void ccm_set_nonce (struct ccm_ctx *CTX, const void + *CIPHER, nettle_cipher_func *F, size_t NONCELEN, const uint8_t + *NONCE, size_t AUTHLEN, size_t MSGLEN, size_t TAGLEN) + Initializes CTX using the given nonce and the sizes of the + authenticated data, message, and MAC to be processed. + + -- Function: void ccm_update (struct ccm_ctx *CTX, const void *CIPHER, + nettle_cipher_func *F, size_t LENGTH, const uint8_t *DATA) + Provides associated data to be authenticated. Must be called after + ‘ccm_set_nonce’, and before ‘ccm_encrypt’, ‘ccm_decrypt’, or + ‘ccm_digest’. + + -- Function: void ccm_encrypt (struct ccm_ctx *CTX, const void *CIPHER, + nettle_cipher_func *F, size_t LENGTH, uint8_t *DST, const + uint8_t *SRC) + -- Function: void ccm_decrypt (struct ccm_ctx *CTX, const void *CIPHER, + nettle_cipher_func *F, size_t LENGTH, uint8_t *DST, const + uint8_t *SRC) + Encrypts or decrypts the message data. Must be called after + ‘ccm_set_nonce’ and before ‘ccm_digest’. All but the last call for + each message _must_ use a length that is a multiple of the block + size. + + -- Function: void ccm_digest (struct ccm_ctx *CTX, const void *CIPHER, + nettle_cipher_func *F, size_t LENGTH, uint8_t *DIGEST) + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. LENGTH is + usually equal to the TAGLEN parameter supplied to ‘ccm_set_nonce’, + but if you provide a smaller value, only the first LENGTH octets of + the digest are written. + + To encrypt a message using the general CCM interface, set the message +nonce and length using ‘ccm_set_nonce’ and then call ‘ccm_update’ to +generate the digest of any authenticated data. After all of the +authenticated data has been digested use ‘ccm_encrypt’ to encrypt the +plaintext. Finally, use ‘ccm_digest’ to return the encrypted MAC. + + To decrypt a message, use ‘ccm_set_nonce’ and ‘ccm_update’ the same +as you would for encryption, and then call ‘ccm_decrypt’ to decrypt the +ciphertext. After decrypting the ciphertext ‘ccm_digest’ will return +the encrypted MAC which should be identical to the MAC in the received +message. + +6.4.3.2 CCM message interface +............................. + +The CCM message fuctions provides a simple interface that will perform +authentication and message encryption in a single function call. The +length of the cleartext is given by MLENGTH and the length of the +ciphertext is given by CLENGTH, always exactly TLENGTH bytes longer than +the corresponding plaintext. The length argument passed to a function +is always the size for the result, CLENGTH for the encryption functions, +and MLENGTH for the decryption functions. + + -- Function: void ccm_encrypt_message (void *CIPHER, nettle_cipher_func + *F, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t CLENGTH, uint8_t + *DST, const uint8_t *SRC) + Computes the message digest from the ADATA and SRC parameters, + encrypts the plaintext from SRC, appends the encrypted MAC to + ciphertext and outputs it to DST. + + -- Function: int ccm_decrypt_message (void *CIPHER, nettle_cipher_func + *F, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t MLENGTH, uint8_t + *DST, const uint8_t *SRC) + Decrypts the ciphertext from SRC, outputs the plaintext to DST, + recalculates the MAC from ADATA and the plaintext, and compares it + to the final TLENGTH bytes of SRC. If the values of the received + and calculated MACs are equal, this will return 1 indicating a + valid and authenticated message. Otherwise, this function will + return zero. + +6.4.3.3 CCM-AES interface +......................... + +The AES CCM functions provide an API for using CCM mode with the AES +block ciphers. The parameters all have the same meaning as the general +and message interfaces, except that the CIPHER, F, and CTX parameters +are replaced with an AES context structure, and a set-key function must +be called before using any of the other functions in this interface. + + -- Context struct: struct ccm_aes128_ctx + Holds state corresponding to a particular message encrypted using + the AES-128 block cipher. + + -- Context struct: struct ccm_aes192_ctx + Holds state corresponding to a particular message encrypted using + the AES-192 block cipher. + + -- Context struct: struct ccm_aes256_ctx + Holds state corresponding to a particular message encrypted using + the AES-256 block cipher. + + -- Function: void ccm_aes128_set_key (struct ccm_aes128_ctx *CTX, const + uint8_t *KEY) + -- Function: void ccm_aes192_set_key (struct ccm_aes192_ctx *CTX, const + uint8_t *KEY) + -- Function: void ccm_aes256_set_key (struct ccm_aes256_ctx *CTX, const + uint8_t *KEY) + Initializes the encryption key for the AES block cipher. One of + these functions must be called before any of the other functions in + the AES CCM interface. + + -- Function: void ccm_aes128_set_nonce (struct ccm_aes128_ctx *CTX, + size_t NONCELEN, const uint8_t *NONCE, size_t AUTHLEN, size_t + MSGLEN, size_t TAGLEN) + -- Function: void ccm_aes192_set_nonce (struct ccm_aes192_ctx *CTX, + size_t NONCELEN, const uint8_t *NONCE, size_t AUTHLEN, size_t + MSGLEN, size_t TAGLEN) + -- Function: void ccm_aes256_set_nonce (struct ccm_aes256_ctx *CTX, + size_t NONCELEN, const uint8_t *NONCE, size_t AUTHLEN, size_t + MSGLEN, size_t TAGLEN) + These are identical to ‘ccm_set_nonce’, except that CIPHER, F, and + CTX are replaced with a context structure. + + -- Function: void ccm_aes128_update (struct ccm_aes128_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void ccm_aes192_update (struct ccm_aes192_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + -- Function: void ccm_aes256_update (struct ccm_aes256_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + These are identical to ‘ccm_set_update’, except that CIPHER, F, and + CTX are replaced with a context structure. + + -- Function: void ccm_aes128_encrypt (struct ccm_aes128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void ccm_aes192_encrypt (struct ccm_aes192_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void ccm_aes256_encrypt (struct ccm_aes256_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void ccm_aes128_decrypt (struct ccm_aes128_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void ccm_aes192_decrypt (struct ccm_aes192_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void ccm_aes256_decrypt (struct ccm_aes256_ctx *CTX, + size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + These are identical to ‘ccm_set_encrypt’ and ‘ccm_set_decrypt’, + except that CIPHER, F, and CTX are replaced with a context + structure. + + -- Function: void ccm_aes128_digest (struct ccm_aes128_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void ccm_aes192_digest (struct ccm_aes192_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + -- Function: void ccm_aes256_digest (struct ccm_aes256_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + These are identical to ‘ccm_set_digest’, except that CIPHER, F, and + CTX are replaced with a context structure. + + -- Function: void ccm_aes128_encrypt_message (struct ccm_aes128_ctx + *CTX, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t CLENGTH, uint8_t + *DST, const uint8_t *SRC) + -- Function: void ccm_aes192_encrypt_message (struct ccm_aes192_ctx + *CTX, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t CLENGTH, uint8_t + *DST, const uint8_t *SRC) + -- Function: void ccm_aes256_encrypt_message (struct ccm_aes256_ctx + *CTX, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t CLENGTH, uint8_t + *DST, const uint8_t *SRC) + -- Function: int ccm_aes128_decrypt_message (struct ccm_aes128_ctx + *CTX, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t MLENGTH, uint8_t + *DST, const uint8_t *SRC) + -- Function: int ccm_aes192_decrypt_message (struct ccm_aes192_ctx + *CTX, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t MLENGTH, uint8_t + *DST, const uint8_t *SRC) + -- Function: int ccm_aes192_decrypt_message (struct ccm_aes256_ctx + *CTX, size_t NLENGTH, const uint8_t *NONCE, size_t ALENGTH, + const uint8_t *ADATA, size_t TLENGTH, size_t MLENGTH, uint8_t + *DST, const uint8_t *SRC) + These are identical to ‘ccm_encrypt_message’ and + ‘ccm_decrypt_message’ except that CIPHER and F are replaced with a + context structure. + + +File: nettle.info, Node: ChaCha-Poly1305, Next: nettle_aead abstraction, Prev: CCM, Up: Authenticated encryption + +6.4.4 ChaCha-Poly1305 +--------------------- + +ChaCha-Poly1305 is a combination of the ChaCha stream cipher and the +poly1305 message authentication code (*note Poly1305::). It originates +from the NaCl cryptographic library by D. J. Bernstein et al, which +defines a similar construction but with Salsa20 instead of ChaCha. + + Nettle’s implementation ChaCha-Poly1305 should be considered +*experimental*. At the time of this writing, there is no authoritative +specification for ChaCha-Poly1305, and a couple of different +incompatible variants. Nettle implements it using the original +definition of ChaCha, with 64 bits (8 octets) each for the nonce and the +block counter. Some protocols prefer to use nonces of 12 bytes, and +it’s a small change to ChaCha to use the upper 32 bits of the block +counter as a nonce, instead limiting message size to 2^32 blocks or 256 +GBytes, but that variant is currently not supported. + + For ChaCha-Poly1305, the ChaCha cipher is initialized with a key, of +256 bits, and a per-message nonce. The first block of the key stream +(counter all zero) is set aside for the authentication subkeys. Of this +64-octet block, the first 16 octets specify the poly1305 evaluation +point, and the next 16 bytes specify the value to add in for the final +digest. The final 32 bytes of this block are unused. Note that unlike +poly1305-aes, the evaluation point depends on the nonce. This is +preferable, because it leaks less information in case the attacker for +some reason is lucky enough to forge a valid authentication tag, and +observe (from the receiver’s behaviour) that the forgery succeeded. + + The ChaCha key stream, starting with counter value 1, is then used to +encrypt the message. For authentication, poly1305 is applied to the +concatenation of the associated data, the cryptotext, and the lengths of +the associated data and the message, each a 64-bit number (eight octets, +little-endian). Nettle defines ChaCha-Poly1305 in +‘’. + + -- Constant: CHACHA_POLY1305_BLOCK_SIZE + Same as the ChaCha block size, 64. + + -- Constant: CHACHA_POLY1305_KEY_SIZE + ChaCha-Poly1305 key size, 32. + + -- Constant: CHACHA_POLY1305_NONCE_SIZE + Same as the ChaCha nonce size, 16. + + -- Constant: CHACHA_POLY1305_DIGEST_SIZE + Digest size, 16. + + -- Context struct: struct chacha_poly1305_ctx + + -- Function: void chacha_poly1305_set_key (struct chacha_poly1305_ctx + *CTX, const uint8_t *KEY) + Initializes CTX using the given key. Before using the context, you + _must_ also call ‘chacha_poly1305_set_nonce’, see below. + + -- Function: void chacha_poly1305_set_nonce (struct chacha_poly1305_ctx + *CTX, const uint8_t *NONCE) + Initializes the per-message state, using the given nonce. + + -- Function: void chacha_poly1305_update (struct chacha_poly1305_ctx + *CTX, size_t LENGTH, const uint8_t *DATA) + Process associated data for authentication. + + -- Function: void chacha_poly1305_encrypt (struct chacha_poly1305_ctx + *CTX, size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + -- Function: void chacha_poly1305_decrypt (struct chacha_poly1305_ctx + *CTX, size_t LENGTH, uint8_t *DST, const uint8_t *SRC) + Encrypts or decrypts the data of a message. All but the last call + for each message _must_ use a length that is a multiple of the + block size. + + -- Function: void chacha_poly1305_digest (struct chacha_poly1305_ctx + *CTX, size_t LENGTH, uint8_t *DIGEST) + Extracts the message digest (also known “authentication tag”). + This is the final operation when processing a message. If LENGTH + is smaller than ‘CHACHA_POLY1305_DIGEST_SIZE’, only the first + LENGTH octets of the digest are written. + + +File: nettle.info, Node: nettle_aead abstraction, Prev: ChaCha-Poly1305, Up: Authenticated encryption + +6.4.5 The ‘struct nettle_aead’ abstraction +------------------------------------------ + +Nettle includes a struct including information about the supported hash +functions. It is defined in ‘’. + + -- Meta struct: ‘struct nettle_aead’ name context_size block_size + key_size nonce_size digest_size set_encrypt_key + set_decrypt_key set_nonce update encrypt decrypt digest + The last seven attributes are function pointers. + + -- Constant Struct: struct nettle_aead nettle_gcm_aes128 + -- Constant Struct: struct nettle_aead nettle_gcm_aes192 + -- Constant Struct: struct nettle_aead nettle_gcm_aes256 + -- Constant Struct: struct nettle_aead nettle_gcm_camellia128 + -- Constant Struct: struct nettle_aead nettle_gcm_camellia256 + -- Constant Struct: struct nettle_aead nettle_eax_aes128 + -- Constant Struct: struct nettle_aead nettle_chacha_poly1305 + These are most of the AEAD constructions that Nettle implements. + Note that CCM is missing; it requirement that the message size is + specified in advance makes it incompatible with the ‘nettle_aead’ + abstraction. + + Nettle also exports a list of all these constructions. + + -- Function: const struct nettle_aead **nettle_get_aeads(void) + Returns a NULL-terminated list of pointers to supported + algorithms.This list can be used to dynamically enumerate or search + the supported algorithms. + + -- Macro: nettle_aeads + A macro expanding to a call to nettle_get_aeads. In earlier + versions, this was not a macro but the actual array of pointers. + + +File: nettle.info, Node: Keyed hash functions, Next: Key derivation functions, Prev: Authenticated encryption, Up: Reference + +6.5 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. + +* Menu: + +* HMAC:: +* UMAC:: +* Poly1305:: + + +File: nettle.info, Node: HMAC, Next: UMAC, Prev: Keyed hash functions, Up: Keyed hash functions + +6.5.1 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-RIPEMD160 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, size_t 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, size_t 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, size_t 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 to + { + 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. + +6.5.2 Concrete HMAC functions +----------------------------- + +Now we come to the specialized HMAC functions, which are easier to use +than the general HMAC functions. + +6.5.2.1 HMAC-MD5 +................ + + -- Context struct: struct hmac_md5_ctx + + -- Function: void hmac_md5_set_key (struct hmac_md5_ctx *CTX, size_t + KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + -- Function: void hmac_md5_update (struct hmac_md5_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Process some more data. + + -- Function: void hmac_md5_digest (struct hmac_md5_ctx *CTX, size_t + 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. + +6.5.2.2 HMAC-RIPEMD160 +...................... + + -- Context struct: struct hmac_ripemd160_ctx + + -- Function: void hmac_ripemd160_set_key (struct hmac_ripemd160_ctx + *CTX, size_t KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + -- Function: void hmac_ripemd160_update (struct hmac_ripemd160_ctx + *CTX, size_t LENGTH, const uint8_t *DATA) + Process some more data. + + -- Function: void hmac_ripemd160_digest (struct hmac_ripemd160_ctx + *CTX, size_t LENGTH, uint8_t *DIGEST) + Extracts the MAC, writing it to DIGEST. LENGTH may be smaller than + ‘RIPEMD160_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. + +6.5.2.3 HMAC-SHA1 +................. + + -- Context struct: struct hmac_sha1_ctx + + -- Function: void hmac_sha1_set_key (struct hmac_sha1_ctx *CTX, size_t + KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + -- Function: void hmac_sha1_update (struct hmac_sha1_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + Process some more data. + + -- Function: void hmac_sha1_digest (struct hmac_sha1_ctx *CTX, size_t + 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. + +6.5.2.4 HMAC-SHA256 +................... + + -- Context struct: struct hmac_sha256_ctx + + -- Function: void hmac_sha256_set_key (struct hmac_sha256_ctx *CTX, + size_t KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + -- Function: void hmac_sha256_update (struct hmac_sha256_ctx *CTX, + size_t LENGTH, const uint8_t *DATA) + Process some more data. + + -- Function: void hmac_sha256_digest (struct hmac_sha256_ctx *CTX, + size_t 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. + +6.5.2.5 HMAC-SHA512 +................... + + -- Context struct: struct hmac_sha512_ctx + + -- Function: void hmac_sha512_set_key (struct hmac_sha512_ctx *CTX, + size_t KEY_LENGTH, const uint8_t *KEY) + Initializes the context with the key. + + -- Function: void hmac_sha512_update (struct hmac_sha512_ctx *CTX, + size_t LENGTH, const uint8_t *DATA) + Process some more data. + + -- Function: void hmac_sha512_digest (struct hmac_sha512_ctx *CTX, + size_t 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: UMAC, Next: Poly1305, Prev: HMAC, Up: Keyed hash functions + +6.5.3 UMAC +---------- + +UMAC is a message authentication code based on universal hashing, and +designed for high performance on modern processors (in contrast to GCM, +*Note GCM::, which is designed primarily for hardware performance). On +processors with good integer multiplication performance, it can be 10 +times faster than SHA256 and SHA512. UMAC is specified in ‘RFC 4418’. + + The secret key is always 128 bits (16 octets). The key is used as an +encryption key for the AES block cipher. This cipher is used in counter +mode to generate various internal subkeys needed in UMAC. Messages are +of arbitrary size, and for each message, UMAC also needs a unique nonce. +Nonce values must not be reused for two messages with the same key, but +they need not be kept secret. + + The nonce must be at least one octet, and at most 16; nonces shorter +than 16 octets are zero-padded. Nettle’s implementation of UMAC +increments the nonce automatically for each message, so explicitly +setting the nonce for each message is optional. This auto-increment +uses network byte order and it takes the length of the nonce into +account. E.g., if the initial nonce is “abc” (3 octets), this value is +zero-padded to 16 octets for the first message. For the next message, +the nonce is incremented to “abd”, and this incremented value is +zero-padded to 16 octets. + + UMAC is defined in four variants, for different output sizes: 32 bits +(4 octets), 64 bits (8 octets), 96 bits (12 octets) and 128 bits (16 +octets), corresponding to different trade-offs between speed and +security. Using a shorter output size sometimes (but not always!) +gives the same result as using a longer output size and truncating the +result. So it is important to use the right variant. For consistency +with other hash and MAC functions, Nettle’s ‘_digest’ functions for UMAC +accept a length parameter so that the output can be truncated to any +desired size, but it is recommended to stick to the specified output +size and select the umac variant corresponding to the desired size. + + The internal block size of UMAC is 1024 octets, and it also generates +more than 1024 bytes of subkeys. This makes the size of the context +struct quite a bit larger than other hash functions and MAC algorithms +in Nettle. + + Nettle defines UMAC in ‘’. + + -- Context struct: struct umac32_ctx + -- Context struct: struct umac64_ctx + -- Context struct: struct umac96_ctx + -- Context struct: struct umac128_ctx + Each UMAC variant uses its own context struct. + + -- Constant: UMAC_KEY_SIZE + The UMAC key size, 16. + -- Constant: UMAC_MIN_NONCE_SIZE + -- Constant: UMAC_MAX_NONCE_SIZE + The the minimum and maximum sizes for an UMAC nonce, 1 and 16, + respectively. + -- Constant: UMAC32_DIGEST_SIZE + The size of an UMAC32 digest, 4. + -- Constant: UMAC64_DIGEST_SIZE + The size of an UMAC64 digest, 8. + -- Constant: UMAC96_DIGEST_SIZE + The size of an UMAC96 digest, 12. + -- Constant: UMAC128_DIGEST_SIZE + The size of an UMAC128 digest, 16. + -- Constant: UMAC_BLOCK_SIZE + The internal block size of UMAC. + + -- Function: void umac32_set_key (struct umac32_ctx *CTX, const uint8_t + *KEY) + -- Function: void umac64_set_key (struct umac64_ctx *CTX, const uint8_t + *KEY) + -- Function: void umac96_set_key (struct umac96_ctx *CTX, const uint8_t + *KEY) + -- Function: void umac128_set_key (struct umac128_ctx *CTX, const + uint8_t *KEY) + These functions initialize the UMAC context struct. They also + initialize the nonce to zero (with length 16, for auto-increment). + + -- Function: void umac32_set_nonce (struct umac32_ctx *CTX, size_t + LENGTH, const uint8_t *NONCE) + -- Function: void umac64_set_nonce (struct umac64_ctx *CTX, size_t + LENGTH, const uint8_t *NONCE) + -- Function: void umac96_set_nonce (struct umac96_ctx *CTX, size_t + LENGTH, const uint8_t *NONCE) + -- Function: void umac128_set_nonce (struct umac128_ctx *CTX, size_t + LENGTH, const uint8_t *NONCE) + Sets the nonce to be used for the next message. In general, nonces + should be set before processing of the message. This is not + strictly required for UMAC (the nonce only affects the final + processing generating the digest), but it is nevertheless + recommended that this function is called _before_ the first + ‘_update’ call for the message. + + -- Function: void umac32_update (struct umac32_ctx *CTX, size_t LENGTH, + const uint8_t *DATA) + -- Function: void umac64_update (struct umac64_ctx *CTX, size_t LENGTH, + const uint8_t *DATA) + -- Function: void umac96_update (struct umac96_ctx *CTX, size_t LENGTH, + const uint8_t *DATA) + -- Function: void umac128_update (struct umac128_ctx *CTX, size_t + LENGTH, const uint8_t *DATA) + These functions are called zero or more times to process the + message. + + -- Function: void umac32_digest (struct umac32_ctx *CTX, size_t LENGTH, + uint8_t *DIGEST) + -- Function: void umac64_digest (struct umac64_ctx *CTX, size_t LENGTH, + uint8_t *DIGEST) + -- Function: void umac96_digest (struct umac96_ctx *CTX, size_t LENGTH, + uint8_t *DIGEST) + -- Function: void umac128_digest (struct umac128_ctx *CTX, size_t + LENGTH, uint8_t *DIGEST) + Extracts the MAC of the message, writing it to DIGEST. LENGTH is + usually equal to the specified output size, but if you provide a + smaller value, only the first LENGTH octets of the MAC are written. + These functions reset the context for processing of a new message + with the same key. The nonce is incremented as described above, + the new value is used unless you call the ‘_set_nonce’ function + explicitly for each message. + + +File: nettle.info, Node: Poly1305, Prev: UMAC, Up: Keyed hash functions + +6.5.4 Poly1305 +-------------- + +Poly1305-AES is a message authentication code designed by D. J. +Bernstein. It treats the message as a polynomial modulo the prime +number 2^130 - 5. + + The key, 256 bits, consists of two parts, where the first half is an +AES-128 key, and the second half specifies the point where the +polynomial is evaluated. Of the latter half, 22 bits are set to zero, +to enable high-performance implementation, leaving 106 bits for +specifying an evaluation point ‘r’. For each message, one must also +provide a 128-bit nonce. The nonce is encrypted using the AES key, and +that’s the only thing AES is used for. + + The message is split into 128-bit chunks (with final chunk possibly +being shorter), each read as a little-endian integer. Each chunk has a +one-bit appended at the high end. The resulting integers are treated as +polynomial coefficients modulo 2^130 - 5, and the polynomial is +evaluated at the point ‘r’. Finally, this value is reduced modulo +2^128, and added (also modulo 2^128) to the encrypted nonce, to produce +an 128-bit authenticator for the message. See + for further details. + + Clearly, variants using a different cipher than AES could be defined. +Another variant is the ChaCha-Poly1305 AEAD construction (*note +ChaCha-Poly1305::). Nettle defines Poly1305-AES in ‘nettle/poly1305.h’. + + -- Constant: POLY1305_AES_KEY_SIZE + Key size, 32 octets. + + -- Constant: POLY1305_AES_DIGEST_SIZE + Size of the digest or “authenticator”, 16 octets. + + -- Constant: POLY1305_AES_NONCE_SIZE + Nonce size, 16 octets. + + -- Context struct: struct poly1305_aes_ctx + The poly1305-aes context struct. + + -- Function: void poly1305_aes_set_key (struct poly1305_aes_ctx *CTX, + const uint8_t *KEY) + Initialize the context struct. Also sets the nonce to zero. + + -- Function: void poly1305_aes_set_nonce (struct poly1305_aes_ctx *CTX, + const uint8_t *NONCE) + Sets the nonce. Calling this function is optional, since the nonce + is incremented automatically for each message. + + -- Function: void poly1305_aes_update (struct poly1305_aes_ctx *CTX, + size_t LENGTH, const uint8_t *DATA) + Process more data. + + -- Function: void poly1305_aes_digest (struct poly1305_aes_ctx *CTX, + size_t LENGTH, uint8_t *DIGEST) + Extracts the digest. If LENGTH is smaller than + ‘POLY1305_AES_DIGEST_SIZE’, only the first LENGTH octets are + written. Also increments the nonce, and prepares the context for + processing a new message. + + +File: nettle.info, Node: Key derivation functions, Next: Public-key algorithms, Prev: Keyed hash functions, Up: Reference + +6.6 Key derivation Functions +============================ + +A “key derivation function” (KDF) is a function that from a given +symmetric key derives other symmetric keys. A sub-class of KDFs is the +“password-based key derivation functions” (PBKDFs), which take as input +a password or passphrase, and its purpose is typically to strengthen it +and protect against certain pre-computation attacks by using salting and +expensive computation. + +6.6.1 HKDF: HMAC-based Extract-and-Expand +----------------------------------------- + +HKDF is a key derivation function used as a building block of +higher-level protocols like TLS 1.3. It is a derivation function based +on HMAC described in ‘RFC 5869’, and is split into two logical modules, +called ’extract’ and ’expand’. The extract module takes an initial +secret and a random salt to "extract" a fixed-length pseudorandom key +(PRK). The second stage takes as input the previous PRK and some +informational data (e.g., text) and expands them into multiple keys. + + Nettle’s HKDF functions are defined in ‘’. There are +two abstract functions for the extract and expand operations that +operate on any HMAC implemented via the ‘nettle_hash_update_func’, and +‘nettle_hash_digest_func’ interfaces. + + -- Function: void hkdf_extract (void *mac_ctx, nettle_hash_update_func + *update, nettle_hash_digest_func *digest, size_t + digest_size,size_t secret_size, const uint8_t *secret, uint8_t + *dst) + Extract a Pseudorandom Key (PRK) from a secret and a salt according + to HKDF. The HMAC must have been initialized, with its key being + the salt for the Extract operation. This function will call the + UPDATE and DIGEST functions passing the MAC_CTX context parameter + as an argument in order to compute digest of size DIGEST_SIZE. + Inputs are the secret SECRET of length SECRET_LENGTH. The output + length is fixed to DIGEST_SIZE octets, thus the output buffer DST + must have room for at least DIGEST_SIZE octets. + + -- Function: void hkdf_expand (void *mac_ctx, nettle_hash_update_func + *update, nettle_hash_digest_func *digest, size_t digest_size, + size_t info_size, const uint8_t *info, size_t length, uint8_t + *dst) + Expand a Pseudorandom Key (PRK) to an arbitrary size according to + HKDF. The HMAC must have been initialized, with its key being the + PRK from the Extract operation. This function will call the UPDATE + and DIGEST functions passing the MAC_CTX context parameter as an + argument in order to compute digest of size DIGEST_SIZE. Inputs + are the info INFO of length INFO_LENGTH, and the desired derived + output length LENGTH. The output buffer is DST which must have + room for at least LENGTH octets. + +6.6.2 PBKDF2 +------------ + +The most well known PBKDF is the ‘PKCS #5 PBKDF2’ described in ‘RFC +2898’ which uses a pseudo-random function such as HMAC-SHA1. + + Nettle’s PBKDF2 functions are defined in ‘’. There +is an abstract function that operate on any PRF implemented via the +‘nettle_hash_update_func’, ‘nettle_hash_digest_func’ interfaces. There +is also helper macros and concrete functions PBKDF2-HMAC-SHA1 and +PBKDF2-HMAC-SHA256. First, the abstract function: + + -- Function: void pbkdf2 (void *mac_ctx, nettle_hash_update_func + *update, nettle_hash_digest_func *digest, size_t digest_size, + unsigned iterations, size_t salt_length, const uint8_t *salt, + size_t length, uint8_t *dst) + Derive symmetric key from a password according to PKCS #5 PBKDF2. + The PRF is assumed to have been initialized and this function will + call the UPDATE and DIGEST functions passing the MAC_CTX context + parameter as an argument in order to compute digest of size + DIGEST_SIZE. Inputs are the salt SALT of length SALT_LENGTH, the + iteration counter ITERATIONS (> 0), and the desired derived output + length LENGTH. The output buffer is DST which must have room for + at least LENGTH octets. + + Like for CBC and HMAC, there is a macro to help use the function +correctly. + + -- Macro: PBKDF2 (CTX, UPDATE, DIGEST, DIGEST_SIZE, ITERATIONS, + SALT_LENGTH, SALT, LENGTH, DST) + CTX is a pointer to a context struct passed to the UPDATE and + DIGEST functions (of the types ‘nettle_hash_update_func’ and + ‘nettle_hash_digest_func’ respectively) to implement the underlying + PRF with digest size of DIGEST_SIZE. Inputs are the salt SALT of + length SALT_LENGTH, the iteration counter ITERATIONS (> 0), and the + desired derived output length LENGTH. The output buffer is DST + which must have room for at least LENGTH octets. + +6.6.3 Concrete PBKDF2 functions +------------------------------- + +Now we come to the specialized PBKDF2 functions, which are easier to use +than the general PBKDF2 function. + +6.6.3.1 PBKDF2-HMAC-SHA1 +........................ + + -- Function: void pbkdf2_hmac_sha1 (size_t KEY_LENGTH, const uint8_t + *KEY, unsigned ITERATIONS, size_t SALT_LENGTH, const uint8_t + *SALT, size_t LENGTH, uint8_t *DST) + PBKDF2 with HMAC-SHA1. Derive LENGTH bytes of key into buffer DST + using the password KEY of length KEY_LENGTH and salt SALT of length + SALT_LENGTH, with iteration counter ITERATIONS (> 0). The output + buffer is DST which must have room for at least LENGTH octets. + +6.6.3.2 PBKDF2-HMAC-SHA256 +.......................... + + -- Function: void pbkdf2_hmac_sha256 (size_t KEY_LENGTH, const uint8_t + *KEY, unsigned ITERATIONS, size_t SALT_LENGTH, const uint8_t + *SALT, size_t LENGTH, uint8_t *DST) + PBKDF2 with HMAC-SHA256. Derive LENGTH bytes of key into buffer + DST using the password KEY of length KEY_LENGTH and salt SALT of + length SALT_LENGTH, with iteration counter ITERATIONS (> 0). The + output buffer is DST which must have room for at least LENGTH + octets. + + +File: nettle.info, Node: Public-key algorithms, Next: Randomness, Prev: Key derivation functions, Up: Reference + +6.7 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. +* Elliptic curves:: Elliptic curves and ECDSA + + +File: nettle.info, Node: RSA, Next: DSA, Prev: Public-key algorithms, Up: Public-key algorithms + +6.7.1 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 2000 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 2000 bits, ‘p’ and ‘q’ are about 1000 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’. + + The RSA algorithm can also be used for encryption. RSA encryption +uses the public key ‘(n,e)’ to compute the ciphertext ‘m^e mod n’. The +‘PKCS#1’ padding scheme will use at least 8 random and non-zero octets, +using M of the form ‘[00 02 padding 00 plaintext]’. It is required that +‘m < n’, and therefor the plaintext must be smaller than the octet size +of the modulo ‘n’, with some margin. + + To decrypt the message, one needs the private key to compute ‘m = c^e +mod n’ followed by checking and removing the padding. + +6.7.1.1 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. + + For each operation using the private key, there are two variants, +e.g., ‘rsa_sha256_sign’ and ‘rsa_sha256_sign_tr’. The former function +is older, and it should be avoided, because it provides no defenses +against side-channel attacks. The latter function use randomized RSA +blinding, which defends against timing attacks using chosen-ciphertext, +and it also checks the correctness of the private key computation using +the public key, which defends against software or hardware errors which +could leak the private key. + + 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. + + Creating an RSA signature is done with one of the following +functions: + + -- Function: int rsa_md5_sign_tr(const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, struct md5_ctx *HASH, mpz_t + SIGNATURE) + -- Function: int rsa_sha1_sign_tr(const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, struct sha1_ctx *HASH, mpz_t + SIGNATURE) + -- Function: int rsa_sha256_sign_tr(const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, struct sha256_ctx *HASH, mpz_t + SIGNATURE) + -- Function: int rsa_sha512_sign_tr(const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, 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. The RANDOM_CTX and RANDOM pointers are + used to generate the RSA blinding. Returns one on success, or zero + on failure. Signing fails if an error in the computation was + detected, or 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_tr(const struct rsa_public_key + *PUB, const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, const uint8_t *DIGEST, mpz_t + SIGNATURE) + -- Function: int rsa_sha1_sign_digest_tr(const struct rsa_public_key + *PUB, const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, const uint8_t *DIGEST, mpz_t + SIGNATURE) + -- Function: int rsa_sha256_sign_digest_tr(const struct rsa_public_key + *PUB, const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, const uint8_t *DIGEST, mpz_t + SIGNATURE) + -- Function: int rsa_sha512_sign_digest_tr(const struct rsa_public_key + *PUB, const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, 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’, + ‘SHA256_DIGEST_SIZE’, or ‘SHA512_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_pkcs1_sign_tr(const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, size_t LENGTH, const uint8_t + *DIGEST_INFO, mpz_t SIGNATURE) + Similar to the above ‘_sign_digest_tr’ functions, but the input is + not the plain hash digest, but a PKCS#1 “DigestInfo”, an ASN.1 + DER-encoding of the digest together with an object identifier for + the used hash algorithm. + + -- 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; otherwise + analoguous to the above signing functions. DIGEST should point to + a digest of size ‘MD5_DIGEST_SIZE’, ‘SHA1_DIGEST_SIZE’, + ‘SHA256_DIGEST_SIZE’, or ‘SHA512_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_pkcs1_sign(const struct rsa_private_key *KEY, + size_t LENGTH, const uint8_t *DIGEST_INFO, mpz_t S) + Similar to the above _sign_digest functions, but the input is not + the plain hash digest, but a PKCS#1 “DigestInfo”, an ASN.1 + DER-encoding of the digest together with an object identifier for + the used hash algorithm. + + Verifying an RSA signature is done with one of the following +functions: + + -- 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’, ‘SHA256_DIGEST_SIZE’, or ‘SHA512_DIGEST_SIZE’ + respectively. + + -- Function: int rsa_pkcs1_verify(const struct rsa_public_key *KEY, + size_t LENGTH, const uint8_t *DIGEST_INFO, const mpz_t + SIGNATURE) + Similar to the above _verify_digest functions, but the input is not + the plain hash digest, but a PKCS#1 “DigestInfo”, and ASN.1 + DER-encoding of the digest together with an object identifier for + the used hash algorithm. + + While the above functions for the RSA signature operations use the +‘PKCS#1’ padding scheme, Nettle also provides the variants based on the +PSS padding scheme, specified in ‘RFC 3447’. These variants take +advantage of a randomly choosen salt value, which could enhance the +security by causing output to be different for equivalent inputs. +However, assuming the same security level as inverting the RSA +algorithm, a longer salt value does not always mean a better security +. The +typical choices of the length are between 0 and the digest size of the +underlying hash function. + + Creating an RSA signature with the PSS padding scheme is done with +one of the following functions: + + -- Function: int rsa_pss_sha256_sign_digest_tr(const struct + rsa_public_key *PUB, const struct rsa_private_key *KEY, void + *RANDOM_CTX, nettle_random_func *RANDOM, size_t SALT_LENGTH, + const uint8_t *SALT, const uint8_t *DIGEST, mpz_t SIGNATURE) + -- Function: int rsa_pss_sha384_sign_digest_tr(const struct + rsa_public_key *PUB, const struct rsa_private_key *KEY, void + *RANDOM_CTX, nettle_random_func *RANDOM, size_t SALT_LENGTH, + const uint8_t *SALT, const uint8_t *DIGEST, mpz_t SIGNATURE) + -- Function: int rsa_pss_sha512_sign_digest_tr(const struct + rsa_public_key *PUB, const struct rsa_private_key *KEY, void + *RANDOM_CTX, nettle_random_func *RANDOM, size_t SALT_LENGTH, + const uint8_t *SALT, const uint8_t *DIGEST, mpz_t SIGNATURE) + Creates a signature using the PSS padding scheme. SALT should + point to a salt string of size SALT_LENGTH. DIGEST should point to + a digest of size ‘SHA256_DIGEST_SIZE’, ‘SHA384_DIGEST_SIZE’, or + ‘SHA512_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. + + Verifying an RSA signature with the PSS padding scheme is done with +one of the following functions: + + -- Function: int rsa_pss_sha256_verify_digest (const struct + rsa_public_key *KEY, size_t SALT_LENGTH, const uint8_t + *DIGEST, const mpz_t SIGNATURE) + -- Function: int rsa_pss_sha384_verify_digest (const struct + rsa_public_key *KEY, size_t SALT_LENGTH, const uint8_t + *DIGEST, const mpz_t SIGNATURE) + -- Function: int rsa_pss_sha512_verify_digest (const struct + rsa_public_key *KEY, size_t SALT_LENGTH, 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 ‘SHA256_DIGEST_SIZE’, + ‘SHA384_DIGEST_SIZE’, or ‘SHA512_DIGEST_SIZE’ respectively. + + The following function is used to encrypt a clear text message using +RSA. + -- Function: int rsa_encrypt (const struct rsa_public_key *KEY, void + *RANDOM_CTX, nettle_random_func *RANDOM, size_t LENGTH, const + uint8_t *CLEARTEXT, mpz_t CIPHERTEXT) + Returns 1 on success, 0 on failure. If the message is too long + then this will lead to a failure. + The following function is used to decrypt a cipher text message using +RSA. + -- Function: int rsa_decrypt (const struct rsa_private_key *KEY, size_t + *LENGTH, uint8_t *CLEARTEXT, const mpz_t CIPHERTEXT) + Returns 1 on success, 0 on failure. Causes of failure include + decryption failing or the resulting message being to large. The + message buffer pointed to by CLEARTEXT must be of size *LENGTH. + After decryption, *LENGTH will be updated with the size of the + message. + There is also a timing resistant version of decryption that utilizes +randomized RSA blinding. + -- Function: int rsa_decrypt_tr (const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, size_t *LENGTH, uint8_t *MESSAGE, + const mpz_t CIPHERTEXT) + Returns 1 on success, 0 on failure. + + 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: int rsa_compute_root_tr(const struct rsa_public_key *PUB, + const struct rsa_private_key *KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM, mpz_t X, const mpz_t M) + Computes ‘x = m^d’. Returns one on success, or zero if a failure + in the computation was detected. + + -- Function: void rsa_compute_root (struct rsa_private_key *KEY, mpz_t + X, const mpz_t M) + Computes ‘x = m^d’. + + 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, Next: Elliptic curves, Prev: RSA, Up: Public-key algorithms + +6.7.2 DSA +--------- + +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 issued in 2009, and it +adds support for larger hash functions than sha1. + + For DSA, the underlying mathematical problem is the computation of +discrete 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 chosen 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’. + + A DSA group is represented using the following struct. + + -- Context struct: dsa_params p q g + Parameters of the DSA group. + + -- Function: void dsa_params_init (struct dsa_params *PARAMS) + Calls ‘mpz_init’ on all numbers in the struct. + + -- Function: void dsa_params_clear (struct dsa_params *PARAMSparams) + Calls ‘mpz_clear’ on all numbers in the struct. + + -- Function: int dsa_generate_params (struct dsa_params *PARAMS, void + *RANDOM_CTX, nettle_random_func *RANDOM, void *PROGRESS_CTX, + nettle_progress_func *PROGRESS, unsigned P_BITS, unsigned + Q_BITS) + Generates paramaters of a new group. The PARAMS struct 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 *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. + + 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. 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 too small, or too close to P_BITS. + + Signatures are represented using the structure below. + + -- Context struct: dsa_signature r s + + -- Function: void dsa_signature_init (struct dsa_signature *SIGNATURE) + -- Function: void dsa_signature_clear (struct dsa_signature *SIGNATURE) + You must call ‘dsa_signature_init’ before creating or using a + signature, and call ‘dsa_signature_clear’ when you are finished + with it. + + Keys are represented as bignums, of type ‘mpz_t’. A public keys +represent a group element, and is of the same size as ‘p’, while a +private key is an exponent, of the same size as ‘q’. + + -- Function: int dsa_sign (const struct dsa_params *PARAMS, const mpz_t + X, void *RANDOM_CTX, nettle_random_func *RANDOM, size_t + DIGEST_SIZE, const uint8_t *DIGEST, struct dsa_signature + *SIGNATURE) + Creates a signature from the given hash digest, using the private + key X. 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::. Returns one on success, or zero on failure. Signing + can fail only if the key is invalid, so that inversion modulo ‘q’ + fails. + + -- Function: int dsa_verify (const struct dsa_params *PARAMS, const + mpz_t Y, size_t DIGEST_SIZE, const uint8_t *DIGEST, const + struct dsa_signature *SIGNATURE) + Verifies a signature, using the public key y. Returns 1 if the + signature is valid, otherwise 0. + + To generate a keypair, first generate a DSA group using +‘dsa_generate_params’. A keypair in this group is then created using + + -- Function: void dsa_generate_keypair (const struct dsa_params + *PARAMS, mpz_t PUB, mpz_t KEY, void *RANDOM_CTX, + nettle_random_func *RANDOM) + Generates a new keypair, using the group PARAMS. The public key is + stored in PUB, and the private key in KEY. Both variables must be + initialized using ‘mpz_init’ before this call. + + 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::. + +6.7.2.2 Old, deprecated, DSA interface +...................................... + +Versions before nettle-3.0 used a different interface for DSA +signatures, where the group parameters and the public key was packed +together as ‘struct dsa_public_key’. Most of this interface is kept for +backwards compatibility, and declared in ‘nettle/dsa-compat.h’. Below +is the old documentation. The old and new interface use distinct names +and don’t confict, with one exception: The key generation function. The +‘nettle/dsa-compat.h’ redefines ‘dsa_generate_keypair’ as an alias for +‘dsa_compat_generate_keypair’, compatible with the old interface and +documented below. + + The old 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’. + + -- Context struct: dsa_public_key p q g y + The public parameters described above. + + -- Context struct: dsa_private_key x + The private key ‘x’. + + Before use, these structs must be initialized by calling one of + + -- Function: void dsa_public_key_init (struct dsa_public_key *PUB) + -- Function: void dsa_private_key_init (struct dsa_private_key *KEY) + 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 + + -- Function: void dsa_public_key_clear (struct dsa_public_key *PUB) + -- Function: void dsa_private_key_clear (struct dsa_private_key *KEY) + Calls ‘mpz_clear’ on all numbers in the key struct. + + Signatures are represented using ‘struct dsa_signature’, described +earlier. + + 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. + + -- Function: 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) + 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 *Note + 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 + + -- Function: 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) + Verifies a signature. Returns 1 if the signature is valid, + otherwise 0. + + Key generation uses mostly the same parameters as the corresponding +RSA function. + + -- Function: int dsa_compat_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) + 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 *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. + + P_BITS and Q_BITS are the desired sizes of ‘p’ and ‘q’. See + ‘dsa_generate_keypair’ for details. + + +File: nettle.info, Node: Elliptic curves, Prev: DSA, Up: Public-key algorithms + +6.7.3 Elliptic curves +--------------------- + +For cryptographic purposes, an elliptic curve is a mathematical group of +points, and computing logarithms in this group is computationally +difficult problem. Nettle uses additive notation for elliptic curve +groups. If P and Q are two points, and k is an integer, the point sum, +P + Q, and the multiple k P can be computed efficiently, but given only +two points P and Q, finding an integer k such that Q = k P is the +elliptic curve discrete logarithm problem. + + Nettle supports standard curves which are all of the form y^2 = x^3 - +3 x + b (mod p), i.e., the points have coordinates (x,y), both +considered as integers modulo a specified prime p. Curves are +represented as a ‘struct ecc_curve’. It also supports curve25519, which +uses a different form of curve. Supported curves are declared in +‘’, e.g., call ‘nettle_get_secp_256r1’ for a +standardized curve using the 256-bit prime p = 2^{256} - 2^{224} + +2^{192} + 2^{96} - 1. The contents of these structs is not visible to +nettle users. The “bitsize of the curve” is used as a shorthand for the +bitsize of the curve’s prime p, e.g., 256 bits for the SECP 256R1 curve. + +* Menu: + +* Side-channel silence:: +* ECDSA:: +* Curve 25519:: + + +File: nettle.info, Node: Side-channel silence, Next: ECDSA, Up: Elliptic curves + +6.7.3.1 Side-channel silence +............................ + +Nettle’s implementation of the elliptic curve operations is intended to +be side-channel silent. The side-channel attacks considered are: + + • Timing attacks If the timing of operations depends on secret + values, an attacker interacting with your system can measure the + response time, and infer information about your secrets, e.g., a + private signature key. + + • Attacks using memory caches Assume you have some secret data on a + multi-user system, and that this data is properly protected so that + other users get no direct access to it. If you have a process + operating on the secret data, and this process does memory accesses + depending on the data, e.g, an internal lookup table in some + cryptographic algorithm, an attacker running a separate process on + the same system may use behavior of internal CPU caches to get + information about your secrets. This type of attack can even cross + virtual machine boundaries. + + Nettle’s ECC implementation is designed to be “side-channel silent”, +and not leak any information to these attacks. Timing and memory +accesses depend only on the size of the input data and its location in +memory, not on the actual data bits. This implies a performance penalty +in several of the building blocks. + + +File: nettle.info, Node: ECDSA, Next: Curve 25519, Prev: Side-channel silence, Up: Elliptic curves + +6.7.3.2 ECDSA +............. + +ECDSA is a variant of the DSA digital signature scheme (*note DSA::), +which works over an elliptic curve group rather than over a (subgroup +of) integers modulo p. Like DSA, creating a signature requires a unique +random nonce (repeating the nonce with two different messages reveals +the private key, and any leak or bias in the generation of the nonce +also leaks information about the key). + + Unlike DSA, signatures are in general not tied to any particular hash +function or even hash size. Any hash function can be used, and the hash +value is truncated or padded as needed to get a size matching the curve +being used. It is recommended to use a strong cryptographic hash +function with digest size close to the bit size of the curve, e.g., +SHA256 is a reasonable choice when using ECDSA signature over the curve +secp256r1. A protocol or application using ECDSA has to specify which +curve and which hash function to use, or provide some mechanism for +negotiating. + + Nettle defines ECDSA in ‘’. We first need to define +the data types used to represent public and private keys. + + -- struct: struct ecc_point + Represents a point on an elliptic curve. In particular, it is used + to represent an ECDSA public key. + + -- Function: void ecc_point_init (struct ecc_point *P, const struct + ecc_curve *ECC) + Initializes P to represent points on the given curve ECC. + Allocates storage for the coordinates, using the same allocation + functions as GMP. + + -- Function: void ecc_point_clear (struct ecc_point *P) + Deallocate storage. + + -- Function: int ecc_point_set (struct ecc_point *P, const mpz_t X, + const mpz_t Y) + Check that the given coordinates represent a point on the curve. + If so, the coordinates are copied and converted to internal + representation, and the function returns 1. Otherwise, it returns + 0. Currently, the infinity point (or zero point, with additive + notation) is not allowed. + + -- Function: void ecc_point_get (const struct ecc_point *P, mpz_t X, + mpz_t Y) + Extracts the coordinate of the point P. The output parameters X or + Y may be NULL if the caller doesn’t want that coordinate. + + -- struct: struct ecc_scalar + Represents an integer in the range 0 < x < group order, where the + “group order” refers to the order of an ECC group. In particular, + it is used to represent an ECDSA private key. + + -- Function: void ecc_scalar_init (struct ecc_scalar *S, const struct + ecc_curve *ECC) + Initializes S to represent a scalar suitable for the given curve + ECC. Allocates storage using the same allocation functions as GMP. + + -- Function: void ecc_scalar_clear (struct ecc_scalar *S) + Deallocate storage. + + -- Function: int ecc_scalar_set (struct ecc_scalar *S, const mpz_t Z) + Check that Z is in the correct range. If so, copies the value to S + and returns 1, otherwise returns 0. + + -- Function: void ecc_scalar_get (const struct ecc_scalar *S, mpz_t Z) + Extracts the scalar, in GMP ‘mpz_t’ representation. + + To create and verify ECDSA signatures, the following functions are +used. + + -- Function: void ecdsa_sign (const struct ecc_scalar *KEY, void + *RANDOM_CTX, nettle_random_func *RANDOM, size_t DIGEST_LENGTH, + const uint8_t *DIGEST, struct dsa_signature *SIGNATURE) + Uses the private key KEY to create a signature on DIGEST. + RANDOM_CTX and RANDOM is a randomness generator. + ‘random(random_ctx, length, dst)’ should generate ‘length’ random + octets and store them at ‘dst’. The signature is stored in + SIGNATURE, in the same was as for plain DSA. + + -- Function: int ecdsa_verify (const struct ecc_point *PUB, size_t + LENGTH, const uint8_t *DIGEST, const struct dsa_signature + *SIGNATURE) + Uses the public key PUB to verify that SIGNATURE is a valid + signature for the message digest DIGEST (of LENGTH octets). + Returns 1 if the signature is valid, otherwise 0. + + Finally, generating a new ECDSA key pair: + + -- Function: void ecdsa_generate_keypair (struct ecc_point *PUB, struct + ecc_scalar *KEY, void *RANDOM_CTX, nettle_random_func + *RANDOM); + PUB and KEY is where the resulting key pair is stored. The structs + should be initialized, for the desired ECC curve, 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 *Note + Randomness::. + + +File: nettle.info, Node: Curve 25519, Prev: ECDSA, Up: Elliptic curves + +6.7.3.3 Curve25519 +.................. + +Curve25519 is an elliptic curve of Montgomery type, y^2 = x^3 + 486662 +x^2 + x (mod p), with p = 2^255 - 19. Montgomery curves have the +advantage of simple and efficient point addition based on the +x-coordinate only. This particular curve was proposed by D. J. +Bernstein in 2006, for fast Diffie-Hellman key exchange, and is also +described in ‘RFC 7748’. The group generator is defined by x = 9 (there +are actually two points with x = 9, differing by the sign of the +y-coordinate, but that doesn’t matter for the curve25519 operations +which work with the x-coordinate only). + + The curve25519 functions are defined as operations on octet strings, +representing 255-bit scalars or x-coordinates, in little-endian byte +order. The most significant input bit, i.e, the most significant bit of +the last octet, is always ignored. + + For scalars, in addition, the least significant three bits are +ignored, and treated as zero, and the second most significant bit is +ignored too, and treated as one. Then the scalar input string always +represents 8 times a number in the range 2^251 <= s < 2^252. + + Of all the possible input strings, only about half correspond to +x-coordinates of points on curve25519, i.e., a value x for which the the +curve equation can be solved for y. The other half correspond to points +on a related “twist curve”. The function ‘curve25519_mul’ uses a +Montgomery ladder for the scalar multiplication, as suggested in the +curve25519 literature, and required by ‘RFC 7748’. The output is +therefore well defined for _all_ possible inputs, no matter if the input +string represents a valid point on the curve or not. + + Note that the curve25519 implementation in earlier versions of Nettle +deviates slightly from ‘RFC 7748’, in that bit 255 of the x coordinate +of the point input to curve25519_mul was not ignored. The +‘nette/curve25519.h’ defines a preprocessor symbol +‘NETTLE_CURVE25519_RFC7748’ to indicate conformance with the standard. + + Nettle defines Curve 25519 in ‘’. + + -- Constant: NETTLE_CURVE25519_RFC7748 + Defined to 1 in Nettle versions conforming to RFC 7748. Undefined + in earlier versions. + + -- Constant: CURVE25519_SIZE + The size of the strings representing curve25519 points and scalars, + 32. + + -- Function: void curve25519_mul_g (uint8_t *Q, const uint8_t *N) + Computes Q = N G, where G is the group generator and N is an + integer. The input argument N and the output argument Q use a + little-endian representation of the scalar and the x-coordinate, + respectively. They are both of size ‘CURVE25519_SIZE’. + + This function is intended to be compatible with the function + ‘crypto_scalar_mult_base’ in the NaCl library. + + -- Function: void curve25519_mul (uint8_t *Q, const uint8_t *N, const + uint8_t *P) + Computes Q = N P, where P is an input point and N is an integer. + The input arguments N and P and the output argument Q use a + little-endian representation of the scalar and the x-coordinates, + respectively. They are all of size ‘CURVE25519_SIZE’. + + This function is intended to be compatible with the function + ‘crypto_scalar_mult’ in the NaCl library. + +6.7.3.4 EdDSA +............. + +EdDSA is a signature scheme proposed by D. J. Bernstein et al. in 2011. +It is defined using a “Twisted Edwards curve”, of the form -x^2 + y^2 = +1 + d x^2 y^2. The specific signature scheme Ed25519 uses a curve which +is equivalent to curve25519: The two groups used differ only by a simple +change of coordinates, so that the discrete logarithm problem is of +equal difficulty in both groups. + + Unlike other signature schemes in Nettle, the input to the EdDSA sign +and verify functions is the possibly large message itself, not a hash +digest. EdDSA is a variant of Schnorr signatures, where the message is +hashed together with other data during the signature process, providing +resilience to hash-collisions: A successful attack finding collisions in +the hash function does not automatically translate into an attack to +forge signatures. EdDSA also avoids the use of a randomness source by +generating the needed signature nonce from a hash of the private key and +the message, which means that the message is actually hashed twice when +creating a signature. If signing huge messages, it is possible to hash +the message first and pass the short message digest as input to the sign +and verify functions, however, the resilience to hash collision is then +lost. + + -- Constant: ED25519_KEY_SIZE + The size of a private or public Ed25519 key, 32 octets. + + -- Constant: ED25519_SIGNATURE_SIZE + The size of an Ed25519 signature, 64 octets. + + -- Function: void ed25519_sha512_public_key (uint8_t *PUB, const + uint8_t *PRIV) + Computes the public key corresponding to the given private key. + Both input and output are of size ‘ED25519_KEY_SIZE’. + + -- Function: void ed25519_sha512_sign (const uint8_t *PUB, const + uint8_t *PRIV, size_t LENGTH, const uint8_t *MSG, uint8_t + *SIGNATURE) + Signs a message using the provided key pair. + + -- Function: int ed25519_sha512_verify (const uint8_t *PUB, size_t + LENGTH, const uint8_t *MSG, const uint8_t *SIGNATURE) + Verifies a message using the provided public key. Returns 1 if the + signature is valid, otherwise 0. + + +File: nettle.info, Node: Randomness, Next: ASCII encoding, Prev: Public-key algorithms, Up: Reference + +6.8 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 ‘’ 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. + +6.8.1 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 + Recommended 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, size_t + 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, size_t 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, size_t + 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: ASCII encoding, Next: Miscellaneous functions, Prev: Randomness, Up: Reference + +6.9 ASCII encoding +================== + +Encryption will transform your data from text into binary format, and +that may be a problem if, for example, you want to send the data as if +it was plain text in an email, or store it along with descriptive text +in a file. You may then use an encoding from binary to text: each +binary byte is translated into a number of bytes of plain text. + + A base-N encoding of data is one representation of data that only +uses N different symbols (instead of the 256 possible values of a byte). + + The base64 encoding will always use alphanumeric (upper and lower +case) characters and the ’+’, ’/’ and ’=’ symbols to represent the data. +Four output characters are generated for each three bytes of input. In +case the length of the input is not a multiple of three, padding +characters are added at the end. There’s also a “URL safe” variant, +which is useful for encoding binary data into URLs and filenames. See +‘RFC 4648’. + + The base16 encoding, also known as “hexadecimal”, uses the decimal +digits and the letters from A to F. Two hexadecimal digits are generated +for each input byte. + + Nettle supports both base64 and base16 encoding and decoding. + + Encoding and decoding uses a context struct to maintain its state +(with the exception of base16 encoding, which doesn’t need any). To +encode or decode the data, first initialize the context, then call the +update function as many times as necessary, and complete the operation +by calling the final function. + + The following functions can be used to perform base64 encoding and +decoding. They are defined in ‘’. + + -- Context struct: struct base64_encode_ctx + + -- Function: void base64_encode_init (struct base64_encode_ctx *CTX) + -- Function: void base64url_encode_init (struct base64_encode_ctx *CTX) + Initializes a base64 context. This is necessary before starting an + encoding session. ‘base64_encode_init’ selects the standard base64 + alphabet, while ‘base64url_encode_init’ selects the URL safe + alphabet. + + -- Function: size_t base64_encode_single (struct base64_encode_ctx + *CTX, uint8_t *DST, uint8_t SRC) + Encodes a single byte. Returns amount of output (always 1 or 2). + + -- Macro: BASE64_ENCODE_LENGTH (LENGTH) + The maximum number of output bytes when passing LENGTH input bytes + to ‘base64_encode_update’. + + -- Function: size_t base64_encode_update (struct base64_encode_ctx + *CTX, uint8_t *DST, size_t LENGTH, const uint8_t *SRC) + After CTX is initialized, this function may be called to encode + LENGTH bytes from SRC. The result will be placed in DST, and the + return value will be the number of bytes generated. Note that DST + must be at least of size BASE64_ENCODE_LENGTH(LENGTH). + + -- Constant: BASE64_ENCODE_FINAL_LENGTH + The maximum amount of output from ‘base64_encode_final’. + + -- Function: size_t base64_encode_final (struct base64_encode_ctx *CTX, + uint8_t *DST) + After calling base64_encode_update one or more times, this function + should be called to generate the final output bytes, including any + needed paddding. The return value is the number of output bytes + generated. + + -- Context struct: struct base64_decode_ctx + + -- Function: void base64_decode_init (struct base64_decode_ctx *CTX) + -- Function: void base64url_decode_init (struct base64_decode_ctx *CTX) + Initializes a base64 decoding context. This is necessary before + starting a decoding session. ‘base64_decode_init’ selects the + standard base64 alphabet, while ‘base64url_decode_init’ selects the + URL safe alphabet. + + -- Function: int base64_decode_single (struct base64_decode_ctx *CTX, + uint8_t *DST, uint8_t SRC) + Decodes a single byte (SRC) and stores the result in DST. Returns + amount of output (0 or 1), or -1 on errors. + + -- Macro: BASE64_DECODE_LENGTH (LENGTH) + The maximum number of output bytes when passing LENGTH input bytes + to ‘base64_decode_update’. + + -- Function: void base64_decode_update (struct base64_decode_ctx *CTX, + size_t *DST_LENGTH, uint8_t *DST, size_t SRC_LENGTH, const + uint8_t *SRC) + After CTX is initialized, this function may be called to decode + SRC_LENGTH bytes from SRC. DST should point to an area of size at + least BASE64_DECODE_LENGTH(SRC_LENGTH). The amount of data + generated is returned in *DST_LENGTH. Returns 1 on success and 0 + on error. + + -- Function: int base64_decode_final (struct base64_decode_ctx *CTX) + Check that final padding is correct. Returns 1 on success, and 0 + on error. + + Similarly to the base64 functions, the following functions perform +base16 encoding, and are defined in ‘’. Note that +there is no encoding context necessary for doing base16 encoding. + + -- Function: void base16_encode_single (uint8_t *DST, uint8_t SRC) + Encodes a single byte. Always stores two digits in DST[0] and + DST[1]. + + -- Macro: BASE16_ENCODE_LENGTH (LENGTH) + The number of output bytes when passing LENGTH input bytes to + ‘base16_encode_update’. + + -- Function: void base16_encode_update (uint8_t *DST, size_t LENGTH, + const uint8_t *SRC) + Always stores BASE16_ENCODE_LENGTH(LENGTH) digits in DST. + + -- Context struct: struct base16_decode_ctx + + -- Function: void base16_decode_init (struct base16_decode_ctx *CTX) + Initializes a base16 decoding context. This is necessary before + starting a decoding session. + + -- Function: int base16_decode_single (struct base16_decode_ctx *CTX, + uint8_t *DST, uint8_t SRC) + Decodes a single byte from SRC into DST. Returns amount of output + (0 or 1), or -1 on errors. + + -- Macro: BASE16_DECODE_LENGTH (LENGTH) + The maximum number of output bytes when passing LENGTH input bytes + to ‘base16_decode_update’. + + -- Function: int base16_decode_update (struct base16_decode_ctx *CTX, + size_t *DST_LENGTH, uint8_t *DST, size_t SRC_LENGTH, const + uint8_t *SRC) + After CTX is initialized, this function may be called to decode + SRC_LENGTH bytes from SRC. DST should point to an area of size at + least BASE16_DECODE_LENGTH(SRC_LENGTH). The amount of data + generated is returned in *DST_LENGTH. Returns 1 on success and 0 + on error. + + -- Function: int base16_decode_final (struct base16_decode_ctx *CTX) + Checks that the end of data is correct (i.e., an even number of + hexadecimal digits have been seen). Returns 1 on success, and 0 on + error. + + +File: nettle.info, Node: Miscellaneous functions, Next: Compatibility functions, Prev: ASCII encoding, Up: Reference + +6.10 Miscellaneous functions +============================ + + -- Function: void * memxor (void *DST, const void *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. + + -- Function: void * memxor3 (void *DST, const void *A, const void *B, + size_t N) + Like ‘memxor’, but takes two source areas and separate destination + area. + + -- Function: int memeql_sec (const void *A, const void *B, size_t N) + Side-channel silent comparison of the N bytes at A and B. I.e., + instructions executed and memory accesses are identical no matter + where the areas differ, *note Side-channel silence::. Return + non-zero if the areas are equal, and zero if they differ. + + These functions are declared in ‘’. For +compatibility with earlier versions of Nettle, ‘memxor’ and ‘memxor3’ +are also declared in ‘’. + + +File: nettle.info, Node: Compatibility functions, Prev: Miscellaneous functions, Up: Reference + +6.11 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 + +7 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 + +8 Installation +************** + +Nettle uses ‘autoconf’. To build it, unpack the source and run + + ./configure + make + make check + make install + +to install it under the default prefix, ‘/usr/local’. Using GNU make is +strongly recommended. By default, both static and shared libraries are +built and installed. + + To get a list of configure options, use ‘./configure --help’. Some +of the more interesting are: + +‘--enable-fat’ + Include multiple versions of certain functions in the library, and + select the ones to use at run-time, depending on available + processor features. Supported for ARM and x86_64. + +‘--enable-mini-gmp’ + Use the smaller and slower “mini-gmp” implementation of the bignum + functions needed for public-key cryptography, instead of the real + GNU GMP library. This option is intended primarily for smaller + embedded systems. Note that builds using mini-gmp are *not* binary + compatible with regular builds of Nettle, and more likely to leak + side-channel information. + +‘--disable-shared’ + Omit building the shared libraries. + +‘--disable-dependency-tracking’ + Disable the automatic dependency tracking. You will likely need + this option to be able to build with BSD make. + + +File: nettle.info, Node: Index, Prev: Installation, Up: Top + +Function and Concept Index +************************** + +