summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore11
-rw-r--r--AUTHOR3
-rw-r--r--Changelog4
-rw-r--r--LICENSE341
-rw-r--r--Makefile139
-rw-r--r--Makefile_base113
-rw-r--r--README0
-rw-r--r--aes.c1436
-rw-r--r--aes.h54
-rw-r--r--blowfish.c444
-rw-r--r--blowfish.h52
-rw-r--r--buffer_read.c14
-rw-r--r--buffer_write.c14
-rw-r--r--conf-arch1
-rw-r--r--conf-cc5
-rw-r--r--conf-ld3
-rw-r--r--crypto_buffer.c82
-rw-r--r--crypto_buffer.h77
-rw-r--r--crypto_buffer_get.c182
-rw-r--r--crypto_buffer_put.c112
-rw-r--r--cryptot.c570
-rw-r--r--cryptot.h38
-rw-r--r--des.c1218
-rw-r--r--des.h63
-rw-r--r--douint.c76
-rw-r--r--find-systype.sh147
-rw-r--r--ipv4.h38
-rw-r--r--ipv4_scan.c19
-rw-r--r--md4.c213
-rw-r--r--md4.h46
-rw-r--r--md5.c212
-rw-r--r--md5.h41
-rwxr-xr-xmypass57
-rw-r--r--scan.h7
-rw-r--r--scan_ulong.c12
-rw-r--r--sha1.c192
-rw-r--r--sha1.h42
-rw-r--r--sha256.c149
-rw-r--r--sha256.h28
-rw-r--r--sha512.c301
-rw-r--r--sha512.h36
-rw-r--r--socket.h51
-rw-r--r--socket_accept.c22
-rw-r--r--socket_bind.c33
-rw-r--r--socket_conn.c35
-rw-r--r--socket_listen.c8
-rw-r--r--socket_local.c17
-rw-r--r--socket_remote.c17
-rw-r--r--socket_tcp.c16
-rwxr-xr-xtest.sh53
-rw-r--r--test_crypto_api.c325
-rw-r--r--test_crypto_buffer.c222
-rw-r--r--timespec.h20
-rw-r--r--try_clock_gettime.c12
-rw-r--r--trycpp.c7
-rw-r--r--twofish.c859
-rw-r--r--twofish.h74
-rw-r--r--u8_read.c14
-rw-r--r--u8_write.c14
-rw-r--r--uint16.h13
-rw-r--r--uint16_pack.c13
-rw-r--r--uint16_unpack.c21
-rw-r--r--warn-auto.sh2
-rw-r--r--x86cpuid.c39
64 files changed, 8479 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6a1d587
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+*.o
+*.a
+compile
+cryptot
+douint
+load
+rt.lib
+test_crypto_api
+test_crypto_buffer
+uint.h
+
diff --git a/AUTHOR b/AUTHOR
new file mode 100644
index 0000000..090fc27
--- /dev/null
+++ b/AUTHOR
@@ -0,0 +1,3 @@
+
+Zurcher Jeremy <jeremy@asynk.ch>
+
diff --git a/Changelog b/Changelog
new file mode 100644
index 0000000..49c6535
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,4 @@
+
+07.09.04 cryptot : resolve_ip : replace "localhost" by gethostname
+
+07.09.04 cryptot : : -S option added
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7bb1a0b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,341 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e97a28e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,139 @@
+DIR=.
+
+include Makefile_base
+
+aes.o : compile aes.c aes.h uint.h
+ @./compile aes.c
+
+blowfish.o : compile blowfish.c blowfish.h uint.h
+ @./compile blowfish.c
+
+cryptot : load cryptot.o crypto_buffer.a ipv4_scan.o scan_ulong.o \
+ socket_accept.o socket_bind.o socket_conn.o socket_listen.o socket_local.o socket_remote.o socket_tcp.o \
+ rt.lib uint16_pack.o uint16_unpack.o
+ @./load c cryptot ipv4_scan.o scan_ulong.o \
+ socket_accept.o socket_bind.o socket_conn.o socket_listen.o socket_local.o socket_remote.o socket_tcp.o \
+ `cat rt.lib` uint16_pack.o uint16_unpack.o crypto_buffer.a
+
+cryptot.o : compile cryptot.c cryptot.h crypto_buffer.h ipv4.h scan.h socket.h
+ @./compile cryptot.c
+
+crypto_api.a : load aes.o des.o blowfish.o twofish.o md4.o md5.o sha1.o sha256.o sha512.o
+ @./load s crypto_api.a aes.o des.o blowfish.o twofish.o md4.o md5.o sha1.o sha256.o sha512.o
+
+crypto_buffer.a : load crypto_buffer.o crypto_buffer_put.o crypto_buffer_get.o u8_read.o u8_write.o \
+aes.o des.o blowfish.o twofish.o
+ @./load s crypto_buffer.a crypto_buffer.o crypto_buffer_get.o crypto_buffer_put.o \
+ u8_read.o u8_write.o aes.o des.o blowfish.o twofish.o
+
+crypto_buffer.o : compile crypto_buffer.c crypto_buffer.h
+ @./compile crypto_buffer.c
+
+crypto_buffer_get.o : compile crypto_buffer_get.c crypto_buffer.h
+ @./compile crypto_buffer_get.c
+
+crypto_buffer_put.o : compile crypto_buffer_put.c crypto_buffer.h
+ @./compile crypto_buffer_put.c
+
+des.o : compile des.c des.h uint.h
+ @./compile des.c
+
+ipv4_scan.o : compile ipv4_scan.c ipv4.h
+ @./compile ipv4_scan.c
+
+md4.o : compile md4.c md4.h uint.h
+ @./compile md4.c
+
+md5.o : compile md5.c md5.h uint.h
+ @./compile md5.c
+
+rt.lib : compile load try_clock_gettime.c
+ @( ( ./compile try_clock_gettime.c && ./load c try_clock_gettime ) \
+ >/dev/null 2>&1 && exit 0 || echo "-lrt" ) > rt.lib
+
+scan_ulong.o : compile scan_ulong.c scan.h
+ @./compile scan_ulong.c
+
+sha1.o : compile sha1.c sha1.h uint.h
+ @./compile sha1.c
+
+sha256.o : compile sha256.c sha256.h uint.h
+ @./compile sha256.c
+
+sha512.o : compile sha512.c sha512.h uint.h
+ @./compile sha512.c
+
+socket_accept.o : compile socket_accept.c socket.h
+ @./compile socket_accept.c
+
+socket_bind.o : compile socket_bind.c socket.h
+ @./compile socket_bind.c
+
+socket_conn.o : compile socket_conn.c socket.h
+ @./compile socket_conn.c
+
+socket_listen.o : compile socket_listen.c socket.h
+ @./compile socket_listen.c
+
+socket_local.o : compile socket_local.c socket.h
+ @./compile socket_local.c
+
+socket_remote.o : compile socket_remote.c socket.h
+ @./compile socket_remote.c
+
+socket_tcp.o : compile socket_tcp.c socket.h
+ @./compile socket_tcp.c
+
+test_crypto_api.o : compile test_crypto_api.c
+ @./compile test_crypto_api.c
+
+test_crypto_api : load test_crypto_api.o crypto_api.a
+ @./load c test_crypto_api crypto_api.a
+
+test_crypto_buffer.o : compile test_crypto_buffer.c
+ @./compile test_crypto_buffer.c
+
+test_crypto_buffer : load test_crypto_buffer.o crypto_buffer.a
+ @./load c test_crypto_buffer crypto_buffer.a
+
+twofish.o : compile twofish.c twofish.h uint.h
+ @./compile twofish.c
+
+uint.h : compile load douint.c
+ @./compile douint.c
+ @./load c douint
+ @./douint > uint.h
+
+uint16_pack.o : compile uint16_pack.c uint.h
+ @./compile uint16_pack.c
+
+uint16_unpack.o : compile uint16_unpack.c uint.h
+ @./compile uint16_unpack.c
+
+u8_read.o : compile u8_read.c uint.h
+ @./compile u8_read.c
+
+u8_write.o : compile u8_write.c uint.h
+ @./compile u8_write.c
+
+
+
+# HIGH LEVEL SPECIFIC TARGETS
+
+clean : cleanstd
+ @if [ -f cryptot ]; then rm cryptot; fi
+ @if [ -f crypto_file ]; then rm crypto_file; fi
+ @if [ -f douint ]; then rm douint; fi
+ @if [ -f rt.lib ]; then rm rt.lib; fi
+ @if [ -f test_crypto_api ]; then rm test_crypto_api; fi
+ @if [ -f test_crypto_buffer ]; then rm test_crypto_buffer; fi
+ @if [ -f try_clock_gettime ]; then rm try_clock_gettime; fi
+ @if [ -f uint.h ]; then rm uint.h; fi
+
+arch: buildarch
+ -@./buildarch test.sh mypass
+
+build : crypto_api.a test_crypto_api crypto_buffer.a test_crypto_buffer cryptot
+
+install : build
+ cp cryptot /home/jeyzu/bin
diff --git a/Makefile_base b/Makefile_base
new file mode 100644
index 0000000..8dd8be3
--- /dev/null
+++ b/Makefile_base
@@ -0,0 +1,113 @@
+
+# Don't edit this Makefile! Use conf-* for configuration.
+
+######################################
+
+SHELL=/bin/sh
+
+CYAN=\033[3;36m
+RED=\033[3;31m
+NORM=\033[0m
+
+default: build
+
+
+# GENERATE : buildarch - choose - compile - load - testflag
+
+buildarch : ${DIR}/warn-auto.sh conf-arch LICENSE README AUTHOR Changelog
+ @echo -e "$(CYAN)generating buildarch$(NORM)"
+ @( cat ${DIR}/warn-auto.sh; \
+ echo "ARCH=`head -1 conf-arch`"; \
+ echo 'echo -e "building $(RED)$${ARCH}$(NORM)"'; \
+ echo 'P=`pwd` && P=$${P##*/};'; \
+ echo 'FILES="$${P}/Makefile* $${P}/warn-auto.sh $${P}/LICENSE $${P}/README $${P}/AUTHOR $${P}/Changelog\
+ $${P}/conf-* $${P}/*.h* $${P}/*.c*";'; \
+ echo 'for I in $$@; do FILES="$${FILES} $${P}/$$I "; done;'; \
+ echo 'cd .. && tar -chzf $${P}/$${ARCH} $${FILES} 2>/dev/null' \
+ ) > buildarch
+ @chmod 755 buildarch
+
+choose : ${DIR}/warn-auto.sh
+ @echo -e "$(CYAN)generating choose$(NORM)"
+ @( cat ${DIR}/warn-auto.sh; \
+ echo 'result="$$3"'; \
+ echo 'case "$$1" in'; \
+ echo ' *c*) ./compile $$2.c >/dev/null 2>&1 || result="$$4" ;;'; \
+ echo 'esac'; \
+ echo 'case "$$1" in'; \
+ echo ' *l*) ./load c $$2 >/dev/null 2>&1 || result="$$4" ;;'; \
+ echo 'esac'; \
+ echo 'case "$$1" in'; \
+ echo ' *r*) ./$$2 >/dev/null 2>&1 || result="$$4" ;;'; \
+ echo 'esac'; \
+ echo 'rm -f $$2.o $$2'; \
+ echo 'cat $$result'; \
+ ) > choose
+ @chmod 755 choose
+
+compile : ${DIR}/warn-auto.sh conf-cc
+ @echo -e "$(CYAN)generating compile$(NORM)"
+ @( cat ${DIR}/warn-auto.sh; \
+ echo 'echo -e "`head -1 conf-cc` -c $(RED)$${1} $(NORM)"'; \
+ echo '`head -1 conf-cc` -c "$$1"'; \
+ ) > compile
+ @chmod 755 compile
+
+load : ${DIR}/warn-auto.sh conf-ld
+ @echo -e "$(CYAN)generating load$(NORM)"
+ @( cat ${DIR}/warn-auto.sh; \
+ echo 'choice=$$1; shift;'; \
+ echo 'name=$$1; shift;'; \
+ echo 'case "$$choice" in'; \
+ echo ' *c*)'; \
+ echo ' echo -e "`head -1 conf-ld` -o $(RED)$${name} $${name}.o $${1+"$$@"} $(NORM)"'; \
+ echo ' `head -1 conf-ld` -o "$$name" "$$name".o $${1+"$$@"}'; \
+ echo ' ;;'; \
+ echo ' *d*)'; \
+ echo ' echo -e "`head -1 conf-ld`$$name -o $(RED)$${name} $${1+"$$@"} $(NORM)"'; \
+ echo ' `head -1 conf-ld`"$$name" -o "$$name" $${1+"$$@"}'; \
+ echo ' ;;'; \
+ echo ' *s*)'; \
+ echo ' echo -e "ar -cr $(RED)$${name} $${1+"$$@"} $(NORM)"'; \
+ echo ' rm -f "$$name"; ar -cr "$$name" $${1+"$$@"}; ranlib "$$name"'; \
+ echo ' ;;'; \
+ echo 'esac'; \
+ ) > load
+ @chmod 755 load
+
+testflag : ${DIR}/warn-auto.sh
+ @echo -e "$(CYAN)generating testflag$(NORM)"
+ @( cat ${DIR}/warn-auto.sh; \
+ echo 'FLAG="$$1"; shift'; \
+ echo 'for I in "$$@"; do echo "#include \"$$I\""; done;'; \
+ echo 'echo "int main() {"'; \
+ echo 'echo "#ifdef "$$FLAG"" '; \
+ echo 'echo " return 0;"'; \
+ echo 'echo "#else"'; \
+ echo 'echo " return 1;"'; \
+ echo 'echo "#endif"'; \
+ echo 'echo }'; \
+ ) > testflag
+ @chmod 755 testflag
+
+# HIGH LEVEL GENERAL TARGETS
+buildstd :
+ @echo -e "$(CYAN)building `pwd`$(NORM)";
+ @for I in ${SUBDIR}; do \
+ ( echo -e "$(CYAN)building `pwd`/$$I$(NORM)" && cd $$I && make -s ); \
+ done;
+cleanstd :
+ @echo -e "$(CYAN)cleaning `pwd`$(NORM)";
+ @for I in ${SUBDIR}; do ( cd $$I && make -s clean ); done;
+ @if [ -f conf-arch ]; then if [ -f `head -1 conf-arch` ]; then rm `head -1 conf-arch`; fi; fi
+ @if [ -f buildarch ]; then rm buildarch; fi
+ @if [ -f choose ]; then rm choose; fi
+ @if [ -f compile ]; then rm compile; fi
+ @if [ -f load ]; then rm load; fi
+ @if [ -f testflag ]; then rm testflag; fi
+ @if [ "x`ls *~ 2>/dev/null`" != "x" ]; then rm *~; fi
+ @if [ "x`ls *.a 2>/dev/null`" != "x" ]; then rm *.a; fi
+ @if [ "x`ls *.o 2>/dev/null`" != "x" ]; then rm *.o; fi
+ @if [ "x`ls *.so* 2>/dev/null`" != "x" ]; then rm *.so*; fi
+
+# PACKAGE SPECIFIC TARGETS
diff --git a/README b/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/README
diff --git a/aes.c b/aes.c
new file mode 100644
index 0000000..b067505
--- /dev/null
+++ b/aes.c
@@ -0,0 +1,1436 @@
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "uint.h"
+#include "aes.h"
+
+/*
+ * rk[ 4*(Nr+1) ]
+void rijndaelEncrypt(u32 rk[], int Nr, const u8 pt[16], u8 ct[16]);
+void rijndaelDecrypt(u32 rk[], int Nr, const u8 ct[16], u8 pt[16]);
+*/
+
+#ifdef INTERMEDIATE_VALUE_KAT
+void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
+void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
+#endif /* INTERMEDIATE_VALUE_KAT */
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+static const u32 Te0[256] = {
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+static const u32 Td0[256] = {
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const u32 rcon[] = {
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+
+#ifdef _MSC_VER
+#define GETU32(p) SWAP(*((u32 *)(p)))
+#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+#endif
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+
+int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+ int i = 0;
+ u32 temp;
+
+ rk[0] = GETU32(cipherKey );
+ rk[1] = GETU32(cipherKey + 4);
+ rk[2] = GETU32(cipherKey + 8);
+ rk[3] = GETU32(cipherKey + 12);
+ if (keyBits == 128) {
+ for (;;) {
+ temp = rk[3];
+ rk[4] = rk[0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10) {
+ return 10;
+ }
+ rk += 4;
+ }
+ }
+ rk[4] = GETU32(cipherKey + 16);
+ rk[5] = GETU32(cipherKey + 20);
+ if (keyBits == 192) {
+ for (;;) {
+ temp = rk[ 5];
+ rk[ 6] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 7] = rk[ 1] ^ rk[ 6];
+ rk[ 8] = rk[ 2] ^ rk[ 7];
+ rk[ 9] = rk[ 3] ^ rk[ 8];
+ if (++i == 8) {
+ return 12;
+ }
+ rk[10] = rk[ 4] ^ rk[ 9];
+ rk[11] = rk[ 5] ^ rk[10];
+ rk += 6;
+ }
+ }
+ rk[6] = GETU32(cipherKey + 24);
+ rk[7] = GETU32(cipherKey + 28);
+ if (keyBits == 256) {
+ for (;;) {
+ temp = rk[ 7];
+ rk[ 8] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 9] = rk[ 1] ^ rk[ 8];
+ rk[10] = rk[ 2] ^ rk[ 9];
+ rk[11] = rk[ 3] ^ rk[10];
+ if (++i == 7) {
+ return 14;
+ }
+ temp = rk[11];
+ rk[12] = rk[ 4] ^
+ (Te4[(temp >> 24) ] & 0xff000000) ^
+ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp ) & 0xff] & 0x000000ff);
+ rk[13] = rk[ 5] ^ rk[12];
+ rk[14] = rk[ 6] ^ rk[13];
+ rk[15] = rk[ 7] ^ rk[14];
+
+ rk += 8;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+ int Nr, i, j;
+ u32 temp;
+
+ /* expand the cipher key: */
+ Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
+ /* invert the order of the round keys: */
+ for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
+ temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
+ temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+ temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+ temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+ }
+ /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+ for (i = 1; i < Nr; i++) {
+ rk += 4;
+ rk[0] =
+ Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[0] ) & 0xff] & 0xff];
+ rk[1] =
+ Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[1] ) & 0xff] & 0xff];
+ rk[2] =
+ Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[2] ) & 0xff] & 0xff];
+ rk[3] =
+ Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[3] ) & 0xff] & 0xff];
+ }
+ return Nr;
+}
+
+int aes_setkey(void *cx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ struct aes_ctx *ctx = cx;
+ int Nr = 0;
+
+ if (keylen != 16 && keylen != 24 && keylen != 32) return -1;
+ switch (keylen) {
+ case(16): Nr = 10; break;
+ case(24): Nr = 12; break;
+ case(32): Nr = 14; break;
+ }
+ ctx->rounds = Nr;
+ rijndaelKeySetupEnc(ctx->ek, key, keylen*8);
+ rijndaelKeySetupDec(ctx->dk, key, keylen*8);
+ return 0;
+}
+#define FULL_UNROLL
+void aes_encrypt(void *cx, u8 *dst, const u8 *src)
+{
+ struct aes_ctx *ctx = cx;
+ int Nr = ctx->rounds;
+ u32 *rk = ctx->ek;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(src ) ^ rk[0];
+ s1 = GETU32(src + 4) ^ rk[1];
+ s2 = GETU32(src + 8) ^ rk[2];
+ s3 = GETU32(src + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+ if (Nr > 10) {
+ /* round 10: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+ if (Nr > 12) {
+ /* round 12: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = Nr >> 1;
+ for (;;) {
+ t0 =
+ Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
+
+ s0 =
+ Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Te4[(t0 >> 24) ] & 0xff000000) ^
+ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(dst , s0);
+ s1 =
+ (Te4[(t1 >> 24) ] & 0xff000000) ^
+ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(dst + 4, s1);
+ s2 =
+ (Te4[(t2 >> 24) ] & 0xff000000) ^
+ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(dst + 8, s2);
+ s3 =
+ (Te4[(t3 >> 24) ] & 0xff000000) ^
+ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(dst + 12, s3);
+}
+
+void aes_decrypt(void *cx, u8 *dst, const u8 *src)
+{
+ struct aes_ctx *ctx = cx;
+ int Nr = ctx->rounds;
+ u32 *rk = ctx->dk;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(src ) ^ rk[0];
+ s1 = GETU32(src + 4) ^ rk[1];
+ s2 = GETU32(src + 8) ^ rk[2];
+ s3 = GETU32(src + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+ if (Nr > 10) {
+ /* round 10: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+ if (Nr > 12) {
+ /* round 12: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = Nr >> 1;
+ for (;;) {
+ t0 =
+ Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
+
+ s0 =
+ Td0[(t0 >> 24) ] ^
+ Td1[(t3 >> 16) & 0xff] ^
+ Td2[(t2 >> 8) & 0xff] ^
+ Td3[(t1 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Td0[(t1 >> 24) ] ^
+ Td1[(t0 >> 16) & 0xff] ^
+ Td2[(t3 >> 8) & 0xff] ^
+ Td3[(t2 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Td0[(t2 >> 24) ] ^
+ Td1[(t1 >> 16) & 0xff] ^
+ Td2[(t0 >> 8) & 0xff] ^
+ Td3[(t3 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Td0[(t3 >> 24) ] ^
+ Td1[(t2 >> 16) & 0xff] ^
+ Td2[(t1 >> 8) & 0xff] ^
+ Td3[(t0 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Td4[(t0 >> 24) ] & 0xff000000) ^
+ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(dst , s0);
+ s1 =
+ (Td4[(t1 >> 24) ] & 0xff000000) ^
+ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(dst + 4, s1);
+ s2 =
+ (Td4[(t2 >> 24) ] & 0xff000000) ^
+ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(dst + 8, s2);
+ s3 =
+ (Td4[(t3 >> 24) ] & 0xff000000) ^
+ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(dst + 12, s3);
+}
+
+#ifdef INTERMEDIATE_VALUE_KAT
+
+void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) {
+ int r;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(block ) ^ rk[0];
+ s1 = GETU32(block + 4) ^ rk[1];
+ s2 = GETU32(block + 8) ^ rk[2];
+ s3 = GETU32(block + 12) ^ rk[3];
+ rk += 4;
+
+ /*
+ * Nr - 1 full rounds:
+ */
+ for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) {
+ t0 =
+ Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[0];
+ t1 =
+ Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[1];
+ t2 =
+ Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[2];
+ t3 =
+ Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[3];
+
+ s0 = t0;
+ s1 = t1;
+ s2 = t2;
+ s3 = t3;
+ rk += 4;
+
+ }
+
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ if (rounds == Nr) {
+ t0 =
+ (Te4[(s0 >> 24) ] & 0xff000000) ^
+ (Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(s2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(s3 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ t1 =
+ (Te4[(s1 >> 24) ] & 0xff000000) ^
+ (Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(s3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(s0 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ t2 =
+ (Te4[(s2 >> 24) ] & 0xff000000) ^
+ (Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(s0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(s1 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ t3 =
+ (Te4[(s3 >> 24) ] & 0xff000000) ^
+ (Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(s1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(s2 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+
+ s0 = t0;
+ s1 = t1;
+ s2 = t2;
+ s3 = t3;
+ }
+
+ PUTU32(block , s0);
+ PUTU32(block + 4, s1);
+ PUTU32(block + 8, s2);
+ PUTU32(block + 12, s3);
+}
+
+void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) {
+ int r;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(block ) ^ rk[0];
+ s1 = GETU32(block + 4) ^ rk[1];
+ s2 = GETU32(block + 8) ^ rk[2];
+ s3 = GETU32(block + 12) ^ rk[3];
+ rk += 4;
+
+ /*
+ * Nr - 1 full rounds:
+ */
+ for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) {
+ t0 =
+ Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[0];
+ t1 =
+ Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[1];
+ t2 =
+ Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[2];
+ t3 =
+ Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[3];
+
+ s0 = t0;
+ s1 = t1;
+ s2 = t2;
+ s3 = t3;
+ rk += 4;
+
+ }
+
+ /*
+ * complete the last round and
+ * map cipher state to byte array block:
+ */
+ t0 =
+ (Td4[(s0 >> 24) ] & 0xff000000) ^
+ (Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(s2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(s1 ) & 0xff] & 0x000000ff);
+ t1 =
+ (Td4[(s1 >> 24) ] & 0xff000000) ^
+ (Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(s3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(s2 ) & 0xff] & 0x000000ff);
+ t2 =
+ (Td4[(s2 >> 24) ] & 0xff000000) ^
+ (Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(s0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(s3 ) & 0xff] & 0x000000ff);
+ t3 =
+ (Td4[(s3 >> 24) ] & 0xff000000) ^
+ (Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(s1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(s0 ) & 0xff] & 0x000000ff);
+
+ if (rounds == Nr) {
+ t0 ^= rk[0];
+ t1 ^= rk[1];
+ t2 ^= rk[2];
+ t3 ^= rk[3];
+ }
+
+ PUTU32(block , t0);
+ PUTU32(block + 4, t1);
+ PUTU32(block + 8, t2);
+ PUTU32(block + 12, t3);
+}
+
+#endif /* INTERMEDIATE_VALUE_KAT */
diff --git a/aes.h b/aes.h
new file mode 100644
index 0000000..ff1f28c
--- /dev/null
+++ b/aes.h
@@ -0,0 +1,54 @@
+/*
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _AES_
+#define _AES_
+
+/*
+ * FULL_UNROLL may be defined
+ */
+
+#include "uint.h"
+
+#define AES_BLOCK_SIZE 16
+
+#define MAXKC (256/32)
+#define MAXKB (256/8)
+#define MAXNR 14
+
+struct aes_ctx {
+ u32 ek[ 4*(MAXNR+1) ];
+ u32 dk[ 4*(MAXNR+1) ];
+ int rounds;
+};
+
+int aes_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags);
+
+void aes_encrypt(void *cx, u8 *dst, const u8 *src);
+
+void aes_decrypt(void *cx, u8 *dst, const u8 *src);
+
+#endif
diff --git a/blowfish.c b/blowfish.c
new file mode 100644
index 0000000..dd22cff
--- /dev/null
+++ b/blowfish.c
@@ -0,0 +1,444 @@
+/*
+ * Cryptographic API.
+ *
+ * Blowfish Cipher Algorithm, by Bruce Schneier.
+ * http://www.counterpane.com/blowfish.html
+ *
+ * Adapated from Kerneli implementation.
+ *
+ * Copyright (c) Herbert Valerio Riedel <hvr@hvrlab.org>
+ * Copyright (c) Kyle McMartin <kyle@debian.org>
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#include "blowfish.h"
+
+#define be32_to_cpu(x) (u32)(x)
+#define cpu_to_be32(x) (u32)(x)
+
+static const u32 bf_pbox[16 + 2] = {
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+ 0x9216d5d9, 0x8979fb1b,
+};
+
+static const u32 bf_sbox[256 * 4] = {
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
+};
+
+/*
+ * Round loop unrolling macros, S is a pointer to a S-Box array
+ * organized in 4 unsigned longs at a row.
+ */
+#define GET32_3(x) (((x) & 0xff))
+#define GET32_2(x) (((x) >> (8)) & (0xff))
+#define GET32_1(x) (((x) >> (16)) & (0xff))
+#define GET32_0(x) (((x) >> (24)) & (0xff))
+
+#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
+ S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
+
+#define ROUND(a, b, n) b ^= P[n]; a ^= bf_F (b)
+
+/*
+ * The blowfish encipher, processes 64-bit blocks.
+ * NOTE: This function MUSTN'T respect endianess
+ */
+static __inline void encrypt_block(struct blowfish_ctx *bctx, u32 *dst, u32 *src)
+{
+ const u32 *P = bctx->p;
+ const u32 *S = bctx->s;
+ u32 yl = src[0];
+ u32 yr = src[1];
+
+ ROUND(yr, yl, 0);
+ ROUND(yl, yr, 1);
+ ROUND(yr, yl, 2);
+ ROUND(yl, yr, 3);
+ ROUND(yr, yl, 4);
+ ROUND(yl, yr, 5);
+ ROUND(yr, yl, 6);
+ ROUND(yl, yr, 7);
+ ROUND(yr, yl, 8);
+ ROUND(yl, yr, 9);
+ ROUND(yr, yl, 10);
+ ROUND(yl, yr, 11);
+ ROUND(yr, yl, 12);
+ ROUND(yl, yr, 13);
+ ROUND(yr, yl, 14);
+ ROUND(yl, yr, 15);
+
+ yl ^= P[16];
+ yr ^= P[17];
+
+ dst[0] = yr;
+ dst[1] = yl;
+}
+
+void blowfish_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ const u32 *in_blk = (const u32 *)src;
+ u32 *const out_blk = (u32 *)dst;
+ u32 in32[2], out32[2];
+
+ in32[0] = be32_to_cpu(in_blk[0]);
+ in32[1] = be32_to_cpu(in_blk[1]);
+ encrypt_block(ctx, out32, in32);
+ out_blk[0] = cpu_to_be32(out32[0]);
+ out_blk[1] = cpu_to_be32(out32[1]);
+}
+
+void blowfish_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ const u32 *in_blk = (const u32 *)src;
+ u32 *const out_blk = (u32 *)dst;
+ const u32 *P = ((struct blowfish_ctx *)ctx)->p;
+ const u32 *S = ((struct blowfish_ctx *)ctx)->s;
+ u32 yl = be32_to_cpu(in_blk[0]);
+ u32 yr = be32_to_cpu(in_blk[1]);
+
+ ROUND(yr, yl, 17);
+ ROUND(yl, yr, 16);
+ ROUND(yr, yl, 15);
+ ROUND(yl, yr, 14);
+ ROUND(yr, yl, 13);
+ ROUND(yl, yr, 12);
+ ROUND(yr, yl, 11);
+ ROUND(yl, yr, 10);
+ ROUND(yr, yl, 9);
+ ROUND(yl, yr, 8);
+ ROUND(yr, yl, 7);
+ ROUND(yl, yr, 6);
+ ROUND(yr, yl, 5);
+ ROUND(yl, yr, 4);
+ ROUND(yr, yl, 3);
+ ROUND(yl, yr, 2);
+
+ yl ^= P[1];
+ yr ^= P[0];
+
+ out_blk[0] = cpu_to_be32(yr);
+ out_blk[1] = cpu_to_be32(yl);
+}
+
+/*
+ * Calculates the blowfish S and P boxes for encryption and decryption.
+ */
+int blowfish_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ short i, j, count;
+ u32 data[2], temp;
+ u32 *P = ((struct blowfish_ctx *)ctx)->p;
+ u32 *S = ((struct blowfish_ctx *)ctx)->s;
+
+ /* Copy the initialization s-boxes */
+ for (i = 0, count = 0; i < 256; i++)
+ for (j = 0; j < 4; j++, count++)
+ S[count] = bf_sbox[count];
+
+ /* Set the p-boxes */
+ for (i = 0; i < 16 + 2; i++)
+ P[i] = bf_pbox[i];
+
+ /* Actual subkey generation */
+ for (j = 0, i = 0; i < 16 + 2; i++) {
+ temp = (((u32 )key[j] << 24) |
+ ((u32 )key[(j + 1) % keylen] << 16) |
+ ((u32 )key[(j + 2) % keylen] << 8) |
+ ((u32 )key[(j + 3) % keylen]));
+
+ P[i] = P[i] ^ temp;
+ j = (j + 4) % keylen;
+ }
+
+ data[0] = 0x00000000;
+ data[1] = 0x00000000;
+
+ for (i = 0; i < 16 + 2; i += 2) {
+ encrypt_block((struct blowfish_ctx *)ctx, data, data);
+
+ P[i] = data[0];
+ P[i + 1] = data[1];
+ }
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
+ encrypt_block((struct blowfish_ctx *)ctx, data, data);
+
+ S[count] = data[0];
+ S[count + 1] = data[1];
+ }
+ }
+
+ /* Bruce says not to bother with the weak key check. */
+ return 0;
+}
+
+/*
+#include <stdio.h>
+#include <string.h>
+void blowfish_encrypt_fake(void *ctx, u8 *dst, const u8 *src){fprintf(stderr,"encrypt\n");memcpy(dst,src,BF_BLOCK_SIZE);}
+void blowfish_decrypt_fake(void *ctx, u8 *dst, const u8 *src){fprintf(stderr,"decrypt\n");memcpy(dst,src,BF_BLOCK_SIZE);}
+*/
diff --git a/blowfish.h b/blowfish.h
new file mode 100644
index 0000000..d0f2bce
--- /dev/null
+++ b/blowfish.h
@@ -0,0 +1,52 @@
+/*
+ * Cryptographic API.
+ *
+ * Blowfish Cipher Algorithm, by Bruce Schneier.
+ * http://www.counterpane.com/blowfish.html
+ *
+ * Adapated from Kerneli implementation.
+ *
+ * Copyright (c) Herbert Valerio Riedel <hvr@hvrlab.org>
+ * Copyright (c) Kyle McMartin <kyle@debian.org>
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _BLOWFISH_
+#define _BLOWFISH_
+
+#include "uint.h"
+
+#define BF_BLOCK_SIZE 8
+
+/* key length from 32 to 448 bits, but no checks are made */
+#define BF_MIN_KEY_SIZE 4
+#define BF_MAX_KEY_SIZE 56
+
+struct blowfish_ctx {
+ u32 p[18];
+ u32 s[1024];
+};
+
+/*
+ * Calculates the blowfish S and P boxes for encryption and decryption.
+ */
+int blowfish_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags);
+
+void blowfish_encrypt(void *cx, u8 *dst, const u8 *src);
+
+void blowfish_decrypt(void *cx, u8 *dst, const u8 *src);
+
+
+/* memcpy */
+/*
+void blowfish_encrypt_fake(void *cx, u8 *dst, const u8 *src);
+void blowfish_decrypt_fake(void *cx, u8 *dst, const u8 *src);
+*/
+
+#endif
diff --git a/buffer_read.c b/buffer_read.c
new file mode 100644
index 0000000..f9ccfac
--- /dev/null
+++ b/buffer_read.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include "buffer.h"
+
+int buffer_unix_read(int fd,char *buf,unsigned int len)
+{
+ return read(fd,buf,len);
+}
+
+int buffer_tcp_read(int fd,char *buf, unsigned int len)
+{
+ return recv(fd, buf,len,0);
+}
diff --git a/buffer_write.c b/buffer_write.c
new file mode 100644
index 0000000..1b71086
--- /dev/null
+++ b/buffer_write.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include "buffer.h"
+
+int buffer_unix_write(int fd,const char *buf,unsigned int len)
+{
+ return write(fd,buf,len);
+}
+
+int buffer_tcp_write(int fd, const char *buf, unsigned int len)
+{
+ return send(fd, buf,len,0);
+}
diff --git a/conf-arch b/conf-arch
new file mode 100644
index 0000000..14ae354
--- /dev/null
+++ b/conf-arch
@@ -0,0 +1 @@
+crypto.tar.gz
diff --git a/conf-cc b/conf-cc
new file mode 100644
index 0000000..7f98c4c
--- /dev/null
+++ b/conf-cc
@@ -0,0 +1,5 @@
+gcc -O2 -Wall -ansi -D_GNU_SOURCE
+
+no -pedantic-errors because of netdb.h
+
+This will be used to compile .c files.
diff --git a/conf-ld b/conf-ld
new file mode 100644
index 0000000..59a0de7
--- /dev/null
+++ b/conf-ld
@@ -0,0 +1,3 @@
+gcc -s
+
+This will be used to link .o files into an executable.
diff --git a/crypto_buffer.c b/crypto_buffer.c
new file mode 100644
index 0000000..d17e805
--- /dev/null
+++ b/crypto_buffer.c
@@ -0,0 +1,82 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "crypto_buffer.h"
+
+
+#include <stdio.h>
+int crypto_buffer_init(crypto_buffer *s, int fd, operation op, u32 blocks, int type, u8 *key, u32 key_len)
+{
+ int ret;
+ int size;
+
+ if(blocks<3) return -1; /* magic + info + data */
+
+ s->fd = fd;
+ s->op = op;
+
+ if(type & BLOWFISH){
+ size = BF_BLOCK_SIZE;
+ ret = blowfish_setkey((struct blowfish_ctx*)&s->ctx, key, key_len, 0);
+ if(type & DECRYPT){ s->cipher = blowfish_decrypt; }
+ else { s->cipher = blowfish_encrypt; }
+ }
+ else if(type & TWOFISH){
+ size = TF_BLOCK_SIZE;
+ ret = twofish_setkey((struct twofish_ctx*)&s->ctx, key, key_len, 0);
+ if(type & DECRYPT) { s->cipher = twofish_decrypt; }
+ else {s->cipher = twofish_encrypt; }
+ }
+ else if(type & AES){
+ size = AES_BLOCK_SIZE;
+ ret = aes_setkey((struct aes_ctx*)&s->ctx, key, key_len, 0);
+ if(type & DECRYPT) { s->cipher = aes_decrypt; }
+ else {s->cipher = aes_encrypt; }
+ }
+ else if(type & DES){
+ size = DES_BLOCK_SIZE;
+ ret = des_setkey((struct des_ctx*)&s->ctx, key, key_len, 0);
+ if(type & DECRYPT) { s->cipher = des_decrypt; }
+ else {s->cipher = des_encrypt; }
+ }
+ else if(type & DES3_EDE){
+ size = DES3_EDE_BLOCK_SIZE;
+ ret = des3_ede_setkey((struct des3_ede_ctx*)&s->ctx, key, key_len, 0);
+ if(type & DECRYPT) { s->cipher = des3_ede_decrypt; }
+ else {s->cipher = des3_ede_encrypt; }
+ }
+ else return -1;
+ if(ret!=0) return -1;
+
+ if((U32_MAX / size) < blocks) return -1;
+
+ s->block_size = size;
+ s->e_len = size * blocks; /* TODO check overflow */
+ s->data_st.bytes = s->data_st.strlen = 0;
+ /* clear buffer */
+ s->c_buffer = malloc(size);
+ if(s->c_buffer==NULL) return -1;
+ s->c_ptr = s->c_buffer;
+ s->c_end = s->c_buffer + size;
+ /* encrypte buffer */
+ s->e_buffer = malloc(s->e_len);
+ if(s->e_buffer==NULL) return -1;
+ memset(s->e_buffer,0x5a,size); /* for write operation */
+ s->e_data = (struct info*)(s->e_buffer + size);
+ s->e_end = s->e_buffer + s->e_len;
+ if(type & DECRYPT){
+ s->e_ptr = s->e_buffer;
+ }
+ else{
+ s->e_ptr = s->e_buffer + (size << 1);
+ s->e_len -= (size << 1);
+ }
+/*
+ fprintf(stderr,"e_buffer : %x\n",s->e_buffer);
+ fprintf(stderr,"e_data : %x\n",s->e_data);
+ fprintf(stderr,"e_ptr : %x\n",s->e_ptr);
+ fprintf(stderr,"e_end : %x\n",s->e_end);
+ fprintf(stderr,"length : %d\n",s->e_len);
+*/
+ return ret;
+}
diff --git a/crypto_buffer.h b/crypto_buffer.h
new file mode 100644
index 0000000..51e233e
--- /dev/null
+++ b/crypto_buffer.h
@@ -0,0 +1,77 @@
+#ifndef CRYPTO_BUFFER_H
+#define CRYPTO_BUFFER_H
+
+#include "uint.h"
+#include "blowfish.h"
+#include "twofish.h"
+#include "aes.h"
+#include "des.h"
+
+struct info{
+ u32 strlen; /* number of uint8 of clear data */
+ u32 bytes; /* number of bytes of encrypted data */
+};
+#define ENCRYPT 0x0000
+#define DECRYPT 0x0001
+#define BLOWFISH 0x0002
+#define TWOFISH 0x0004
+#define AES 0x0008
+#define DES 0x0010
+#define DES3_EDE 0x0020
+
+typedef int (*operation)(int ,u8* ,u32);
+
+typedef struct crypto_buffer {
+ u8 *c_buffer; /* clear data buffer */
+ u8* c_ptr; /* clear data to read */
+ u8* c_end; /* end of c_buffer */
+ u8 *e_buffer; /* encrypted data buffer */
+ u8* e_ptr; /* encrypted data to read */
+ u8* e_end; /* end of e_buffer */
+ u32 e_len; /* length of e_buffer */
+ u32 block_size; /* size of blocks used by cipher */
+ struct info *e_data; /* pointer for write operations */
+ struct info data_st; /* info structure for read and write operations */
+ int fd; /* file descriptor */
+ operation op; /* read/write operation */
+ void (*cipher)(void*, u8 *, const u8 *); /* encryption/decryption function */
+ union{ /* cipher ctx */
+ struct blowfish_ctx bf_cxt;
+ struct twofish_ctx tf_cxt;
+ }ctx;
+} crypto_buffer;
+
+
+/* initialize a buffer for read or write operation
+ * buffer struct
+ * file descriptor
+ * read or write operation
+ * number of blocks in buffer
+ * type of cipher (BLOWFISH/TWOFISH/AES | ENCRYPT/DECRYPT)
+ * encryption key
+ * length of encryption key
+ */
+int crypto_buffer_init(crypto_buffer *b, int fd, operation op, u32 blocks, int type, u8 *key, u32 k_len);
+
+
+/* force write on fd */
+int crypto_buffer_flush(crypto_buffer *b);
+
+/* read data from buffer */
+int crypto_buffer_get(crypto_buffer *b, u8 *s, u32 len);
+
+/* add data to buffer */
+int crypto_buffer_put(crypto_buffer *b, const u8 *s, u32 len);
+
+/* add data to buffer then force write on fd */
+int crypto_buffer_putflush(crypto_buffer *b, const u8 *s, u32 len);
+
+/* read/write to fd */
+int u8_unix_read(int fd, u8 *s, u32 len);
+int u8_unix_write(int fd, u8 *s, u32 len);
+/* not really usefull read/write also work */
+int u8_tcp_read(int sd, u8 *s, u32 len);
+int u8_tcp_write(int sd, u8 *s, u32 len);
+
+
+#endif
diff --git a/crypto_buffer_get.c b/crypto_buffer_get.c
new file mode 100644
index 0000000..33e99f0
--- /dev/null
+++ b/crypto_buffer_get.c
@@ -0,0 +1,182 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "crypto_buffer.h"
+
+
+/* after this s->e_ptr and s->e_end are updated */
+static int firstread(crypto_buffer *s)
+{
+ register u8 *ptr1, *ptr2, *buffer;
+ register u32 size;
+ u32 r, i;
+
+ /* look for the 0x5a block */
+ buffer = s->e_buffer;
+ size = s->block_size;
+ for(;;){
+ ptr1 = ptr2 = buffer;
+ r = s->op(s->fd, buffer, s->e_len);
+ if (r == 0) return 0; /* end of file */
+ if (r == -1){
+ if (errno == EINTR) continue; /* reread */
+ return r; /* read error */
+ }
+ if (r <= (size << 1)) return -1; /* no data */
+ i = r;
+ do{
+ i -= (ptr1-ptr2);
+ if (i==0) { ptr2 = NULL; break; } /* force reread */
+ ptr2 = memchr(ptr1, 0x5a, i);
+ if (ptr2 == NULL) break; /* reread */
+ ptr1 = ptr2;
+ for(;;) { if(*ptr1++!=0x5a) break; }
+ }while(ptr1-ptr2 < size);
+ if (ptr2 != NULL) break;
+ }
+ /* now ptr2 points to the 0x5a block */
+ ptr2 += size;
+ /* decrypt info */
+ s->cipher(&s->ctx,buffer, ptr2);
+ s->data_st.bytes = ((struct info *)buffer)->bytes;
+ s->data_st.strlen = ((struct info *)buffer)->strlen;
+ s->e_ptr = ptr2 + size;
+ r -= (size << 1);
+ i = s->e_ptr - (u8*)s->e_data - size;
+ if(i>0){
+ memmove(s->e_ptr-i, s->e_ptr, r-i);
+ s->e_ptr -= i;
+ if(s->op(s->fd, s->e_ptr+r-i, i)<=0) return r; /* really bad */
+ }
+ s->e_end = s->e_ptr + r;
+ return r;
+}
+
+
+/* after this s->e_ptr and s->e_end are updated */
+static int oneread(crypto_buffer *s)
+{
+ int r;
+ for (;;) {
+ r = s->op(s->fd,s->e_buffer,s->e_len);
+ if (r == -1) if (errno == EINTR) continue;
+ s->e_ptr = s->e_buffer;
+ s->e_end = s->e_ptr + r;
+ return r;
+ }
+}
+
+
+/* after this s->e_ptr is updated */
+static int eatinfo(crypto_buffer *s, u8* start)
+{
+ register u32 size;
+ register u8* buffer;
+ register u8* current;
+ int ret;
+
+ /* be really carefull */
+ current = start;
+ size = s->block_size;
+ buffer = s->e_buffer;
+ if(current == s->e_end){
+ ret = oneread(s);
+ if(ret<=0) return ret; /* error */
+ current = buffer;
+ }
+ /* TODO ?? verify that it's a magic block */
+ current += size; /* jump over 0x5a block */
+ if(current == s->e_end){
+ ret = oneread(s);
+ if(ret<=0) return ret; /* error */
+ current = buffer;
+ }
+ s->cipher(&s->ctx,buffer,current);
+ s->data_st.bytes = ((struct info *)buffer)->bytes;
+ s->data_st.strlen = ((struct info *)buffer)->strlen;
+ current += size; /* jump over info */
+ if(current == s->e_end){
+ ret = oneread(s);
+ if(ret<=0) return ret; /* error */
+ current = buffer;
+ }
+ s->e_ptr = current;
+ return 1;
+}
+
+
+/* afer this s->c_ptr is updated */
+static int getthis(crypto_buffer *s, u8 *buf, u32 len)
+{
+ int available;
+
+ available = s->c_end - s->c_ptr;
+ if (len > available) len = available;
+ memcpy(buf, s->c_ptr, len);
+ s->c_ptr += len;
+ return len;
+}
+
+
+int crypto_buffer_get(crypto_buffer *s, u8 *buf, u32 len)
+{
+ register u32 need;
+ register u32 size;
+ register u8* e_end;
+ register u8* e_ptr;
+ int r, ret;
+
+ r = 0;
+ need = len;
+ size = s->block_size;
+ if(s->e_ptr == s->e_buffer){
+ ret = firstread(s);
+ if(ret <=0) return ret;
+ }
+ if (s->c_ptr != s->c_buffer){ /* TODO maybe else if */
+ r = getthis(s,buf,need);
+ if (r == need )return r;
+ need -= r;
+ buf += r;
+ }
+ /* now s->c_buffer is empty */
+ e_end = s->e_end;
+ e_ptr = s->e_ptr;
+ while(need){
+ if(e_ptr == e_end){
+ /* buffer empty */
+ ret = oneread(s);
+ if(ret < 0) return ret;
+ if(ret == 0) return r;
+ e_ptr = s->e_ptr;
+ e_end = s->e_end;
+ }
+ if(s->data_st.bytes == 0) {
+ /* end of raw encrypted data */
+ ret = eatinfo(s,e_ptr);
+ if(ret < 0) return ret;
+ if(ret == 0) return r;
+ e_ptr = s->e_ptr;
+ }
+ s->cipher(&s->ctx, s->c_buffer, e_ptr);
+ s->data_st.bytes -= size;
+ e_ptr += size;
+ /* now c_buffer is full */
+ if(s->data_st.strlen < size){
+ /* non fully used block */
+ s->c_ptr = s->c_end - s->data_st.strlen;
+ memmove(s->c_ptr, s->c_buffer, s->data_st.strlen);
+ } else {
+ s->data_st.strlen -= size;
+ s->c_ptr = s->c_buffer;
+ }
+ ret = getthis(s,buf,need);
+ need -= ret;
+ buf += ret;
+ r+= ret;
+ }
+ s->e_ptr = e_ptr;
+ return r;
+}
diff --git a/crypto_buffer_put.c b/crypto_buffer_put.c
new file mode 100644
index 0000000..74f30a0
--- /dev/null
+++ b/crypto_buffer_put.c
@@ -0,0 +1,112 @@
+#include <errno.h>
+#include <string.h>
+
+#include "crypto_buffer.h"
+
+
+/* s->data_st must have been set */
+/* after this s->e_ptr is updated */
+static int allwrite(crypto_buffer *s)
+{
+ u8 *buffer;
+ int w, bytes;
+
+ buffer = s->e_buffer;
+ bytes = s->data_st.bytes + (s->block_size << 1);
+ s->cipher(&s->ctx,(u8*)s->e_data,(u8*)&s->data_st);
+ while (bytes) {
+ w = s->op(s->fd,buffer,bytes);
+ if (w == -1) {
+ if (errno == EINTR) continue;
+ return -1; /* note that some data may have been written */
+ }
+ if (w == 0) ; /* luser's fault */
+ buffer += w;
+ bytes -= w;
+ }
+ s->e_ptr = (u8*)s->e_data + s->block_size;
+ return 0;
+}
+
+
+/* after this s->e_ptr and s->c_ptr are updated */
+int crypto_buffer_flush(crypto_buffer *s)
+{
+ register u32 len, len2;
+ register u8* e_ptr;
+
+ len = s->e_len;
+ e_ptr = s->e_ptr;
+ if(e_ptr == s->e_end) {
+ s->data_st.bytes = s->data_st.strlen = len;
+ if (allwrite(s) == -1) return -1;
+ e_ptr = s->e_ptr;
+ }
+ len2 = len = e_ptr + s->e_len - s->e_end; /* used bytes in e_buffer */
+ if(s->c_ptr != s->c_buffer){
+ s->cipher(&s->ctx, e_ptr, s->c_buffer);
+ len += s->block_size;
+ len2 += s->c_ptr - s->c_buffer;
+ }
+ s->data_st.bytes = len;
+ s->data_st.strlen = len2;
+ if (allwrite(s) == -1) return -1;
+ s->c_ptr = s->c_buffer;
+ return 0;
+}
+
+int crypto_buffer_put(crypto_buffer *s,const u8 *buf,u32 len)
+{
+ register u32 size;
+ register u8* e_ptr;
+ register u8* e_end;
+ u32 free;
+
+ free = s->c_end - s->c_ptr;
+ if (len > free) {
+ if(free){
+ memcpy(s->c_ptr, buf, free);
+ buf += free;
+ len -= free;
+ }
+ /* now c_buffer is full */
+ e_ptr = s->e_ptr;
+ e_end = s->e_end;
+ size = s->block_size;
+ if(e_ptr == e_end) {
+ /* e_buffer full */
+ s->data_st.bytes = s->data_st.strlen = s->e_len;
+ if (allwrite(s) == -1) return -1;
+ e_ptr = s->e_ptr;
+ }
+ s->cipher(&s->ctx, e_ptr, s->c_buffer);
+ e_ptr += size;
+ s->c_ptr = s->c_buffer;
+ /* now c_buffer is empty */
+ while(len > size){
+ if(e_ptr == e_end) {
+ s->data_st.bytes = s->data_st.strlen = s->e_len;
+ if (allwrite(s) == -1) return -1;
+ e_ptr = s->e_ptr;
+ }
+ s->cipher(&s->ctx, e_ptr, buf);
+ e_ptr += size;
+ buf += size;
+ len -= size;
+ }
+ /* don't forget */
+ s->e_ptr = e_ptr;
+ }
+ /* now len < s->block_size + s->c_buffer - s->c_ptr */
+ if(len){
+ memcpy(s->c_ptr, buf, len);
+ s->c_ptr += len;
+ }
+ return 0;
+}
+
+int crypto_buffer_putflush(crypto_buffer *s,const u8 *buf,u32 len)
+{
+ if (crypto_buffer_put(s, buf, len) == -1) return -1;
+ return crypto_buffer_flush(s);
+}
diff --git a/cryptot.c b/cryptot.c
new file mode 100644
index 0000000..da565e1
--- /dev/null
+++ b/cryptot.c
@@ -0,0 +1,570 @@
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "cryptot.h"
+#include "crypto_buffer.h"
+#include "ipv4.h"
+#include "scan.h"
+#include "socket.h"
+
+#define HOSTLEN 64 /* length of hostname string in resolvip */
+
+/*
+ * adding ciphers, fct to update :
+ * usage_cipher
+ * change_cipher
+ * allocate_buffer
+ * do_stats
+ */
+
+
+static void connect_to_dist(int sock, struct cryptot_st *data, int verbose)
+{
+ int retry = 5;
+ char buf[2];
+ if(socket_local4(sock,data->local_ip,&data->local_port)==-1)
+ fprintf(stderr,"%s : socket_local4 error.\n",PROG_NAME);
+ if(verbose){
+ fprintf(stderr,"%s : trying to connect to %03d.%03d.%03d.%03d:%d "
+ "from %03d.%03d.%03d.%03d:%d\n",PROG_NAME,
+ NIPQUAD(data->dist_ip),data->dist_port,NIPQUAD(data->local_ip),data->local_port);
+ }
+ while(retry--){
+ if(!socket_connect4(sock,data->dist_ip,data->dist_port)){
+ /* TODO we may be rejected by -S option */
+ if(!recv(sock,buf,2,0)){
+ fprintf(stderr,"%s : rejected (because of -S option ?).\n",PROG_NAME); exit(1);
+ }
+ if(strncmp(buf,"OK",2)) {
+ fprintf(stderr,"%s : protocol error (middle man ?).\n",PROG_NAME); exit(1);
+ }
+ if(verbose)fprintf(stderr,"%s : connected.\n",PROG_NAME);
+ return;
+ }
+ sleep(3);
+ fprintf(stderr,"%s : connect failed, retry\n",PROG_NAME);
+ }
+ fprintf(stderr,"%s socket_connect4 error :",PROG_NAME);
+ perror("");
+ exit(1);
+}
+
+static int wait_connection(int sock, struct cryptot_st *data, int verbose)
+{
+ int client;
+ char peer_ip[4];
+ unsigned int peer_port;
+
+ for(;;){
+ if(verbose)
+ fprintf(stderr,"%s : waiting for a connection on %03d.%03d.%03d.%03d:%d.\n",
+ PROG_NAME, NIPQUAD(data->local_ip),data->local_port);
+ client = socket_accept4(sock,peer_ip,&peer_port);
+ if(client<0){ fprintf(stderr,"%s socket_accept error : ",PROG_NAME); perror(""); exit(1); }
+
+ if(data->check_accept){
+ if(peer_port != data->src_port || memcmp(data->src_ip,peer_ip,4)){
+ fprintf(stderr,"%s : REFUSE connection from %03d.%03d.%03d.%03d:%d.\n",
+ PROG_NAME,NIPQUAD(peer_ip),peer_port);
+ shutdown(client,SHUT_RDWR);
+ close(client);
+ continue;
+ }
+ }
+ send(client,"OK",2,0);
+ if(verbose)
+ fprintf(stderr,"%s : accept connection from %03d.%03d.%03d.%03d:%d.\n",
+ PROG_NAME,NIPQUAD(peer_ip),peer_port);
+ return client;
+ }
+}
+
+static void do_stats(struct cryptot_st *data, struct timespec *s0, struct timespec *s1, unsigned int count)
+{
+ char *cipher=NULL;
+ char b[6] = "bytes";
+ char kb[3] = "Kb";
+ char mb[3] = "Mb";
+ char gb[3] = "Gb";
+ char *unit = b;
+ float time;
+ int size =0;
+ float nbr =(float)count;
+
+ if(nbr> 1024){ nbr/=1024; unit=kb;}
+ if(nbr> 1024){ nbr/=1024; unit=mb;}
+ if(nbr> 1024){ nbr/=1024; unit=gb;}
+
+ time = (float)(s1->tv_sec - s0->tv_sec)+((float)(s1->tv_nsec-s0->tv_nsec))/1E9;
+ if (data->cipher & BLOWFISH) { cipher ="blowfish"; size = data->blocks*BF_BLOCK_SIZE;}
+ else if (data->cipher & TWOFISH) { cipher ="twofish"; size = data->blocks*TF_BLOCK_SIZE; }
+ else if (data->cipher & AES) { cipher ="aes"; size = data->blocks*AES_BLOCK_SIZE; }
+ else if (data->cipher & DES) { cipher ="des"; size = data->blocks*DES_BLOCK_SIZE; }
+ else if (data->cipher & DES3_EDE) { cipher ="des3_ede"; size = data->blocks*DES3_EDE_BLOCK_SIZE; }
+ fprintf(stderr,"\n%s statistics :\n",PROG_NAME);
+ fprintf(stderr,"\nusing %s cipher with a buffer of %d bytes.\n",cipher, size);
+ fprintf(stderr,"\n%.3f %s read in %0.2f second(s) ",nbr,unit,time);
+ fprintf(stderr,"=> %.3f %s/sec.\n",nbr/time,unit);
+}
+
+static void usage(void)
+{
+ fprintf(stderr,"%s version %s, Copyright (C) 2004 Zurcher Jeremy\n",PROG_NAME,VERSION);
+ fprintf(stderr,"\tThis program is free software; you can redistribute it and/or modify\n");
+ fprintf(stderr,"\tit under the terms of the GNU General Public License as published by\n");
+ fprintf(stderr,"\tthe Free Software Foundation; either version 2 of the License, or\n");
+ fprintf(stderr,"\t(at your option) any later version.\n");
+ fprintf(stderr,"\tThis program is distributed in the hope that it will be useful,\n");
+ fprintf(stderr,"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n");
+ fprintf(stderr,"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
+ fprintf(stderr,"\tGNU General Public License for more details.\n\n");
+
+ fprintf(stderr,"usage : %s [-v] [-x] [-c cipher] [-n nbr_blocks]\n"
+ " [-s [ip]:[port]] [-d [ip]:[port]] [-b [ip]:[port]] [-S [ip]:[port]] key\n",PROG_NAME);
+ fprintf(stderr,"\t\t-v : verbose mode (statistics)\n");
+ fprintf(stderr,"\t\t-x : decrypt input (default is encrypt input)\n");
+ fprintf(stderr,"\t\t-c cipher : -c h for help (default = blowfish)\n");
+ fprintf(stderr,"\t\t-n nbr_blocks : nbr blocks in buffer (default = %d/CIPHER_BLOCK_SIZE)\n",BUFFER_LENGTH);
+ fprintf(stderr,"\t\t-s ip:port : local address to read from\n");
+ fprintf(stderr,"\t\t-d ip:port : distant address to write to\n");
+ fprintf(stderr,"\t\t-b ip:port : local address used for distant connection (use with -d option)\n");
+ fprintf(stderr,"\t\t-S ip:port : distant address to accept connection from (use with -s option)\n");
+ fprintf(stderr,"\t\t key : symetric secret key (see '-c h' for tips about key length)\n");
+ fprintf(stderr,"\t\t MUST be the last argument of the command line.\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\twithout -s option reads input from stdin.\n");
+ fprintf(stderr,"\twithout -d option writes output to stdout.\n");
+ fprintf(stderr,"\twithout -S option accept connection from 'the first one'.\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\tif no ip is provided with s, d, b or S option, hostname is resolved and used.\n");
+ fprintf(stderr,"\tif no port is provided with s, d, b or S option %d is used.\n",DEFAULT_PORT);
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\texample:\n\t\t%s -s :5000 -S 10.10.10.10:200 -d 10.10.10.10: -b : my_secret_key\n",PROG_NAME);
+ fprintf(stderr,"\t\twill listen on hostname:5000 for incoming data from 10.10.10.10:200, \n");
+ fprintf(stderr,"\t\tencrypt it and send it to 10.10.10.10:%d through hostname:%d. \n",DEFAULT_PORT,DEFAULT_PORT);
+ fprintf(stderr,"\n");
+ exit(1);
+}
+
+static void usage_cipher(void)
+{
+ fprintf(stderr,"available ciphers :\n");
+ fprintf(stderr,"\t0 : _Blowfish : A 64-Bit Block Cipher_ by Bruce Schneier...\n");
+ fprintf(stderr,"\t1 : _Towfish : A 128-Bit Block Cipher_ by Bruce Schneier... (keylength : 16,24,32)\n");
+ fprintf(stderr,"\t2 : _aes : A 128-Bit Block Cipher_ known as Rijndael... (keylength : 16,24,32)\n");
+ fprintf(stderr,"\t3 : _des : A 64-Bit BLock Cipher_ improvement of Lucifer from IBM.. (keylength : 56)\n");
+ fprintf(stderr,"\t4 : _des3_ede : Tripple des C = des_enc(des_dec(des_enc(M)))\n");
+ fprintf(stderr,"\tnext to come : ??\n\n");
+ exit(1);
+}
+
+static void init_data(struct cryptot_st *data)
+{
+ data->key = NULL;
+ data->buffer = NULL;
+ data->size = -1;
+ data->blocks = -1;
+ data->cipher = DEFAULT_CIPHER;
+ data->check_accept = 0;
+ data->in_fd = 0;
+ data->out_fd = 1;
+ data->src_port = DEFAULT_PORT;
+ data->dist_port = DEFAULT_PORT;
+ data->local_port = DEFAULT_PORT;
+ data->src_ip[0] = data->src_ip[1] = data->src_ip[2] = data->src_ip[3] = 0;
+ data->dist_ip[0] = data->dist_ip[1] = data->dist_ip[2] = data->dist_ip[3] = 0;
+ data->local_ip[0] = data->local_ip[1] = data->local_ip[2] = data->local_ip[3] = 0;
+}
+
+/* update cipher param */
+static void change_cipher(unsigned int *cipher, unsigned long param)
+{
+ *cipher &= DECRYPT;
+ if(param==0){ *cipher |= BLOWFISH; return ; }
+ if(param==1){ *cipher |= TWOFISH; return; }
+ if(param==2){ *cipher |= AES; return; }
+ if(param==3){ *cipher |= DES; return; }
+ if(param==4){ *cipher |= DES3_EDE; return; }
+ fprintf(stderr,"%s : unknown cipher.\n",PROG_NAME);
+ exit(1);
+}
+
+/* set ip to localhost if == 0:0:0:0 */
+static void resolve_ip(char *ip)
+{
+ char hostname[HOSTLEN];
+ struct hostent *hp;
+
+ if(ip[0] == ip[1] && ip[1] == ip[2] && ip[2] == ip[3] && ip[3] == 0){
+ if(gethostname(hostname,HOSTLEN)==-1){
+ fprintf(stderr,"%s error ",PROG_NAME);
+ perror("gethostname "); exit(1);
+ }
+ if((hp = gethostbyname(hostname))==NULL){
+ fprintf(stderr,"%s : can't resolve %s, ",PROG_NAME,hostname);
+ herror("\tgethostbyname "); exit(1);
+ }
+ memcpy(ip,hp->h_addr,4);
+ }
+}
+
+
+/* if ip is 0:0:0:0 use localhost, bind to ip/port call listen if required */
+static int bind_to(char *ip, int port, int listen)
+{
+ int socket;
+
+ if((socket = socket_tcp(1))==-1) { fprintf(stderr,"%s error in ",PROG_NAME); perror("socket_tcp "); exit(1); }
+
+ if(socket_bind4(socket,ip,port)==-1) {
+ fprintf(stderr,"%s : unable to bind to %03d.%03d.%03d.%03d:%d",PROG_NAME,NIPQUAD(*ip),port);
+ perror("\tsocket_bind "); exit(1);
+ }
+
+ if(listen) if(socket_listen(socket,20)==-1) {
+ fprintf(stderr,"%s error in ",PROG_NAME); perror("socket_listen "); exit(1);
+ }
+
+ return socket;
+}
+
+/* compute blocks if == -1, allocate buffer, set size */
+static char* allocate_buffer(unsigned int cipher, unsigned int *blocks, unsigned int *size)
+{
+ char *buffer = NULL;
+ int tmp = *blocks;
+
+ if(tmp==-1){
+ if(cipher & BLOWFISH) tmp = BUFFER_LENGTH/BF_BLOCK_SIZE;
+ else if(cipher & TWOFISH) tmp = BUFFER_LENGTH/TF_BLOCK_SIZE;
+ else if(cipher & AES) tmp = BUFFER_LENGTH/AES_BLOCK_SIZE;
+ else if(cipher & DES) tmp = BUFFER_LENGTH/DES_BLOCK_SIZE;
+ else if(cipher & DES3_EDE) tmp = BUFFER_LENGTH/DES3_EDE_BLOCK_SIZE;
+ buffer = (char*)malloc(BUFFER_LENGTH);
+ } else {
+ if(cipher & BLOWFISH) buffer = (char*)malloc(tmp*BF_BLOCK_SIZE);
+ else if(cipher & TWOFISH) buffer = (char*)malloc(tmp*TF_BLOCK_SIZE);
+ else if(cipher & AES) buffer = (char*)malloc(tmp*AES_BLOCK_SIZE);
+ else if(cipher & DES) buffer = (char*)malloc(tmp*DES_BLOCK_SIZE);
+ else if(cipher & DES3_EDE) buffer = (char*)malloc(tmp*DES3_EDE_BLOCK_SIZE);
+ }
+ if(buffer==NULL) { fprintf(stderr,"%s : not enough memory for buffer.\n",PROG_NAME); exit(1); }
+ if(cipher & BLOWFISH) *size = tmp * BF_BLOCK_SIZE;
+ else if(cipher & TWOFISH) *size = tmp * TF_BLOCK_SIZE;
+ else if(cipher & AES) *size = tmp * AES_BLOCK_SIZE;
+ else if(cipher & DES) *size = tmp * DES_BLOCK_SIZE;
+ else if(cipher & DES3_EDE) *size = tmp * DES3_EDE_BLOCK_SIZE;
+ *blocks = tmp;
+ return buffer;
+}
+
+static void c_encrypt(struct cryptot_st *data, int verbose)
+{
+ register unsigned int ret = 0;
+ register unsigned int reg = 0;
+ register unsigned int size = data->size;
+ register u8 *buffer = (u8*)data->buffer;
+
+ operation op;
+ int input, output;
+ crypto_buffer c_buffer;
+ struct timespec s0, s1;
+
+ input = data->in_fd;
+ output = data->out_fd;
+
+ if(output==1) op = &u8_unix_write;
+ else{
+ op = &u8_tcp_write;
+ connect_to_dist(output,data,verbose);
+ }
+ if(crypto_buffer_init(&c_buffer, output, op, data->blocks, data->cipher, (u8*)data->key, strlen(data->key))==-1){
+ fprintf(stderr,"%s : crypto_buffer_init_error. Check your key len. (try -c h)\n",PROG_NAME); exit(1);
+ }
+ /* now I'm ready to write */
+
+ if(input==0){
+ if(verbose){
+ clock_gettime(MY_CLOCK, &s0);
+ while((ret=read(input, buffer, size))>0){
+ reg += ret;
+ if(crypto_buffer_put(&c_buffer,buffer,ret)==-1){
+ fprintf(stderr,"%s crypto_buffer_put error ",PROG_NAME); perror(""); exit(1);
+ }
+ }
+ }
+ else{
+ reg = (unsigned int)&c_buffer;
+ while((ret=read(input, buffer, size))>0)
+ if(crypto_buffer_put((crypto_buffer*)reg,buffer,ret)==-1){
+ fprintf(stderr,"%s crypto_buffer_put error ",PROG_NAME); perror(""); exit(1);
+ }
+ }
+ } else {
+ reg = wait_connection(input,data,verbose);
+ if(verbose){
+ clock_gettime(MY_CLOCK, &s0);
+ while((ret=recv(reg, buffer, size, 0))>0){
+ reg += ret;
+ if(crypto_buffer_put(&c_buffer,buffer,ret)==-1){
+ fprintf(stderr,"%s crypto_buffer_put error ",PROG_NAME); perror(""); exit(1);
+ }
+ }
+ }
+ else{
+ reg = (unsigned int)&c_buffer;
+ while((ret=recv(reg, buffer, size, 0))>0)
+ if(crypto_buffer_put((crypto_buffer*)reg,buffer,ret)==-1){
+ fprintf(stderr,"%s crypto_buffer_put error ",PROG_NAME); perror(""); exit(1);
+ }
+ }
+ shutdown(reg,SHUT_RDWR);
+ close(reg); /* close client socket */
+ }
+ crypto_buffer_flush(&c_buffer);
+ if(ret==-1){ fprintf(stderr,"%s read error ",PROG_NAME); perror(""); exit(1); }
+ if(verbose) {
+ clock_gettime(MY_CLOCK, &s1);
+ do_stats(data, &s0, &s1, reg);
+ }
+}
+
+static void c_decrypt(struct cryptot_st *data, int verbose)
+{
+ register int n = 0;
+ register unsigned int ret = 0;
+ register unsigned int reg = 0;
+ register unsigned int size = data->size;
+ register u8 *buffer = (u8*)data->buffer;
+
+ operation op;
+ int input, output;
+ crypto_buffer c_buffer;
+ struct timespec s0, s1;
+
+ input = data->in_fd;
+ output = data->out_fd;
+
+ if(input==0) op = &u8_unix_read;
+ else{
+ op = &u8_tcp_read;
+ input = wait_connection(input,data,verbose);
+ }
+ if(crypto_buffer_init(&c_buffer, input, op, data->blocks, data->cipher, (u8*)data->key, strlen(data->key))==-1){
+ fprintf(stderr,"%s : crypto_buffer_init_error. Check your key len. (try -c ?)\n",PROG_NAME); exit(1);
+ }
+ /* now I'm ready to read */
+
+ if(output==1){
+ if(verbose){
+ clock_gettime(MY_CLOCK, &s0);
+ while((ret=crypto_buffer_get(&c_buffer, buffer, size))>0){
+ reg += ret;
+ n = write(output, buffer, ret);
+ }
+ }
+ else{
+ reg = (unsigned int)&c_buffer;
+ while((ret=crypto_buffer_get(&c_buffer, buffer, size))>0)
+ n = write(output, buffer, ret);
+ }
+ } else {
+ connect_to_dist(output,data,verbose);
+ if(verbose){
+ clock_gettime(MY_CLOCK, &s0);
+ while((ret=crypto_buffer_get(&c_buffer, buffer, size))>0){
+ reg += ret;
+ if(send(output, buffer, ret, MSG_CONFIRM)==-1){
+ fprintf(stderr,"%s send error ",PROG_NAME); perror(""); exit(1);
+ }
+ }
+ }
+ else{
+ reg = (unsigned int)&c_buffer;
+ while((ret=crypto_buffer_get(&c_buffer, buffer, size))>0)
+ if(send(output, buffer, ret, MSG_CONFIRM)==-1){
+ fprintf(stderr,"%s send error ",PROG_NAME); perror(""); exit(1);
+ }
+ }
+
+ }
+ if(input!=0) { shutdown(input,SHUT_RDWR); close(input); } /* close client socket */
+ if(ret==-1){ fprintf(stderr,"%s read error ",PROG_NAME); perror(""); exit(1); }
+ if(verbose) {
+ clock_gettime(MY_CLOCK, &s1);
+ do_stats(data, &s0, &s1, reg);
+ }
+}
+
+static void argument_error(char opt, int wrong)
+{
+ if(wrong) fprintf(stderr,"%s : -%c option, wrong argument.\n",PROG_NAME,opt);
+ else fprintf(stderr,"%s : -%c option, argument missing.\n",PROG_NAME,opt);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ /* general */
+ int ret;
+ char *tmp;
+ unsigned long param;
+ unsigned int verbose = 0;
+ char bind_ip[4];
+ unsigned int bind_port;
+
+ /* crypto */
+ struct cryptot_st data;
+
+ init_data(&data);
+ bind_ip[0] = bind_ip[1] = bind_ip[2] = bind_ip[3] = 0;
+ bind_port = DEFAULT_PORT;
+
+ if(!--argc) usage();
+ ++argv;
+ while(argc--){
+ if((*argv)[0]=='-'){
+ if((*argv)[1]=='v') verbose = 1;
+
+ else if((*argv)[1]=='x') data.cipher|=DECRYPT;
+
+ else if((*argv)[1]=='n') {
+ if(!argc--) argument_error('n',0);
+ ret=scan_ulong(*(++argv),&param);
+ if(!ret || (*argv)[ret]) argument_error('n',1);
+ data.blocks = (unsigned int)param;
+ }
+
+ else if((*argv)[1]=='c') {
+ if(!argc--) argument_error('c',0);
+ if(*(*(++argv))=='h') usage_cipher();
+ ret=scan_ulong(*argv,&param);
+ if(!ret || (*argv)[ret])argument_error('c',1);
+ change_cipher(&data.cipher,param);
+ }
+
+ else if((*argv)[1]=='s') {
+ if(!argc--) argument_error('s',0);
+ ret=ipv4_scan(*(++argv),data.local_ip);
+ tmp = &(*argv)[ret];
+ if(*tmp++!=':') argument_error('s',1);
+ ret=scan_ulong(tmp,&param);
+ if(ret) data.local_port = (unsigned int)param;
+ if(*(tmp+ret)) argument_error('s',1);
+ data.in_fd = -1;
+ }
+
+ else if((*argv)[1]=='b') {
+ if(!argc--) argument_error('b',0);
+ ret=ipv4_scan(*(++argv),bind_ip);
+ tmp = &(*argv)[ret];
+ if(*tmp++!=':') argument_error('b',1);
+ ret=scan_ulong(tmp,&param);
+ if(ret) bind_port = (unsigned int)param;
+ if(*(tmp+ret)) argument_error('b',1);
+ }
+
+ else if((*argv)[1]=='d') {
+ if(!argc--) argument_error('d',0);
+ ret=ipv4_scan(*(++argv),data.dist_ip);
+ tmp = &(*argv)[ret];
+ if(*tmp++!=':') argument_error('d',1);
+ ret=scan_ulong(tmp,&param);
+ if(ret) data.dist_port = (unsigned int)param;
+ if(*(tmp+ret)) argument_error('d',1);
+ data.out_fd = -1;
+ }
+
+ else if((*argv)[1]=='S') {
+ if(!argc--) argument_error('S',0);
+ ret=ipv4_scan(*(++argv),data.src_ip);
+ tmp = &(*argv)[ret];
+ if(*tmp++!=':') argument_error('S',1);
+ ret=scan_ulong(tmp,&param);
+ if(ret) data.src_port = (unsigned int)param;
+ if(*(tmp+ret)) argument_error('S',1);
+ data.check_accept = 1;
+ }
+ else usage();
+ }
+ else { data.key = *argv; break; }
+ argv++;
+ }
+ if(!data.key) usage();
+
+ /* if ip is 0:0:0:0 call gethostname and gethostbyname */
+ if(data.in_fd != 0) resolve_ip(data.local_ip);
+ if(data.out_fd != 1){ resolve_ip(data.dist_ip); resolve_ip(bind_ip); }
+ if(data.in_fd != 0 && data.check_accept) resolve_ip(data.src_ip);
+
+ /* if input AND output have been changed, check that local != bind AND local != distant */
+ if(data.in_fd != 0 && data.out_fd != 1){
+ if(data.local_port == bind_port && !memcmp(data.local_ip,bind_ip,4)){
+ fprintf(stderr,"%s : trying to bind twice to same address; use -b option.\n",PROG_NAME);
+ exit(1);
+ }
+ if(data.local_port == data.dist_port && !memcmp(data.local_ip,data.dist_ip,4)){
+ fprintf(stderr,"%s : trying to read from output, you crazy !\n",PROG_NAME);
+ exit(1);
+ }
+ }
+
+ if(data.in_fd != 0) data.in_fd = bind_to(data.local_ip, data.local_port, 1); /* bind and listen */
+ if(data.out_fd != 1) data.out_fd = bind_to(bind_ip, bind_port, 0); /* bind */
+
+ data.buffer = allocate_buffer(data.cipher, &data.blocks, &data.size); /* allocate buffer and set blocks & size */
+
+#ifdef _DEBUG_
+ fprintf(stderr,"user defind aprameters :\n");
+ fprintf(stderr,"\tcipher : %d\n",data.cipher);
+ fprintf(stderr,"\tblocks : %d\n",data.blocks);
+ fprintf(stderr,"\tsize : %d\n",data.size);
+ fprintf(stderr,"\tkey : %s\n",data.key);
+ fprintf(stderr,"\tlocal %03d.%03d.%03d.%03d:%d\n",
+ NIPQUAD(data.local_ip),data.local_port);
+ fprintf(stderr,"\tdist %03d.%03d.%03d.%03d:%d\n",
+ NIPQUAD(data.dist_ip),data.dist_port);
+ fprintf(stderr,"\tbind %03d.%03d.%03d.%03d:%d\n",
+ NIPQUAD(bind_ip),bind_port);
+ fprintf(stderr,"\tsrc %03d.%03d.%03d.%03d:%d\n",
+ NIPQUAD(src_ip),src_port);
+#endif
+
+ if(verbose){
+ fprintf(stderr,"%s : running in verbose mode:\n",PROG_NAME);
+ if(data.in_fd !=0){
+ socket_local4(data.in_fd,data.local_ip,&data.local_port);
+ fprintf(stderr,"%s : reading from : %03d.%03d.%03d.%03d:%d\n",
+ PROG_NAME,NIPQUAD(data.local_ip),data.local_port);
+ if(data.check_accept) fprintf(stderr,"%s : accept connection from : %03d.%03d.%03d.%03d:%d\n",
+ PROG_NAME,NIPQUAD(data.src_ip),data.src_port);
+ else fprintf(stderr,"%s : accept connection from anywhere.\n",PROG_NAME);
+ }
+ else fprintf(stderr,"%s : reading from stdin\n",PROG_NAME);
+ if(data.out_fd !=1){
+ socket_local4(data.out_fd,data.local_ip,&data.local_port);
+ fprintf(stderr,"%s : writing through to : %03d.%03d.%03d.%03d:%d\n",
+ PROG_NAME,NIPQUAD(data.local_ip),data.local_port);
+ }
+ else fprintf(stderr,"%s : writing to stdout\n",PROG_NAME);
+ }
+
+ if(data.cipher&DECRYPT){
+ c_decrypt(&data,verbose);
+ }
+ else{
+ c_encrypt(&data,verbose);
+ }
+
+ /* close sockets */
+ if(data.in_fd !=0) close(data.in_fd);
+ if(data.out_fd !=0) close(data.out_fd);
+
+ return 0;
+}
diff --git a/cryptot.h b/cryptot.h
new file mode 100644
index 0000000..e16e4a7
--- /dev/null
+++ b/cryptot.h
@@ -0,0 +1,38 @@
+#ifndef _CRYPTOT_H
+#define _CRYPTOT_H
+
+#define DEFAULT_CIPHER BLOWFISH | ENCRYPT
+
+#define DEFAULT_PORT 4666
+
+#define BUFFER_LENGTH 8192
+
+#define PROG_NAME "cryptot"
+#define VERSION "0.7.0"
+
+#define MY_CLOCK CLOCK_REALTIME
+
+/*
+#define _DEBUG_
+*/
+
+struct cryptot_st{
+ /* crypto */
+ char *key;
+ char *buffer;
+ unsigned int blocks;
+ unsigned int size;
+ unsigned int cipher;
+ /* input / output */
+ int check_accept;
+ int in_fd;
+ int out_fd;
+ char src_ip[4];
+ char dist_ip[4];
+ char local_ip[4];
+ unsigned int src_port;
+ unsigned int dist_port;
+ unsigned int local_port;
+};
+
+#endif
diff --git a/des.c b/des.c
new file mode 100644
index 0000000..52df628
--- /dev/null
+++ b/des.c
@@ -0,0 +1,1218 @@
+/*
+ * Cryptographic API.
+ *
+ * DES & Triple DES EDE Cipher Algorithms.
+ *
+ * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
+ * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
+ * Derived from Cryptoapi and Nettle implementations, adapted for in-place
+ * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL.
+ *
+ * Copyright (c) 1992 Dana L. How.
+ * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de>
+ * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no>
+ * Copyright (C) 2001 Niels Möller.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#include "des.h"
+#include <string.h>
+
+#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o))
+
+static const u32 des_keymap[] = {
+ 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,
+};
+
+static const u8 rotors[] = {
+ 34, 13, 5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
+ 14, 36, 30, 24, 49, 2, 15, 37, 42, 50, 0, 21,
+ 38, 48, 6, 26, 39, 4, 52, 25, 12, 27, 31, 40,
+ 1, 17, 28, 29, 23, 51, 35, 7, 3, 22, 9, 43,
+
+ 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
+ 21, 43, 37, 0, 1, 9, 22, 44, 49, 2, 7, 28,
+ 45, 55, 13, 33, 46, 11, 6, 32, 19, 34, 38, 47,
+ 8, 24, 35, 36, 30, 3, 42, 14, 10, 29, 16, 50,
+
+ 55, 34, 26, 38, 11, 39, 53, 5, 32, 45, 54, 41,
+ 35, 2, 51, 14, 15, 23, 36, 3, 8, 16, 21, 42,
+ 6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52, 4,
+ 22, 7, 49, 50, 44, 17, 1, 28, 24, 43, 30, 9,
+
+ 12, 48, 40, 52, 25, 53, 38, 19, 46, 6, 11, 55,
+ 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35, 1,
+ 20, 26, 41, 4, 45, 39, 34, 31, 47, 5, 13, 18,
+ 36, 21, 8, 9, 3, 0, 15, 42, 7, 2, 44, 23,
+
+ 26, 5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
+ 8, 30, 24, 42, 43, 51, 9, 0, 36, 44, 49, 15,
+ 34, 40, 55, 18, 6, 53, 48, 45, 4, 19, 27, 32,
+ 50, 35, 22, 23, 17, 14, 29, 1, 21, 16, 3, 37,
+
+ 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
+ 22, 44, 7, 1, 2, 10, 23, 14, 50, 3, 8, 29,
+ 48, 54, 12, 32, 20, 38, 5, 6, 18, 33, 41, 46,
+ 9, 49, 36, 37, 0, 28, 43, 15, 35, 30, 17, 51,
+
+ 54, 33, 25, 41, 38, 13, 27, 4, 6, 48, 53, 40,
+ 36, 3, 21, 15, 16, 24, 37, 28, 9, 17, 22, 43,
+ 5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
+ 23, 8, 50, 51, 14, 42, 2, 29, 49, 44, 0, 10,
+
+ 11, 47, 39, 55, 52, 27, 41, 18, 20, 5, 38, 54,
+ 50, 17, 35, 29, 30, 7, 51, 42, 23, 0, 36, 2,
+ 19, 25, 40, 31, 48, 13, 33, 34, 46, 4, 12, 45,
+ 37, 22, 9, 10, 28, 1, 16, 43, 8, 3, 14, 24,
+
+ 18, 54, 46, 5, 6, 34, 48, 25, 27, 12, 45, 4,
+ 2, 24, 42, 36, 37, 14, 3, 49, 30, 7, 43, 9,
+ 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
+ 44, 29, 16, 17, 35, 8, 23, 50, 15, 10, 21, 0,
+
+ 32, 11, 31, 19, 20, 48, 5, 39, 41, 26, 6, 18,
+ 16, 7, 1, 50, 51, 28, 17, 8, 44, 21, 2, 23,
+ 40, 46, 4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
+ 3, 43, 30, 0, 49, 22, 37, 9, 29, 24, 35, 14,
+
+ 46, 25, 45, 33, 34, 5, 19, 53, 55, 40, 20, 32,
+ 30, 21, 15, 9, 10, 42, 0, 22, 3, 35, 16, 37,
+ 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
+ 17, 2, 44, 14, 8, 36, 51, 23, 43, 7, 49, 28,
+
+ 31, 39, 6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
+ 44, 35, 29, 23, 24, 1, 14, 36, 17, 49, 30, 51,
+ 11, 45, 32, 27, 40, 5, 25, 26, 13, 53, 4, 41,
+ 0, 16, 3, 28, 22, 50, 10, 37, 2, 21, 8, 42,
+
+ 45, 53, 20, 4, 5, 33, 47, 52, 26, 11, 48, 31,
+ 3, 49, 43, 37, 7, 15, 28, 50, 0, 8, 44, 10,
+ 25, 6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
+ 14, 30, 17, 42, 36, 9, 24, 51, 16, 35, 22, 1,
+
+ 6, 38, 34, 18, 19, 47, 4, 13, 40, 25, 5, 45,
+ 17, 8, 2, 51, 21, 29, 42, 9, 14, 22, 3, 24,
+ 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
+ 28, 44, 0, 1, 50, 23, 7, 10, 30, 49, 36, 15,
+
+ 20, 52, 48, 32, 33, 4, 18, 27, 54, 39, 19, 6,
+ 0, 22, 16, 10, 35, 43, 1, 23, 28, 36, 17, 7,
+ 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
+ 42, 3, 14, 15, 9, 37, 21, 24, 44, 8, 50, 29,
+
+ 27, 6, 55, 39, 40, 11, 25, 34, 4, 46, 26, 13,
+ 7, 29, 23, 17, 42, 50, 8, 30, 35, 43, 24, 14,
+ 31, 41, 52, 19, 32, 54, 45, 18, 5, 20, 53, 33,
+ 49, 10, 21, 22, 16, 44, 28, 0, 51, 15, 2, 36,
+};
+
+static const u8 parity[] = {
+ 8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
+ 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+ 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+ 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+ 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+ 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+ 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+ 4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+};
+
+
+static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src)
+{
+ u32 x, y, z;
+
+ x = src[7];
+ x <<= 8;
+ x |= src[6];
+ x <<= 8;
+ x |= src[5];
+ x <<= 8;
+ x |= src[4];
+ y = src[3];
+ y <<= 8;
+ y |= src[2];
+ y <<= 8;
+ y |= src[1];
+ y <<= 8;
+ y |= src[0];
+ z = ((x >> 004) ^ y) & 0x0F0F0F0FL;
+ x ^= z << 004;
+ y ^= z;
+ z = ((y >> 020) ^ x) & 0x0000FFFFL;
+ y ^= z << 020;
+ x ^= z;
+ z = ((x >> 002) ^ y) & 0x33333333L;
+ x ^= z << 002;
+ y ^= z;
+ z = ((y >> 010) ^ x) & 0x00FF00FFL;
+ y ^= z << 010;
+ x ^= z;
+ x = x >> 1 | x << 31;
+ z = (x ^ y) & 0x55555555L;
+ y ^= z;
+ x ^= z;
+ y = y >> 1 | y << 31;
+ z = expkey[0];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[1];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[2];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[3];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[4];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[5];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[6];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[7];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[8];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[9];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[10];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[11];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[12];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[13];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[14];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[15];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[16];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[17];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[18];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[19];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[20];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[21];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[22];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[23];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[24];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[25];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[26];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[27];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[28];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[29];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[30];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[31];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ x = x << 1 | x >> 31;
+ z = (x ^ y) & 0x55555555L;
+ y ^= z;
+ x ^= z;
+ y = y << 1 | y >> 31;
+ z = ((x >> 010) ^ y) & 0x00FF00FFL;
+ x ^= z << 010;
+ y ^= z;
+ z = ((y >> 002) ^ x) & 0x33333333L;
+ y ^= z << 002;
+ x ^= z;
+ z = ((x >> 020) ^ y) & 0x0000FFFFL;
+ x ^= z << 020;
+ y ^= z;
+ z = ((y >> 004) ^ x) & 0x0F0F0F0FL;
+ y ^= z << 004;
+ x ^= z;
+ dst[0] = x;
+ x >>= 8;
+ dst[1] = x;
+ x >>= 8;
+ dst[2] = x;
+ x >>= 8;
+ dst[3] = x;
+ dst[4] = y;
+ y >>= 8;
+ dst[5] = y;
+ y >>= 8;
+ dst[6] = y;
+ y >>= 8;
+ dst[7] = y;
+}
+
+static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src)
+{
+ u32 x, y, z;
+
+ x = src[7];
+ x <<= 8;
+ x |= src[6];
+ x <<= 8;
+ x |= src[5];
+ x <<= 8;
+ x |= src[4];
+ y = src[3];
+ y <<= 8;
+ y |= src[2];
+ y <<= 8;
+ y |= src[1];
+ y <<= 8;
+ y |= src[0];
+ z = ((x >> 004) ^ y) & 0x0F0F0F0FL;
+ x ^= z << 004;
+ y ^= z;
+ z = ((y >> 020) ^ x) & 0x0000FFFFL;
+ y ^= z << 020;
+ x ^= z;
+ z = ((x >> 002) ^ y) & 0x33333333L;
+ x ^= z << 002;
+ y ^= z;
+ z = ((y >> 010) ^ x) & 0x00FF00FFL;
+ y ^= z << 010;
+ x ^= z;
+ x = x >> 1 | x << 31;
+ z = (x ^ y) & 0x55555555L;
+ y ^= z;
+ x ^= z;
+ y = y >> 1 | y << 31;
+ z = expkey[31];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[30];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[29];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[28];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[27];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[26];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[25];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[24];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[23];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[22];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[21];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[20];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[19];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[18];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[17];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[16];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[15];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[14];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[13];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[12];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[11];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[10];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[9];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[8];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[7];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[6];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[5];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[4];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[3];
+ z ^= y;
+ z = z << 4 | z >> 28;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[2];
+ z ^= y;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ z = expkey[1];
+ z ^= x;
+ z = z << 4 | z >> 28;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
+ z = expkey[0];
+ z ^= x;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
+ z >>= 8;
+ y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
+ x = x << 1 | x >> 31;
+ z = (x ^ y) & 0x55555555L;
+ y ^= z;
+ x ^= z;
+ y = y << 1 | y >> 31;
+ z = ((x >> 010) ^ y) & 0x00FF00FFL;
+ x ^= z << 010;
+ y ^= z;
+ z = ((y >> 002) ^ x) & 0x33333333L;
+ y ^= z << 002;
+ x ^= z;
+ z = ((x >> 020) ^ y) & 0x0000FFFFL;
+ x ^= z << 020;
+ y ^= z;
+ z = ((y >> 004) ^ x) & 0x0F0F0F0FL;
+ y ^= z << 004;
+ x ^= z;
+ dst[0] = x;
+ x >>= 8;
+ dst[1] = x;
+ x >>= 8;
+ dst[2] = x;
+ x >>= 8;
+ dst[3] = x;
+ dst[4] = y;
+ y >>= 8;
+ dst[5] = y;
+ y >>= 8;
+ dst[6] = y;
+ y >>= 8;
+ dst[7] = y;
+}
+
+/*
+ * RFC2451: Weak key checks SHOULD be performed.
+ */
+static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ const u8 *k;
+ u8 *b0, *b1;
+ u32 n, w;
+ u8 bits0[56], bits1[56];
+
+ n = parity[key[0]]; n <<= 4;
+ n |= parity[key[1]]; n <<= 4;
+ n |= parity[key[2]]; n <<= 4;
+ n |= parity[key[3]]; n <<= 4;
+ n |= parity[key[4]]; n <<= 4;
+ n |= parity[key[5]]; n <<= 4;
+ n |= parity[key[6]]; n <<= 4;
+ n |= parity[key[7]];
+ w = 0x88888888L;
+
+ if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
+ && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */
+ if (n < 0x41415151) {
+ if (n < 0x31312121) {
+ if (n < 0x14141515) {
+ /* 01 01 01 01 01 01 01 01 */
+ if (n == 0x11111111) goto weak;
+ /* 01 1F 01 1F 01 0E 01 0E */
+ if (n == 0x13131212) goto weak;
+ } else {
+ /* 01 E0 01 E0 01 F1 01 F1 */
+ if (n == 0x14141515) goto weak;
+ /* 01 FE 01 FE 01 FE 01 FE */
+ if (n == 0x16161616) goto weak;
+ }
+ } else {
+ if (n < 0x34342525) {
+ /* 1F 01 1F 01 0E 01 0E 01 */
+ if (n == 0x31312121) goto weak;
+ /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
+ if (n == 0x33332222) goto weak;
+ } else {
+ /* 1F E0 1F E0 0E F1 0E F1 */
+ if (n == 0x34342525) goto weak;
+ /* 1F FE 1F FE 0E FE 0E FE */
+ if (n == 0x36362626) goto weak;
+ }
+ }
+ } else {
+ if (n < 0x61616161) {
+ if (n < 0x44445555) {
+ /* E0 01 E0 01 F1 01 F1 01 */
+ if (n == 0x41415151) goto weak;
+ /* E0 1F E0 1F F1 0E F1 0E */
+ if (n == 0x43435252) goto weak;
+ } else {
+ /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
+ if (n == 0x44445555) goto weak;
+ /* E0 FE E0 FE F1 FE F1 FE */
+ if (n == 0x46465656) goto weak;
+ }
+ } else {
+ if (n < 0x64646565) {
+ /* FE 01 FE 01 FE 01 FE 01 */
+ if (n == 0x61616161) goto weak;
+ /* FE 1F FE 1F FE 0E FE 0E */
+ if (n == 0x63636262) goto weak;
+ } else {
+ /* FE E0 FE E0 FE F1 FE F1 */
+ if (n == 0x64646565) goto weak;
+ /* FE FE FE FE FE FE FE FE */
+ if (n == 0x66666666) goto weak;
+ }
+ }
+ }
+
+ goto not_weak;
+weak:
+ *flags |= CRYPTO_TFM_RES_WEAK_KEY;
+ return -1;
+ }
+
+not_weak:
+
+ /* explode the bits */
+ n = 56;
+ b0 = bits0;
+ b1 = bits1;
+
+ do {
+ w = (256 | *key++) << 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;
+
+ 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 ]];
+ expkey[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 */
+ expkey[1] = w;
+
+ k += 48;
+ expkey += 2;
+ } while (--n);
+
+ return 0;
+}
+
+int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+ return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags);
+}
+
+void des_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+}
+
+void des_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+}
+
+/*
+ * RFC2451:
+ *
+ * For DES-EDE3, there is no known need to reject weak or
+ * complementation keys. Any weakness is obviated by the use of
+ * multiple keys.
+ *
+ * However, if the first two or last two independent 64-bit keys are
+ * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
+ * same as DES. Implementers MUST reject keys that exhibit this
+ * property.
+ *
+ */
+int des3_ede_setkey(void *ctx, const u8 *key,
+ unsigned int keylen, u32 *flags)
+{
+ unsigned int i, off;
+ struct des3_ede_ctx *dctx = ctx;
+
+ if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
+ memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
+ DES_KEY_SIZE))) {
+
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
+ return -1;
+ }
+
+ for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS,
+ key += DES_KEY_SIZE) {
+ int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct des3_ede_ctx *dctx = ctx;
+
+ des_small_fips_encrypt(dctx->expkey, dst, src);
+ des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
+ des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst);
+}
+
+void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+ struct des3_ede_ctx *dctx = ctx;
+
+ des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src);
+ des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
+ des_small_fips_decrypt(dctx->expkey, dst, dst);
+}
diff --git a/des.h b/des.h
new file mode 100644
index 0000000..dd71a08
--- /dev/null
+++ b/des.h
@@ -0,0 +1,63 @@
+/*
+ * Cryptographic API.
+ *
+ * DES & Triple DES EDE Cipher Algorithms.
+ *
+ * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
+ * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
+ * Derived from Cryptoapi and Nettle implementations, adapted for in-place
+ * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL.
+ *
+ * Copyright (c) 1992 Dana L. How.
+ * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de>
+ * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no>
+ * Copyright (C) 2001 Niels Möller.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#ifndef _DES_
+#define _DES_
+
+#include "uint.h"
+
+#define DES_KEY_SIZE 8
+#define DES_EXPKEY_WORDS 32
+#define DES_BLOCK_SIZE 8
+
+#define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE)
+#define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS)
+#define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE
+
+#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
+#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
+#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
+
+struct des_ctx {
+ u8 iv[DES_BLOCK_SIZE];
+ u32 expkey[DES_EXPKEY_WORDS];
+};
+
+struct des3_ede_ctx {
+ u8 iv[DES_BLOCK_SIZE];
+ u32 expkey[DES3_EDE_EXPKEY_WORDS];
+};
+
+int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags);
+
+void des_encrypt(void *ctx, u8 *dst, const u8 *src);
+
+void des_decrypt(void *ctx, u8 *dst, const u8 *src);
+
+
+int des3_ede_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags);
+
+void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src);
+
+void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src);
+
+#endif
diff --git a/douint.c b/douint.c
new file mode 100644
index 0000000..bccf4a9
--- /dev/null
+++ b/douint.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+int main(void)
+{
+ unsigned char us; /* using short makes twofish colapse */
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long long ull;
+
+ printf("#ifndef _UINT_H\n#define _UINT_H\n\n");
+ printf(" /* This file was auto-generated. Do not edit! */\n\n");
+ /* u8 */
+ us = 1<<6;
+ us += us;
+ if(us)printf("typedef unsigned char u8;\n\n");
+ else{
+ ui = 1<<6;
+ ui += ui;
+ if(ui) printf("typedef unsigned int u8;\n\n");
+ }
+ printf("#define U8_MAX 0xFF\n\n");
+
+ /* u16 */
+ ui = 1<<14;
+ ui += ui;
+ if(ui)printf("typedef unsigned int u16;\n\n");
+ else{
+ ul = 1<<14;
+ ul += ul;
+ if(ul) printf("typedef unsigned long u16;\n\n");
+ }
+ printf("#define U16_MAX 0xFFFF\n\n");
+
+ /* u32 */
+ ui = 1<<30;
+ ui += ui;
+ if(ui)printf("typedef unsigned int u32;\n\n");
+ else{
+ ul = 1<<30;
+ ul += ul;
+ if(ul) printf("typedef unsigned long u32;\n\n");
+ else{
+ ull = 1<<30;
+ ull += ull;
+ if(ull) printf("typedef unsigned long long u32;\n\n");
+ }
+ }
+ printf("#define U32_MAX 0xFFFFFFFF\n\n");
+
+ /* u64 */
+ ui = 1<<31;
+ ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui;
+ ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui;
+ ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui;
+ ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui; ui += ui;
+ if(ui)printf("typedef unsigned int u64;\n\n");
+ else{
+ ul = 1<<31;
+ ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul;
+ ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul;
+ ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul;
+ ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul; ul += ul;
+ if(ul) printf("typedef unsigned long u64;\n\n");
+ else{
+ ull = 1<<31;
+ ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull;
+ ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull;
+ ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull;
+ ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull; ull += ull;
+ if(ull) printf("typedef unsigned long long u64;\n\n");
+ else printf(" * no u64 available !! *\n\n");
+ }
+ }
+ printf("#define U64_MAX 0xFFFFFFFFFFFFFFFF\n\n");
+ printf("#endif\n");
+ return 0;
+}
diff --git a/find-systype.sh b/find-systype.sh
new file mode 100644
index 0000000..2c5b3a3
--- /dev/null
+++ b/find-systype.sh
@@ -0,0 +1,147 @@
+# oper-:arch-:syst-:chip-:kern-
+# oper = operating system type; e.g., sunos-4.1.4
+# arch = machine language; e.g., sparc
+# syst = which binaries can run; e.g., sun4
+# chip = chip model; e.g., micro-2-80
+# kern = kernel version; e.g., sun4m
+# dependence: arch --- chip
+# \ \
+# oper --- syst --- kern
+# so, for example, syst is interpreted in light of oper, but chip is not.
+# anyway, no slashes, no extra colons, no uppercase letters.
+# the point of the extra -'s is to ease parsing: can add hierarchies later.
+# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium,
+# and i386-486 (486s do have more instructions, you know) as well as i386.
+# the idea here is to include ALL useful available information.
+
+exec 2>/dev/null
+
+sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`"
+if [ x"$sys" != x ]; then
+ unamer="`uname -r | tr /: ..`"
+ unamem="`uname -m | tr /: ..`"
+ unamev="`uname -v | tr /: ..`"
+
+ case "$sys" in
+ bsd.os|freebsd|netbsd|openbsd)
+ # in bsd 4.4, uname -v does not have useful info.
+ # in bsd 4.4, uname -m is arch, not chip.
+ oper="$sys-$unamer"
+ arch="$unamem"
+ syst=""
+ chip="`sysctl -n hw.model`" # hopefully
+ kern=""
+ ;;
+
+ linux)
+ # as in bsd 4.4, uname -v does not have useful info.
+ oper="$sys-$unamer"
+ syst=""
+ chip="$unamem"
+ kern=""
+ case "$chip" in
+ i386|i486|i586|i686)
+ arch="i386"
+ ;;
+ alpha)
+ arch="alpha"
+ ;;
+ esac
+ ;;
+
+ aix)
+ # naturally IBM has to get uname -r and uname -v backwards. dorks.
+ oper="$sys-$unamev-$unamer"
+ arch="`arch | tr /: ..`"
+ syst=""
+ chip="$unamem"
+ kern=""
+ ;;
+
+ sunos)
+ oper="$sys-$unamer-$unamev"
+ arch="`(uname -p || mach) | tr /: ..`"
+ syst="`arch | tr /: ..`"
+ chip="$unamem" # this is wrong; is there any way to get the real info?
+ kern="`arch -k | tr /: ..`"
+ ;;
+ unix_sv)
+ oper="$sys-$unamer-$unamev"
+ arch="`uname -m`"
+ syst=""
+ chip="$unamem"
+ kern=""
+ ;;
+
+ *)
+ oper="$sys-$unamer-$unamev"
+ arch="`arch | tr /: ..`"
+ syst=""
+ chip="$unamem"
+ kern=""
+ ;;
+ esac
+else
+ gcc -c trycpp.c
+ gcc -o trycpp trycpp.o
+ case `./trycpp` in
+ nextstep)
+ oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`"
+ arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`"
+ syst=""
+ chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`"
+ kern=""
+ ;;
+
+ *)
+ oper="unknown"
+ arch=""
+ syst=""
+ chip=""
+ kern=""
+ ;;
+ esac
+ rm -f trycpp.o trycpp
+fi
+
+case "$chip" in
+ 80486)
+ # let's try to be consistent here. (BSD/OS)
+ chip=i486
+ ;;
+ i486DX)
+ # respect the hyphen hierarchy. (FreeBSD)
+ chip=i486-dx
+ ;;
+ i486.DX2)
+ # respect the hyphen hierarchy. (FreeBSD)
+ chip=i486-dx2
+ ;;
+ Intel.586)
+ # no, you nitwits, there is no such chip. (NeXTStep)
+ chip=pentium
+ ;;
+ i586)
+ # no, you nitwits, there is no such chip. (Linux)
+ chip=pentium
+ ;;
+ i686)
+ # STOP SAYING THAT! (Linux)
+ chip=ppro
+esac
+
+if gcc -c x86cpuid.c
+then
+ if gcc -o x86cpuid x86cpuid.o
+ then
+ x86cpuid="`./x86cpuid | tr /: ..`"
+ case "$x86cpuid" in
+ ?*)
+ chip="$x86cpuid"
+ ;;
+ esac
+ fi
+fi
+rm -f x86cpuid x86cpuid.o
+
+echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]'
diff --git a/ipv4.h b/ipv4.h
new file mode 100644
index 0000000..608b901
--- /dev/null
+++ b/ipv4.h
@@ -0,0 +1,38 @@
+#ifndef _INTE4_H
+#define _INTE4_H
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+#define MAC(hwaddr) \
+ ((unsigned char *)&hwaddr)[0], \
+ ((unsigned char *)&hwaddr)[1], \
+ ((unsigned char *)&hwaddr)[2], \
+ ((unsigned char *)&hwaddr)[3], \
+ ((unsigned char *)&hwaddr)[4], \
+ ((unsigned char *)&hwaddr)[5]
+
+
+int ipv4_get_addr (const char *interface, char *ip, int *family);
+int ipv4_get_broad (const char *interface, char *ip, int *family);
+int ipv4_get_dest (const char *interface, char *ip, int *family);
+int ipv4_get_mask (const char *interface, char *ip, int *family);
+int ipv4_get_hwaddr(const char *ifname, char *mac, int *family);
+
+int ipv4_set_addr (const char *interface, const char *ip, int family);
+int ipv4_set_broad (const char *interface, const char *ip, int family);
+int ipv4_set_dest (const char *interface, const char *ip, int family);
+int ipv4_set_mask (const char *interface, const char *ip, int family);
+int ipv4_set_hwaddr(const char *ifname, const char *mac, int family);
+
+/* set ifname up/down state 1/0 */
+int ipv4_set_up(const char *ifname, unsigned int state);
+int ipv4_get_up(const char *ifname);
+
+/* numbers -gt 255 are truncated ( 256=>0 ; 257=>1 ) */
+unsigned int ipv4_scan(const char *s,char *ip);
+
+#endif
diff --git a/ipv4_scan.c b/ipv4_scan.c
new file mode 100644
index 0000000..b4906c0
--- /dev/null
+++ b/ipv4_scan.c
@@ -0,0 +1,19 @@
+
+#include "scan.h"
+
+unsigned int ipv4_scan(const char *s,char ip[4])
+{
+ unsigned int i;
+ unsigned int len;
+ unsigned long u;
+
+ len = 0;
+ i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i;
+ if (*s != '.') return 0; ++s; ++len;
+ i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i;
+ if (*s != '.') return 0; ++s; ++len;
+ i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i;
+ if (*s != '.') return 0; ++s; ++len;
+ i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i;
+ return len;
+}
diff --git a/md4.c b/md4.c
new file mode 100644
index 0000000..00477de
--- /dev/null
+++ b/md4.c
@@ -0,0 +1,213 @@
+/*
+ * Cryptographic API.
+ *
+ * MD4 Message Digest Algorithm (RFC1320).
+ *
+ * Implementation derived from Andrew Tridgell and Steve French's
+ * CIFS MD4 implementation, and the cryptoapi implementation
+ * originally based on the public domain implementation written
+ * by Colin Plumb in 1993.
+ *
+ * Copyright (c) Andrew Tridgell 1997-1998.
+ * Modified by Steve French (sfrench@us.ibm.com) 2002
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#include "md4.h"
+#include <string.h>
+
+static __inline u32 lshift(u32 x, unsigned int s)
+{
+ x &= 0xFFFFFFFF;
+ return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
+}
+
+static __inline u32 F(u32 x, u32 y, u32 z)
+{
+ return (x & y) | ((~x) & z);
+}
+
+static __inline u32 G(u32 x, u32 y, u32 z)
+{
+ return (x & y) | (x & z) | (y & z);
+}
+
+static __inline u32 H(u32 x, u32 y, u32 z)
+{
+ return x ^ y ^ z;
+}
+
+#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
+#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
+#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
+
+/* XXX: this stuff can be optimized */
+/*
+static __inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __le32_to_cpus(buf);
+ buf++;
+ }
+}
+
+static __inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __cpu_to_le32s(buf);
+ buf++;
+ }
+}
+*/
+
+static void md4_transform(u32 *hash, u32 const *in)
+{
+ u32 a, b, c, d;
+
+ a = hash[0];
+ b = hash[1];
+ c = hash[2];
+ d = hash[3];
+
+ ROUND1(a, b, c, d, in[0], 3);
+ ROUND1(d, a, b, c, in[1], 7);
+ ROUND1(c, d, a, b, in[2], 11);
+ ROUND1(b, c, d, a, in[3], 19);
+ ROUND1(a, b, c, d, in[4], 3);
+ ROUND1(d, a, b, c, in[5], 7);
+ ROUND1(c, d, a, b, in[6], 11);
+ ROUND1(b, c, d, a, in[7], 19);
+ ROUND1(a, b, c, d, in[8], 3);
+ ROUND1(d, a, b, c, in[9], 7);
+ ROUND1(c, d, a, b, in[10], 11);
+ ROUND1(b, c, d, a, in[11], 19);
+ ROUND1(a, b, c, d, in[12], 3);
+ ROUND1(d, a, b, c, in[13], 7);
+ ROUND1(c, d, a, b, in[14], 11);
+ ROUND1(b, c, d, a, in[15], 19);
+
+ ROUND2(a, b, c, d,in[ 0], 3);
+ ROUND2(d, a, b, c, in[4], 5);
+ ROUND2(c, d, a, b, in[8], 9);
+ ROUND2(b, c, d, a, in[12], 13);
+ ROUND2(a, b, c, d, in[1], 3);
+ ROUND2(d, a, b, c, in[5], 5);
+ ROUND2(c, d, a, b, in[9], 9);
+ ROUND2(b, c, d, a, in[13], 13);
+ ROUND2(a, b, c, d, in[2], 3);
+ ROUND2(d, a, b, c, in[6], 5);
+ ROUND2(c, d, a, b, in[10], 9);
+ ROUND2(b, c, d, a, in[14], 13);
+ ROUND2(a, b, c, d, in[3], 3);
+ ROUND2(d, a, b, c, in[7], 5);
+ ROUND2(c, d, a, b, in[11], 9);
+ ROUND2(b, c, d, a, in[15], 13);
+
+ ROUND3(a, b, c, d,in[ 0], 3);
+ ROUND3(d, a, b, c, in[8], 9);
+ ROUND3(c, d, a, b, in[4], 11);
+ ROUND3(b, c, d, a, in[12], 15);
+ ROUND3(a, b, c, d, in[2], 3);
+ ROUND3(d, a, b, c, in[10], 9);
+ ROUND3(c, d, a, b, in[6], 11);
+ ROUND3(b, c, d, a, in[14], 15);
+ ROUND3(a, b, c, d, in[1], 3);
+ ROUND3(d, a, b, c, in[9], 9);
+ ROUND3(c, d, a, b, in[5], 11);
+ ROUND3(b, c, d, a, in[13], 15);
+ ROUND3(a, b, c, d, in[3], 3);
+ ROUND3(d, a, b, c, in[11], 9);
+ ROUND3(c, d, a, b, in[7], 11);
+ ROUND3(b, c, d, a, in[15], 15);
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+}
+
+static __inline void md4_transform_helper(struct md4_ctx *ctx)
+{
+ /*
+ le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+ */
+ md4_transform(ctx->hash, ctx->block);
+}
+
+void md4_init(void *ctx)
+{
+ struct md4_ctx *mctx = ctx;
+
+ mctx->hash[0] = 0x67452301;
+ mctx->hash[1] = 0xefcdab89;
+ mctx->hash[2] = 0x98badcfe;
+ mctx->hash[3] = 0x10325476;
+ mctx->byte_count = 0;
+}
+
+void md4_update(void *ctx, const u8 *data, unsigned int len)
+{
+ struct md4_ctx *mctx = ctx;
+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+ mctx->byte_count += len;
+
+ if (avail > len) {
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, len);
+ return;
+ }
+
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, avail);
+
+ md4_transform_helper(mctx);
+ data += avail;
+ len -= avail;
+
+ while (len >= sizeof(mctx->block)) {
+ memcpy(mctx->block, data, sizeof(mctx->block));
+ md4_transform_helper(mctx);
+ data += sizeof(mctx->block);
+ len -= sizeof(mctx->block);
+ }
+
+ memcpy(mctx->block, data, len);
+}
+
+void md4_final(void *ctx, u8 *out)
+{
+ struct md4_ctx *mctx = ctx;
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (u64));
+ md4_transform_helper(mctx);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = mctx->byte_count << 3;
+ mctx->block[15] = mctx->byte_count >> 29;
+ /*
+ le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+ sizeof(u64)) / sizeof(u32));
+ */
+ md4_transform(mctx->hash, mctx->block);
+ /*
+ cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
+ */
+ memcpy(out, mctx->hash, sizeof(mctx->hash));
+ memset(mctx, 0, sizeof(*mctx));
+}
diff --git a/md4.h b/md4.h
new file mode 100644
index 0000000..f1a2897
--- /dev/null
+++ b/md4.h
@@ -0,0 +1,46 @@
+/*
+ * Cryptographic API.
+ *
+ * MD4 Message Digest Algorithm (RFC1320).
+ *
+ * Implementation derived from Andrew Tridgell and Steve French's
+ * CIFS MD4 implementation, and the cryptoapi implementation
+ * originally based on the public domain implementation written
+ * by Colin Plumb in 1993.
+ *
+ * Copyright (c) Andrew Tridgell 1997-1998.
+ * Modified by Steve French (sfrench@us.ibm.com) 2002
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _MD4_
+#define _MD4_
+
+#include "uint.h"
+
+#define MD4_DIGEST_SIZE 16
+#define MD4_HMAC_BLOCK_SIZE 64
+#define MD4_BLOCK_WORDS 16
+#define MD4_HASH_WORDS 4
+
+struct md4_ctx {
+ u32 hash[MD4_HASH_WORDS];
+ u32 block[MD4_BLOCK_WORDS];
+ u64 byte_count;
+};
+
+void md4_init(void *ctx);
+
+void md4_update(void *ctx, const u8 *data, unsigned int len);
+
+void md4_final(void *ctx, u8 *out);
+
+#endif
diff --git a/md5.c b/md5.c
new file mode 100644
index 0000000..a366d99
--- /dev/null
+++ b/md5.c
@@ -0,0 +1,212 @@
+/*
+ * Cryptographic API.
+ *
+ * MD5 Message Digest Algorithm (RFC1321).
+ *
+ * Derived from cryptoapi implementation, originally based on the
+ * public domain implementation written by Colin Plumb in 1993.
+ *
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#include "md5.h"
+#include <string.h>
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#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))
+
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+
+static void md5_transform(u32 *hash, u32 const *in)
+{
+ u32 a, b, c, d;
+
+ a = hash[0];
+ b = hash[1];
+ c = hash[2];
+ d = hash[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+}
+
+/* XXX: this stuff can be optimized */
+/*
+static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __le32_to_cpus(buf);
+ buf++;
+ }
+}
+
+static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
+{
+ while (words--) {
+ __cpu_to_le32s(buf);
+ buf++;
+ }
+}
+*/
+
+static __inline void md5_transform_helper(struct md5_ctx *ctx)
+{
+ /*
+ le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
+ */
+ md5_transform(ctx->hash, ctx->block);
+}
+
+void md5_init(void *ctx)
+{
+ struct md5_ctx *mctx = ctx;
+
+ mctx->hash[0] = 0x67452301;
+ mctx->hash[1] = 0xefcdab89;
+ mctx->hash[2] = 0x98badcfe;
+ mctx->hash[3] = 0x10325476;
+ mctx->byte_count = 0;
+}
+
+void md5_update(void *ctx, const u8 *data, unsigned int len)
+{
+ struct md5_ctx *mctx = ctx;
+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
+
+ mctx->byte_count += len;
+
+ if (avail > len) {
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, len);
+ return;
+ }
+
+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
+ data, avail);
+
+ md5_transform_helper(mctx);
+ data += avail;
+ len -= avail;
+
+ while (len >= sizeof(mctx->block)) {
+ memcpy(mctx->block, data, sizeof(mctx->block));
+ md5_transform_helper(mctx);
+ data += sizeof(mctx->block);
+ len -= sizeof(mctx->block);
+ }
+
+ memcpy(mctx->block, data, len);
+}
+
+void md5_final(void *ctx, u8 *out)
+{
+ struct md5_ctx *mctx = ctx;
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (u64));
+ md5_transform_helper(mctx);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = mctx->byte_count << 3;
+ mctx->block[15] = mctx->byte_count >> 29;
+ /*
+ le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
+ sizeof(u64)) / sizeof(u32));
+ */
+ md5_transform(mctx->hash, mctx->block);
+ /*
+ cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
+ */
+ memcpy(out, mctx->hash, sizeof(mctx->hash));
+ memset(mctx, 0, sizeof(*mctx));
+}
diff --git a/md5.h b/md5.h
new file mode 100644
index 0000000..af42f76
--- /dev/null
+++ b/md5.h
@@ -0,0 +1,41 @@
+/*
+ * Cryptographic API.
+ *
+ * MD5 Message Digest Algorithm (RFC1321).
+ *
+ * Derived from cryptoapi implementation, originally based on the
+ * public domain implementation written by Colin Plumb in 1993.
+ *
+ * Copyright (c) Cryptoapi developers.
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * 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.
+ *
+ */
+#ifndef _MD5_
+#define _MD5_
+
+#include "uint.h"
+
+#define MD5_DIGEST_SIZE 16
+#define MD5_HMAC_BLOCK_SIZE 64
+#define MD5_BLOCK_WORDS 16
+#define MD5_HASH_WORDS 4
+
+struct md5_ctx {
+ u32 hash[MD5_HASH_WORDS];
+ u32 block[MD5_BLOCK_WORDS];
+ u64 byte_count;
+};
+
+
+void md5_init(void *ctx);
+
+void md5_update(void *ctx, const u8 *data, unsigned int len);
+
+void md5_final(void *ctx, u8 *out);
+
+#endif
diff --git a/mypass b/mypass
new file mode 100755
index 0000000..e524b2c
--- /dev/null
+++ b/mypass
@@ -0,0 +1,57 @@
+#! /bin/sh
+
+BIN="cryptot"
+CIPHER="-c 2"
+
+usage () {
+ echo "usage : `basename $0` -(e|d) input_file password [output_file]"
+ echo " -e : encryption."
+ echo " -d : decryption."
+ echo " if output_file is omited, output is written to stdout."
+}
+
+work () {
+ if [ "$1" == "-e" ];then
+ echo "encrypt : $2"
+ MODE=""
+ else
+ echo "decrypt : $2"
+ MODE="-x"
+ fi
+ echo "use password : $3"
+ if [ $# -eq 4 ]; then
+ echo "write output to : $4"
+ else
+ echo "write output to : stdout"
+ fi
+ echo "hit Enter to proceed. type Ctrl-C to abort."
+ read -t 5 A
+ if [ $? -ne 0 ]; then echo "=> timeout ... operation aborted." && exit; fi
+ CMD="${BIN} ${MODE} ${CIPHER} $3"
+ if [ $# -eq 4 ]; then
+ cat $2 | ${CMD} > $4
+ else
+ cat $2 | ${CMD}
+ fi
+ if [ "$1" == "-e" ];then
+ echo "hit Enter to remove $2. type Ctrl-C to abort."
+ read -t 4 A
+ if [ $? -ne 0 ]; then echo "=> timeout ... nothing done." && exit; fi
+ rm $2 $2~ 2>/dev/null
+ fi
+}
+
+
+if [ $# -lt 3 -o $# -gt 4 ]; then usage && exit; fi
+if [ ! -f $2 ];then
+ echo "$2 isn't a regular file"
+ exit
+fi
+case "$1" in
+ "-e"|"-d")
+ work $@
+ ;;
+ *)
+ echo $CHOICE
+ usage;;
+esac
diff --git a/scan.h b/scan.h
new file mode 100644
index 0000000..b18ad65
--- /dev/null
+++ b/scan.h
@@ -0,0 +1,7 @@
+#ifndef _SCAN_H
+#define _SCAN_H
+
+unsigned int scan_ulong(register const char *s,register unsigned long *u);
+unsigned int scan_uint(register const char *s,register unsigned int *u);
+
+#endif
diff --git a/scan_ulong.c b/scan_ulong.c
new file mode 100644
index 0000000..b38df10
--- /dev/null
+++ b/scan_ulong.c
@@ -0,0 +1,12 @@
+unsigned int scan_ulong(register const char *s,register unsigned long *u)
+{
+ register unsigned int pos = 0;
+ register unsigned long result = 0;
+ register unsigned long c;
+ while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) {
+ result = result * 10 + c;
+ ++pos;
+ }
+ *u = result;
+ return pos;
+}
diff --git a/sha1.c b/sha1.c
new file mode 100644
index 0000000..2a928fb
--- /dev/null
+++ b/sha1.c
@@ -0,0 +1,192 @@
+/*
+ * Cryptographic API.
+ *
+ * SHA1 Secure Hash Algorithm.
+ *
+ * Derived from cryptoapi implementation, adapted for in-place
+ * scatterlist interface. Originally based on the public domain
+ * implementation written by Steve Reid.
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ *
+ * 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.
+ *
+ */
+
+#include "sha1.h"
+#include <string.h>
+
+/*
+#define ___swab32(x) \
+({ \
+ u32 __x = (x); \
+ ((u32)( \
+ (((u32)(__x) & (u32)0x000000ffUL) << 24) | \
+ (((u32)(__x) & (u32)0x0000ff00UL) << 8) | \
+ (((u32)(__x) & (u32)0x00ff0000UL) >> 8) | \
+ (((u32)(__x) & (u32)0xff000000UL) >> 24) )); \
+})
+*/
+
+static __inline u32 rol(u32 value, u32 bits)
+{
+ return (((value) << (bits)) | ((value) >> (32 - (bits))));
+}
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifndef WORDS_BIGENDIAN
+# define blk0(i) (block32[i] = (rol(block32[i],24)&0xFF00FF00) \
+ |(rol(block32[i],8)&0x00FF00FF))
+#else
+# define blk0(i) block32[i]
+#endif
+
+#define blk(i) (block32[i&15] = rol(block32[(i+13)&15]^block32[(i+8)&15] \
+ ^block32[(i+2)&15]^block32[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \
+ w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5); \
+ w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \
+ w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+static void sha1_transform(u32 *state, const u8 *in)
+{
+ u32 a, b, c, d, e;
+ u32 block32[16];
+
+ /* convert/copy data to workspace */
+ for (a = 0; a < sizeof(block32)/sizeof(u32); a++){
+ block32[a] = ((const u32 *)in)[a];
+ /*
+ block32[a]=0;
+ block32[a] |= (((const u32 *)in)[a] & 0x000000ffUL) << 24;
+ block32[a] |= (((const u32 *)in)[a] & 0x0000ff00UL) << 8;
+ block32[a] |= (((const u32 *)in)[a] & 0x00ff0000UL) >> 8;
+ block32[a] |= (((const u32 *)in)[a] & 0xff000000UL) >> 24;
+ */
+ }
+
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+ memset (block32, 0x00, sizeof block32);
+}
+
+void sha1_init(void *ctx)
+{
+ struct sha1_ctx *sctx = ctx;
+ static const struct sha1_ctx initstate = {
+ 0,
+ { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
+ { 0, }
+ };
+
+ *sctx = initstate;
+}
+
+void sha1_update(void *ctx, const u8 *data, unsigned int len)
+{
+ struct sha1_ctx *sctx = ctx;
+ unsigned int i, j;
+
+ j = (sctx->count >> 3) & 0x3f;
+ sctx->count += len << 3;
+
+ if ((j + len) > 63) {
+ memcpy(&sctx->buffer[j], data, (i = 64-j));
+ sha1_transform(sctx->state, sctx->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ sha1_transform(sctx->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&sctx->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+void sha1_final(void* ctx, u8 *out)
+{
+ struct sha1_ctx *sctx = ctx;
+ u32 i, j, index, padlen;
+ u64 t;
+ u8 bits[8] = { 0, };
+ static const u8 padding[64] = { 0x80, };
+
+ t = sctx->count;
+ bits[7] = 0xff & t; t>>=8;
+ bits[6] = 0xff & t; t>>=8;
+ bits[5] = 0xff & t; t>>=8;
+ bits[4] = 0xff & t; t>>=8;
+ bits[3] = 0xff & t; t>>=8;
+ bits[2] = 0xff & t; t>>=8;
+ bits[1] = 0xff & t; t>>=8;
+ bits[0] = 0xff & t;
+
+ /* Pad out to 56 mod 64 */
+ index = (sctx->count >> 3) & 0x3f;
+ padlen = (index < 56) ? (56 - index) : ((64+56) - index);
+ sha1_update(sctx, padding, padlen);
+
+ /* Append length */
+ sha1_update(sctx, bits, sizeof bits);
+
+ /* Store state in digest */
+ for (i = j = 0; i < 5; i++, j += 4) {
+ u32 t2 = sctx->state[i];
+ out[j+3] = t2 & 0xff; t2>>=8;
+ out[j+2] = t2 & 0xff; t2>>=8;
+ out[j+1] = t2 & 0xff; t2>>=8;
+ out[j ] = t2 & 0xff;
+ }
+
+ /* Wipe context */
+ memset(sctx, 0, sizeof *sctx);
+}
diff --git a/sha1.h b/sha1.h
new file mode 100644
index 0000000..900e027
--- /dev/null
+++ b/sha1.h
@@ -0,0 +1,42 @@
+/*
+ * Cryptographic API.
+ *
+ * SHA1 Secure Hash Algorithm.
+ *
+ * Derived from cryptoapi implementation, adapted for in-place
+ * scatterlist interface. Originally based on the public domain
+ * implementation written by Steve Reid.
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ *
+ * 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.
+ *
+ */
+
+#ifndef _SHA1_
+#define _SHA1_
+
+#include "uint.h"
+
+#define SHA1_DIGEST_SIZE 20
+#define SHA1_HMAC_BLOCK_SIZE 64
+
+struct sha1_ctx {
+ u64 count;
+ u32 state[5];
+ u8 buffer[64];
+};
+
+void sha1_init(void *ctx);
+
+void sha1_update(void *ctx, const u8 *data, unsigned int len);
+
+/* Add padding and return the message digest. */
+void sha1_final(void* ctx, u8 *out);
+
+#endif
diff --git a/sha256.c b/sha256.c
new file mode 100644
index 0000000..ce13e22
--- /dev/null
+++ b/sha256.c
@@ -0,0 +1,149 @@
+/*
+ * An implementation of the SHA-256 hash function, this is endian neutral
+ * so should work just about anywhere.
+ *
+ * Revised Code: Complies to SHA-256 standard now.
+ *
+ * Tom St Denis -- http://tomstdenis.home.dhs.org
+ */
+
+#include "sha256.h"
+#include <string.h>
+
+/* the K array */
+static const u32 K[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Various logical functions */
+#define Ch(x,y,z) ((x & y) ^ (~x & z)) /* z ^ (x & (y ^z)) */
+#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) /* (x & y) | (z & (x | y)) */
+#define S(x, n) (((x)>>((n)&31))|((x)<<(32-((n)&31))))
+#define R(x, n) ((x)>>(n))
+#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+
+/* compress 512-bits */
+static void sha_compress(struct sha256_ctx *md)
+{
+ u32 S[8], W[64], t0, t1;
+ int i;
+
+ /* copy state into S */
+ for (i = 0; i < 8; i++)
+ S[i] = md->state[i];
+
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ W[i] = (((unsigned long) md->buf[(4 * i) + 0]) << 24) |
+ (((unsigned long) md->buf[(4 * i) + 1]) << 16) |
+ (((unsigned long) md->buf[(4 * i) + 2]) << 8) |
+ (((unsigned long) md->buf[(4 * i) + 3]));
+
+ /* fill W[16..63] */
+ for (i = 16; i < 64; i++)
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+
+ /* Compress */
+ for (i = 0; i < 64; i++) {
+ t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
+ t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
+ S[7] = S[6];
+ S[6] = S[5];
+ S[5] = S[4];
+ S[4] = S[3] + t0;
+ S[3] = S[2];
+ S[2] = S[1];
+ S[1] = S[0];
+ S[0] = t0 + t1;
+ }
+
+ /* feedback */
+ for (i = 0; i < 8; i++)
+ md->state[i] += S[i];
+}
+
+/* init the SHA state */
+void sha256_init(void *ctx)
+{
+ struct sha256_ctx *md = ctx;
+ md->curlen = md->length = 0;
+ md->state[0] = 0x6A09E667UL;
+ md->state[1] = 0xBB67AE85UL;
+ md->state[2] = 0x3C6EF372UL;
+ md->state[3] = 0xA54FF53AUL;
+ md->state[4] = 0x510E527FUL;
+ md->state[5] = 0x9B05688CUL;
+ md->state[6] = 0x1F83D9ABUL;
+ md->state[7] = 0x5BE0CD19UL;
+}
+
+void sha256_update(void *ctx, const u8 *buf, unsigned int len)
+{
+ struct sha256_ctx *md = ctx;
+ while (len--) {
+ /* copy byte */
+ md->buf[md->curlen++] = *buf++;
+ /* is 64 bytes full? */
+ if (md->curlen == 64) {
+ sha_compress(md);
+ md->length += 512;
+ md->curlen = 0;
+ }
+ }
+}
+
+void sha256_final(void *ctx, u8 *hash)
+{
+ struct sha256_ctx *md = ctx;
+ int i;
+
+ /* increase the length of the message */
+ md->length += md->curlen * 8;
+
+ /* append the '1' bit */
+ md->buf[md->curlen++] = 0x80;
+
+ /* if the length is currenlly above 56 bytes we append zeros
+ * then compress. Then we can fall back to padding zeros and length
+ * encoding like normal.
+ */
+
+ if (md->curlen >= 56) {
+ for (; md->curlen < 64;)
+ md->buf[md->curlen++] = 0;
+ sha_compress(md);
+ md->curlen = 0;
+ }
+
+ /* pad upto 56 bytes of zeroes */
+ for (; md->curlen < 56;)
+ md->buf[md->curlen++] = 0;
+
+ /* since all messages are under 2^32 bits we mark the top bits zero */
+ for (i = 56; i < 60; i++)
+ md->buf[i] = 0;
+
+ /* append length */
+ for (i = 60; i < 64; i++)
+ md->buf[i] = (md->length >> ((63 - i) * 8)) & 255;
+ sha_compress(md);
+
+ /* copy output */
+ for (i = 0; i < 32; i++)
+ hash[i] = (md->state[i >> 2] >> (((3 - i) & 3) << 3)) & 255;
+}
diff --git a/sha256.h b/sha256.h
new file mode 100644
index 0000000..fa98d42
--- /dev/null
+++ b/sha256.h
@@ -0,0 +1,28 @@
+/*
+ * An implementation of the SHA-256 hash function, this is endian neutral
+ * so should work just about anywhere.
+ *
+ * Revised Code: Complies to SHA-256 standard now.
+ *
+ * Tom St Denis -- http://tomstdenis.home.dhs.org
+ */
+
+#ifndef _SHA256_
+#define _SHA256_
+
+#include "uint.h"
+
+#define SHA256_DIGEST_SIZE 32
+
+struct sha256_ctx{
+ unsigned long state[8], length, curlen;
+ unsigned char buf[64];
+};
+
+void sha256_init(void *ctx);
+
+void sha256_update(void *ctx, const u8 *data, unsigned int len);
+
+void sha256_final(void *ctx, u8 *out);
+
+#endif
diff --git a/sha512.c b/sha512.c
new file mode 100644
index 0000000..7373467
--- /dev/null
+++ b/sha512.c
@@ -0,0 +1,301 @@
+/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ */
+
+#include "sha512.h"
+#include <string.h>
+
+static __inline u64 Ch(u64 x, u64 y, u64 z)
+{
+ return z ^ (x & (y ^ z));
+}
+
+static __inline u64 Maj(u64 x, u64 y, u64 z)
+{
+ return (x & y) | (z & (x | y));
+}
+
+static __inline u64 RORu64(u64 x, u64 y)
+{
+ return (x >> y) | (x << (64 - y));
+}
+
+const u64 sha512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+};
+
+#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
+#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
+#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
+#define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
+
+/* H* initial state for SHA-512 */
+#define H0 0x6a09e667f3bcc908ULL
+#define H1 0xbb67ae8584caa73bULL
+#define H2 0x3c6ef372fe94f82bULL
+#define H3 0xa54ff53a5f1d36f1ULL
+#define H4 0x510e527fade682d1ULL
+#define H5 0x9b05688c2b3e6c1fULL
+#define H6 0x1f83d9abfb41bd6bULL
+#define H7 0x5be0cd19137e2179ULL
+
+/* H'* initial state for SHA-384 */
+#define HP0 0xcbbb9d5dc1059ed8ULL
+#define HP1 0x629a292a367cd507ULL
+#define HP2 0x9159015a3070dd17ULL
+#define HP3 0x152fecd8f70e5939ULL
+#define HP4 0x67332667ffc00b31ULL
+#define HP5 0x8eb44a8768581511ULL
+#define HP6 0xdb0c2e0d64f98fa7ULL
+#define HP7 0x47b5481dbefa4fa4ULL
+
+static __inline void LOAD_OP(int I, u64 *W, const u8 *input)
+{
+ u64 t1 = input[(8*I) ] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+1] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+2] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+3] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+4] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+5] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+6] & 0xff;
+ t1 <<= 8;
+ t1 |= input[(8*I)+7] & 0xff;
+ W[I] = t1;
+}
+
+static __inline void BLEND_OP(int I, u64 *W)
+{
+ W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+}
+
+static void
+sha512_transform(u64 *state, const u8 *input)
+{
+ u64 a, b, c, d, e, f, g, h, t1, t2;
+ u64 W[80];
+
+ int i;
+
+ /* load the input */
+ for (i = 0; i < 16; i++)
+ LOAD_OP(i, W, input);
+
+ for (i = 16; i < 80; i++) {
+ BLEND_OP(i, W);
+ }
+
+ /* load the state into our registers */
+ a=state[0]; b=state[1]; c=state[2]; d=state[3];
+ e=state[4]; f=state[5]; g=state[6]; h=state[7];
+
+ /* now iterate */
+ for (i=0; i<80; i+=8) {
+ t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ];
+ t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
+ t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
+ t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
+ t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
+ t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
+ t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
+ t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
+ t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
+ t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
+ t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
+ t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
+ t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
+ t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
+ t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
+ t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
+ }
+
+ state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+ state[4] += e; state[5] += f; state[6] += g; state[7] += h;
+
+ /* erase our data */
+ a = b = c = d = e = f = g = h = t1 = t2 = 0;
+ memset(W, 0, 80 * sizeof(u64));
+}
+
+void
+sha512_init(void *ctx)
+{
+ struct sha512_ctx *sctx = ctx;
+ sctx->state[0] = H0;
+ sctx->state[1] = H1;
+ sctx->state[2] = H2;
+ sctx->state[3] = H3;
+ sctx->state[4] = H4;
+ sctx->state[5] = H5;
+ sctx->state[6] = H6;
+ sctx->state[7] = H7;
+ sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+ memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+void
+sha384_init(void *ctx)
+{
+ struct sha512_ctx *sctx = ctx;
+ sctx->state[0] = HP0;
+ sctx->state[1] = HP1;
+ sctx->state[2] = HP2;
+ sctx->state[3] = HP3;
+ sctx->state[4] = HP4;
+ sctx->state[5] = HP5;
+ sctx->state[6] = HP6;
+ sctx->state[7] = HP7;
+ sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+ memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+void
+sha512_update(void *ctx, const u8 *data, unsigned int len)
+{
+ struct sha512_ctx *sctx = ctx;
+
+ unsigned int i, index, part_len;
+
+ /* Compute number of bytes mod 128 */
+ index = (unsigned int)((sctx->count[0] >> 3) & 0x7F);
+
+ /* Update number of bits */
+ if ((sctx->count[0] += (len << 3)) < (len << 3)) {
+ if ((sctx->count[1] += 1) < 1)
+ if ((sctx->count[2] += 1) < 1)
+ sctx->count[3]++;
+ sctx->count[1] += (len >> 29);
+ }
+
+ part_len = 128 - index;
+
+ /* Transform as many times as possible. */
+ if (len >= part_len) {
+ memcpy(&sctx->buf[index], data, part_len);
+ sha512_transform(sctx->state, sctx->buf);
+
+ for (i = part_len; i + 127 < len; i+=128)
+ sha512_transform(sctx->state, &data[i]);
+
+ index = 0;
+ } else {
+ i = 0;
+ }
+
+ /* Buffer remaining input */
+ memcpy(&sctx->buf[index], &data[i], len - i);
+}
+
+void
+sha512_final(void *ctx, u8 *hash)
+{
+ struct sha512_ctx *sctx = ctx;
+
+ static u8 padding[128] = { 0x80, };
+
+ u32 t;
+ u64 t2;
+ u8 bits[128];
+ unsigned int index, pad_len;
+ int i, j;
+
+ index = pad_len = t = i = j = 0;
+ t2 = 0;
+
+ /* Save number of bits */
+ t = sctx->count[0];
+ bits[15] = t; t>>=8;
+ bits[14] = t; t>>=8;
+ bits[13] = t; t>>=8;
+ bits[12] = t;
+ t = sctx->count[1];
+ bits[11] = t; t>>=8;
+ bits[10] = t; t>>=8;
+ bits[9 ] = t; t>>=8;
+ bits[8 ] = t;
+ t = sctx->count[2];
+ bits[7 ] = t; t>>=8;
+ bits[6 ] = t; t>>=8;
+ bits[5 ] = t; t>>=8;
+ bits[4 ] = t;
+ t = sctx->count[3];
+ bits[3 ] = t; t>>=8;
+ bits[2 ] = t; t>>=8;
+ bits[1 ] = t; t>>=8;
+ bits[0 ] = t;
+
+ /* Pad out to 112 mod 128. */
+ index = (sctx->count[0] >> 3) & 0x7f;
+ pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
+ sha512_update(sctx, padding, pad_len);
+
+ /* Append length (before padding) */
+ sha512_update(sctx, bits, 16);
+
+ /* Store state in digest */
+ for (i = j = 0; i < 8; i++, j += 8) {
+ t2 = sctx->state[i];
+ hash[j+7] = (char)t2 & 0xff; t2>>=8;
+ hash[j+6] = (char)t2 & 0xff; t2>>=8;
+ hash[j+5] = (char)t2 & 0xff; t2>>=8;
+ hash[j+4] = (char)t2 & 0xff; t2>>=8;
+ hash[j+3] = (char)t2 & 0xff; t2>>=8;
+ hash[j+2] = (char)t2 & 0xff; t2>>=8;
+ hash[j+1] = (char)t2 & 0xff; t2>>=8;
+ hash[j ] = (char)t2 & 0xff;
+ }
+
+ /* Zeroize sensitive information. */
+ memset(sctx, 0, sizeof(struct sha512_ctx));
+}
+
+void sha384_final(void *ctx, u8 *hash)
+{
+ struct sha512_ctx *sctx = ctx;
+ u8 D[64];
+
+ sha512_final(sctx, D);
+
+ memcpy(hash, D, 48);
+ memset(D, 0, 64);
+}
diff --git a/sha512.h b/sha512.h
new file mode 100644
index 0000000..41161ec
--- /dev/null
+++ b/sha512.h
@@ -0,0 +1,36 @@
+/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ */
+#ifndef _SHA512_
+#define _SHA512_
+
+#include "uint.h"
+
+#define SHA384_DIGEST_SIZE 48
+#define SHA512_DIGEST_SIZE 64
+#define SHA384_HMAC_BLOCK_SIZE 96
+#define SHA512_HMAC_BLOCK_SIZE 128
+
+struct sha512_ctx {
+ u64 state[8];
+ u32 count[4];
+ u8 buf[128];
+};
+void sha512_init(void *ctx);
+void sha384_init(void *ctx);
+
+void sha512_update(void *ctx, const u8 *data, unsigned int len);
+
+void sha512_final(void *ctx, u8 *hash);
+void sha384_final(void *ctx, u8 *hash);
+
+#endif
diff --git a/socket.h b/socket.h
new file mode 100644
index 0000000..35e9551
--- /dev/null
+++ b/socket.h
@@ -0,0 +1,51 @@
+#ifndef _SOCKET_H
+#define _SOCKET_H
+
+#include "uint.h"
+
+/* accept a connection, returns socket fd, ip and port */
+int socket_accept4(int s, char *ip, u16 *port);
+
+/* bind s to local ip and port */
+int socket_bind4(int s, char *ip, u16 port);
+
+/* set SO_REUSEADDR before calling socket_bind4 */
+int socket_bind4_reuse(int s, char *ip, u16 port);
+
+/* connect s to ip and port */
+int socket_connect4(int s, const char *ip, u16 port);
+
+/* return 1 if connected */
+int socket_connected(int s);
+
+/* reset socket options */
+int socket_ipoptionskill(int s);
+
+/* just call listen */
+int socket_listen(int s,int backlog);
+
+/* get local ip and port */
+int socket_local4(int s, char *ip, u16 *port);
+
+/* feed buffer ip and port */
+int socket_recv4(int s, char *,int,char *ip, u16 *port);
+
+/* get distant ip and port */
+int socket_remote4(int s, char *ip, u16 *port);
+
+/* send buffer to ip and port */
+int socket_send4(int s, const char *,int,const char *ip, u16 port);
+
+/* returns a sock-stream socket if(!block) set O_NONBLOCK */
+int socket_tcp(int block);
+
+/* set TCP_NODELAY */
+int socket_tcpnodelay(int s);
+
+/* try to set input buffer size */
+void socket_tryreservein(int s, int size);
+
+/* returns a sock-dgram socket if(!block) set O_NONBLOCK */
+int socket_udp(int block);
+
+#endif
diff --git a/socket_accept.c b/socket_accept.c
new file mode 100644
index 0000000..61de070
--- /dev/null
+++ b/socket_accept.c
@@ -0,0 +1,22 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "socket.h"
+#include "uint16.h"
+
+
+int socket_accept4(int s,char ip[4],u16 *port)
+{
+ struct sockaddr_in sa;
+ socklen_t dummy = sizeof sa;
+ int fd;
+
+ fd = accept(s,(struct sockaddr *) &sa,&dummy);
+ if (fd == -1) return -1;
+
+ memcpy(ip,(char *) &sa.sin_addr,4);
+ u16_unpack_big((char *) &sa.sin_port,port);
+
+ return fd;
+}
diff --git a/socket_bind.c b/socket_bind.c
new file mode 100644
index 0000000..5a6a0a0
--- /dev/null
+++ b/socket_bind.c
@@ -0,0 +1,33 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "socket.h"
+#include "uint16.h"
+
+int socket_bind4(int s,char ip[4],u16 port)
+{
+ struct sockaddr_in sa;
+
+ memset(&sa,0,sizeof sa);
+ sa.sin_family = AF_INET;
+ u16_pack_big((char *) &sa.sin_port,port);
+ memcpy((char *) &sa.sin_addr,ip,4);
+
+ return bind(s,(struct sockaddr *) &sa,sizeof sa);
+}
+
+int socket_bind4_reuse(int s,char ip[4],u16 port)
+{
+ int opt = 1;
+ setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt);
+ return socket_bind4(s,ip,port);
+}
+
+void socket_tryreservein(int s,int size)
+{
+ while (size >= 1024) {
+ if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,&size,sizeof size) == 0) return;
+ size -= (size >> 5);
+ }
+}
diff --git a/socket_conn.c b/socket_conn.c
new file mode 100644
index 0000000..0d3b7f9
--- /dev/null
+++ b/socket_conn.c
@@ -0,0 +1,35 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include "socket.h"
+#include "uint16.h"
+
+
+int socket_connect4(int s,const char ip[4],u16 port)
+{
+ struct sockaddr_in sa;
+
+ memset(&sa,0,sizeof sa);
+ sa.sin_family = AF_INET;
+ u16_pack_big((char *) &sa.sin_port,port);
+ memcpy((char *) &sa.sin_addr,ip,4);
+
+ return connect(s,(struct sockaddr *) &sa,sizeof sa);
+}
+
+int socket_connected(int s)
+{
+ struct sockaddr_in sa;
+ socklen_t dummy;
+ char ch;
+ int r;
+
+ dummy = sizeof sa;
+ if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) {
+ r = read(s,&ch,1); /* sets errno */
+ return 0;
+ }
+ return 1;
+}
diff --git a/socket_listen.c b/socket_listen.c
new file mode 100644
index 0000000..5132508
--- /dev/null
+++ b/socket_listen.c
@@ -0,0 +1,8 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "socket.h"
+
+int socket_listen(int s,int backlog)
+{
+ return listen(s,backlog);
+}
diff --git a/socket_local.c b/socket_local.c
new file mode 100644
index 0000000..b676ee5
--- /dev/null
+++ b/socket_local.c
@@ -0,0 +1,17 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "socket.h"
+#include "uint16.h"
+
+int socket_local4(int s,char ip[4],u16 *port)
+{
+ struct sockaddr_in sa;
+ unsigned int dummy = sizeof sa;
+
+ if (getsockname(s,(struct sockaddr *) &sa,&dummy) == -1) return -1;
+ memcpy(ip,(char *) &sa.sin_addr,4);
+ u16_unpack_big((char *) &sa.sin_port,port);
+ return 0;
+}
diff --git a/socket_remote.c b/socket_remote.c
new file mode 100644
index 0000000..7ea339a
--- /dev/null
+++ b/socket_remote.c
@@ -0,0 +1,17 @@
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "socket.h"
+#include "uint16.h"
+
+int socket_remote4(int s,char ip[4],u16 *port)
+{
+ struct sockaddr_in sa;
+ unsigned int dummy = sizeof sa;
+
+ if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) return -1;
+ memcpy(ip,(char *) &sa.sin_addr,4);
+ u16_unpack_big((char *) &sa.sin_port,port);
+ return 0;
+}
diff --git a/socket_tcp.c b/socket_tcp.c
new file mode 100644
index 0000000..5a7c920
--- /dev/null
+++ b/socket_tcp.c
@@ -0,0 +1,16 @@
+#include "socket.h"
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+int socket_tcp(int block)
+{
+ int s;
+ s = socket(AF_INET,SOCK_STREAM,0);
+ if (s == -1) return -1;
+ if(block) return s;
+ if (fcntl(s,F_SETFL,fcntl(s,F_GETFL,0) | O_NONBLOCK) == -1) { close(s); return -1; }
+ return s;
+}
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..2c184c7
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+
+FILE="test_file"
+TMP="test_tmp"
+KEY="secret_key_yeah_" # 16 bytes for twofish
+BIN="./cryptot"
+
+if [ ! -x ${BIN} ]; then
+ echo "" && exit 1;
+fi;
+
+# 80 Mb file
+echo "generate a 70Mb file from source files."
+if [ -f ${FILE} ]; then rm ${FILE}; fi;
+if [ -f ${TMP} ]; then rm ${TMP}; fi;
+cat *.c > ${FILE};
+cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} && cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} && \
+cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} && cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} && \
+cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} && cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} && \
+cat ${FILE} >> ${TMP} && cat ${TMP} >> ${FILE} || exit 1;
+echo "done."
+rm ${TMP}
+
+ARGS1="-v -c 1 -n 700 "
+ARGS2="-v -x -c 1 -n 600 "
+ARGSD="-d 127.0.0.1:4779"
+ARGSS="-s 127.0.0.1:4779"
+
+local(){
+
+ cat ${FILE} | ${BIN} ${ARGS1} ${KEY} | ${BIN} -x ${ARGS2} ${KEY} > DEC
+}
+
+dist (){
+
+ ${BIN} -x ${ARGS2} ${ARGSS} ${KEY} > DEC & PID=$!
+ sleep 2
+ cat ${FILE} | ${BIN} ${ARGS1} ${ARGSD} ${KEY} || ( echo "error !!"; exit 1 )
+ wait ${PID}
+}
+
+local
+echo "running diff"
+diff ${FILE} DEC || echo "ERROR"
+echo "OK."
+rm DEC
+
+dist
+echo "running diff"
+diff ${FILE} DEC || echo "ERROR"
+echo "OK."
+
+rm DEC ${FILE}
diff --git a/test_crypto_api.c b/test_crypto_api.c
new file mode 100644
index 0000000..5a20c77
--- /dev/null
+++ b/test_crypto_api.c
@@ -0,0 +1,325 @@
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "aes.h"
+#include "des.h"
+#include "blowfish.h"
+#include "twofish.h"
+#include "md4.h"
+#include "md5.h"
+#include "sha1.h"
+#include "sha256.h"
+#include "sha512.h"
+
+
+int main(void)
+{
+ int i,j;
+
+ struct blowfish_ctx bf_ctx;
+ struct twofish_ctx tf_ctx;
+ struct aes_ctx a_ctx;
+ struct des_ctx d_ctx;
+ struct des3_ede_ctx d3_ctx;
+ struct md4_ctx md4;
+ struct md5_ctx md5;
+ struct sha1_ctx sha1;
+ struct sha256_ctx sha256;
+ struct sha512_ctx sha512;
+ u32 flags;
+
+ u8 key[]="9_&pass/#word%_0";
+
+ const u8 phrase[64] = "this#is/only|a?test,@nothing%more&nothing~less 0123456789 voila";
+ u8 encrypt[64] = "";
+ u8 decrypt[64] = "";
+ u8 md4_hash[MD4_DIGEST_SIZE];
+ u8 md5_hash[MD5_DIGEST_SIZE];
+ u8 sha1_hash[SHA1_DIGEST_SIZE];
+ u8 sha256_hash[SHA256_DIGEST_SIZE];
+ u8 sha512_hash[SHA512_DIGEST_SIZE];
+
+ const u8 T1[64] = "123456";
+ const u8 T2[64] = "789101";
+
+ printf("crypto api tests\n");
+ printf("\n\tused phrase : '%s'\n\tlength : %d\n\n",phrase,strlen((char*)phrase));
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ /* test blowfish */
+ printf("_Blwofish: A 64-Bit Block Cipher_ by Bruce Schneier...\n");
+ if(blowfish_setkey(&bf_ctx, key, strlen((char*)key), &flags)!=0){
+ fprintf(stderr,"bf_setkey error.\n");
+ _exit(1);
+ }
+ for(i=0; i<sizeof(phrase)/BF_BLOCK_SIZE; i++){
+ blowfish_encrypt(&bf_ctx, encrypt, phrase+i*BF_BLOCK_SIZE);
+ blowfish_decrypt(&bf_ctx, decrypt+i*BF_BLOCK_SIZE, encrypt);
+ printf("\tencrypted block => ");
+ for(j=0; j<BF_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ }
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(phrase,decrypt,64)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ printf("\twith non-full blocks\n");
+ printf("\tfirst string : '%s'\n\tsecond string : '%s'\n",T1,T2);
+ blowfish_encrypt(&bf_ctx, encrypt, T1);
+ blowfish_encrypt(&bf_ctx, encrypt+BF_BLOCK_SIZE, T2);
+ printf("\tencrypted block => ");
+ for(j=0; j<BF_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ printf("\tencrypted block => ");
+ for(j=0; j<BF_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j+BF_BLOCK_SIZE]);
+ printf("\n");
+ blowfish_decrypt(&bf_ctx, decrypt, encrypt);
+ blowfish_decrypt(&bf_ctx, decrypt+strlen((char*)T1), encrypt+BF_BLOCK_SIZE);
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(decrypt,"123456789101",12)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+
+
+ /* test twofish */
+ printf("_Twofish: A 128-Bit Block Cipher_ by Bruce Schneier...\n");
+ if(twofish_setkey(&tf_ctx, key, strlen((char*)key),&flags)!=0){
+ fprintf(stderr,"twofish_setkey error.\n");
+ _exit(1);
+ }
+
+ for(i=0; i<sizeof(phrase)/TF_BLOCK_SIZE; i++){
+ twofish_encrypt(&tf_ctx, encrypt, phrase+i*TF_BLOCK_SIZE);
+ twofish_decrypt(&tf_ctx, decrypt+i*TF_BLOCK_SIZE, encrypt);
+ printf("\tencrypted block => ");
+ for(j=0; j<TF_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ }
+ printf("\n");
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(phrase,decrypt,64)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ printf("\twith non-full blocks\n");
+ printf("\tfirst string : '%s'\n\tsecond string : '%s'\n",T1,T2);
+ twofish_encrypt(&bf_ctx, encrypt, T1);
+ twofish_encrypt(&bf_ctx, encrypt+TF_BLOCK_SIZE, T2);
+ printf("\tencrypted block => ");
+ for(j=0; j<TF_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ printf("\tencrypted block => ");
+ for(j=0; j<TF_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j+TF_BLOCK_SIZE]);
+ printf("\n");
+ twofish_decrypt(&bf_ctx, decrypt, encrypt);
+ twofish_decrypt(&bf_ctx, decrypt+strlen((char*)T1), encrypt+TF_BLOCK_SIZE);
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(decrypt,"123456789101",12)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+
+ /* test aes */
+ printf("_aes \n");
+ if(aes_setkey(&a_ctx, key, strlen((char*)key),&flags)!=0){
+ fprintf(stderr,"aes_setkey error.\n");
+ _exit(1);
+ }
+
+ for(i=0; i<sizeof(phrase)/AES_BLOCK_SIZE; i++){
+ aes_encrypt(&a_ctx, encrypt, phrase+i*AES_BLOCK_SIZE);
+ aes_decrypt(&a_ctx, decrypt+i*AES_BLOCK_SIZE, encrypt);
+ printf("\tencrypted block => ");
+ for(j=0; j<AES_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ }
+ printf("\n");
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(phrase,decrypt,64)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ printf("\twith non-full blocks\n");
+ printf("\tfirst string : '%s'\n\tsecond string : '%s'\n",T1,T2);
+ aes_encrypt(&a_ctx, encrypt, T1);
+ aes_encrypt(&a_ctx, encrypt+AES_BLOCK_SIZE, T2);
+ printf("\tencrypted block => ");
+ for(j=0; j<AES_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ printf("\tencrypted block => ");
+ for(j=0; j<AES_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j+AES_BLOCK_SIZE]);
+ printf("\n");
+ aes_decrypt(&a_ctx, decrypt, encrypt);
+ aes_decrypt(&a_ctx, decrypt+strlen((char*)T1), encrypt+AES_BLOCK_SIZE);
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(decrypt,"123456789101",12)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ /* test des */
+ printf("_des \n");
+ if(des_setkey(&d_ctx, key, strlen((char*)key),&flags)!=0){
+ fprintf(stderr,"des_setkey error.\n");
+ _exit(1);
+ }
+
+ for(i=0; i<sizeof(phrase)/DES_BLOCK_SIZE; i++){
+ des_encrypt(&d_ctx, encrypt, phrase+i*DES_BLOCK_SIZE);
+ des_decrypt(&d_ctx, decrypt+i*DES_BLOCK_SIZE, encrypt);
+ printf("\tencrypted block => ");
+ for(j=0; j<DES_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ }
+ printf("\n");
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(phrase,decrypt,64)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ printf("\twith non-full blocks\n");
+ printf("\tfirst string : '%s'\n\tsecond string : '%s'\n",T1,T2);
+ des_encrypt(&d_ctx, encrypt, T1);
+ des_encrypt(&d_ctx, encrypt+DES_BLOCK_SIZE, T2);
+ printf("\tencrypted block => ");
+ for(j=0; j<DES_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ printf("\tencrypted block => ");
+ for(j=0; j<DES_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j+DES_BLOCK_SIZE]);
+ printf("\n");
+ des_decrypt(&d_ctx, decrypt, encrypt);
+ des_decrypt(&d_ctx, decrypt+strlen((char*)T1), encrypt+DES_BLOCK_SIZE);
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(decrypt,"123456789101",12)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ /* test des3_ede */
+ printf("_des3_ede \n");
+ if(des3_ede_setkey(&d3_ctx, key, strlen((char*)key),&flags)!=0){
+ fprintf(stderr,"des_setkey error.\n");
+ _exit(1);
+ }
+
+ for(i=0; i<sizeof(phrase)/DES3_EDE_BLOCK_SIZE; i++){
+ des3_ede_encrypt(&d3_ctx, encrypt, phrase+i*DES3_EDE_BLOCK_SIZE);
+ des3_ede_decrypt(&d3_ctx, decrypt+i*DES3_EDE_BLOCK_SIZE, encrypt);
+ printf("\tencrypted block => ");
+ for(j=0; j<DES3_EDE_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ }
+ printf("\n");
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(phrase,decrypt,64)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ printf("\twith non-full blocks\n");
+ printf("\tfirst string : '%s'\n\tsecond string : '%s'\n",T1,T2);
+ des3_ede_encrypt(&d3_ctx, encrypt, T1);
+ des3_ede_encrypt(&d3_ctx, encrypt+DES3_EDE_BLOCK_SIZE, T2);
+ printf("\tencrypted block => ");
+ for(j=0; j<DES3_EDE_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j]);
+ printf("\n");
+ printf("\tencrypted block => ");
+ for(j=0; j<DES3_EDE_BLOCK_SIZE; j++)
+ printf("%02x ",encrypt[j+DES3_EDE_BLOCK_SIZE]);
+ printf("\n");
+ des3_ede_decrypt(&d3_ctx, decrypt, encrypt);
+ des3_ede_decrypt(&d3_ctx, decrypt+strlen((char*)T1), encrypt+DES3_EDE_BLOCK_SIZE);
+ printf("\n\tdecrypted => '%s'\n\n",decrypt);
+ assert(memcmp(decrypt,"123456789101",12)==0);
+
+ memset(encrypt,0,sizeof(encrypt));
+ memset(encrypt,0,sizeof(decrypt));
+
+ /* md4 */
+ printf("MD4: one way hash with a %d bits output digest.\n",MD4_DIGEST_SIZE);
+ md4_init(&md4);
+ md4_update(&md4,(u8*)phrase,32);
+ md4_update(&md4,(u8*)phrase+32,strlen((char*)phrase)-32);
+ md4_final(&md4,md4_hash);
+ printf("\n\tdigest : ");
+ for(i=0; i<MD4_DIGEST_SIZE; i++)
+ printf("%02x",md4_hash[i]);
+ printf("\n\n");
+
+ /* md5 */
+ printf("MD5: one way hash with a %d bits output digest.\n",MD5_DIGEST_SIZE);
+ md5_init(&md5);
+ md5_update(&md5,(u8*)phrase,32);
+ md5_update(&md5,(u8*)phrase+32,strlen((char*)phrase)-32);
+ md5_final(&md5,md5_hash);
+ printf("\n\tdigest : ");
+ for(i=0; i<MD5_DIGEST_SIZE; i++)
+ printf("%02x",md5_hash[i]);
+ printf("\n\n");
+
+ /* sha1 */
+ printf("SHA1: one way hash with a %d bits output digest.\n",SHA1_DIGEST_SIZE);
+ sha1_init(&sha1);
+ sha1_update(&sha1,(u8*)phrase,32);
+ sha1_update(&sha1,(u8*)phrase+32,strlen((char*)phrase)-32);
+ sha1_final(&sha1,sha1_hash);
+ printf("\n\tdigest : ");
+ for(i=0; i<SHA1_DIGEST_SIZE; i++)
+ printf("%02x",sha1_hash[i]);
+ printf("\n\n");
+
+ /* sha256 */
+ printf("SHA256: one way hash with a %d bits output digest.\n",SHA256_DIGEST_SIZE);
+ sha256_init(&sha256);
+ sha256_update(&sha256,(u8*)phrase,32);
+ sha256_update(&sha256,(u8*)phrase+32,strlen((char*)phrase)-32);
+ sha256_final(&sha256,sha256_hash);
+ printf("\n\tdigest : ");
+ for(i=0; i<SHA256_DIGEST_SIZE; i++)
+ printf("%02x",sha256_hash[i]);
+ printf("\n\n");
+
+ /* sha512 */
+ printf("SHA512: one way hash with a %d bits output digest.\n",SHA512_DIGEST_SIZE);
+ sha512_init(&sha512);
+ sha512_update(&sha512,(u8*)phrase,32);
+ sha512_update(&sha512,(u8*)phrase+32,strlen((char*)phrase)-32);
+ sha512_final(&sha512,sha512_hash);
+ printf("\n\tdigest : ");
+ for(i=0; i<SHA512_DIGEST_SIZE/2; i++)
+ printf("%02x",sha512_hash[i]);
+ printf("\n\t ");
+ for(; i<SHA512_DIGEST_SIZE; i++)
+ printf("%02x",sha512_hash[i]);
+ printf("\n\n");
+
+ printf("tests ok\n");
+
+ return 0;
+}
diff --git a/test_crypto_buffer.c b/test_crypto_buffer.c
new file mode 100644
index 0000000..25e6c93
--- /dev/null
+++ b/test_crypto_buffer.c
@@ -0,0 +1,222 @@
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "crypto_buffer.h"
+
+
+int main(void)
+{
+ static int fd, ret;
+ static crypto_buffer out_buffer;
+ static crypto_buffer in_buffer;
+ static u8 phrase[64]="blah_et_vlan_et_rantanplan_=_rien_de_cohérent.";
+ static u8 decrypted[64]="";
+
+/* blowfish */
+ printf("** crypto buffer tests with BLOWFISH **\n\n");
+
+ /* write */
+ fd = open("./crypto_file",O_WRONLY|O_CREAT|O_TRUNC,0644);
+ if(fd == -1) return -1;
+ ret = write(fd,"AAA",3);
+ assert(ret==3);
+ if(crypto_buffer_init(&out_buffer, fd, u8_unix_write, 4,
+ BLOWFISH|ENCRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ crypto_buffer_putflush(&out_buffer,phrase,5);
+ close(fd);
+ printf("file written\n");
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, u8_unix_read, 5,
+ BLOWFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,64));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,5)==0);
+ memset(decrypted,0,64);
+
+ /* write */
+ fd = open("./crypto_file",O_WRONLY|O_CREAT|O_TRUNC,0644);
+ if(fd == -1) return -1;
+ ret = write(fd,"AAA",3);
+ assert(ret==3);
+ if(crypto_buffer_init(&out_buffer, fd, &u8_unix_write, 4,
+ BLOWFISH|ENCRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ crypto_buffer_putflush(&out_buffer,phrase,8);
+ close(fd);
+ printf("file written\n");
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ BLOWFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,64));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,8)==0);
+ memset(decrypted,0,64);
+
+ /* write */
+ fd = open("./crypto_file",O_WRONLY|O_CREAT|O_TRUNC,0644);
+ if(fd == -1) return -1;
+ ret = write(fd,"AAA",0);
+ assert(ret==0);
+ if(crypto_buffer_init(&out_buffer, fd, &u8_unix_write, 4,
+ BLOWFISH|ENCRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ crypto_buffer_putflush(&out_buffer,phrase,64);
+ close(fd);
+ printf("file written\n");
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ BLOWFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,64));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ BLOWFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,8));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+8,15));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+23,24));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+47,5));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ /* write */
+ fd = open("./crypto_file",O_WRONLY|O_CREAT|O_TRUNC,0644);
+ if(fd == -1) return -1;
+ ret = write(fd,"AAAAA",5);
+ assert(ret==5);
+ if(crypto_buffer_init(&out_buffer, fd, &u8_unix_write, 4,
+ BLOWFISH|ENCRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ crypto_buffer_put(&out_buffer,phrase,12);
+ crypto_buffer_putflush(&out_buffer,phrase+12,14);
+ crypto_buffer_putflush(&out_buffer,phrase+26,23);
+ close(fd);
+ printf("file written\n");
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ BLOWFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,64));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ BLOWFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,9));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+9,9));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+18,20));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+38,22));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+
+/* twofish */
+ printf("** crypto buffer tests with TWOFISH **\n\n");
+ /* write */
+ fd = open("./crypto_file",O_WRONLY|O_CREAT|O_TRUNC,0644);
+ if(fd == -1) return -1;
+ ret = write(fd,"AAA",3);
+ assert(ret==3);
+ if(crypto_buffer_init(&out_buffer, fd, &u8_unix_write, 4,
+ TWOFISH|ENCRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ crypto_buffer_putflush(&out_buffer,phrase,64);
+ close(fd);
+ printf("file written\n");
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ TWOFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,64));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ TWOFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,9));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+9,9));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+18,20));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+38,22));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ /* write */
+ fd = open("./crypto_file",O_WRONLY|O_CREAT|O_TRUNC,0644);
+ if(fd == -1) return -1;
+ ret = write(fd,"AAAA",4);
+ assert(ret==4);
+ if(crypto_buffer_init(&out_buffer, fd, &u8_unix_write, 4,
+ TWOFISH|ENCRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ crypto_buffer_put(&out_buffer,phrase,12);
+ crypto_buffer_putflush(&out_buffer,phrase+12,14);
+ crypto_buffer_putflush(&out_buffer,phrase+26,21);
+ close(fd);
+ printf("file written\n");
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ TWOFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,64));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ /* read */
+ fd = open("./crypto_file",O_RDONLY);
+ if(fd == -1) return -1;
+ if(crypto_buffer_init(&in_buffer, fd, &u8_unix_read, 5,
+ TWOFISH|DECRYPT, (u8*)"secret_key_hah!!", 16)!=0) return -1;
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted,16));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+16,7));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+23,28));
+ printf("read : %d\n",crypto_buffer_get(&in_buffer,decrypted+51,13));
+ printf("decrypted => '%s'\n\n",decrypted);
+ close(fd);
+ assert(memcmp(phrase,decrypted,64)==0);
+ memset(decrypted,0,64);
+
+ printf("tests ok\n");
+ return 0;
+}
diff --git a/timespec.h b/timespec.h
new file mode 100644
index 0000000..5c23e69
--- /dev/null
+++ b/timespec.h
@@ -0,0 +1,20 @@
+#ifndef _TIMESPEC_H
+#define _TIMESPEC_H
+
+/*
+ * on my OpenBSD 3.5 CLOCK_ REALTIME and MONOTONIC work but not VIRTUAL and PROF
+ * on my slackware 10.0 nor MONOTONIC neither PROCESS_CPU_ID or THREAD_CPUTIME_ID work, only REALTIME is ok
+ */
+
+/* BSD compare macro */
+#ifndef timespeccmp
+#define timespeccmp(pt_a,pt_b,sign) ( ((pt_a)->tv_sec==(pt_b)->tv_sec) ? \
+ ((pt_a)->tv_nsec sign (pt_b)->tv_nsec) : \
+ ((pt_a)->tv_sec sign (pt_b)->tv_sec) )
+#endif
+
+/* compute macro */
+#define timespec_compute(pt_a,pt_b) ((float)((pt_b)->tv_sec - (pt_a)->tv_sec) + \
+ ((float)((pt_b)->tv_nsec - (pt_a)->tv_nsec))/1E9)
+
+#endif
diff --git a/try_clock_gettime.c b/try_clock_gettime.c
new file mode 100644
index 0000000..239900e
--- /dev/null
+++ b/try_clock_gettime.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+int main(void)
+{
+ struct timespec s;
+ clock_gettime(CLOCK_REALTIME, &s);
+ return EXIT_SUCCESS;
+}
+
+
diff --git a/trycpp.c b/trycpp.c
new file mode 100644
index 0000000..0d51ebd
--- /dev/null
+++ b/trycpp.c
@@ -0,0 +1,7 @@
+int main()
+{
+#ifdef NeXT
+ printf("nextstep\n"); exit(0);
+#endif
+ printf("unknown\n"); exit(0);
+}
diff --git a/twofish.c b/twofish.c
new file mode 100644
index 0000000..0900c00
--- /dev/null
+++ b/twofish.c
@@ -0,0 +1,859 @@
+/*
+ * Twofish for CryptoAPI
+ *
+ * Originaly Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
+ * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors
+ * have put this under the GNU General Public License.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+#include <errno.h>
+#include "twofish.h"
+
+
+/* The large precomputed tables for the Twofish cipher (twofish.c)
+ * Taken from the same source as twofish.c
+ * Marc Mutz <Marc@Mutz.com>
+ */
+
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const u8 q0[256] = {
+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+ 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+ 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+ 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+ 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+ 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+ 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+ 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+ 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+ 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+ 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+ 0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const u8 q1[256] = {
+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+ 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+ 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+ 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+ 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+ 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+ 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+ 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+ 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+ 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+ 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+ 0x55, 0x09, 0xBE, 0x91
+};
+
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing. Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs. Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+ {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+ 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+ 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+ 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+ 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+ 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+ 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+ 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+ 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+ 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+ 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+ 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+ 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+ 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+ 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+ 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+ 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+ 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+ 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+ 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+ 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+ 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+ 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+ 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+ 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+ 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+ 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+ 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+ 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+ 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+ 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+ 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+ 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+ 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+ 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+ 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+ 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+ 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+ 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+ 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+ 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+ 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+ 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+ {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+ 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+ 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+ 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+ 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+ 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+ 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+ 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+ 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+ 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+ 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+ 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+ 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+ 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+ 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+ 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+ 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+ 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+ 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+ 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+ 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+ 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+ 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+ 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+ 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+ 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+ 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+ 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+ 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+ 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+ 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+ 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+ 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+ 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+ 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+ 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+ 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+ 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+ 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+ 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+ 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+ 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+ 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+ {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+ 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+ 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+ 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+ 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+ 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+ 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+ 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+ 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+ 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+ 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+ 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+ 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+ 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+ 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+ 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+ 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+ 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+ 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+ 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+ 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+ 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+ 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+ 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+ 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+ 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+ 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+ 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+ 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+ 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+ 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+ 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+ 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+ 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+ 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+ 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+ 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+ 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+ 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+ 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+ 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+ 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+ 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+ {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+ 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+ 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+ 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+ 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+ 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+ 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+ 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+ 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+ 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+ 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+ 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+ 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+ 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+ 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+ 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+ 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+ 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+ 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+ 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+ 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+ 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+ 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+ 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+ 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+ 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+ 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+ 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+ 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+ 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+ 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+ 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+ 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+ 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+ 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+ 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+ 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+ 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+ 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+ 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+ 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+ 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+ 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule. Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2). In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support. To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation. So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ * 1. if p=0 or q=0 then pq=0
+ * 2. otherwise, find m and n such that p=x^m and q=x^n
+ * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
+ * in action, look at the CALC_S macro. As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper. I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491. I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch. I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const u8 poly_to_exp[255] = {
+ 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+ 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+ 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+ 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+ 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+ 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+ 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+ 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+ 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+ 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+ 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+ 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+ 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+ 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+ 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+ 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+ 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+ 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+ 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+ 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+ 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+ 0x85, 0xC8, 0xA1
+};
+
+static const u8 exp_to_poly[492] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+ 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+ 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+ 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+ 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+ 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+ 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+ 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+ 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+ 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+ 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+ 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+ 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+ 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+ 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+ 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+ 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+ 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+ 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+ 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+ 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+ 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+ 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+ 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+ 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+ 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+ 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+ 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+ 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+ 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+ 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+ 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+ 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+ 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+ 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+ 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+ 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+ 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+ 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+ 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static const u8 calc_sb_tbl[512] = {
+ 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+ 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+ 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+ 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+ 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+ 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+ 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+ 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+ 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+ 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+ 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+ 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+ 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+ 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+ 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+ 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+ 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+ 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+ 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+ 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+ 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+ 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+ 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+ 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+ 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+ 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+ 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+ 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+ 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+ 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+ 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+ 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+ 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+ 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+ 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+ 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+ 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+ 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+ 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+ 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+ 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+ 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+ 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+ 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+ 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+ 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+ 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+ 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+ 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+ 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+ 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+ 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+ 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+ 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+ 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+ 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+ 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+ 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+ 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+ 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+ 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+ 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+ 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+ 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+
+/* Macro to perform one column of the RS matrix multiplication. The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+ if (key[i]) { \
+ tmp = poly_to_exp[key[i] - 1]; \
+ (a) ^= exp_to_poly[tmp + (w)]; \
+ (b) ^= exp_to_poly[tmp + (x)]; \
+ (c) ^= exp_to_poly[tmp + (y)]; \
+ (d) ^= exp_to_poly[tmp + (z)]; \
+ }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S. CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively. */
+
+#define CALC_SB_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+ ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+ ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+ ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
+
+#define CALC_SB192_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
+ ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
+ ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
+ ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
+
+/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+ ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+ ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+ ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages. For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages. j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations. Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
+ * additional lookup-and-XOR stage. The parameters a, b, c and d are the
+ * four bytes going into the last three stages. For 192-bit keys, c = d
+ * are the index preprocessed through q0, and a = b are the index
+ * preprocessed through q1; j is the index of the first key byte to use.
+ * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
+ * instead of CALC_K_2.
+ * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
+ * additional lookup-and-XOR stage. The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use. CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+ mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+ ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+ ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+ ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+ x = CALC_K_2 (k, l, k, l, 0); \
+ y = CALC_K_2 (m, n, m, n, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K192_2(a, b, c, d, j) \
+ CALC_K_2 (q0[a ^ key[(j) + 16]], \
+ q1[b ^ key[(j) + 17]], \
+ q0[c ^ key[(j) + 18]], \
+ q1[d ^ key[(j) + 19]], j)
+
+#define CALC_K192(a, j, k, l, m, n) \
+ x = CALC_K192_2 (l, l, k, k, 0); \
+ y = CALC_K192_2 (n, n, m, m, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+ CALC_K192_2 (q1[b ^ key[(j) + 24]], \
+ q1[a ^ key[(j) + 25]], \
+ q0[a ^ key[(j) + 26]], \
+ q0[b ^ key[(j) + 27]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+ x = CALC_K256_2 (k, l, 0); \
+ y = CALC_K256_2 (m, n, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds. G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+ (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+ ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+ (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+ ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds. Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations. The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+ x = G1 (a); y = G2 (b); \
+ x += y; y += x + ctx->k[2 * (n) + 1]; \
+ (c) ^= x + ctx->k[2 * (n)]; \
+ (c) = ((c) >> 1) + ((c) << 31); \
+ (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+ x = G1 (a); y = G2 (b); \
+ x += y; y += x; \
+ (d) ^= y + ctx->k[2 * (n) + 1]; \
+ (d) = ((d) >> 1) + ((d) << 31); \
+ (c) = (((c) << 1)+((c) >> 31)); \
+ (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+ ENCROUND (2 * (n), a, b, c, d); \
+ ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+ DECROUND (2 * (n) + 1, c, d, a, b); \
+ DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step. INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+ x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+ ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+ x ^= ctx->w[m]; \
+ out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+ out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+
+/* Perform the key setup. */
+int twofish_setkey(void *cx, const u8 *key, unsigned int key_len, u32 *flags)
+{
+
+ struct twofish_ctx *ctx = cx;
+
+ int i, j, k;
+
+ /* Temporaries for CALC_K. */
+ u32 x, y;
+
+ /* The S vector used to key the S-boxes, split up into individual bytes.
+ * 128-bit keys use only sa through sh; 256-bit use all of them. */
+ u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+ u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+ /* Temporary for CALC_S. */
+ u8 tmp;
+
+ /* Check key length. */
+ if (key_len != 16 && key_len != 24 && key_len != 32)
+ return -1; /* unsupported key length */
+
+ /* Compute the first two words of the S vector. The magic numbers are
+ * the entries of the RS matrix, preprocessed through poly_to_exp. The
+ * numbers in the comments are the original (polynomial form) matrix
+ * entries. */
+ CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+ CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+ if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
+ /* Calculate the third word of the S vector */
+ CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+ }
+
+ if (key_len == 32) { /* 256-bit key */
+ /* Calculate the fourth word of the S vector */
+ CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+ /* Compute the S-boxes. */
+ for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+ CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ } else if (key_len == 24) { /* 192-bit key */
+ /* Compute the S-boxes. */
+ for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+ CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ } else { /* 128-bit key */
+ /* Compute the S-boxes. */
+ for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+ CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ }
+
+ return 0;
+}
+
+/* Encrypt one block. in and out may be the same. */
+void twofish_encrypt(void *cx, u8 *out, const u8 *in)
+{
+ struct twofish_ctx *ctx = cx;
+
+ /* The four 32-bit chunks of the text. */
+ u32 a, b, c, d;
+
+ /* Temporaries used by the round function. */
+ u32 x, y;
+
+ /* Input whitening and packing. */
+ INPACK (0, a, 0);
+ INPACK (1, b, 1);
+ INPACK (2, c, 2);
+ INPACK (3, d, 3);
+
+ /* Encryption Feistel cycles. */
+ ENCCYCLE (0);
+ ENCCYCLE (1);
+ ENCCYCLE (2);
+ ENCCYCLE (3);
+ ENCCYCLE (4);
+ ENCCYCLE (5);
+ ENCCYCLE (6);
+ ENCCYCLE (7);
+
+ /* Output whitening and unpacking. */
+ OUTUNPACK (0, c, 4);
+ OUTUNPACK (1, d, 5);
+ OUTUNPACK (2, a, 6);
+ OUTUNPACK (3, b, 7);
+
+}
+
+/* Decrypt one block. in and out may be the same. */
+void twofish_decrypt(void *cx, u8 *out, const u8 *in)
+{
+ struct twofish_ctx *ctx = cx;
+
+ /* The four 32-bit chunks of the text. */
+ u32 a, b, c, d;
+
+ /* Temporaries used by the round function. */
+ u32 x, y;
+
+ /* Input whitening and packing. */
+ INPACK (0, c, 4);
+ INPACK (1, d, 5);
+ INPACK (2, a, 6);
+ INPACK (3, b, 7);
+
+ /* Encryption Feistel cycles. */
+ DECCYCLE (7);
+ DECCYCLE (6);
+ DECCYCLE (5);
+ DECCYCLE (4);
+ DECCYCLE (3);
+ DECCYCLE (2);
+ DECCYCLE (1);
+ DECCYCLE (0);
+
+ /* Output whitening and unpacking. */
+ OUTUNPACK (0, a, 0);
+ OUTUNPACK (1, b, 1);
+ OUTUNPACK (2, c, 2);
+ OUTUNPACK (3, d, 3);
+
+}
+
+/*
+#include <stdio.h>
+#include <string.h>
+void twofish_encrypt_fake(void *cx, u8 *out, const u8 *in){fprintf(stderr,"encrypt\n");memcpy(out,in,TF_BLOCK_SIZE);}
+void twofish_decrypt_fake(void *cx, u8 *out, const u8 *in){fprintf(stderr,"decrypt\n");memcpy(out,in,TF_BLOCK_SIZE);}
+*/
diff --git a/twofish.h b/twofish.h
new file mode 100644
index 0000000..dee029b
--- /dev/null
+++ b/twofish.h
@@ -0,0 +1,74 @@
+/*
+ * Twofish for CryptoAPI
+ *
+ * Originaly Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
+ * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors
+ * have put this under the GNU General Public License.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+#ifndef _TWOFISH_
+#define _TWOFISH_
+
+#include "uint.h"
+
+#define TF_MIN_KEY_SIZE 16
+#define TF_MAX_KEY_SIZE 32
+#define TF_BLOCK_SIZE 16
+
+/* Structure for an expanded Twofish key. s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+struct twofish_ctx {
+ u32 s[4][256], w[8], k[32];
+};
+
+/* Perform the key setup. return -1 if unsupported key length */
+int twofish_setkey(void *cx, const u8 *key, u32 key_len, u32 *flags);
+
+
+/* Encrypt one block. in and out may be the same. */
+void twofish_encrypt(void *cx, u8 *out, const u8 *in);
+
+
+/* Decrypt one block. in and out may be the same. */
+void twofish_decrypt(void *cx, u8 *out, const u8 *in);
+
+/* memcpy */
+/*
+void twofish_decrypt_fake(void *cx, u8 *out, const u8 *in);
+void twofish_encrypt_fake(void *cx, u8 *out, const u8 *in);
+*/
+
+#endif
diff --git a/u8_read.c b/u8_read.c
new file mode 100644
index 0000000..71e3ad7
--- /dev/null
+++ b/u8_read.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include "uint.h"
+
+int u8_unix_read(int fd,u8 *buf,u32 len)
+{
+ return read(fd,(char*)buf,(int)len);
+}
+
+int u8_tcp_read(int fd,u8 *buf, u32 len)
+{
+ return recv(fd, (char*)buf,(int)len,0);
+}
diff --git a/u8_write.c b/u8_write.c
new file mode 100644
index 0000000..4609658
--- /dev/null
+++ b/u8_write.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include "uint.h"
+
+int u8_unix_write(int fd, u8 *buf, u32 len)
+{
+ return write(fd,(char*)buf,(int)len);
+}
+
+int u8_tcp_write(int fd, u8 *buf, u32 len)
+{
+ return send(fd, (char*)buf,(int)len,0);
+}
diff --git a/uint16.h b/uint16.h
new file mode 100644
index 0000000..a254d9d
--- /dev/null
+++ b/uint16.h
@@ -0,0 +1,13 @@
+#ifndef _UINT16_H
+#define _UINT16_H
+
+#include "uint.h"
+/*
+ * pack and unpack an unsigned int in or out of a two bytes char
+ */
+void u16_pack(char s[2],u16 u);
+void u16_pack_big(char s[2],u16 u);
+void u16_unpack(const char s[2],u16 *u);
+void u16_unpack_big(const char s[2],u16 *u);
+
+#endif
diff --git a/uint16_pack.c b/uint16_pack.c
new file mode 100644
index 0000000..285cecf
--- /dev/null
+++ b/uint16_pack.c
@@ -0,0 +1,13 @@
+#include "uint16.h"
+
+__inline void u16_pack(char s[2],u16 u)
+{
+ s[0] = u & 255;
+ s[1] = u >> 8;
+}
+
+__inline void u16_pack_big(char s[2],u16 u)
+{
+ s[1] = u & 255;
+ s[0] = u >> 8;
+}
diff --git a/uint16_unpack.c b/uint16_unpack.c
new file mode 100644
index 0000000..3821853
--- /dev/null
+++ b/uint16_unpack.c
@@ -0,0 +1,21 @@
+#include "uint16.h"
+
+__inline void u16_unpack(const char s[2],u16 *u)
+{
+ u16 result;
+
+ result = (unsigned char) s[1]; result <<= 8;
+ result += (unsigned char) s[0];
+
+ *u = result;
+}
+
+__inline void u16_unpack_big(const char s[2],u16 *u)
+{
+ u16 result;
+
+ result = (unsigned char) s[0]; result <<= 8;
+ result += (unsigned char) s[1];
+
+ *u = result;
+}
diff --git a/warn-auto.sh b/warn-auto.sh
new file mode 100644
index 0000000..36d2313
--- /dev/null
+++ b/warn-auto.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+# WARNING: This file was auto-generated. Do not edit!
diff --git a/x86cpuid.c b/x86cpuid.c
new file mode 100644
index 0000000..7cdd87b
--- /dev/null
+++ b/x86cpuid.c
@@ -0,0 +1,39 @@
+#include <signal.h>
+
+void nope()
+{
+ exit(1);
+}
+
+int main()
+{
+ unsigned long x[4];
+ unsigned long y[4];
+ int i;
+ int j;
+ char c;
+
+ signal(SIGILL,nope);
+
+ x[0] = 0;
+ x[1] = 0;
+ x[2] = 0;
+ x[3] = 0;
+
+ asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) );
+ if (!x[0]) return 0;
+ asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) );
+
+ for (i = 1;i < 4;++i){
+ for (j = 0;j < 4;++j) {
+ c = x[i] >> (8 * j);
+ if (c < 32) c = 32;
+ if (c > 126) c = 126;
+ putchar(c);
+ }
+ }
+
+ printf("-%08x-%08x\n",y[0],y[3]);
+
+ return 0;
+}