added polarssl-0.14.0

This commit is contained in:
NIIBE Yutaka
2010-08-30 09:45:41 +09:00
parent 4e397a033c
commit 0e2a614ed3
230 changed files with 43387 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 2.6)
project(POLARSSL C)
enable_testing()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wdeclaration-after-statement")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_C_FLAGS_COVERAGE "-g -O0 -fprofile-arcs -ftest-coverage -lgcov")
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
set(CMAKE_SHARED_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
include_directories(include/)
add_subdirectory(library)
add_subdirectory(tests)
add_subdirectory(programs)

310
polarssl-0.14.0/ChangeLog Normal file
View File

@@ -0,0 +1,310 @@
PolarSSL ChangeLog
= Version 0.14.0 released on 2010-08-16
Features
* Added support for SSL_EDH_RSA_AES_128_SHA and
SSL_EDH_RSA_CAMELLIA_128_SHA ciphersuites
* Added compile-time and run-time version information
* Expanded ssl_client2 arguments for more flexibility
* Added support for TLS v1.1
Changes
* Made Makefile cleaner
* Removed dependency on rand() in rsa_pkcs1_encrypt().
Now using random fuction provided to function and
changed the prototype of rsa_pkcs1_encrypt(),
rsa_init() and rsa_gen_key().
* Some SSL defines were renamed in order to avoid
future confusion
Bug fixes
* Fixed CMake out of source build for tests (found by
kkert)
* rsa_check_private() now supports PKCS1v2 keys as well
* Fixed deadlock in rsa_pkcs1_encrypt() on failing random
generator
= Version 0.13.1 released on 2010-03-24
Bug fixes
* Fixed Makefile in library that was mistakenly merged
* Added missing const string fixes
= Version 0.13.0 released on 2010-03-21
Features
* Added option parsing for host and port selection to
ssl_client2
* Added support for GeneralizedTime in X509 parsing
* Added cert_app program to allow easy reading and
printing of X509 certificates from file or SSL
connection.
Changes
* Added const correctness for main code base
* X509 signature algorithm determination is now
in a function to allow easy future expansion
* Changed symmetric cipher functions to
identical interface (returning int result values)
* Changed ARC4 to use seperate input/output buffer
* Added reset function for HMAC context as speed-up
for specific use-cases
Bug fixes
* Fixed bug resulting in failure to send the last
certificate in the chain in ssl_write_certificate() and
ssl_write_certificate_request() (found by fatbob)
* Added small fixes for compiler warnings on a Mac
(found by Frank de Brabander)
* Fixed algorithmic bug in mpi_is_prime() (found by
Smbat Tonoyan)
= Version 0.12.1 released on 2009-10-04
Changes
* Coverage test definitions now support 'depends_on'
tagging system.
* Tests requiring specific hashing algorithms now honor
the defines.
Bug fixes
* Changed typo in #ifdef in x509parse.c (found
by Eduardo)
= Version 0.12.0 released on 2009-07-28
Features
* Added CMake makefiles as alternative to regular Makefiles.
* Added preliminary Code Coverage tests for AES, ARC4,
Base64, MPI, SHA-family, MD-family, HMAC-SHA-family,
Camellia, DES, 3-DES, RSA PKCS#1, XTEA, Diffie-Hellman
and X509parse.
Changes
* Error codes are not (necessarily) negative. Keep
this is mind when checking for errors.
* RSA_RAW renamed to SIG_RSA_RAW for consistency.
* Fixed typo in name of POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE.
* Changed interface for AES and Camellia setkey functions
to indicate invalid key lengths.
Bug fixes
* Fixed include location of endian.h on FreeBSD (found by
Gabriel)
* Fixed include location of endian.h and name clash on
Apples (found by Martin van Hensbergen)
* Fixed HMAC-MD2 by modifying md2_starts(), so that the
required HMAC ipad and opad variables are not cleared.
(found by code coverage tests)
* Prevented use of long long in bignum if
POLARSSL_HAVE_LONGLONG not defined (found by Giles
Bathgate).
* Fixed incorrect handling of negative strings in
mpi_read_string() (found by code coverage tests).
* Fixed segfault on handling empty rsa_context in
rsa_check_pubkey() and rsa_check_privkey() (found by
code coverage tests).
* Fixed incorrect handling of one single negative input
value in mpi_add_abs() (found by code coverage tests).
* Fixed incorrect handling of negative first input
value in mpi_sub_abs() (found by code coverage tests).
* Fixed incorrect handling of negative first input
value in mpi_mod_mpi() and mpi_mod_int(). Resulting
change also affects mpi_write_string() (found by code
coverage tests).
* Corrected is_prime() results for 0, 1 and 2 (found by
code coverage tests).
* Fixed Camellia and XTEA for 64-bit Windows systems.
= Version 0.11.1 released on 2009-05-17
* Fixed missing functionality for SHA-224, SHA-256, SHA384,
SHA-512 in rsa_pkcs1_sign()
= Version 0.11.0 released on 2009-05-03
* Fixed a bug in mpi_gcd() so that it also works when both
input numbers are even and added testcases to check
(found by Pierre Habouzit).
* Added support for SHA-224, SHA-256, SHA-384 and SHA-512
one way hash functions with the PKCS#1 v1.5 signing and
verification.
* Fixed minor bug regarding mpi_gcd located within the
POLARSSL_GENPRIME block.
* Fixed minor memory leak in x509parse_crt() and added better
handling of 'full' certificate chains (found by Mathias
Olsson).
* Centralized file opening and reading for x509 files into
load_file()
* Made definition of net_htons() endian-clean for big endian
systems (Found by Gernot).
* Undefining POLARSSL_HAVE_ASM now also handles prevents asm in
padlock and timing code.
* Fixed an off-by-one buffer allocation in ssl_set_hostname()
responsible for crashes and unwanted behaviour.
* Added support for Certificate Revocation List (CRL) parsing.
* Added support for CRL revocation to x509parse_verify() and
SSL/TLS code.
* Fixed compatibility of XTEA and Camellia on a 64-bit system
(found by Felix von Leitner).
= Version 0.10.0 released on 2009-01-12
* Migrated XySSL to PolarSSL
* Added XTEA symmetric cipher
* Added Camellia symmetric cipher
* Added support for ciphersuites: SSL_RSA_CAMELLIA_128_SHA,
SSL_RSA_CAMELLIA_256_SHA and SSL_EDH_RSA_CAMELLIA_256_SHA
* Fixed dangerous bug that can cause a heap overflow in
rsa_pkcs1_decrypt (found by Christophe Devine)
================================================================
XySSL ChangeLog
= Version 0.9 released on 2008-03-16
* Added support for ciphersuite: SSL_RSA_AES_128_SHA
* Enabled support for large files by default in aescrypt2.c
* Preliminary openssl wrapper contributed by David Barrett
* Fixed a bug in ssl_write() that caused the same payload to
be sent twice in non-blocking mode when send returns EAGAIN
* Fixed ssl_parse_client_hello(): session id and challenge must
not be swapped in the SSLv2 ClientHello (found by Greg Robson)
* Added user-defined callback debug function (Krystian Kolodziej)
* Before freeing a certificate, properly zero out all cert. data
* Fixed the "mode" parameter so that encryption/decryption are
not swapped on PadLock; also fixed compilation on older versions
of gcc (bug reported by David Barrett)
* Correctly handle the case in padlock_xcryptcbc() when input or
ouput data is non-aligned by falling back to the software
implementation, as VIA Nehemiah cannot handle non-aligned buffers
* Fixed a memory leak in x509parse_crt() which was reported by Greg
Robson-Garth; some x509write.c fixes by Pascal Vizeli, thanks to
Matthew Page who reported several bugs
* Fixed x509_get_ext() to accept some rare certificates which have
an INTEGER instead of a BOOLEAN for BasicConstraints::cA.
* Added support on the client side for the TLS "hostname" extension
(patch contributed by David Patino)
* Make x509parse_verify() return BADCERT_CN_MISMATCH when an empty
string is passed as the CN (bug reported by spoofy)
* Added an option to enable/disable the BN assembly code
* Updated rsa_check_privkey() to verify that (D*E) = 1 % (P-1)*(Q-1)
* Disabled obsolete hash functions by default (MD2, MD4); updated
selftest and benchmark to not test ciphers that have been disabled
* Updated x509parse_cert_info() to correctly display byte 0 of the
serial number, setup correct server port in the ssl client example
* Fixed a critical denial-of-service with X.509 cert. verification:
peer may cause xyssl to loop indefinitely by sending a certificate
for which the RSA signature check fails (bug reported by Benoit)
* Added test vectors for: AES-CBC, AES-CFB, DES-CBC and 3DES-CBC,
HMAC-MD5, HMAC-SHA1, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512
* Fixed HMAC-SHA-384 and HMAC-SHA-512 (thanks to Josh Sinykin)
* Modified ssl_parse_client_key_exchange() to protect against
Daniel Bleichenbacher attack on PKCS#1 v1.5 padding, as well
as the Klima-Pokorny-Rosa extension of Bleichenbacher's attack
* Updated rsa_gen_key() so that ctx->N is always nbits in size
* Fixed assembly PPC compilation errors on Mac OS X, thanks to
David Barrett and Dusan Semen
= Version 0.8 released on 2007-10-20
* Modified the HMAC functions to handle keys larger
than 64 bytes, thanks to Stephane Desneux and gary ng
* Fixed ssl_read_record() to properly update the handshake
message digests, which fixes IE6/IE7 client authentication
* Cleaned up the XYSSL* #defines, suggested by Azriel Fasten
* Fixed net_recv(), thanks to Lorenz Schori and Egon Kocjan
* Added user-defined callbacks for handling I/O and sessions
* Added lots of debugging output in the SSL/TLS functions
* Added preliminary X.509 cert. writing by Pascal Vizeli
* Added preliminary support for the VIA PadLock routines
* Added AES-CFB mode of operation, contributed by chmike
* Added an SSL/TLS stress testing program (ssl_test.c)
* Updated the RSA PKCS#1 code to allow choosing between
RSA_PUBLIC and RSA_PRIVATE, as suggested by David Barrett
* Updated ssl_read() to skip 0-length records from OpenSSL
* Fixed the make install target to comply with *BSD make
* Fixed a bug in mpi_read_binary() on 64-bit platforms
* mpi_is_prime() speedups, thanks to Kevin McLaughlin
* Fixed a long standing memory leak in mpi_is_prime()
* Replaced realloc with malloc in mpi_grow(), and set
the sign of zero as positive in mpi_init() (reported
by Jonathan M. McCune)
= Version 0.7 released on 2007-07-07
* Added support for the MicroBlaze soft-core processor
* Fixed a bug in ssl_tls.c which sometimes prevented SSL
connections from being established with non-blocking I/O
* Fixed a couple bugs in the VS6 and UNIX Makefiles
* Fixed the "PIC register ebx clobbered in asm" bug
* Added HMAC starts/update/finish support functions
* Added the SHA-224, SHA-384 and SHA-512 hash functions
* Fixed the net_set_*block routines, thanks to Andreas
* Added a few demonstration programs: md5sum, sha1sum,
dh_client, dh_server, rsa_genkey, rsa_sign, rsa_verify
* Added new bignum import and export helper functions
* Rewrote README.txt in program/ssl/ca to better explain
how to create a test PKI
= Version 0.6 released on 2007-04-01
* Ciphers used in SSL/TLS can now be disabled at compile
time, to reduce the memory footprint on embedded systems
* Added multiply assembly code for the TriCore and modified
havege_struct for this processor, thanks to David Pati<74>o
* Added multiply assembly code for 64-bit PowerPCs,
thanks to Peking University and the OSU Open Source Lab
* Added experimental support of Quantum Cryptography
* Added support for autoconf, contributed by Arnaud Cornet
* Fixed "long long" compilation issues on IA-64 and PPC64
* Fixed a bug introduced in xyssl-0.5/timing.c: hardclock
was not being correctly defined on ARM and MIPS
= Version 0.5 released on 2007-03-01
* Added multiply assembly code for SPARC and Alpha
* Added (beta) support for non-blocking I/O operations
* Implemented session resuming and client authentication
* Fixed some portability issues on WinCE, MINIX 3, Plan9
(thanks to Benjamin Newman), HP-UX, FreeBSD and Solaris
* Improved the performance of the EDH key exchange
* Fixed a bug that caused valid packets with a payload
size of 16384 bytes to be rejected
= Version 0.4 released on 2007-02-01
* Added support for Ephemeral Diffie-Hellman key exchange
* Added multiply asm code for SSE2, ARM, PPC, MIPS and M68K
* Various improvement to the modular exponentiation code
* Rewrote the headers to generate the API docs with doxygen
* Fixed a bug in ssl_encrypt_buf (incorrect padding was
generated) and in ssl_parse_client_hello (max. client
version was not properly set), thanks to Didier Rebeix
* Fixed another bug in ssl_parse_client_hello: clients with
cipherlists larger than 96 bytes were incorrectly rejected
* Fixed a couple memory leak in x509_read.c
= Version 0.3 released on 2007-01-01
* Added server-side SSLv3 and TLSv1.0 support
* Multiple fixes to enhance the compatibility with g++,
thanks to Xos<6F> Ant<6E>n Otero Ferreira
* Fixed a bug in the CBC code, thanks to dowst; also,
the bignum code is no longer dependant on long long
* Updated rsa_pkcs1_sign to handle arbitrary large inputs
* Updated timing.c for improved compatibility with i386
and 486 processors, thanks to Arnaud Cornet
= Version 0.2 released on 2006-12-01
* Updated timing.c to support ARM and MIPS arch
* Updated the MPI code to support 8086 on MSVC 1.5
* Added the copyright notice at the top of havege.h
* Fixed a bug in sha2_hmac, thanks to newsoft/Wenfang Zhang
* Fixed a bug reported by Adrian R<>egsegger in x509_read_key
* Fixed a bug reported by Torsten Lauter in ssl_read_record
* Fixed a bug in rsa_check_privkey that would wrongly cause
valid RSA keys to be dismissed (thanks to oldwolf)
* Fixed a bug in mpi_is_prime that caused some primes to fail
the Miller-Rabin primality test
I'd also like to thank Youn<75>s Hafri for the CRUX linux port,
Khalil Petit who added XySSL into pkgsrc and Arnaud Cornet
who maintains the Debian package :-)
= Version 0.1 released on 2006-11-01

View File

@@ -0,0 +1,3 @@
Site: localhost
BuildName: PolarSSL-test
CoverageCommand: /usr/bin/gcov

339
polarssl-0.14.0/LICENSE Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<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 Lesser General
Public License instead of this License.

34
polarssl-0.14.0/Makefile Normal file
View File

@@ -0,0 +1,34 @@
DESTDIR=/usr/local
PREFIX=polarssl_
.SILENT:
all:
cd library && $(MAKE) all && cd ..
cd programs && $(MAKE) all && cd ..
cd tests && $(MAKE) all && cd ..
install:
mkdir -p $(DESTDIR)/include/polarssl
cp -r include/polarssl $(DESTDIR)/include
mkdir -p $(DESTDIR)/lib
cp library/libpolarssl.* $(DESTDIR)/lib
mkdir -p $(DESTDIR)/bin
for p in programs/*/* ; do \
if [ -x $$p ] && [ ! -d $$p ] ; \
then \
f=$(PREFIX)`basename $$p` ; \
cp $$p $(DESTDIR)/bin/$$f ; \
fi \
done
clean:
cd library && $(MAKE) clean && cd ..
cd programs && $(MAKE) clean && cd ..
cd tests && $(MAKE) clean && cd ..
check:
( cd tests && $(MAKE) check )

40
polarssl-0.14.0/README Normal file
View File

@@ -0,0 +1,40 @@
README for PolarSSL
-- COMPILING
There are currently three active build systems within the PolarSSL releases:
- Make
- CMake
- Microsoft Visual Studio
The main system used for development is CMake. That system is always the most up-to-date. The others should reflect all changes present in the CMake build system, but some features are not ported there by default.
--- Make
In order to build the source using Make, just enter at the command line:
make
In order to run the tests, enter:
make check
--- CMake
In order to build the source using CMake, just enter at the command line:
cmake .
make
There are 3 different active build modes specified within the CMake buildsystem:
- Release
This generates the default code without any unnecessary information in the binary files.
- Debug
This generates debug information and disables optimization of the code.
- Coverage
This generates code coverage information in addition to debug information.
Switching build modes in CMake is simple. For debug mode, enter at the command line:
cmake -D CMAKE_BUILD_TYPE:String="Debug" .
In order to run the tests, enter:
make test
--- Microsoft Visual Studio
The build files for Microsoft Visual Studio are generated for Visual Studio 6.0 all future Visual Studio's should be able to open and use this older version of the build files.
The workspace 'polarssl.dsw' contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need a perl environment as well.

View File

@@ -0,0 +1,32 @@
#!/bin/sh
indent --blank-lines-after-declarations \
--blank-lines-after-procedures \
--swallow-optional-blank-lines \
--blank-lines-before-block-comments \
--format-all-comments \
--format-first-column-comments \
--comment-delimiters-on-blank-lines \
--start-left-side-of-comments \
--braces-after-if-line \
--braces-after-struct-decl-line \
--brace-indent 0 \
--dont-cuddle-else \
--dont-cuddle-do-while \
--case-indentation 4 \
--case-brace-indentation 0 \
--dont-space-special-semicolon \
--no-space-after-function-call-names \
--no-space-after-casts \
--no-space-after-for \
--no-space-after-if \
--no-space-after-while \
--space-after-parentheses \
--no-blank-lines-after-commas \
--break-function-decl-args \
--dont-break-function-decl-args-end \
--dont-break-procedure-type \
--indent-level 4 \
--continue-at-parentheses \
"$@"

View File

@@ -0,0 +1,139 @@
/**
* \file aes.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_AES_H
#define POLARSSL_AES_H
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0800
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0810
/**
* \brief AES context structure
*/
typedef struct
{
int nr; /*!< number of rounds */
unsigned long *rk; /*!< AES round keys */
unsigned long buf[68]; /*!< unaligned data */
}
aes_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int aes_crypt_ecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
*/
int aes_crypt_cbc( aes_context *ctx,
int mode,
int length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int aes_crypt_cfb128( aes_context *ctx,
int mode,
int length,
int *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int aes_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

View File

@@ -0,0 +1,76 @@
/**
* \file arc4.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ARC4_H
#define POLARSSL_ARC4_H
/**
* \brief ARC4 context structure
*/
typedef struct
{
int x; /*!< permutation index */
int y; /*!< permutation index */
unsigned char m[256]; /*!< permutation table */
}
arc4_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief ARC4 key schedule
*
* \param ctx ARC4 context to be initialized
* \param key the secret key
* \param keylen length of the key
*/
void arc4_setup( arc4_context *ctx, const unsigned char *key, int keylen );
/**
* \brief ARC4 cipher function
*
* \param ctx ARC4 context
* \param length length of the input data
* \param input buffer holding the input data
* \param output buffer for the output data
*
* \return 0 if successful
*/
int arc4_crypt( arc4_context *ctx, int length, const unsigned char *input,
unsigned char *output );
/*
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int arc4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* arc4.h */

View File

@@ -0,0 +1,83 @@
/**
* \file base64.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_BASE64_H
#define POLARSSL_BASE64_H
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the buffer
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
* *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_encode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer
* \param dlen size of the buffer
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
* POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
* correct. *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_decode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int base64_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* base64.h */

View File

@@ -0,0 +1,533 @@
/**
* \file bignum.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_BIGNUM_H
#define POLARSSL_BIGNUM_H
#include <stdio.h>
#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
/*
* Define the base integer type, architecture-wise
*/
#if defined(POLARSSL_HAVE_INT8)
typedef unsigned char t_int;
typedef unsigned short t_dbl;
#else
#if defined(POLARSSL_HAVE_INT16)
typedef unsigned short t_int;
typedef unsigned long t_dbl;
#else
typedef unsigned long t_int;
#if defined(_MSC_VER) && defined(_M_IX86)
typedef unsigned __int64 t_dbl;
#else
#if defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__)
typedef unsigned int t_dbl __attribute__((mode(TI)));
#else
#if defined(POLARSSL_HAVE_LONGLONG)
typedef unsigned long long t_dbl;
#endif
#endif
#endif
#endif
#endif
/**
* \brief MPI structure
*/
typedef struct
{
int s; /*!< integer sign */
int n; /*!< total # of limbs */
t_int *p; /*!< pointer to limbs */
}
mpi;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize one or more mpi
*/
void mpi_init( mpi *X, ... );
/**
* \brief Unallocate one or more mpi
*/
void mpi_free( mpi *X, ... );
/**
* \brief Enlarge to the specified number of limbs
*
* \param X MPI to grow
* \param nblimbs The target number of limbs
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_grow( mpi *X, int nblimbs );
/**
* \brief Copy the contents of Y into X
*
* \param X Destination MPI
* \param Y Source MPI
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_copy( mpi *X, const mpi *Y );
/**
* \brief Swap the contents of X and Y
*
* \param X First MPI value
* \param Y Second MPI value
*/
void mpi_swap( mpi *X, mpi *Y );
/**
* \brief Set value from integer
*
* \param X MPI to set
* \param z Value to use
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_lset( mpi *X, int z );
/**
* \brief Return the number of least significant bits
*
* \param X MPI to use
*/
int mpi_lsb( const mpi *X );
/**
* \brief Return the number of most significant bits
*
* \param X MPI to use
*/
int mpi_msb( const mpi *X );
/**
* \brief Return the total size in bytes
*
* \param X MPI to use
*/
int mpi_size( const mpi *X );
/**
* \brief Import from an ASCII string
*
* \param X Destination MPI
* \param radix Input numeric base
* \param s Null-terminated string buffer
*
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
*/
int mpi_read_string( mpi *X, int radix, const char *s );
/**
* \brief Export into an ASCII string
*
* \param X Source MPI
* \param radix Output numeric base
* \param s String buffer
* \param slen String buffer size
*
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
* *slen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *slen = 0 to obtain the
* minimum required buffer size in *slen.
*/
int mpi_write_string( const mpi *X, int radix, char *s, int *slen );
/**
* \brief Read X from an opened file
*
* \param X Destination MPI
* \param radix Input numeric base
* \param fin Input file handle
*
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
*/
int mpi_read_file( mpi *X, int radix, FILE *fin );
/**
* \brief Write X into an opened file, or stdout if fout is NULL
*
* \param p Prefix, can be NULL
* \param X Source MPI
* \param radix Output numeric base
* \param fout Output file handle (can be NULL)
*
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
*
* \note Set fout == NULL to print X on the console.
*/
int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen );
/**
* \brief Export X into unsigned binary data, big endian
*
* \param X Source MPI
* \param buf Output buffer
* \param buflen Output buffer size
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
*/
int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen );
/**
* \brief Left-shift: X <<= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_shift_l( mpi *X, int count );
/**
* \brief Right-shift: X >>= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_shift_r( mpi *X, int count );
/**
* \brief Compare unsigned values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if |X| is greater than |Y|,
* -1 if |X| is lesser than |Y| or
* 0 if |X| is equal to |Y|
*/
int mpi_cmp_abs( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if X is greater than Y,
* -1 if X is lesser than Y or
* 0 if X is equal to Y
*/
int mpi_cmp_mpi( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param z The integer value to compare to
*
* \return 1 if X is greater than z,
* -1 if X is lesser than z or
* 0 if X is equal to z
*/
int mpi_cmp_int( const mpi *X, int z );
/**
* \brief Unsigned addition: X = |A| + |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Unsigned substraction: X = |A| - |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
*/
int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed addition: X = A + B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed substraction: X = A - B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed addition: X = A + b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to add
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_add_int( mpi *X, const mpi *A, int b );
/**
* \brief Signed substraction: X = A - b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to subtract
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_sub_int( mpi *X, const mpi *A, int b );
/**
* \brief Baseline multiplication: X = A * B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Baseline multiplication: X = A * b
* Note: b is an unsigned integer type, thus
* Negative values of b are ignored.
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to multiply with
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_mul_int( mpi *X, const mpi *A, t_int b );
/**
* \brief Division by mpi: A = Q * B + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
*
* \note Either Q or R can be NULL.
*/
int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
/**
* \brief Division by int: A = Q * b + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
*
* \note Either Q or R can be NULL.
*/
int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b );
/**
* \brief Modulo: R = A mod B
*
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
*/
int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
/**
* \brief Modulo: r = A mod b
*
* \param r Destination t_int
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
*/
int mpi_mod_int( t_int *r, const mpi *A, int b );
/**
* \brief Sliding-window exponentiation: X = A^E mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param E Exponent MPI
* \param N Modular MPI
* \param _RR Speed-up MPI used for recalculations
*
* \return 0 if successful,
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
*
* \note _RR is used to avoid re-computing R*R mod N across
* multiple calls, which speeds up things a bit. It can
* be set to NULL if the extra performance is unneeded.
*/
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
/**
* \brief Greatest common divisor: G = gcd(A, B)
*
* \param G Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed
*/
int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
/**
* \brief Modular inverse: X = A^-1 mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param N Right-hand MPI
*
* \return 0 if successful,
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
*/
int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
/**
* \brief Miller-Rabin primality test
*
* \param X MPI to check
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
*/
int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
/**
* \brief Prime number generation
*
* \param X Destination MPI
* \param nbits Required size of X in bits
* \param dh_flag If 1, then (X-1)/2 will be prime too
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* 1 if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
*/
int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
int (*f_rng)(void *), void *p_rng );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mpi_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* bignum.h */

View File

@@ -0,0 +1,736 @@
/**
* \file bn_mul.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef POLARSSL_BN_MUL_H
#define POLARSSL_BN_MUL_H
#include "polarssl/config.h"
#if defined(POLARSSL_HAVE_ASM)
#if defined(__GNUC__)
#if defined(__i386__)
#define MULADDC_INIT \
asm( " \
movl %%ebx, %0; \
movl %5, %%esi; \
movl %6, %%edi; \
movl %7, %%ecx; \
movl %8, %%ebx; \
"
#define MULADDC_CORE \
" \
lodsl; \
mull %%ebx; \
addl %%ecx, %%eax; \
adcl $0, %%edx; \
addl (%%edi), %%eax; \
adcl $0, %%edx; \
movl %%edx, %%ecx; \
stosl; \
"
#if defined(POLARSSL_HAVE_SSE2)
#define MULADDC_HUIT \
" \
movd %%ecx, %%mm1; \
movd %%ebx, %%mm0; \
movd (%%edi), %%mm3; \
paddq %%mm3, %%mm1; \
movd (%%esi), %%mm2; \
pmuludq %%mm0, %%mm2; \
movd 4(%%esi), %%mm4; \
pmuludq %%mm0, %%mm4; \
movd 8(%%esi), %%mm6; \
pmuludq %%mm0, %%mm6; \
movd 12(%%esi), %%mm7; \
pmuludq %%mm0, %%mm7; \
paddq %%mm2, %%mm1; \
movd 4(%%edi), %%mm3; \
paddq %%mm4, %%mm3; \
movd 8(%%edi), %%mm5; \
paddq %%mm6, %%mm5; \
movd 12(%%edi), %%mm4; \
paddq %%mm4, %%mm7; \
movd %%mm1, (%%edi); \
movd 16(%%esi), %%mm2; \
pmuludq %%mm0, %%mm2; \
psrlq $32, %%mm1; \
movd 20(%%esi), %%mm4; \
pmuludq %%mm0, %%mm4; \
paddq %%mm3, %%mm1; \
movd 24(%%esi), %%mm6; \
pmuludq %%mm0, %%mm6; \
movd %%mm1, 4(%%edi); \
psrlq $32, %%mm1; \
movd 28(%%esi), %%mm3; \
pmuludq %%mm0, %%mm3; \
paddq %%mm5, %%mm1; \
movd 16(%%edi), %%mm5; \
paddq %%mm5, %%mm2; \
movd %%mm1, 8(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm7, %%mm1; \
movd 20(%%edi), %%mm5; \
paddq %%mm5, %%mm4; \
movd %%mm1, 12(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm2, %%mm1; \
movd 24(%%edi), %%mm5; \
paddq %%mm5, %%mm6; \
movd %%mm1, 16(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm4, %%mm1; \
movd 28(%%edi), %%mm5; \
paddq %%mm5, %%mm3; \
movd %%mm1, 20(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm6, %%mm1; \
movd %%mm1, 24(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm3, %%mm1; \
movd %%mm1, 28(%%edi); \
addl $32, %%edi; \
addl $32, %%esi; \
psrlq $32, %%mm1; \
movd %%mm1, %%ecx; \
"
#define MULADDC_STOP \
" \
emms; \
movl %4, %%ebx; \
movl %%ecx, %1; \
movl %%edi, %2; \
movl %%esi, %3; \
" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
" \
movl %4, %%ebx; \
movl %%ecx, %1; \
movl %%edi, %2; \
movl %%esi, %3; \
" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
asm( "movq %0, %%rsi " :: "m" (s)); \
asm( "movq %0, %%rdi " :: "m" (d)); \
asm( "movq %0, %%rcx " :: "m" (c)); \
asm( "movq %0, %%rbx " :: "m" (b)); \
asm( "xorq %r8, %r8 " );
#define MULADDC_CORE \
asm( "movq (%rsi),%rax " ); \
asm( "mulq %rbx " ); \
asm( "addq $8, %rsi " ); \
asm( "addq %rcx, %rax " ); \
asm( "movq %r8, %rcx " ); \
asm( "adcq $0, %rdx " ); \
asm( "nop " ); \
asm( "addq %rax, (%rdi) " ); \
asm( "adcq %rdx, %rcx " ); \
asm( "addq $8, %rdi " );
#define MULADDC_STOP \
asm( "movq %%rcx, %0 " : "=m" (c)); \
asm( "movq %%rdi, %0 " : "=m" (d)); \
asm( "movq %%rsi, %0 " : "=m" (s) :: \
"rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
#endif /* AMD64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
asm( "movl %0, %%a2 " :: "m" (s)); \
asm( "movl %0, %%a3 " :: "m" (d)); \
asm( "movl %0, %%d3 " :: "m" (c)); \
asm( "movl %0, %%d2 " :: "m" (b)); \
asm( "moveq #0, %d0 " );
#define MULADDC_CORE \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "moveq #0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "addxl %d4, %d3 " );
#define MULADDC_STOP \
asm( "movl %%d3, %0 " : "=m" (c)); \
asm( "movl %%a3, %0 " : "=m" (d)); \
asm( "movl %%a2, %0 " : "=m" (s) :: \
"d0", "d1", "d2", "d3", "d4", "a2", "a3" );
#define MULADDC_HUIT \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d4:%d1 " ); \
asm( "addxl %d3, %d1 " ); \
asm( "addxl %d0, %d4 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "movel %a2@+, %d1 " ); \
asm( "mulul %d2, %d3:%d1 " ); \
asm( "addxl %d4, %d1 " ); \
asm( "addxl %d0, %d3 " ); \
asm( "addl %d1, %a3@+ " ); \
asm( "addxl %d0, %d3 " );
#endif /* MC68000 */
#if defined(__powerpc__) || defined(__ppc__)
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( "ld r3, %0 " :: "m" (s)); \
asm( "ld r4, %0 " :: "m" (d)); \
asm( "ld r5, %0 " :: "m" (c)); \
asm( "ld r6, %0 " :: "m" (b)); \
asm( "addi r3, r3, -8 " ); \
asm( "addi r4, r4, -8 " ); \
asm( "addic r5, r5, 0 " );
#define MULADDC_CORE \
asm( "ldu r7, 8(r3) " ); \
asm( "mulld r8, r7, r6 " ); \
asm( "mulhdu r9, r7, r6 " ); \
asm( "adde r8, r8, r5 " ); \
asm( "ld r7, 8(r4) " ); \
asm( "addze r5, r9 " ); \
asm( "addc r8, r8, r7 " ); \
asm( "stdu r8, 8(r4) " );
#define MULADDC_STOP \
asm( "addze r5, r5 " ); \
asm( "addi r4, r4, 8 " ); \
asm( "addi r3, r3, 8 " ); \
asm( "std r5, %0 " : "=m" (c)); \
asm( "std r4, %0 " : "=m" (d)); \
asm( "std r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#else
#define MULADDC_INIT \
asm( "ld %%r3, %0 " :: "m" (s)); \
asm( "ld %%r4, %0 " :: "m" (d)); \
asm( "ld %%r5, %0 " :: "m" (c)); \
asm( "ld %%r6, %0 " :: "m" (b)); \
asm( "addi %r3, %r3, -8 " ); \
asm( "addi %r4, %r4, -8 " ); \
asm( "addic %r5, %r5, 0 " );
#define MULADDC_CORE \
asm( "ldu %r7, 8(%r3) " ); \
asm( "mulld %r8, %r7, %r6 " ); \
asm( "mulhdu %r9, %r7, %r6 " ); \
asm( "adde %r8, %r8, %r5 " ); \
asm( "ld %r7, 8(%r4) " ); \
asm( "addze %r5, %r9 " ); \
asm( "addc %r8, %r8, %r7 " ); \
asm( "stdu %r8, 8(%r4) " );
#define MULADDC_STOP \
asm( "addze %r5, %r5 " ); \
asm( "addi %r4, %r4, 8 " ); \
asm( "addi %r3, %r3, 8 " ); \
asm( "std %%r5, %0 " : "=m" (c)); \
asm( "std %%r4, %0 " : "=m" (d)); \
asm( "std %%r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#endif
#else /* PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( "lwz r3, %0 " :: "m" (s)); \
asm( "lwz r4, %0 " :: "m" (d)); \
asm( "lwz r5, %0 " :: "m" (c)); \
asm( "lwz r6, %0 " :: "m" (b)); \
asm( "addi r3, r3, -4 " ); \
asm( "addi r4, r4, -4 " ); \
asm( "addic r5, r5, 0 " );
#define MULADDC_CORE \
asm( "lwzu r7, 4(r3) " ); \
asm( "mullw r8, r7, r6 " ); \
asm( "mulhwu r9, r7, r6 " ); \
asm( "adde r8, r8, r5 " ); \
asm( "lwz r7, 4(r4) " ); \
asm( "addze r5, r9 " ); \
asm( "addc r8, r8, r7 " ); \
asm( "stwu r8, 4(r4) " );
#define MULADDC_STOP \
asm( "addze r5, r5 " ); \
asm( "addi r4, r4, 4 " ); \
asm( "addi r3, r3, 4 " ); \
asm( "stw r5, %0 " : "=m" (c)); \
asm( "stw r4, %0 " : "=m" (d)); \
asm( "stw r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#else
#define MULADDC_INIT \
asm( "lwz %%r3, %0 " :: "m" (s)); \
asm( "lwz %%r4, %0 " :: "m" (d)); \
asm( "lwz %%r5, %0 " :: "m" (c)); \
asm( "lwz %%r6, %0 " :: "m" (b)); \
asm( "addi %r3, %r3, -4 " ); \
asm( "addi %r4, %r4, -4 " ); \
asm( "addic %r5, %r5, 0 " );
#define MULADDC_CORE \
asm( "lwzu %r7, 4(%r3) " ); \
asm( "mullw %r8, %r7, %r6 " ); \
asm( "mulhwu %r9, %r7, %r6 " ); \
asm( "adde %r8, %r8, %r5 " ); \
asm( "lwz %r7, 4(%r4) " ); \
asm( "addze %r5, %r9 " ); \
asm( "addc %r8, %r8, %r7 " ); \
asm( "stwu %r8, 4(%r4) " );
#define MULADDC_STOP \
asm( "addze %r5, %r5 " ); \
asm( "addi %r4, %r4, 4 " ); \
asm( "addi %r3, %r3, 4 " ); \
asm( "stw %%r5, %0 " : "=m" (c)); \
asm( "stw %%r4, %0 " : "=m" (d)); \
asm( "stw %%r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#endif
#endif /* PPC32 */
#endif /* PPC64 */
#if defined(__sparc__)
#define MULADDC_INIT \
asm( "ld %0, %%o0 " :: "m" (s)); \
asm( "ld %0, %%o1 " :: "m" (d)); \
asm( "ld %0, %%o2 " :: "m" (c)); \
asm( "ld %0, %%o3 " :: "m" (b));
#define MULADDC_CORE \
asm( "ld [%o0], %o4 " ); \
asm( "inc 4, %o0 " ); \
asm( "ld [%o1], %o5 " ); \
asm( "umul %o3, %o4, %o4 " ); \
asm( "addcc %o4, %o2, %o4 " ); \
asm( "rd %y, %g1 " ); \
asm( "addx %g1, 0, %g1 " ); \
asm( "addcc %o4, %o5, %o4 " ); \
asm( "st %o4, [%o1] " ); \
asm( "addx %g1, 0, %o2 " ); \
asm( "inc 4, %o1 " );
#define MULADDC_STOP \
asm( "st %%o2, %0 " : "=m" (c)); \
asm( "st %%o1, %0 " : "=m" (d)); \
asm( "st %%o0, %0 " : "=m" (s) :: \
"g1", "o0", "o1", "o2", "o3", "o4", "o5" );
#endif /* SPARCv8 */
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
asm( "lwi r3, %0 " :: "m" (s)); \
asm( "lwi r4, %0 " :: "m" (d)); \
asm( "lwi r5, %0 " :: "m" (c)); \
asm( "lwi r6, %0 " :: "m" (b)); \
asm( "andi r7, r6, 0xffff" ); \
asm( "bsrli r6, r6, 16 " );
#define MULADDC_CORE \
asm( "lhui r8, r3, 0 " ); \
asm( "addi r3, r3, 2 " ); \
asm( "lhui r9, r3, 0 " ); \
asm( "addi r3, r3, 2 " ); \
asm( "mul r10, r9, r6 " ); \
asm( "mul r11, r8, r7 " ); \
asm( "mul r12, r9, r7 " ); \
asm( "mul r13, r8, r6 " ); \
asm( "bsrli r8, r10, 16 " ); \
asm( "bsrli r9, r11, 16 " ); \
asm( "add r13, r13, r8 " ); \
asm( "add r13, r13, r9 " ); \
asm( "bslli r10, r10, 16 " ); \
asm( "bslli r11, r11, 16 " ); \
asm( "add r12, r12, r10 " ); \
asm( "addc r13, r13, r0 " ); \
asm( "add r12, r12, r11 " ); \
asm( "addc r13, r13, r0 " ); \
asm( "lwi r10, r4, 0 " ); \
asm( "add r12, r12, r10 " ); \
asm( "addc r13, r13, r0 " ); \
asm( "add r12, r12, r5 " ); \
asm( "addc r5, r13, r0 " ); \
asm( "swi r12, r4, 0 " ); \
asm( "addi r4, r4, 4 " );
#define MULADDC_STOP \
asm( "swi r5, %0 " : "=m" (c)); \
asm( "swi r4, %0 " : "=m" (d)); \
asm( "swi r3, %0 " : "=m" (s) :: \
"r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
"r9", "r10", "r11", "r12", "r13" );
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
asm( "ld.a %%a2, %0 " :: "m" (s)); \
asm( "ld.a %%a3, %0 " :: "m" (d)); \
asm( "ld.w %%d4, %0 " :: "m" (c)); \
asm( "ld.w %%d1, %0 " :: "m" (b)); \
asm( "xor %d5, %d5 " );
#define MULADDC_CORE \
asm( "ld.w %d0, [%a2+] " ); \
asm( "madd.u %e2, %e4, %d0, %d1 " ); \
asm( "ld.w %d0, [%a3] " ); \
asm( "addx %d2, %d2, %d0 " ); \
asm( "addc %d3, %d3, 0 " ); \
asm( "mov %d4, %d3 " ); \
asm( "st.w [%a3+], %d2 " );
#define MULADDC_STOP \
asm( "st.w %0, %%d4 " : "=m" (c)); \
asm( "st.a %0, %%a3 " : "=m" (d)); \
asm( "st.a %0, %%a2 " : "=m" (s) :: \
"d0", "d1", "e2", "d4", "a2", "a3" );
#endif /* TriCore */
#if defined(__arm__)
#define MULADDC_INIT \
asm( "ldr r0, %0 " :: "m" (s)); \
asm( "ldr r1, %0 " :: "m" (d)); \
asm( "ldr r2, %0 " :: "m" (c)); \
asm( "ldr r3, %0 " :: "m" (b));
#define MULADDC_CORE \
asm( "ldr r4, [r0], #4 " ); \
asm( "mov r5, #0 " ); \
asm( "ldr r6, [r1] " ); \
asm( "umlal r2, r5, r3, r4 " ); \
asm( "adds r7, r6, r2 " ); \
asm( "adc r2, r5, #0 " ); \
asm( "str r7, [r1], #4 " );
#define MULADDC_STOP \
asm( "str r2, %0 " : "=m" (c)); \
asm( "str r1, %0 " : "=m" (d)); \
asm( "str r0, %0 " : "=m" (s) :: \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
asm( "ldq $1, %0 " :: "m" (s)); \
asm( "ldq $2, %0 " :: "m" (d)); \
asm( "ldq $3, %0 " :: "m" (c)); \
asm( "ldq $4, %0 " :: "m" (b));
#define MULADDC_CORE \
asm( "ldq $6, 0($1) " ); \
asm( "addq $1, 8, $1 " ); \
asm( "mulq $6, $4, $7 " ); \
asm( "umulh $6, $4, $6 " ); \
asm( "addq $7, $3, $7 " ); \
asm( "cmpult $7, $3, $3 " ); \
asm( "ldq $5, 0($2) " ); \
asm( "addq $7, $5, $7 " ); \
asm( "cmpult $7, $5, $5 " ); \
asm( "stq $7, 0($2) " ); \
asm( "addq $2, 8, $2 " ); \
asm( "addq $6, $3, $3 " ); \
asm( "addq $5, $3, $3 " );
#define MULADDC_STOP \
asm( "stq $3, %0 " : "=m" (c)); \
asm( "stq $2, %0 " : "=m" (d)); \
asm( "stq $1, %0 " : "=m" (s) :: \
"$1", "$2", "$3", "$4", "$5", "$6", "$7" );
#endif /* Alpha */
#if defined(__mips__)
#define MULADDC_INIT \
asm( "lw $10, %0 " :: "m" (s)); \
asm( "lw $11, %0 " :: "m" (d)); \
asm( "lw $12, %0 " :: "m" (c)); \
asm( "lw $13, %0 " :: "m" (b));
#define MULADDC_CORE \
asm( "lw $14, 0($10) " ); \
asm( "multu $13, $14 " ); \
asm( "addi $10, $10, 4 " ); \
asm( "mflo $14 " ); \
asm( "mfhi $9 " ); \
asm( "addu $14, $12, $14 " ); \
asm( "lw $15, 0($11) " ); \
asm( "sltu $12, $14, $12 " ); \
asm( "addu $15, $14, $15 " ); \
asm( "sltu $14, $15, $14 " ); \
asm( "addu $12, $12, $9 " ); \
asm( "sw $15, 0($11) " ); \
asm( "addu $12, $12, $14 " ); \
asm( "addi $11, $11, 4 " );
#define MULADDC_STOP \
asm( "sw $12, %0 " : "=m" (c)); \
asm( "sw $11, %0 " : "=m" (d)); \
asm( "sw $10, %0 " : "=m" (s) :: \
"$9", "$10", "$11", "$12", "$13", "$14", "$15" );
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
__asm mov esi, s \
__asm mov edi, d \
__asm mov ecx, c \
__asm mov ebx, b
#define MULADDC_CORE \
__asm lodsd \
__asm mul ebx \
__asm add eax, ecx \
__asm adc edx, 0 \
__asm add eax, [edi] \
__asm adc edx, 0 \
__asm mov ecx, edx \
__asm stosd
#if defined(POLARSSL_HAVE_SSE2)
#define EMIT __asm _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#else
#define MULADDC_STOP \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* POLARSSL_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(POLARSSL_HAVE_LONGLONG)
#define MULADDC_INIT \
{ \
t_dbl r; \
t_int r0, r1;
#define MULADDC_CORE \
r = *(s++) * (t_dbl) b; \
r0 = r; \
r1 = r >> biL; \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
t_int s0, s1, b0, b1; \
t_int r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */

View File

@@ -0,0 +1,145 @@
/**
* \file camellia.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CAMELLIA_H
#define POLARSSL_CAMELLIA_H
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define CAMELLIA_ENCRYPT 1
#define CAMELLIA_DECRYPT 0
#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0a00
#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0a10
/**
* \brief CAMELLIA context structure
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t rk[68]; /*!< CAMELLIA round keys */
}
camellia_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CAMELLIA key schedule (encryption)
*
* \param ctx CAMELLIA context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, int keysize );
/**
* \brief CAMELLIA key schedule (decryption)
*
* \param ctx CAMELLIA context to be initialized
* \param key decryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, int keysize );
/**
* \brief CAMELLIA-ECB block encryption/decryption
*
* \param ctx CAMELLIA context
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int camellia_crypt_ecb( camellia_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief CAMELLIA-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \param ctx CAMELLIA context
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int camellia_crypt_cbc( camellia_context *ctx,
int mode,
int length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief CAMELLIA-CFB128 buffer encryption/decryption
*
* \param ctx CAMELLIA context
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int camellia_crypt_cfb128( camellia_context *ctx,
int mode,
int length,
int *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int camellia_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* camellia.h */

View File

@@ -0,0 +1,44 @@
/**
* \file certs.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CERTS_H
#define POLARSSL_CERTS_H
#ifdef __cplusplus
extern "C" {
#endif
extern const char test_ca_crt[];
extern const char test_ca_key[];
extern const char test_ca_pwd[];
extern const char test_srv_crt[];
extern const char test_srv_key[];
extern const char test_cli_crt[];
extern const char test_cli_key[];
#ifdef __cplusplus
}
#endif
#endif /* certs.h */

View File

@@ -0,0 +1,336 @@
/**
* \file config.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
* memory footprint.
*/
#ifndef POLARSSL_CONFIG_H
#define POLARSSL_CONFIG_H
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
/*
* Uncomment if native integers are 8-bit wide.
*
#define POLARSSL_HAVE_INT8
*/
/*
* Uncomment if native integers are 16-bit wide.
*
#define POLARSSL_HAVE_INT16
*/
/*
* Uncomment if the compiler supports long long.
*
#define POLARSSL_HAVE_LONGLONG
*/
/*
* Uncomment to enable the use of assembly code.
*
* Requires support for asm() in compiler.
*
* Used in:
* library/timing.c
* library/padlock.c
* include/polarssl/bn_mul.h
*
*/
#define POLARSSL_HAVE_ASM
/*
* Uncomment if the CPU supports SSE2 (IA-32 specific).
*
#define POLARSSL_HAVE_SSE2
*/
/*
* Enable all SSL/TLS debugging messages.
*/
#define POLARSSL_DEBUG_MSG
/*
* Enable the checkup functions (*_self_test).
*/
#define POLARSSL_SELF_TEST
/*
* Enable run-time version information functions
*/
#define POLARSSL_VERSION_C
/*
* Enable the prime-number generation code.
*/
#define POLARSSL_GENPRIME
/*
* Uncomment this macro to store the AES tables in ROM.
*
#define POLARSSL_AES_ROM_TABLES
*/
/*
* Module: library/aes.c
* Caller: library/ssl_tls.c
*
* This module enables the following ciphersuites:
* SSL_RSA_AES_128_SHA
* SSL_RSA_AES_256_SHA
* SSL_EDH_RSA_AES_256_SHA
*/
#define POLARSSL_AES_C
/*
* Module: library/arc4.c
* Caller: library/ssl_tls.c
*
* This module enables the following ciphersuites:
* SSL_RSA_RC4_128_MD5
* SSL_RSA_RC4_128_SHA
*/
#define POLARSSL_ARC4_C
/*
* Module: library/base64.c
* Caller: library/x509parse.c
*
* This module is required for X.509 support.
*/
#define POLARSSL_BASE64_C
/*
* Module: library/bignum.c
* Caller: library/dhm.c
* library/rsa.c
* library/ssl_tls.c
* library/x509parse.c
*
* This module is required for RSA and DHM support.
*/
#define POLARSSL_BIGNUM_C
/*
* Module: library/camellia.c
* Caller: library/ssl_tls.c
*
* This module enabled the following cipher suites:
* SSL_RSA_CAMELLIA_128_SHA
* SSL_RSA_CAMELLIA_256_SHA
* SSL_EDH_RSA_CAMELLIA_256_SHA
*/
#define POLARSSL_CAMELLIA_C
/*
* Module: library/certs.c
* Caller:
*
* This module is used for testing (ssl_client/server).
*/
#define POLARSSL_CERTS_C
/*
* Module: library/debug.c
* Caller: library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
*
* This module provides debugging functions.
*/
#define POLARSSL_DEBUG_C
/*
* Module: library/des.c
* Caller: library/ssl_tls.c
*
* This module enables the following ciphersuites:
* SSL_RSA_DES_168_SHA
* SSL_EDH_RSA_DES_168_SHA
*/
#define POLARSSL_DES_C
/*
* Module: library/dhm.c
* Caller: library/ssl_cli.c
* library/ssl_srv.c
*
* This module enables the following ciphersuites:
* SSL_EDH_RSA_DES_168_SHA
* SSL_EDH_RSA_AES_256_SHA
* SSL_EDH_RSA_CAMELLIA_256_SHA
*/
#define POLARSSL_DHM_C
/*
* Module: library/havege.c
* Caller:
*
* This module enables the HAVEGE random number generator.
*/
#define POLARSSL_HAVEGE_C
/*
* Module: library/md2.c
* Caller: library/x509parse.c
*
* Uncomment to enable support for (rare) MD2-signed X.509 certs.
*
#define POLARSSL_MD2_C
*/
/*
* Module: library/md4.c
* Caller: library/x509parse.c
*
* Uncomment to enable support for (rare) MD4-signed X.509 certs.
*
#define POLARSSL_MD4_C
*/
/*
* Module: library/md5.c
* Caller: library/ssl_tls.c
* library/x509parse.c
*
* This module is required for SSL/TLS and X.509.
*/
#define POLARSSL_MD5_C
/*
* Module: library/net.c
* Caller:
*
* This module provides TCP/IP networking routines.
*/
#define POLARSSL_NET_C
/*
* Module: library/padlock.c
* Caller: library/aes.c
*
* This modules adds support for the VIA PadLock on x86.
*/
#define POLARSSL_PADLOCK_C
/*
* Module: library/rsa.c
* Caller: library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
* library/x509.c
*
* This module is required for SSL/TLS and MD5-signed certificates.
*/
#define POLARSSL_RSA_C
/*
* Module: library/sha1.c
* Caller: library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
* library/x509parse.c
*
* This module is required for SSL/TLS and SHA1-signed certificates.
*/
#define POLARSSL_SHA1_C
/*
* Module: library/sha2.c
* Caller:
*
* This module adds support for SHA-224 and SHA-256.
*/
#define POLARSSL_SHA2_C
/*
* Module: library/sha4.c
* Caller:
*
* This module adds support for SHA-384 and SHA-512.
*/
#define POLARSSL_SHA4_C
/*
* Module: library/ssl_cli.c
* Caller:
*
* This module is required for SSL/TLS client support.
*/
#define POLARSSL_SSL_CLI_C
/*
* Module: library/ssl_srv.c
* Caller:
*
* This module is required for SSL/TLS server support.
*/
#define POLARSSL_SSL_SRV_C
/*
* Module: library/ssl_tls.c
* Caller: library/ssl_cli.c
* library/ssl_srv.c
*
* This module is required for SSL/TLS.
*/
#define POLARSSL_SSL_TLS_C
/*
* Module: library/timing.c
* Caller: library/havege.c
*
* This module is used by the HAVEGE random number generator.
*/
#define POLARSSL_TIMING_C
/*
* Module: library/x509parse.c
* Caller: library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
*
* This module is required for X.509 certificate parsing.
*/
#define POLARSSL_X509_PARSE_C
/*
* Module: library/x509_write.c
* Caller:
*
* This module is required for X.509 certificate writing.
*/
#define POLARSSL_X509_WRITE_C
/*
* Module: library/xtea.c
* Caller:
*/
#define POLARSSL_XTEA_C
#endif /* config.h */

View File

@@ -0,0 +1,87 @@
/**
* \file debug.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef SSL_DEBUG_H
#define SSL_DEBUG_H
#include "polarssl/config.h"
#include "polarssl/ssl.h"
#if defined(POLARSSL_DEBUG_MSG)
#define SSL_DEBUG_MSG( level, args ) \
debug_print_msg( ssl, level, __FILE__, __LINE__, debug_fmt args );
#define SSL_DEBUG_RET( level, text, ret ) \
debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret );
#define SSL_DEBUG_BUF( level, text, buf, len ) \
debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len );
#define SSL_DEBUG_MPI( level, text, X ) \
debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X );
#define SSL_DEBUG_CRT( level, text, crt ) \
debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt );
#else
#define SSL_DEBUG_MSG( level, args ) do { } while( 0 )
#define SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
#define SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
#define SSL_DEBUG_MPI( level, text, X ) do { } while( 0 )
#define SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#endif
#ifdef __cplusplus
extern "C" {
#endif
char *debug_fmt( const char *format, ... );
void debug_print_msg( const ssl_context *ssl, int level,
const char *file, int line, const char *text );
void debug_print_ret( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret );
void debug_print_buf( const ssl_context *ssl, int level,
const char *file, int line, const char *text,
unsigned char *buf, int len );
void debug_print_mpi( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mpi *X );
void debug_print_crt( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const x509_cert *crt );
#ifdef __cplusplus
}
#endif
#endif /* debug.h */

View File

@@ -0,0 +1,178 @@
/**
* \file des.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_DES_H
#define POLARSSL_DES_H
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0C00
/**
* \brief DES context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
unsigned long sk[32]; /*!< DES subkeys */
}
des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
unsigned long sk[96]; /*!< 3DES subkeys */
}
des3_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*/
void des_setkey_enc( des_context *ctx, const unsigned char key[8] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*/
void des_setkey_dec( des_context *ctx, const unsigned char key[8] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*/
void des3_set2key_enc( des3_context *ctx, const unsigned char key[16] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*/
void des3_set2key_dec( des3_context *ctx, const unsigned char key[16] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*/
void des3_set3key_enc( des3_context *ctx, const unsigned char key[24] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*/
void des3_set3key_dec( des3_context *ctx, const unsigned char key[24] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int des_crypt_ecb( des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
/**
* \brief DES-CBC buffer encryption/decryption
*
* \param ctx DES context
* \param mode DES_ENCRYPT or DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
int des_crypt_cbc( des_context *ctx,
int mode,
int length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int des3_crypt_ecb( des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \param ctx 3DES context
* \param mode DES_ENCRYPT or DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH
*/
int des3_crypt_cbc( des3_context *ctx,
int mode,
int length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
/*
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int des_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* des.h */

View File

@@ -0,0 +1,143 @@
/**
* \file dhm.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_DHM_H
#define POLARSSL_DHM_H
#include "polarssl/bignum.h"
#define POLARSSL_ERR_DHM_BAD_INPUT_DATA 0x0480
#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED 0x0490
#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED 0x04A0
#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED 0x04B0
#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED 0x04C0
#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED 0x04D0
typedef struct
{
int len; /*!< size(P) in chars */
mpi P; /*!< prime modulus */
mpi G; /*!< generator */
mpi X; /*!< secret value */
mpi GX; /*!< self = G^X mod P */
mpi GY; /*!< peer = G^Y mod P */
mpi K; /*!< key = GY^X mod P */
mpi RP; /*!< cached R^2 mod P */
}
dhm_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Parse the ServerKeyExchange parameters
*
* \param ctx DHM context
* \param p &(start of input buffer)
* \param end end of buffer
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_read_params( dhm_context *ctx,
unsigned char **p,
const unsigned char *end );
/**
* \brief Setup and write the ServerKeyExchange parameters
*
* \param ctx DHM context
* \param x_size private value size in bytes
* \param output destination buffer
* \param olen number of chars written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note This function assumes that ctx->P and ctx->G
* have already been properly set (for example
* using mpi_read_string or mpi_read_binary).
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_make_params( dhm_context *ctx, int x_size,
unsigned char *output, int *olen,
int (*f_rng)(void *), void *p_rng );
/**
* \brief Import the peer's public value G^Y
*
* \param ctx DHM context
* \param input input buffer
* \param ilen size of buffer
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_read_public( dhm_context *ctx,
const unsigned char *input, int ilen );
/**
* \brief Create own private value X and export G^X
*
* \param ctx DHM context
* \param x_size private value size in bits
* \param output destination buffer
* \param olen must be equal to ctx->P.len
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_make_public( dhm_context *ctx, int s_size,
unsigned char *output, int olen,
int (*f_rng)(void *), void *p_rng );
/**
* \brief Derive and export the shared secret (G^Y)^X mod P
*
* \param ctx DHM context
* \param output destination buffer
* \param olen number of chars written
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_calc_secret( dhm_context *ctx,
unsigned char *output, int *olen );
/*
* \brief Free the components of a DHM key
*/
void dhm_free( dhm_context *ctx );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int dhm_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,65 @@
/**
* \file havege.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_HAVEGE_H
#define POLARSSL_HAVEGE_H
#define COLLECT_SIZE 1024
/**
* \brief HAVEGE state structure
*/
typedef struct
{
int PT1, PT2, offset[2];
int pool[COLLECT_SIZE];
int WALK[8192];
}
havege_state;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief HAVEGE initialization
*
* \param hs HAVEGE state to be initialized
*/
void havege_init( havege_state *hs );
/**
* \brief HAVEGE rand function
*
* \param p_rng A HAVEGE state
*
* \return A random int
*/
int havege_rand( void *p_rng );
#ifdef __cplusplus
}
#endif
#endif /* havege.h */

View File

@@ -0,0 +1,148 @@
/**
* \file md2.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD2_H
#define POLARSSL_MD2_H
/**
* \brief MD2 context structure
*/
typedef struct
{
unsigned char cksum[16]; /*!< checksum of the data block */
unsigned char state[48]; /*!< intermediate digest state */
unsigned char buffer[16]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
int left; /*!< amount of data in buffer */
}
md2_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD2 context setup
*
* \param ctx context to be initialized
*/
void md2_starts( md2_context *ctx );
/**
* \brief MD2 process buffer
*
* \param ctx MD2 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md2_update( md2_context *ctx, const unsigned char *input, int ilen );
/**
* \brief MD2 final digest
*
* \param ctx MD2 context
* \param output MD2 checksum result
*/
void md2_finish( md2_context *ctx, unsigned char output[16] );
/**
* \brief Output = MD2( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD2 checksum result
*/
void md2( const unsigned char *input, int ilen, unsigned char output[16] );
/**
* \brief Output = MD2( file contents )
*
* \param path input file name
* \param output MD2 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int md2_file( const char *path, unsigned char output[16] );
/**
* \brief MD2 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md2_hmac_starts( md2_context *ctx, const unsigned char *key, int keylen );
/**
* \brief MD2 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md2_hmac_update( md2_context *ctx, const unsigned char *input, int ilen );
/**
* \brief MD2 HMAC final digest
*
* \param ctx HMAC context
* \param output MD2 HMAC checksum result
*/
void md2_hmac_finish( md2_context *ctx, unsigned char output[16] );
/**
* \brief MD2 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void md2_hmac_reset( md2_context *ctx );
/**
* \brief Output = HMAC-MD2( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD2 result
*/
void md2_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md2_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md2.h */

View File

@@ -0,0 +1,147 @@
/**
* \file md4.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD4_H
#define POLARSSL_MD4_H
/**
* \brief MD4 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md4_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD4 context setup
*
* \param ctx context to be initialized
*/
void md4_starts( md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md4_update( md4_context *ctx, const unsigned char *input, int ilen );
/**
* \brief MD4 final digest
*
* \param ctx MD4 context
* \param output MD4 checksum result
*/
void md4_finish( md4_context *ctx, unsigned char output[16] );
/**
* \brief Output = MD4( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*/
void md4( const unsigned char *input, int ilen, unsigned char output[16] );
/**
* \brief Output = MD4( file contents )
*
* \param path input file name
* \param output MD4 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int md4_file( const char *path, unsigned char output[16] );
/**
* \brief MD4 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, int keylen );
/**
* \brief MD4 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md4_hmac_update( md4_context *ctx, const unsigned char *input, int ilen );
/**
* \brief MD4 HMAC final digest
*
* \param ctx HMAC context
* \param output MD4 HMAC checksum result
*/
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] );
/**
* \brief MD4 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void md4_hmac_reset( md4_context *ctx );
/**
* \brief Output = HMAC-MD4( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD4 result
*/
void md4_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md4.h */

View File

@@ -0,0 +1,149 @@
/**
* \file md5.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD5_H
#define POLARSSL_MD5_H
/**
* \brief MD5 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md5_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*/
void md5_starts( md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_update( md5_context *ctx, const unsigned char *input, int ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*/
void md5_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*/
void md5( const unsigned char *input, int ilen, unsigned char output[16] );
/**
* \brief Output = MD5( file contents )
*
* \param path input file name
* \param output MD5 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int md5_file( const char *path, unsigned char output[16] );
/**
* \brief MD5 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md5_hmac_starts( md5_context *ctx,
const unsigned char *key, int keylen );
/**
* \brief MD5 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_hmac_update( md5_context *ctx,
const unsigned char *input, int ilen );
/**
* \brief MD5 HMAC final digest
*
* \param ctx HMAC context
* \param output MD5 HMAC checksum result
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief MD5 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void md5_hmac_reset( md5_context *ctx );
/**
* \brief Output = HMAC-MD5( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD5 result
*/
void md5_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md5_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md5.h */

View File

@@ -0,0 +1,152 @@
/**
* \file net.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_NET_H
#define POLARSSL_NET_H
#define POLARSSL_ERR_NET_UNKNOWN_HOST -0x0F00
#define POLARSSL_ERR_NET_SOCKET_FAILED -0x0F10
#define POLARSSL_ERR_NET_CONNECT_FAILED -0x0F20
#define POLARSSL_ERR_NET_BIND_FAILED -0x0F30
#define POLARSSL_ERR_NET_LISTEN_FAILED -0x0F40
#define POLARSSL_ERR_NET_ACCEPT_FAILED -0x0F50
#define POLARSSL_ERR_NET_RECV_FAILED -0x0F60
#define POLARSSL_ERR_NET_SEND_FAILED -0x0F70
#define POLARSSL_ERR_NET_CONN_RESET -0x0F80
#define POLARSSL_ERR_NET_TRY_AGAIN -0x0F90
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initiate a TCP connection with host:port
*
* \param fd Socket to use
* \param host Host to connect to
* \param port Port to connect to
*
* \return 0 if successful, or one of:
* POLARSSL_ERR_NET_SOCKET_FAILED,
* POLARSSL_ERR_NET_UNKNOWN_HOST,
* POLARSSL_ERR_NET_CONNECT_FAILED
*/
int net_connect( int *fd, const char *host, int port );
/**
* \brief Create a listening socket on bind_ip:port.
* If bind_ip == NULL, all interfaces are binded.
*
* \param fd Socket to use
* \param bind_ip IP to bind to, can be NULL
* \param port Port number to use
*
* \return 0 if successful, or one of:
* POLARSSL_ERR_NET_SOCKET_FAILED,
* POLARSSL_ERR_NET_BIND_FAILED,
* POLARSSL_ERR_NET_LISTEN_FAILED
*/
int net_bind( int *fd, const char *bind_ip, int port );
/**
* \brief Accept a connection from a remote client
*
* \param bind_fd Relevant socket
* \param client_fd Will contain the connected client socket
* \param client_ip Will contain the client IP address
*
* \return 0 if successful, POLARSSL_ERR_NET_ACCEPT_FAILED, or
* POLARSSL_ERR_NET_WOULD_BLOCK is bind_fd was set to
* non-blocking and accept() is blocking.
*/
int net_accept( int bind_fd, int *client_fd, void *client_ip );
/**
* \brief Set the socket blocking
*
* \param fd Socket to set
*
* \return 0 if successful, or a non-zero error code
*/
int net_set_block( int fd );
/**
* \brief Set the socket non-blocking
*
* \param fd Socket to set
*
* \return 0 if successful, or a non-zero error code
*/
int net_set_nonblock( int fd );
/**
* \brief Portable usleep helper
*
* \param usec Amount of microseconds to sleep
*
* \note Real amount of time slept will not be less than
* select()'s timeout granularity (typically, 10ms).
*/
void net_usleep( unsigned long usec );
/**
* \brief Read at most 'len' characters. If no error occurs,
* the actual amount read is returned.
*
* \param ctx Socket
* \param buf The buffer to write to
* \param len Maximum length of the buffer
*
* \return This function returns the number of bytes received,
* or a non-zero error code; POLARSSL_ERR_NET_TRY_AGAIN
* indicates read() is blocking.
*/
int net_recv( void *ctx, unsigned char *buf, int len );
/**
* \brief Write at most 'len' characters. If no error occurs,
* the actual amount read is returned.
*
* \param ctx Socket
* \param buf The buffer to read from
* \param len The length of the buffer
*
* \return This function returns the number of bytes sent,
* or a non-zero error code; POLARSSL_ERR_NET_TRY_AGAIN
* indicates write() is blocking.
*/
int net_send( void *ctx, unsigned char *buf, int len );
/**
* \brief Gracefully shutdown the connection
*
* \param fd The socket to close
*/
void net_close( int fd );
#ifdef __cplusplus
}
#endif
#endif /* net.h */

View File

@@ -0,0 +1,134 @@
/**
* \file openssl.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* OpenSSL wrapper contributed by David Barett
*/
#ifndef POLARSSL_OPENSSL_H
#define POLARSSL_OPENSSL_H
#include "polarssl/aes.h"
#include "polarssl/md5.h"
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
#define AES_SIZE 16
#define AES_BLOCK_SIZE 16
#define AES_KEY aes_context
#define MD5_CTX md5_context
#define SHA_CTX sha1_context
#define SHA1_Init( CTX ) \
sha1_starts( (CTX) )
#define SHA1_Update( CTX, BUF, LEN ) \
sha1_update( (CTX), (unsigned char *)(BUF), (LEN) )
#define SHA1_Final( OUT, CTX ) \
sha1_finish( (CTX), (OUT) )
#define MD5_Init( CTX ) \
md5_starts( (CTX) )
#define MD5_Update( CTX, BUF, LEN ) \
md5_update( (CTX), (unsigned char *)(BUF), (LEN) )
#define MD5_Final( OUT, CTX ) \
md5_finish( (CTX), (OUT) )
#define AES_set_encrypt_key( KEY, KEYSIZE, CTX ) \
aes_setkey_enc( (CTX), (KEY), (KEYSIZE) )
#define AES_set_decrypt_key( KEY, KEYSIZE, CTX ) \
aes_setkey_dec( (CTX), (KEY), (KEYSIZE) )
#define AES_cbc_encrypt( INPUT, OUTPUT, LEN, CTX, IV, MODE ) \
aes_crypt_cbc( (CTX), (MODE), (LEN), (IV), (INPUT), (OUTPUT) )
/*
* RSA stuff follows. TODO: needs cleanup
*/
inline int __RSA_Passthrough( void *output, void *input, int size )
{
memcpy( output, input, size );
return size;
}
inline rsa_context* d2i_RSA_PUBKEY( void *ignore, unsigned char **bufptr,
int len )
{
unsigned char *buffer = *(unsigned char **) bufptr;
rsa_context *rsa;
/*
* Not a general-purpose parser: only parses public key from *exactly*
* openssl genrsa -out privkey.pem 512 (or 1024)
* openssl rsa -in privkey.pem -out privatekey.der -outform der
* openssl rsa -in privkey.pem -out pubkey.der -outform der -pubout
*
* TODO: make a general-purpose parse
*/
if( ignore != 0 || ( len != 94 && len != 162 ) )
return( 0 );
rsa = (rsa_context *) malloc( sizeof( rsa_rsa ) );
if( rsa == NULL )
return( 0 );
memset( rsa, 0, sizeof( rsa_context ) );
if( ( len == 94 &&
mpi_read_binary( &rsa->N, &buffer[ 25], 64 ) == 0 &&
mpi_read_binary( &rsa->E, &buffer[ 91], 3 ) == 0 ) ||
( len == 162 &&
mpi_read_binary( &rsa->N, &buffer[ 29], 128 ) == 0 ) &&
mpi_read_binary( &rsa->E, &buffer[159], 3 ) == 0 )
{
/*
* key read successfully
*/
rsa->len = ( mpi_msb( &rsa->N ) + 7 ) >> 3;
return( rsa );
}
else
{
memset( rsa, 0, sizeof( rsa_context ) );
free( rsa );
return( 0 );
}
}
#define RSA rsa_context
#define RSA_PKCS1_PADDING 1 /* ignored; always encrypt with this */
#define RSA_size( CTX ) (CTX)->len
#define RSA_free( CTX ) rsa_free( CTX )
#define ERR_get_error( ) "ERR_get_error() not supported"
#define RSA_blinding_off( IGNORE )
#define d2i_RSAPrivateKey( a, b, c ) new rsa_context /* TODO: C++ bleh */
inline int RSA_public_decrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PUBLIC, &outsize, input, output ) ) return outsize; else return -1; }
inline int RSA_private_decrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PRIVATE, &outsize, input, output ) ) return outsize; else return -1; }
inline int RSA_public_encrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PUBLIC, size, input, output ) ) return RSA_size(key); else return -1; }
inline int RSA_private_encrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PRIVATE, size, input, output ) ) return RSA_size(key); else return -1; }
#ifdef __cplusplus
}
#endif
#endif /* openssl.h */

View File

@@ -0,0 +1,98 @@
/**
* \file padlock.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_PADLOCK_H
#define POLARSSL_PADLOCK_H
#include "polarssl/aes.h"
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__)
#ifndef POLARSSL_HAVE_X86
#define POLARSSL_HAVE_X86
#endif
#define PADLOCK_RNG 0x000C
#define PADLOCK_ACE 0x00C0
#define PADLOCK_PHE 0x0C00
#define PADLOCK_PMM 0x3000
#define PADLOCK_ALIGN16(x) (unsigned long *) (16 + ((long) x & ~15))
#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x08E0
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief PadLock detection routine
*
* \param The feature to detect
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int padlock_supports( int feature );
/**
* \brief PadLock AES-ECB block en(de)cryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if success, 1 if operation failed
*/
int padlock_xcryptecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief PadLock AES-CBC buffer en(de)cryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if success, 1 if operation failed
*/
int padlock_xcryptcbc( aes_context *ctx,
int mode,
int length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* HAVE_X86 */
#endif /* padlock.h */

View File

@@ -0,0 +1,353 @@
/**
* \file rsa.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_RSA_H
#define POLARSSL_RSA_H
#include "polarssl/bignum.h"
/*
* RSA Error codes
*/
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
/*
* PKCS#1 constants
*/
#define SIG_RSA_RAW 0
#define SIG_RSA_MD2 2
#define SIG_RSA_MD4 3
#define SIG_RSA_MD5 4
#define SIG_RSA_SHA1 5
#define SIG_RSA_SHA224 14
#define SIG_RSA_SHA256 11
#define SIG_RSA_SHA384 12
#define SIG_RSA_SHA512 13
#define RSA_PUBLIC 0
#define RSA_PRIVATE 1
#define RSA_PKCS_V15 0
#define RSA_PKCS_V21 1
#define RSA_SIGN 1
#define RSA_CRYPT 2
#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
#define ASN1_STR_NULL "\x05"
#define ASN1_STR_OID "\x06"
#define ASN1_STR_OCTET_STRING "\x04"
#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
#define OID_ISO_MEMBER_BODIES "\x2a"
#define OID_ISO_IDENTIFIED_ORG "\x2b"
/*
* ISO Member bodies OID parts
*/
#define OID_COUNTRY_US "\x86\x48"
#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
/*
* ISO Identified organization OID parts
*/
#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
/*
* DigestInfo ::= SEQUENCE {
* digestAlgorithm DigestAlgorithmIdentifier,
* digest Digest }
*
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
*
* Digest ::= OCTET STRING
*/
#define ASN1_HASH_MDX \
( \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
ASN1_STR_OID "\x08" \
OID_DIGEST_ALG_MDX \
ASN1_STR_NULL "\x00" \
ASN1_STR_OCTET_STRING "\x10" \
)
#define ASN1_HASH_SHA1 \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
ASN1_STR_OID "\x05" \
OID_HASH_ALG_SHA1 \
ASN1_STR_NULL "\x00" \
ASN1_STR_OCTET_STRING "\x14"
#define ASN1_HASH_SHA2X \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
ASN1_STR_OID "\x09" \
OID_HASH_ALG_SHA2X \
ASN1_STR_NULL "\x00" \
ASN1_STR_OCTET_STRING "\x00"
/**
* \brief RSA context structure
*/
typedef struct
{
int ver; /*!< always 0 */
int len; /*!< size(N) in chars */
mpi N; /*!< public modulus */
mpi E; /*!< public exponent */
mpi D; /*!< private exponent */
mpi P; /*!< 1st prime factor */
mpi Q; /*!< 2nd prime factor */
mpi DP; /*!< D % (P - 1) */
mpi DQ; /*!< D % (Q - 1) */
mpi QP; /*!< 1 / (Q % P) */
mpi RN; /*!< cached R^2 mod N */
mpi RP; /*!< cached R^2 mod P */
mpi RQ; /*!< cached R^2 mod Q */
int padding; /*!< 1.5 or OAEP/PSS */
int hash_id; /*!< hash identifier */
}
rsa_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize an RSA context
*
* \param ctx RSA context to be initialized
* \param padding RSA_PKCS_V15 or RSA_PKCS_V21
* \param hash_id RSA_PKCS_V21 hash identifier
*
* \note The hash_id parameter is actually ignored
* when using RSA_PKCS_V15 padding.
*
* \note Currently, RSA_PKCS_V21 padding
* is not supported.
*/
void rsa_init( rsa_context *ctx,
int padding,
int hash_id);
/**
* \brief Generate an RSA keypair
*
* \param ctx RSA context that will hold the key
* \param f_rng RNG function
* \param p_rng RNG parameter
* \param nbits size of the public key in bits
* \param exponent public exponent (e.g., 65537)
*
* \note rsa_init() must be called beforehand to setup
* the RSA context.
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
int rsa_gen_key( rsa_context *ctx,
int (*f_rng)(void *),
void *p_rng,
int nbits, int exponent );
/**
* \brief Check a public RSA key
*
* \param ctx RSA context to be checked
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
int rsa_check_pubkey( const rsa_context *ctx );
/**
* \brief Check a private RSA key
*
* \param ctx RSA context to be checked
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
int rsa_check_privkey( const rsa_context *ctx );
/**
* \brief Do an RSA public key operation
*
* \param ctx RSA context
* \param input input buffer
* \param output output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note This function does NOT take care of message
* padding. Also, be sure to set input[0] = 0 or assure that
* input is smaller than N.
*
* \note The input and output buffers must be large
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_public( rsa_context *ctx,
const unsigned char *input,
unsigned char *output );
/**
* \brief Do an RSA private key operation
*
* \param ctx RSA context
* \param input input buffer
* \param output output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The input and output buffers must be large
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_private( rsa_context *ctx,
const unsigned char *input,
unsigned char *output );
/**
* \brief Add the message padding, then do an RSA operation
*
* \param ctx RSA context
* \param f_rng RNG function
* \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param ilen contains the plaintext length
* \param input buffer holding the data to be encrypted
* \param output buffer that will hold the ciphertext
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
int (*f_rng)(void *),
void *p_rng,
int mode, int ilen,
const unsigned char *input,
unsigned char *output );
/**
* \brief Do an RSA operation, then remove the message padding
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param input buffer holding the encrypted data
* \param output buffer that will hold the plaintext
* \param olen will contain the plaintext length
* \param output_max_len maximum length of the output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note The output buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
* an error is thrown.
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen,
const unsigned char *input,
unsigned char *output,
int output_max_len );
/**
* \brief Do a private RSA to sign a message digest
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer that will hold the ciphertext
*
* \return 0 if the signing operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_pkcs1_sign( rsa_context *ctx,
int mode,
int hash_id,
int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Do a public RSA and check the message digest
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
* \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer holding the ciphertext
*
* \return 0 if the verify operation was successful,
* or an POLARSSL_ERR_RSA_XXX error code
*
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_pkcs1_verify( rsa_context *ctx,
int mode,
int hash_id,
int hashlen,
const unsigned char *hash,
unsigned char *sig );
/**
* \brief Free the components of an RSA key
*
* \param ctx RSA Context to free
*/
void rsa_free( rsa_context *ctx );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int rsa_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* rsa.h */

View File

@@ -0,0 +1,147 @@
/**
* \file sha1.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_SHA1_H
#define POLARSSL_SHA1_H
/**
* \brief SHA-1 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
sha1_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context setup
*
* \param ctx context to be initialized
*/
void sha1_starts( sha1_context *ctx );
/**
* \brief SHA-1 process buffer
*
* \param ctx SHA-1 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-1 final digest
*
* \param ctx SHA-1 context
* \param output SHA-1 checksum result
*/
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief Output = SHA-1( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-1 checksum result
*/
void sha1( const unsigned char *input, int ilen, unsigned char output[20] );
/**
* \brief Output = SHA-1( file contents )
*
* \param path input file name
* \param output SHA-1 checksum result
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int sha1_file( const char *path, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen );
/**
* \brief SHA-1 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-1 HMAC final digest
*
* \param ctx HMAC context
* \param output SHA-1 HMAC checksum result
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
/**
* \brief SHA-1 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void sha1_hmac_reset( sha1_context *ctx );
/**
* \brief Output = HMAC-SHA-1( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-SHA-1 result
*/
void sha1_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[20] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int sha1_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* sha1.h */

View File

@@ -0,0 +1,155 @@
/**
* \file sha2.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_SHA2_H
#define POLARSSL_SHA2_H
/**
* \brief SHA-256 context structure
*/
typedef struct
{
unsigned long total[2]; /*!< number of bytes processed */
unsigned long state[8]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
int is224; /*!< 0 => SHA-256, else SHA-224 */
}
sha2_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-256 context setup
*
* \param ctx context to be initialized
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void sha2_starts( sha2_context *ctx, int is224 );
/**
* \brief SHA-256 process buffer
*
* \param ctx SHA-256 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-256 final digest
*
* \param ctx SHA-256 context
* \param output SHA-224/256 checksum result
*/
void sha2_finish( sha2_context *ctx, unsigned char output[32] );
/**
* \brief Output = SHA-256( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-224/256 checksum result
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void sha2( const unsigned char *input, int ilen,
unsigned char output[32], int is224 );
/**
* \brief Output = SHA-256( file contents )
*
* \param path input file name
* \param output SHA-224/256 checksum result
* \param is224 0 = use SHA256, 1 = use SHA224
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int sha2_file( const char *path, unsigned char output[32], int is224 );
/**
* \brief SHA-256 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
int is224 );
/**
* \brief SHA-256 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-256 HMAC final digest
*
* \param ctx HMAC context
* \param output SHA-224/256 HMAC checksum result
*/
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] );
/**
* \brief SHA-256 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void sha2_hmac_reset( sha2_context *ctx );
/**
* \brief Output = HMAC-SHA-256( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-SHA-224/256 result
* \param is224 0 = use SHA256, 1 = use SHA224
*/
void sha2_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[32], int is224 );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int sha2_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* sha2.h */

View File

@@ -0,0 +1,163 @@
/**
* \file sha4.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_SHA4_H
#define POLARSSL_SHA4_H
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
#define int64 __int64
#else
#define UL64(x) x##ULL
#define int64 long long
#endif
/**
* \brief SHA-512 context structure
*/
typedef struct
{
unsigned int64 total[2]; /*!< number of bytes processed */
unsigned int64 state[8]; /*!< intermediate digest state */
unsigned char buffer[128]; /*!< data block being processed */
unsigned char ipad[128]; /*!< HMAC: inner padding */
unsigned char opad[128]; /*!< HMAC: outer padding */
int is384; /*!< 0 => SHA-512, else SHA-384 */
}
sha4_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-512 context setup
*
* \param ctx context to be initialized
* \param is384 0 = use SHA512, 1 = use SHA384
*/
void sha4_starts( sha4_context *ctx, int is384 );
/**
* \brief SHA-512 process buffer
*
* \param ctx SHA-512 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha4_update( sha4_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-512 final digest
*
* \param ctx SHA-512 context
* \param output SHA-384/512 checksum result
*/
void sha4_finish( sha4_context *ctx, unsigned char output[64] );
/**
* \brief Output = SHA-512( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output SHA-384/512 checksum result
* \param is384 0 = use SHA512, 1 = use SHA384
*/
void sha4( const unsigned char *input, int ilen,
unsigned char output[64], int is384 );
/**
* \brief Output = SHA-512( file contents )
*
* \param path input file name
* \param output SHA-384/512 checksum result
* \param is384 0 = use SHA512, 1 = use SHA384
*
* \return 0 if successful, 1 if fopen failed,
* or 2 if fread failed
*/
int sha4_file( const char *path, unsigned char output[64], int is384 );
/**
* \brief SHA-512 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param is384 0 = use SHA512, 1 = use SHA384
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, int keylen,
int is384 );
/**
* \brief SHA-512 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void sha4_hmac_update( sha4_context *ctx, const unsigned char *input, int ilen );
/**
* \brief SHA-512 HMAC final digest
*
* \param ctx HMAC context
* \param output SHA-384/512 HMAC checksum result
*/
void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] );
/**
* \brief SHA-512 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void sha4_hmac_reset( sha4_context *ctx );
/**
* \brief Output = HMAC-SHA-512( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-SHA-384/512 result
* \param is384 0 = use SHA512, 1 = use SHA384
*/
void sha4_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[64], int is384 );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int sha4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* sha4.h */

View File

@@ -0,0 +1,576 @@
/**
* \file ssl.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_SSL_H
#define POLARSSL_SSL_H
#include <time.h>
#include "polarssl/net.h"
#include "polarssl/dhm.h"
#include "polarssl/rsa.h"
#include "polarssl/md5.h"
#include "polarssl/sha1.h"
#include "polarssl/x509.h"
/*
* SSL Error codes
*/
#define POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE -0x1000
#define POLARSSL_ERR_SSL_BAD_INPUT_DATA -0x1800
#define POLARSSL_ERR_SSL_INVALID_MAC -0x2000
#define POLARSSL_ERR_SSL_INVALID_RECORD -0x2800
#define POLARSSL_ERR_SSL_INVALID_MODULUS_SIZE -0x3000
#define POLARSSL_ERR_SSL_UNKNOWN_CIPHER -0x3800
#define POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN -0x4000
#define POLARSSL_ERR_SSL_NO_SESSION_FOUND -0x4800
#define POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE -0x5000
#define POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE -0x5800
#define POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED -0x6000
#define POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED -0x6800
#define POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED -0x7000
#define POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE -0x7800
#define POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE -0x8000
#define POLARSSL_ERR_SSL_PEER_VERIFY_FAILED -0x8800
#define POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY -0x9000
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO -0x9800
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO -0xA000
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE -0xA800
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0xB000
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0xB800
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0xC000
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0xC800
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0xD000
#define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0xD800
#define POLARSSL_ERR_SSL_BAD_HS_FINISHED -0xE000
/*
* Various constants
*/
#define SSL_MAJOR_VERSION_3 3
#define SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */
#define SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */
#define SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */
#define SSL_IS_CLIENT 0
#define SSL_IS_SERVER 1
#define SSL_COMPRESS_NULL 0
#define SSL_VERIFY_NONE 0
#define SSL_VERIFY_OPTIONAL 1
#define SSL_VERIFY_REQUIRED 2
#define SSL_MAX_CONTENT_LEN 16384
/*
* Allow an extra 512 bytes for the record header
* and encryption overhead (counter + MAC + padding).
*/
#define SSL_BUFFER_LEN (SSL_MAX_CONTENT_LEN + 512)
/*
* Supported ciphersuites
*/
#define SSL_RSA_RC4_128_MD5 0x04
#define SSL_RSA_RC4_128_SHA 0x05
#define SSL_RSA_DES_168_SHA 0x0A
#define SSL_EDH_RSA_DES_168_SHA 0x16
#define SSL_RSA_AES_128_SHA 0x2F
#define SSL_EDH_RSA_AES_128_SHA 0x33
#define SSL_RSA_AES_256_SHA 0x35
#define SSL_EDH_RSA_AES_256_SHA 0x39
#define SSL_RSA_CAMELLIA_128_SHA 0x41
#define SSL_EDH_RSA_CAMELLIA_128_SHA 0x45
#define SSL_RSA_CAMELLIA_256_SHA 0x84
#define SSL_EDH_RSA_CAMELLIA_256_SHA 0x88
/*
* Message, alert and handshake types
*/
#define SSL_MSG_CHANGE_CIPHER_SPEC 20
#define SSL_MSG_ALERT 21
#define SSL_MSG_HANDSHAKE 22
#define SSL_MSG_APPLICATION_DATA 23
#define SSL_ALERT_LEVEL_WARNING 1
#define SSL_ALERT_LEVEL_FATAL 2
#define SSL_ALERT_MSG_CLOSE_NOTIFY 0
#define SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10
#define SSL_ALERT_MSG_BAD_RECORD_MAD 20
#define SSL_ALERT_MSG_DECRYPTION_FAILED 21
#define SSL_ALERT_MSG_RECORD_OVERFLOW 22
#define SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30
#define SSL_ALERT_MSG_HANDSHAKE_FAILURE 40
#define SSL_ALERT_MSG_NO_CERT 41
#define SSL_ALERT_MSG_BAD_CERT 42
#define SSL_ALERT_MSG_UNSUPPORTED_CERT 43
#define SSL_ALERT_MSG_CERT_REVOKED 44
#define SSL_ALERT_MSG_CERT_EXPIRED 45
#define SSL_ALERT_MSG_CERT_UNKNOWN 46
#define SSL_ALERT_MSG_ILLEGAL_PARAMETER 47
#define SSL_ALERT_MSG_UNKNOWN_CA 48
#define SSL_ALERT_MSG_ACCESS_DENIED 49
#define SSL_ALERT_MSG_DECODE_ERROR 50
#define SSL_ALERT_MSG_DECRYPT_ERROR 51
#define SSL_ALERT_MSG_EXPORT_RESTRICTION 60
#define SSL_ALERT_MSG_PROTOCOL_VERSION 70
#define SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71
#define SSL_ALERT_MSG_INTERNAL_ERROR 80
#define SSL_ALERT_MSG_USER_CANCELED 90
#define SSL_ALERT_MSG_NO_RENEGOTIATION 100
#define SSL_HS_HELLO_REQUEST 0
#define SSL_HS_CLIENT_HELLO 1
#define SSL_HS_SERVER_HELLO 2
#define SSL_HS_CERTIFICATE 11
#define SSL_HS_SERVER_KEY_EXCHANGE 12
#define SSL_HS_CERTIFICATE_REQUEST 13
#define SSL_HS_SERVER_HELLO_DONE 14
#define SSL_HS_CERTIFICATE_VERIFY 15
#define SSL_HS_CLIENT_KEY_EXCHANGE 16
#define SSL_HS_FINISHED 20
/*
* TLS extensions
*/
#define TLS_EXT_SERVERNAME 0
#define TLS_EXT_SERVERNAME_HOSTNAME 0
/*
* SSL state machine
*/
typedef enum
{
SSL_HELLO_REQUEST,
SSL_CLIENT_HELLO,
SSL_SERVER_HELLO,
SSL_SERVER_CERTIFICATE,
SSL_SERVER_KEY_EXCHANGE,
SSL_CERTIFICATE_REQUEST,
SSL_SERVER_HELLO_DONE,
SSL_CLIENT_CERTIFICATE,
SSL_CLIENT_KEY_EXCHANGE,
SSL_CERTIFICATE_VERIFY,
SSL_CLIENT_CHANGE_CIPHER_SPEC,
SSL_CLIENT_FINISHED,
SSL_SERVER_CHANGE_CIPHER_SPEC,
SSL_SERVER_FINISHED,
SSL_FLUSH_BUFFERS,
SSL_HANDSHAKE_OVER
}
ssl_states;
typedef struct _ssl_session ssl_session;
typedef struct _ssl_context ssl_context;
/*
* This structure is used for session resuming.
*/
struct _ssl_session
{
time_t start; /*!< starting time */
int cipher; /*!< chosen cipher */
int length; /*!< session id length */
unsigned char id[32]; /*!< session identifier */
unsigned char master[48]; /*!< the master secret */
ssl_session *next; /*!< next session entry */
};
struct _ssl_context
{
/*
* Miscellaneous
*/
int state; /*!< SSL handshake: current state */
int major_ver; /*!< equal to SSL_MAJOR_VERSION_3 */
int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */
int max_major_ver; /*!< max. major version from client */
int max_minor_ver; /*!< max. minor version from client */
/*
* Callbacks (RNG, debug, I/O)
*/
int (*f_rng)(void *);
void (*f_dbg)(void *, int, const char *);
int (*f_recv)(void *, unsigned char *, int);
int (*f_send)(void *, unsigned char *, int);
void *p_rng; /*!< context for the RNG function */
void *p_dbg; /*!< context for the debug function */
void *p_recv; /*!< context for reading operations */
void *p_send; /*!< context for writing operations */
/*
* Session layer
*/
int resume; /*!< session resuming flag */
int timeout; /*!< sess. expiration time */
ssl_session *session; /*!< current session data */
int (*s_get)(ssl_context *); /*!< (server) get callback */
int (*s_set)(ssl_context *); /*!< (server) set callback */
/*
* Record layer (incoming data)
*/
unsigned char *in_ctr; /*!< 64-bit incoming message counter */
unsigned char *in_hdr; /*!< 5-byte record header (in_ctr+8) */
unsigned char *in_msg; /*!< the message contents (in_hdr+5) */
unsigned char *in_offt; /*!< read offset in application data */
int in_msgtype; /*!< record header: message type */
int in_msglen; /*!< record header: message length */
int in_left; /*!< amount of data read so far */
int in_hslen; /*!< current handshake message length */
int nb_zero; /*!< # of 0-length encrypted messages */
/*
* Record layer (outgoing data)
*/
unsigned char *out_ctr; /*!< 64-bit outgoing message counter */
unsigned char *out_hdr; /*!< 5-byte record header (out_ctr+8) */
unsigned char *out_msg; /*!< the message contents (out_hdr+5) */
int out_msgtype; /*!< record header: message type */
int out_msglen; /*!< record header: message length */
int out_left; /*!< amount of data not yet written */
/*
* PKI layer
*/
rsa_context *rsa_key; /*!< own RSA private key */
x509_cert *own_cert; /*!< own X.509 certificate */
x509_cert *ca_chain; /*!< own trusted CA chain */
x509_crl *ca_crl; /*!< trusted CA CRLs */
x509_cert *peer_cert; /*!< peer X.509 cert chain */
const char *peer_cn; /*!< expected peer CN */
int endpoint; /*!< 0: client, 1: server */
int authmode; /*!< verification mode */
int client_auth; /*!< flag for client auth. */
int verify_result; /*!< verification result */
/*
* Crypto layer
*/
dhm_context dhm_ctx; /*!< DHM key exchange */
md5_context fin_md5; /*!< Finished MD5 checksum */
sha1_context fin_sha1; /*!< Finished SHA-1 checksum */
int do_crypt; /*!< en(de)cryption flag */
int *ciphers; /*!< allowed ciphersuites */
int pmslen; /*!< premaster length */
int keylen; /*!< symmetric key length */
int minlen; /*!< min. ciphertext length */
int ivlen; /*!< IV length */
int maclen; /*!< MAC length */
unsigned char randbytes[64]; /*!< random bytes */
unsigned char premaster[256]; /*!< premaster secret */
unsigned char iv_enc[16]; /*!< IV (encryption) */
unsigned char iv_dec[16]; /*!< IV (decryption) */
unsigned char mac_enc[32]; /*!< MAC (encryption) */
unsigned char mac_dec[32]; /*!< MAC (decryption) */
unsigned long ctx_enc[128]; /*!< encryption context */
unsigned long ctx_dec[128]; /*!< decryption context */
/*
* TLS extensions
*/
unsigned char *hostname;
unsigned long hostname_len;
};
#ifdef __cplusplus
extern "C" {
#endif
extern int ssl_default_ciphers[];
/**
* \brief Initialize an SSL context
*
* \param ssl SSL context
*
* \return 0 if successful, or 1 if memory allocation failed
*/
int ssl_init( ssl_context *ssl );
/**
* \brief Set the current endpoint type
*
* \param ssl SSL context
* \param endpoint must be SSL_IS_CLIENT or SSL_IS_SERVER
*/
void ssl_set_endpoint( ssl_context *ssl, int endpoint );
/**
* \brief Set the certificate verification mode
*
* \param ssl SSL context
* \param mode can be:
*
* SSL_VERIFY_NONE: peer certificate is not checked (default),
* this is insecure and SHOULD be avoided.
*
* SSL_VERIFY_OPTIONAL: peer certificate is checked, however the
* handshake continues even if verification failed;
* ssl_get_verify_result() can be called after the
* handshake is complete.
*
* SSL_VERIFY_REQUIRED: peer *must* present a valid certificate,
* handshake is aborted if verification failed.
*/
void ssl_set_authmode( ssl_context *ssl, int authmode );
/**
* \brief Set the random number generator callback
*
* \param ssl SSL context
* \param f_rng RNG function
* \param p_rng RNG parameter
*/
void ssl_set_rng( ssl_context *ssl,
int (*f_rng)(void *),
void *p_rng );
/**
* \brief Set the debug callback
*
* \param ssl SSL context
* \param f_dbg debug function
* \param p_dbg debug parameter
*/
void ssl_set_dbg( ssl_context *ssl,
void (*f_dbg)(void *, int, const char *),
void *p_dbg );
/**
* \brief Set the underlying BIO read and write callbacks
*
* \param ssl SSL context
* \param f_recv read callback
* \param p_recv read parameter
* \param f_send write callback
* \param p_send write parameter
*/
void ssl_set_bio( ssl_context *ssl,
int (*f_recv)(void *, unsigned char *, int), void *p_recv,
int (*f_send)(void *, unsigned char *, int), void *p_send );
/**
* \brief Set the session callbacks (server-side only)
*
* \param ssl SSL context
* \param s_get session get callback
* \param s_set session set callback
*/
void ssl_set_scb( ssl_context *ssl,
int (*s_get)(ssl_context *),
int (*s_set)(ssl_context *) );
/**
* \brief Set the session resuming flag, timeout and data
*
* \param ssl SSL context
* \param resume if 0 (default), the session will not be resumed
* \param timeout session timeout in seconds, or 0 (no timeout)
* \param session session context
*/
void ssl_set_session( ssl_context *ssl, int resume, int timeout,
ssl_session *session );
/**
* \brief Set the list of allowed ciphersuites
*
* \param ssl SSL context
* \param ciphers 0-terminated list of allowed ciphers
*/
void ssl_set_ciphers( ssl_context *ssl, int *ciphers );
/**
* \brief Set the data required to verify peer certificate
*
* \param ssl SSL context
* \param ca_chain trusted CA chain
* \param ca_crl trusted CA CRLs
* \param peer_cn expected peer CommonName (or NULL)
*
* \note TODO: add two more parameters: depth and crl
*/
void ssl_set_ca_chain( ssl_context *ssl, x509_cert *ca_chain,
x509_crl *ca_crl, const char *peer_cn );
/**
* \brief Set own certificate and private key
*
* \param ssl SSL context
* \param own_cert own public certificate
* \param rsa_key own private RSA key
*/
void ssl_set_own_cert( ssl_context *ssl, x509_cert *own_cert,
rsa_context *rsa_key );
/**
* \brief Set the Diffie-Hellman public P and G values,
* read as hexadecimal strings (server-side only)
*
* \param ssl SSL context
* \param dhm_P Diffie-Hellman-Merkle modulus
* \param dhm_G Diffie-Hellman-Merkle generator
*
* \return 0 if successful
*/
int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G );
/**
* \brief Set hostname for ServerName TLS Extension
*
*
* \param ssl SSL context
* \param hostname the server hostname
*
* \return 0 if successful
*/
int ssl_set_hostname( ssl_context *ssl, const char *hostname );
/**
* \brief Return the number of data bytes available to read
*
* \param ssl SSL context
*
* \return how many bytes are available in the read buffer
*/
int ssl_get_bytes_avail( const ssl_context *ssl );
/**
* \brief Return the result of the certificate verification
*
* \param ssl SSL context
*
* \return 0 if successful, or a combination of:
* BADCERT_EXPIRED
* BADCERT_REVOKED
* BADCERT_CN_MISMATCH
* BADCERT_NOT_TRUSTED
*/
int ssl_get_verify_result( const ssl_context *ssl );
/**
* \brief Return the name of the current cipher
*
* \param ssl SSL context
*
* \return a string containing the cipher name
*/
const char *ssl_get_cipher( const ssl_context *ssl );
/**
* \brief Perform the SSL handshake
*
* \param ssl SSL context
*
* \return 0 if successful, POLARSSL_ERR_NET_TRY_AGAIN,
* or a specific SSL error code.
*/
int ssl_handshake( ssl_context *ssl );
/**
* \brief Read at most 'len' application data bytes
*
* \param ssl SSL context
* \param buf buffer that will hold the data
* \param len how many bytes must be read
*
* \return This function returns the number of bytes read,
* or a negative error code.
*/
int ssl_read( ssl_context *ssl, unsigned char *buf, int len );
/**
* \brief Write exactly 'len' application data bytes
*
* \param ssl SSL context
* \param buf buffer holding the data
* \param len how many bytes must be written
*
* \return This function returns the number of bytes written,
* or a negative error code.
*
* \note When this function returns POLARSSL_ERR_NET_TRY_AGAIN,
* it must be called later with the *same* arguments,
* until it returns a positive value.
*/
int ssl_write( ssl_context *ssl, const unsigned char *buf, int len );
/**
* \brief Notify the peer that the connection is being closed
*
* \param ssl SSL context
*/
int ssl_close_notify( ssl_context *ssl );
/**
* \brief Free an SSL context
*
* \param ssl SSL context
*/
void ssl_free( ssl_context *ssl );
/*
* Internal functions (do not call directly)
*/
int ssl_handshake_client( ssl_context *ssl );
int ssl_handshake_server( ssl_context *ssl );
int ssl_derive_keys( ssl_context *ssl );
void ssl_calc_verify( ssl_context *ssl, unsigned char hash[36] );
int ssl_read_record( ssl_context *ssl );
int ssl_fetch_input( ssl_context *ssl, int nb_want );
int ssl_write_record( ssl_context *ssl );
int ssl_flush_output( ssl_context *ssl );
int ssl_parse_certificate( ssl_context *ssl );
int ssl_write_certificate( ssl_context *ssl );
int ssl_parse_change_cipher_spec( ssl_context *ssl );
int ssl_write_change_cipher_spec( ssl_context *ssl );
int ssl_parse_finished( ssl_context *ssl );
int ssl_write_finished( ssl_context *ssl );
#ifdef __cplusplus
}
#endif
#endif /* ssl.h */

View File

@@ -0,0 +1,73 @@
/**
* \file timing.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_TIMING_H
#define POLARSSL_TIMING_H
/**
* \brief timer structure
*/
struct hr_time
{
unsigned char opaque[32];
};
#ifdef __cplusplus
extern "C" {
#endif
extern int alarmed;
/**
* \brief Return the CPU cycle counter value
*/
unsigned long hardclock( void );
/**
* \brief Return the elapsed time in milliseconds
*
* \param val points to a timer structure
* \param reset if set to 1, the timer is restarted
*/
unsigned long get_timer( struct hr_time *val, int reset );
/**
* \brief Setup an alarm clock
*
* \param seconds delay before the "alarmed" flag is set
*/
void set_alarm( int seconds );
/**
* \brief Sleep for a certain amount of time
*
* \param Delay in milliseconds
*/
void m_sleep( int milliseconds );
#ifdef __cplusplus
}
#endif
#endif /* timing.h */

View File

@@ -0,0 +1,78 @@
/**
* \file version.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This set of compile-time defines and run-time variables can be used to
* determine the version number of the PolarSSL library used.
*/
#ifndef POLARSSL_VERSION_H
#define POLARSSL_VERSION_H
#include "polarssl/config.h"
/**
* The version number x.y.z is split into three parts.
* Major, Minor, Patchlevel
*/
#define POLARSSL_VERSION_MAJOR 0
#define POLARSSL_VERSION_MINOR 14
#define POLARSSL_VERSION_PATCH 0
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define POLARSSL_VERSION_NUMBER 0x000E0000
#define POLARSSL_VERSION_STRING "0.14.0"
#define POLARSSL_VERSION_STRING_FULL "PolarSSL 0.14.0"
#if defined(POLARSSL_VERSION_C)
/**
* Get the version number.
*
* @return The constructed version number in the format
* MMNNPP00 (Major, Minor, Patch).
*/
unsigned int version_get_number();
/**
* Get the version string ("x.y.z").
*
* @param string The string that will receive the value.
* (Should be at least 9 bytes in size)
*/
void version_get_string( char *string );
/**
* Get the full version string ("PolarSSL x.y.z").
*
* @param string The string that will receive the value.
* (Should be at least 18 bytes in size)
*/
void version_get_string_full( char *string );
#endif /* POLARSSL_VERSION_C */
#endif /* version.h */

View File

@@ -0,0 +1,444 @@
/**
* \file x509.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_X509_H
#define POLARSSL_X509_H
#include "polarssl/rsa.h"
/*
* ASN1 Error codes
*
* These error codes will be OR'ed to X509 error codes for
* higher error granularity.
*/
#define POLARSSL_ERR_ASN1_OUT_OF_DATA 0x0014
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG 0x0016
#define POLARSSL_ERR_ASN1_INVALID_LENGTH 0x0018
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH 0x001A
#define POLARSSL_ERR_ASN1_INVALID_DATA 0x001C
/*
* X509 Error codes
*/
#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
/*
* X509 Verify codes
*/
#define BADCERT_EXPIRED 1
#define BADCERT_REVOKED 2
#define BADCERT_CN_MISMATCH 4
#define BADCERT_NOT_TRUSTED 8
#define BADCRL_NOT_TRUSTED 16
#define BADCRL_EXPIRED 32
/*
* DER constants
*/
#define ASN1_BOOLEAN 0x01
#define ASN1_INTEGER 0x02
#define ASN1_BIT_STRING 0x03
#define ASN1_OCTET_STRING 0x04
#define ASN1_NULL 0x05
#define ASN1_OID 0x06
#define ASN1_UTF8_STRING 0x0C
#define ASN1_SEQUENCE 0x10
#define ASN1_SET 0x11
#define ASN1_PRINTABLE_STRING 0x13
#define ASN1_T61_STRING 0x14
#define ASN1_IA5_STRING 0x16
#define ASN1_UTC_TIME 0x17
#define ASN1_GENERALIZED_TIME 0x18
#define ASN1_UNIVERSAL_STRING 0x1C
#define ASN1_BMP_STRING 0x1E
#define ASN1_PRIMITIVE 0x00
#define ASN1_CONSTRUCTED 0x20
#define ASN1_CONTEXT_SPECIFIC 0x80
/*
* various object identifiers
*/
#define X520_COMMON_NAME 3
#define X520_COUNTRY 6
#define X520_LOCALITY 7
#define X520_STATE 8
#define X520_ORGANIZATION 10
#define X520_ORG_UNIT 11
#define PKCS9_EMAIL 1
#define X509_OUTPUT_DER 0x01
#define X509_OUTPUT_PEM 0x02
#define PEM_LINE_LENGTH 72
#define X509_ISSUER 0x01
#define X509_SUBJECT 0x02
#define OID_X520 "\x55\x04"
#define OID_CN "\x55\x04\x03"
#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
#define OID_PKCS1_RSA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
#define OID_PKCS1_RSA_SHA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
#define OID_PKCS9_EMAIL "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
/*
* Structures for parsing X.509 certificates
*/
typedef struct _x509_buf
{
int tag;
int len;
unsigned char *p;
}
x509_buf;
typedef struct _x509_name
{
x509_buf oid;
x509_buf val;
struct _x509_name *next;
}
x509_name;
typedef struct _x509_time
{
int year, mon, day;
int hour, min, sec;
}
x509_time;
typedef struct _x509_cert
{
x509_buf raw;
x509_buf tbs;
int version;
x509_buf serial;
x509_buf sig_oid1;
x509_buf issuer_raw;
x509_buf subject_raw;
x509_name issuer;
x509_name subject;
x509_time valid_from;
x509_time valid_to;
x509_buf pk_oid;
rsa_context rsa;
x509_buf issuer_id;
x509_buf subject_id;
x509_buf v3_ext;
int ca_istrue;
int max_pathlen;
x509_buf sig_oid2;
x509_buf sig;
int sig_alg;
struct _x509_cert *next;
}
x509_cert;
typedef struct _x509_crl_entry
{
x509_buf raw;
x509_buf serial;
x509_time revocation_date;
x509_buf entry_ext;
struct _x509_crl_entry *next;
}
x509_crl_entry;
typedef struct _x509_crl
{
x509_buf raw;
x509_buf tbs;
int version;
x509_buf sig_oid1;
x509_buf issuer_raw;
x509_name issuer;
x509_time this_update;
x509_time next_update;
x509_crl_entry entry;
x509_buf crl_ext;
x509_buf sig_oid2;
x509_buf sig;
int sig_alg;
struct _x509_crl *next;
}
x509_crl;
/*
* Structures for writing X.509 certificates
*/
typedef struct _x509_node
{
unsigned char *data;
unsigned char *p;
unsigned char *end;
size_t len;
}
x509_node;
typedef struct _x509_raw
{
x509_node raw;
x509_node tbs;
x509_node version;
x509_node serial;
x509_node tbs_signalg;
x509_node issuer;
x509_node validity;
x509_node subject;
x509_node subpubkey;
x509_node signalg;
x509_node sign;
}
x509_raw;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Parse one or more certificates and add them
* to the chained list
*
* \param chain points to the start of the chain
* \param buf buffer holding the certificate data
* \param buflen size of the buffer
*
* \return 0 if successful, or a specific X509 error code
*/
int x509parse_crt( x509_cert *chain, const unsigned char *buf, int buflen );
/**
* \brief Load one or more certificates and add them
* to the chained list
*
* \param chain points to the start of the chain
* \param path filename to read the certificates from
*
* \return 0 if successful, or a specific X509 error code
*/
int x509parse_crtfile( x509_cert *chain, const char *path );
/**
* \brief Parse one or more CRLs and add them
* to the chained list
*
* \param chain points to the start of the chain
* \param buf buffer holding the CRL data
* \param buflen size of the buffer
*
* \return 0 if successful, or a specific X509 error code
*/
int x509parse_crl( x509_crl *chain, const unsigned char *buf, int buflen );
/**
* \brief Load one or more CRLs and add them
* to the chained list
*
* \param chain points to the start of the chain
* \param path filename to read the CRLs from
*
* \return 0 if successful, or a specific X509 error code
*/
int x509parse_crlfile( x509_crl *chain, const char *path );
/**
* \brief Parse a private RSA key
*
* \param rsa RSA context to be initialized
* \param key input buffer
* \param keylen size of the buffer
* \param pwd password for decryption (optional)
* \param pwdlen size of the password
*
* \return 0 if successful, or a specific X509 error code
*/
int x509parse_key( rsa_context *rsa,
const unsigned char *key, int keylen,
const unsigned char *pwd, int pwdlen );
/**
* \brief Load and parse a private RSA key
*
* \param rsa RSA context to be initialized
* \param path filename to read the private key from
* \param pwd password to decrypt the file (can be NULL)
*
* \return 0 if successful, or a specific X509 error code
*/
int x509parse_keyfile( rsa_context *rsa, const char *path,
const char *password );
/**
* \brief Store the certificate DN in printable form into buf;
* no more than size characters will be written.
*
* \param buf Buffer to write to
* \param size Maximum size of buffer
* \param dn The X509 name to represent
*
* \return The amount of data written to the buffer, or -1 in
* case of an error.
*/
int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn );
/**
* \brief Returns an informational string about the
* certificate.
*
* \param buf Buffer to write to
* \param size Maximum size of buffer
* \param prefix A line prefix
* \param crt The X509 certificate to represent
*
* \return The amount of data written to the buffer, or -1 in
* case of an error.
*/
int x509parse_cert_info( char *buf, size_t size, const char *prefix,
const x509_cert *crt );
/**
* \brief Returns an informational string about the
* CRL.
*
* \param buf Buffer to write to
* \param size Maximum size of buffer
* \param prefix A line prefix
* \param crt The X509 CRL to represent
*
* \return The amount of data written to the buffer, or -1 in
* case of an error.
*/
int x509parse_crl_info( char *buf, size_t size, const char *prefix,
const x509_crl *crl );
/**
* \brief Check a given x509_time against the system time and check
* if it is valid.
*
* \param time x509_time to check
*
* \return Return 0 if the x509_time is still valid,
* or 1 otherwise.
*/
int x509parse_time_expired( const x509_time *time );
/**
* \brief Verify the certificate signature
*
* \param crt a certificate to be verified
* \param trust_ca the trusted CA chain
* \param ca_crl the CRL chain for trusted CA's
* \param cn expected Common Name (can be set to
* NULL if the CN must not be verified)
* \param flags result of the verification
*
* \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
* in which case *flags will have one or more of
* the following values set:
* BADCERT_EXPIRED --
* BADCERT_REVOKED --
* BADCERT_CN_MISMATCH --
* BADCERT_NOT_TRUSTED
*
* \note TODO: add two arguments, depth and crl
*/
int x509parse_verify( x509_cert *crt,
x509_cert *trust_ca,
x509_crl *ca_crl,
const char *cn, int *flags );
/**
* \brief Unallocate all certificate data
*
* \param crt Certificate chain to free
*/
void x509_free( x509_cert *crt );
/**
* \brief Unallocate all CRL data
*
* \param crt CRL chain to free
*/
void x509_crl_free( x509_crl *crl );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int x509_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* x509.h */

View File

@@ -0,0 +1,86 @@
/**
* \file xtea.h
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_XTEA_H
#define POLARSSL_XTEA_H
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define XTEA_ENCRYPT 1
#define XTEA_DECRYPT 0
/**
* \brief XTEA context structure
*/
typedef struct
{
uint32_t k[4]; /*!< key */
}
xtea_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief XTEA key schedule
*
* \param ctx XTEA context to be initialized
* \param key the secret key
*/
void xtea_setup( xtea_context *ctx, unsigned char key[16] );
/**
* \brief XTEA cipher function
*
* \param ctx XTEA context
* \param mode XTEA_ENCRYPT or XTEA_DECRYPT
* \param input 8-byte input block
* \param output 8-byte output block
*
* \return 0 if successful
*/
int xtea_crypt_ecb( xtea_context *ctx,
int mode,
unsigned char input[8],
unsigned char output[8] );
/*
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int xtea_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* xtea.h */

View File

@@ -0,0 +1,28 @@
add_library(polarssl STATIC
aes.c
arc4.c
base64.c
bignum.c
camellia.c
certs.c
debug.c
des.c
dhm.c
havege.c
md2.c
md4.c
md5.c
net.c
padlock.c
rsa.c
sha1.c
sha2.c
sha4.c
ssl_cli.c
ssl_srv.c
ssl_tls.c
timing.c
version.c
x509parse.c
xtea.c
)

View File

@@ -0,0 +1,58 @@
# Also see "include/polarssl/config.h"
CFLAGS = -I../include -D_FILE_OFFSET_BITS=64 -Wall -Wdeclaration-after-statement
OFLAGS = -O
# MicroBlaze specific options:
# CFLAGS += -mno-xl-soft-mul -mxl-barrel-shift
# To compile on Plan9:
# CFLAGS += -D_BSD_EXTENSION
# To compile as a shared library:
# CFLAGS += -fPIC
DLEXT=so
# OSX shared library extension:
# DLEXT=dylib
OBJS= aes.o arc4.o base64.o \
bignum.o certs.o debug.o \
des.o dhm.o havege.o \
md2.o md4.o md5.o \
net.o padlock.o rsa.o \
sha1.o sha2.o sha4.o \
ssl_cli.o ssl_srv.o ssl_tls.o \
timing.o x509parse.o xtea.o \
camellia.o version.o
.SILENT:
all: static
static: libpolarssl.a
shared: libpolarssl.$(DLEXT)
libpolarssl.a: $(OBJS)
echo " AR $@"
ar r $@ $(OBJS)
echo " RL $@"
ranlib $@
libpolarssl.so: libpolarssl.a
echo " LD $@"
$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS)
libpolarssl.dylib: libpolarssl.a
echo " LD $@"
$(CC) -dynamiclib -o $@ $(OBJS)
.c.o:
echo " CC $<"
$(CC) $(CFLAGS) $(OFLAGS) -c $<
clean:
rm -f *.o libpolarssl.*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
/*
* An implementation of the ARCFOUR algorithm
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The ARCFOUR algorithm was publicly disclosed on 94/09.
*
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ARC4_C)
#include "polarssl/arc4.h"
/*
* ARC4 key schedule
*/
void arc4_setup( arc4_context *ctx, const unsigned char *key, int keylen )
{
int i, j, k, a;
unsigned char *m;
ctx->x = 0;
ctx->y = 0;
m = ctx->m;
for( i = 0; i < 256; i++ )
m[i] = (unsigned char) i;
j = k = 0;
for( i = 0; i < 256; i++, k++ )
{
if( k >= keylen ) k = 0;
a = m[i];
j = ( j + a + key[k] ) & 0xFF;
m[i] = m[j];
m[j] = (unsigned char) a;
}
}
/*
* ARC4 cipher function
*/
int arc4_crypt( arc4_context *ctx, int length, const unsigned char *input,
unsigned char *output )
{
int i, x, y, a, b;
unsigned char *m;
x = ctx->x;
y = ctx->y;
m = ctx->m;
for( i = 0; i < length; i++ )
{
x = ( x + 1 ) & 0xFF; a = m[x];
y = ( y + a ) & 0xFF; b = m[y];
m[x] = (unsigned char) b;
m[y] = (unsigned char) a;
output[i] = (unsigned char)
( input[i] ^ m[(unsigned char)( a + b )] );
}
ctx->x = x;
ctx->y = y;
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
/*
* ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
*
* http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
*/
static const unsigned char arc4_test_key[3][8] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char arc4_test_pt[3][8] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char arc4_test_ct[3][8] =
{
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
};
/*
* Checkup routine
*/
int arc4_self_test( int verbose )
{
int i;
unsigned char ibuf[8];
unsigned char obuf[8];
arc4_context ctx;
for( i = 0; i < 3; i++ )
{
if( verbose != 0 )
printf( " ARC4 test #%d: ", i + 1 );
memcpy( ibuf, arc4_test_pt[i], 8 );
arc4_setup( &ctx, (unsigned char *) arc4_test_key[i], 8 );
arc4_crypt( &ctx, 8, ibuf, obuf );
if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,254 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_BASE64_C)
#include "polarssl/base64.h"
static const unsigned char base64_enc_map[64] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'
};
static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 127, 127, 127, 127, 127
};
/*
* Encode a buffer into base64 format
*/
int base64_encode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen )
{
int i, n;
int C1, C2, C3;
unsigned char *p;
if( slen == 0 )
return( 0 );
n = (slen << 3) / 6;
switch( (slen << 3) - (n * 6) )
{
case 2: n += 3; break;
case 4: n += 2; break;
default: break;
}
if( *dlen < n + 1 )
{
*dlen = n + 1;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
n = (slen / 3) * 3;
for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if( i < slen )
{
C1 = *src++;
C2 = ((i + 1) < slen) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if( (i + 1) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';
*p++ = '=';
}
*dlen = p - dst;
*p = 0;
return( 0 );
}
/*
* Decode a base64-formatted buffer
*/
int base64_decode( unsigned char *dst, int *dlen,
const unsigned char *src, int slen )
{
int i, j, n;
unsigned long x;
unsigned char *p;
for( i = j = n = 0; i < slen; i++ )
{
if( ( slen - i ) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n' )
continue;
if( src[i] == '\n' )
continue;
if( src[i] == '=' && ++j > 2 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( base64_dec_map[src[i]] < 64 && j != 0 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
n++;
}
if( n == 0 )
return( 0 );
n = ((n * 6) + 7) >> 3;
if( *dlen < n )
{
*dlen = n;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '\r' || *src == '\n' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}
*dlen = p - dst;
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
static const unsigned char base64_test_dec[64] =
{
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
};
static const unsigned char base64_test_enc[] =
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
/*
* Checkup routine
*/
int base64_self_test( int verbose )
{
int len;
unsigned char *src, buffer[128];
if( verbose != 0 )
printf( " Base64 encoding test: " );
len = sizeof( buffer );
src = (unsigned char *) base64_test_dec;
if( base64_encode( buffer, &len, src, 64 ) != 0 ||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n Base64 decoding test: " );
len = sizeof( buffer );
src = (unsigned char *) base64_test_enc;
if( base64_decode( buffer, &len, src, 88 ) != 0 ||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n\n" );
return( 0 );
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,867 @@
/*
* Camellia implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The Camellia block cipher was designed by NTT and Mitsubishi Electric
* Corporation.
*
* http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_CAMELLIA_C)
#include "polarssl/camellia.h"
#include <string.h>
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
static const unsigned char SIGMA_CHARS[6][8] =
{
{ 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
{ 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
{ 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
{ 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
{ 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
{ 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
};
#ifdef POLARSSL_CAMELLIA_SMALL_MEMORY
static const unsigned char FSb[256] =
{
112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
};
#define SBOX1(n) FSb[(n)]
#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
#else
static const unsigned char FSb[256] =
{
112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
};
static const unsigned char FSb2[256] =
{
224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130,
70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123,
13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52,
77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154,
23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51,
191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175,
40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68,
253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160,
85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165,
32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41,
15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197,
164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92,
211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178,
240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245,
228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73,
128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61
};
static const unsigned char FSb3[256] =
{
56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160,
145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222,
67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13,
83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166,
197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204,
239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235,
10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17,
127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40,
85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105,
8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74,
195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23,
244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172,
60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125,
57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82,
32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79
};
static const unsigned char FSb4[256] =
{
112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146,
134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108,
139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4,
20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105,
170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221,
135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99,
233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141,
114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128,
130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189,
184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77,
13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215,
88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80,
208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148,
92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46,
121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250,
7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158
};
#define SBOX1(n) FSb[(n)]
#define SBOX2(n) FSb2[(n)]
#define SBOX3(n) FSb3[(n)]
#define SBOX4(n) FSb4[(n)]
#endif
static const unsigned char shifts[2][4][4] =
{
{
{ 1, 1, 1, 1 }, /* KL */
{ 0, 0, 0, 0 }, /* KR */
{ 1, 1, 1, 1 }, /* KA */
{ 0, 0, 0, 0 } /* KB */
},
{
{ 1, 0, 1, 1 }, /* KL */
{ 1, 1, 0, 1 }, /* KR */
{ 1, 1, 1, 0 }, /* KA */
{ 1, 1, 0, 1 } /* KB */
}
};
static const signed char indexes[2][4][20] =
{
{
{ 0, 1, 2, 3, 8, 9, 10, 11, 38, 39,
36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
{ 4, 5, 6, 7, 12, 13, 14, 15, 16, 17,
18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */
},
{
{ 0, 1, 2, 3, 61, 62, 63, 60, -1, -1,
-1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
{ -1, -1, -1, -1, 8, 9, 10, 11, 16, 17,
18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
{ -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
{ 4, 5, 6, 7, 65, 66, 67, 64, 20, 21,
22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */
}
};
static const signed char transposes[2][20] =
{
{
21, 22, 23, 20,
-1, -1, -1, -1,
18, 19, 16, 17,
11, 8, 9, 10,
15, 12, 13, 14
},
{
25, 26, 27, 24,
29, 30, 31, 28,
18, 19, 16, 17,
-1, -1, -1, -1,
-1, -1, -1, -1
}
};
/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
#define ROTL(DEST, SRC, SHIFT) \
{ \
(DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \
(DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \
(DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \
(DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \
}
#define FL(XL, XR, KL, KR) \
{ \
(XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \
(XL) = ((XR) | (KR)) ^ (XL); \
}
#define FLInv(YL, YR, KL, KR) \
{ \
(YL) = ((YR) | (KR)) ^ (YL); \
(YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \
}
#define SHIFT_AND_PLACE(INDEX, OFFSET) \
{ \
TK[0] = KC[(OFFSET) * 4 + 0]; \
TK[1] = KC[(OFFSET) * 4 + 1]; \
TK[2] = KC[(OFFSET) * 4 + 2]; \
TK[3] = KC[(OFFSET) * 4 + 3]; \
\
for ( i = 1; i <= 4; i++ ) \
if (shifts[(INDEX)][(OFFSET)][i -1]) \
ROTL(TK + i * 4, TK, (15 * i) % 32); \
\
for ( i = 0; i < 20; i++ ) \
if (indexes[(INDEX)][(OFFSET)][i] != -1) { \
RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \
} \
}
static void camellia_feistel(const uint32_t x[2], const uint32_t k[2], uint32_t z[2])
{
uint32_t I0, I1;
I0 = x[0] ^ k[0];
I1 = x[1] ^ k[1];
I0 = (SBOX1((I0 >> 24) & 0xFF) << 24) |
(SBOX2((I0 >> 16) & 0xFF) << 16) |
(SBOX3((I0 >> 8) & 0xFF) << 8) |
(SBOX4((I0 ) & 0xFF) );
I1 = (SBOX2((I1 >> 24) & 0xFF) << 24) |
(SBOX3((I1 >> 16) & 0xFF) << 16) |
(SBOX4((I1 >> 8) & 0xFF) << 8) |
(SBOX1((I1 ) & 0xFF) );
I0 ^= (I1 << 8) | (I1 >> 24);
I1 ^= (I0 << 16) | (I0 >> 16);
I0 ^= (I1 >> 8) | (I1 << 24);
I1 ^= (I0 >> 8) | (I0 << 24);
z[0] ^= I1;
z[1] ^= I0;
}
/*
* Camellia key schedule (encryption)
*/
int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, int keysize )
{
int i, idx;
uint32_t *RK;
unsigned char t[64];
uint32_t SIGMA[6][2];
uint32_t KC[16];
uint32_t TK[20];
RK = ctx->rk;
memset(t, 0, 64);
memset(RK, 0, sizeof(ctx->rk));
switch( keysize )
{
case 128: ctx->nr = 3; idx = 0; break;
case 192:
case 256: ctx->nr = 4; idx = 1; break;
default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH );
}
for( i = 0; i < keysize / 8; ++i)
t[i] = key[i];
if (keysize == 192) {
for (i = 0; i < 8; i++)
t[24 + i] = ~t[16 + i];
}
/*
* Prepare SIGMA values
*/
for (i = 0; i < 6; i++) {
GET_ULONG_BE(SIGMA[i][0], SIGMA_CHARS[i], 0);
GET_ULONG_BE(SIGMA[i][1], SIGMA_CHARS[i], 4);
}
/*
* Key storage in KC
* Order: KL, KR, KA, KB
*/
memset(KC, 0, sizeof(KC));
/* Store KL, KR */
for (i = 0; i < 8; i++)
GET_ULONG_BE(KC[i], t, i * 4);
/* Generate KA */
for( i = 0; i < 4; ++i)
KC[8 + i] = KC[i] ^ KC[4 + i];
camellia_feistel(KC + 8, SIGMA[0], KC + 10);
camellia_feistel(KC + 10, SIGMA[1], KC + 8);
for( i = 0; i < 4; ++i)
KC[8 + i] ^= KC[i];
camellia_feistel(KC + 8, SIGMA[2], KC + 10);
camellia_feistel(KC + 10, SIGMA[3], KC + 8);
if (keysize > 128) {
/* Generate KB */
for( i = 0; i < 4; ++i)
KC[12 + i] = KC[4 + i] ^ KC[8 + i];
camellia_feistel(KC + 12, SIGMA[4], KC + 14);
camellia_feistel(KC + 14, SIGMA[5], KC + 12);
}
/*
* Generating subkeys
*/
/* Manipulating KL */
SHIFT_AND_PLACE(idx, 0);
/* Manipulating KR */
if (keysize > 128) {
SHIFT_AND_PLACE(idx, 1);
}
/* Manipulating KA */
SHIFT_AND_PLACE(idx, 2);
/* Manipulating KB */
if (keysize > 128) {
SHIFT_AND_PLACE(idx, 3);
}
/* Do transpositions */
for ( i = 0; i < 20; i++ ) {
if (transposes[idx][i] != -1) {
RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
}
}
return( 0 );
}
/*
* Camellia key schedule (decryption)
*/
int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, int keysize )
{
int i, idx;
camellia_context cty;
uint32_t *RK;
uint32_t *SK;
int ret;
switch( keysize )
{
case 128: ctx->nr = 3; idx = 0; break;
case 192:
case 256: ctx->nr = 4; idx = 1; break;
default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH );
}
RK = ctx->rk;
ret = camellia_setkey_enc(&cty, key, keysize);
if( ret != 0 )
return( ret );
SK = cty.rk + 24 * 2 + 8 * idx * 2;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4)
{
*RK++ = *SK++;
*RK++ = *SK++;
}
SK -= 2;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
memset( &cty, 0, sizeof( camellia_context ) );
return( 0 );
}
/*
* Camellia-ECB block encryption/decryption
*/
int camellia_crypt_ecb( camellia_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
int NR;
uint32_t *RK, X[4];
( (void) mode );
NR = ctx->nr;
RK = ctx->rk;
GET_ULONG_BE( X[0], input, 0 );
GET_ULONG_BE( X[1], input, 4 );
GET_ULONG_BE( X[2], input, 8 );
GET_ULONG_BE( X[3], input, 12 );
X[0] ^= *RK++;
X[1] ^= *RK++;
X[2] ^= *RK++;
X[3] ^= *RK++;
while (NR) {
--NR;
camellia_feistel(X, RK, X + 2);
RK += 2;
camellia_feistel(X + 2, RK, X);
RK += 2;
camellia_feistel(X, RK, X + 2);
RK += 2;
camellia_feistel(X + 2, RK, X);
RK += 2;
camellia_feistel(X, RK, X + 2);
RK += 2;
camellia_feistel(X + 2, RK, X);
RK += 2;
if (NR) {
FL(X[0], X[1], RK[0], RK[1]);
RK += 2;
FLInv(X[2], X[3], RK[0], RK[1]);
RK += 2;
}
}
X[2] ^= *RK++;
X[3] ^= *RK++;
X[0] ^= *RK++;
X[1] ^= *RK++;
PUT_ULONG_BE( X[2], output, 0 );
PUT_ULONG_BE( X[3], output, 4 );
PUT_ULONG_BE( X[0], output, 8 );
PUT_ULONG_BE( X[1], output, 12 );
return( 0 );
}
/*
* Camellia-CBC buffer encryption/decryption
*/
int camellia_crypt_cbc( camellia_context *ctx,
int mode,
int length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[16];
if( length % 16 )
return( POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
if( mode == CAMELLIA_DECRYPT )
{
while( length > 0 )
{
memcpy( temp, input, 16 );
camellia_crypt_ecb( ctx, mode, input, output );
for( i = 0; i < 16; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 16 );
input += 16;
output += 16;
length -= 16;
}
}
else
{
while( length > 0 )
{
for( i = 0; i < 16; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
camellia_crypt_ecb( ctx, mode, output, output );
memcpy( iv, output, 16 );
input += 16;
output += 16;
length -= 16;
}
}
return( 0 );
}
/*
* Camellia-CFB128 buffer encryption/decryption
*/
int camellia_crypt_cfb128( camellia_context *ctx,
int mode,
int length,
int *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int c, n = *iv_off;
if( mode == CAMELLIA_DECRYPT )
{
while( length-- )
{
if( n == 0 )
camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, iv, iv );
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
n = (n + 1) & 0x0F;
}
}
else
{
while( length-- )
{
if( n == 0 )
camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, iv, iv );
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
n = (n + 1) & 0x0F;
}
}
*iv_off = n;
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <stdio.h>
/*
* Camellia test vectors from:
*
* http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
* http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
* http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
* (For each bitlength: Key 0, Nr 39)
*/
#define CAMELLIA_TESTS_ECB 2
static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
{
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
};
static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
{ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
{
{
{ 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
{ 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
},
{
{ 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
{ 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
},
{
{ 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
{ 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
}
};
#define CAMELLIA_TESTS_CBC 3
static const unsigned char camellia_test_cbc_key[3][32] =
{
{ 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
,
{ 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
,
{ 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
};
static const unsigned char camellia_test_cbc_iv[16] =
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
;
static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
{
{ 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
{ 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
{ 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
};
static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
{
{
{ 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
{ 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
{ 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
},
{
{ 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
{ 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
{ 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
},
{
{ 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
{ 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
{ 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
}
};
/*
* Checkup routine
*/
int camellia_self_test( int verbose )
{
int i, j, u, v;
unsigned char key[32];
unsigned char buf[64];
unsigned char src[16];
unsigned char dst[16];
unsigned char iv[16];
camellia_context ctx;
memset( key, 0, 32 );
for (j = 0; j < 6; j++) {
u = j >> 1;
v = j & 1;
if( verbose != 0 )
printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
(v == CAMELLIA_DECRYPT) ? "dec" : "enc");
for (i = 0; i < CAMELLIA_TESTS_ECB; i++ ) {
memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u);
if (v == CAMELLIA_DECRYPT) {
camellia_setkey_dec(&ctx, key, 128 + u * 64);
memcpy(src, camellia_test_ecb_cipher[u][i], 16);
memcpy(dst, camellia_test_ecb_plain[i], 16);
} else { /* CAMELLIA_ENCRYPT */
camellia_setkey_enc(&ctx, key, 128 + u * 64);
memcpy(src, camellia_test_ecb_plain[i], 16);
memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
}
camellia_crypt_ecb(&ctx, v, src, buf);
if( memcmp( buf, dst, 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
/*
* CBC mode
*/
for( j = 0; j < 6; j++ )
{
u = j >> 1;
v = j & 1;
if( verbose != 0 )
printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" );
memcpy( src, camellia_test_cbc_iv, 16);
memcpy( dst, camellia_test_cbc_iv, 16);
memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u);
if (v == CAMELLIA_DECRYPT) {
camellia_setkey_dec(&ctx, key, 128 + u * 64);
} else {
camellia_setkey_enc(&ctx, key, 128 + u * 64);
}
for (i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
if (v == CAMELLIA_DECRYPT) {
memcpy( iv , src, 16 );
memcpy(src, camellia_test_cbc_cipher[u][i], 16);
memcpy(dst, camellia_test_cbc_plain[i], 16);
} else { /* CAMELLIA_ENCRYPT */
memcpy( iv , dst, 16 );
memcpy(src, camellia_test_cbc_plain[i], 16);
memcpy(dst, camellia_test_cbc_cipher[u][i], 16);
}
camellia_crypt_cbc(&ctx, v, 16, iv, src, buf);
if( memcmp( buf, dst, 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return ( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,189 @@
/*
* X.509 test certificates
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_CERTS_C)
const char test_ca_crt[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
"MDkwMjA5MjExMjI1WhcNMTkwMjEwMjExMjI1WjA7MQswCQYDVQQGEwJOTDERMA8G\r\n"
"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n"
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwx0R6mZDvJbXcDZ+VFB+xpnewuZ/X\r\n"
"qf62aJjlUE0znqHTvx77cbPgNap54A/Qbyc6jLMrAWn0mCZHt7pAMNYVLwzkmr87\r\n"
"HuCXtq6Z06KJBeaCP1vtjT26zoum+ecNioktDwcDUkBrrPohnCjy4GNu3UVoxjec\r\n"
"dbx4dJzh8+q0KtWm+KPmor5MWjGywB0SgPszviqMqAnBBQ4LcS77e67SvMBb9TpZ\r\n"
"06I61vSf5VXENw9JRT2qiGp7sbAzgg8HF5RWr6/hXx/SwD/1TRbhtpkoRkNn4F9j\r\n"
"okTBJoQBiXPIU6Ak2iCXCAmO1XdDHjptkkBVhxJcjXlO8I2pZdGeYOfrAgMBAAGj\r\n"
"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUzyIxJ5HYwlT/HtrZ7orFiTKt\r\n"
"DCEwYwYDVR0jBFwwWoAUzyIxJ5HYwlT/HtrZ7orFiTKtDCGhP6Q9MDsxCzAJBgNV\r\n"
"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n"
"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAHBWXOUEAB6MHOjCCy54ByAnz6V9A\r\n"
"/DH1gZhsIaWIWV+YXE2cbE71C5vEBOEWb1kITVf+Dk9TwhBs0A0d57mEeR+UlKmE\r\n"
"g/jJLxxP35IZHmYQjjfVfBTv2cXIyLLBHrfqtsq6aMRjcunqO5YfECcaLVIPaHvq\r\n"
"gAXvfbb3UOiE81c4DWpZmMj7yVYfofr5lCmATJcAja1AYWjOzX1j7OPQGFuslfiV\r\n"
"qCTyUPLyjVfo46qGjP2KnlwCe4WfN4dwdbQUPR52SQ/vau+Vo6yvUaxgTGnPqhM/\r\n"
"oX3Yn5p+NZy1aXBoac1KKEu3jzHuB9eS9VRdtcl44abmFTf33T04R0Sx4g==\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_ca_key[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
"Proc-Type: 4,ENCRYPTED\r\n"
"DEK-Info: DES-EDE3-CBC,EB254D9A7718A8E2\r\n"
"\r\n"
"IOUSKEqvYM6tDkyyoAIxiDjZ/lzwCJAbONOxPnvNWL1bxMNYOMcwJxTh7P/EoC6Z\r\n"
"L+ubHlAAUystPRi+h63aZh8qBEai1KOixy5PjqbEKYczagBi5kTIyhCFwwiTiKzB\r\n"
"ygfFjC69wpkgWufKKJQ5skCYF8Pc7RlwKQeAnoPx/3xOFJUK3AHjHAbUhYWrDrqE\r\n"
"CywZYdnaGc9TiXNPcGmwLlgBLjp2zUOS2+lSt+rOjVh3BcaK9z1PRZSXsp20zC8D\r\n"
"1V3gRpbMPly+6BTOrxNuiiQzPK66Mn5g6BCyheanY3ArkM9PVZHmdFe4hvj/cu1L\r\n"
"Ps82XShxEF1IZ1XtqH3gtsJdpAJ7lp6f7/tvjDOokfw+tId3omT7iJJtRKBqYV/u\r\n"
"ujalWa4BU6Ek7yzexBfAe3C82xcn3TDoyXTCdJ3Jgz51cKO+22wTn/CsKh7excBM\r\n"
"ecl0hwhJumunc+Ftmf81qAAZuN4EPF/SxpwQgfBypZ+OqTWBTAvmIwg5dMq2U8Mj\r\n"
"iIXphhA7xbXiMS/yL+aK0vo8GbWVE7Qpwo1BiMfhxc2wxv/W8UpHH2O2WoWTfhUk\r\n"
"wpK2Nm9jteU3SHg76plc5Qf6JqiF7wVuW6mrs8hut0s+q352waAHkOocVA/3xy2A\r\n"
"qL99o/EkzniepORBFhHAJmYx9BolsVP5GQzokfRZkCkLRDm5b7rjx8J1kbWkiy7o\r\n"
"NqyLVfvOjdDBi8cgU1g1K1BVukCD3bL1TNFjfT55xccCYrsosLb7BJFOX8c38DKF\r\n"
"mXV9fQALqna0SKXoMRdU45JMVYQUp8CoLxWq9cCktzI7BCb0cWkTCwhgW3gOwSlO\r\n"
"zDXXzX9iJhb8ZTYIw53Fbi8+shG3DMoixqv8GvFqU3MmxeLEjde+eFHn/kdDugxF\r\n"
"CM6GLRJTf7URUr/H7ILLRxfgrbAk8XlT9CA8ykK+GKIbat0Q8NchW3k2PPNHo+s0\r\n"
"ya65JH6GfDWP29lM1WFxMC0e6Zxjs/ArId2IWCKXLiEjEnzcuAhYZ9d/e6nPbuSQ\r\n"
"oFEA1OfzGcmHJxWMuSX+boF02K/3Eun+fTQjUmD13qQza36MZVRfhlmcg/ztQy4R\r\n"
"JSwr/wJUu/gZql1T+S4sWBq/TZEW7TaAcBs/TE4mqHHrJH2jKmwPswvl58RE2GKS\r\n"
"JHa3CIpAiyqh09dSOsVS+inEISLgRoKQKHuscL0NhRYxB1Nv1sY5OTU8up2fRe4l\r\n"
"LUYwJ57/pEb2//W2XQRW3nUdV5kYTOdIZPaK4T+diK5LhpA2QydXx5aC9GBLEr7r\r\n"
"E+jO7IOJeESxOwjnreYJR2mNgT7QYch227iichheQ0OKRB+vKqnG/6uelH2QH4vJ\r\n"
"NhvEtLZfyrpC3/dEClbDA9akSxOEyzSx1B/t6K43qZe2IZejLGW8nhsi2ZPDxHjz\r\n"
"qrBef1sd91ySRAevsdsGHzCBiC8Ht0H4G76BLj3s611ww8vsOapJlpH2FrFKQo8R\r\n"
"LAdnwehGccL2rJtq1cb9nxwe1xKUQ2K6iew9ITImDup6q0YA9dvFLtoZAtfxMf4R\r\n"
"7qq3iAZUX0ZftEsM6sioiDhI/HBkUQOQd/2oxaYcEc480cMxf1DueA==\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
const char test_ca_pwd[] = "PolarSSLTest";
const char test_srv_crt[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDNzCCAh+gAwIBAgIBCTANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
"MDkwMjEwMjIxNTEyWhcNMTEwMjEwMjIxNTEyWjA0MQswCQYDVQQGEwJOTDERMA8G\r\n"
"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n"
"AQEBBQADggEPADCCAQoCggEBALAZHUNK4fFngHtEPyW5EPDxrK9Z+1zj5zJJ87eg\r\n"
"wZAngwQsCxv4PR7YwkBnekrAzatRdzTurqwJa3rLICOzRLF+eKCVUFk2lwRXmnZl\r\n"
"4Ah6CV5hFlnCNevgof2S9dV2w1fzZBkl/6njSFrJt613xYEkLceZ1aUVEmdpACrN\r\n"
"Tk9GQFF4NrUmFZxznNy9+f6sYtwKyKCeqgbp5ZTCvS9G1FQI19aYaR/eY/wJcPKZ\r\n"
"yGMn9wCWHq3D7s6A6HXOUGtsScjEkgSgJXwZbtbgQ0Uq1ypESgO5chekxwG5ToiM\r\n"
"gmMPu8KJmIaObdVeuwu/jNBvlxU5/hHJy97FWyxHZQcgts8CAwEAAaNNMEswCQYD\r\n"
"VR0TBAIwADAdBgNVHQ4EFgQUkgyLP+nT7m8II2IL0Wj9rKYRj18wHwYDVR0jBBgw\r\n"
"FoAUzyIxJ5HYwlT/HtrZ7orFiTKtDCEwDQYJKoZIhvcNAQEFBQADggEBAGlRaNdC\r\n"
"zAy6fShrCjZ1gc5Wp5qEgPdpFDNWHPC0faE3U/F77ExBgb7UPO0BY2GkeCz5wwPS\r\n"
"qwdbIrZ7Y2r5JPlP2JdxTYL0GlkgK5qxy4hl+pO7qvTnUDHQyLHguMymX37/VCXe\r\n"
"id8Sxf4PDsAUuz+Xt7Vor6sFc21i0MQrqy3CvC/TvgvnVYolwqwc9kCIjyGMvSHb\r\n"
"uZ+3s0Rby4zMpQj37vkfkr0P9S7Bc2yYep1Lk06x7H63S3/TxCwNAf66Z2Nqpewp\r\n"
"vQA6RrVDW/gnlOV7ooCalht7S3P7O8Yi3BF+J6aVvjsQ3uqBbTtx3wcTnCwjpifW\r\n"
"Brn4x0KTWpIPMpc=\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_srv_key[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
"MIIEowIBAAKCAQEAsBkdQ0rh8WeAe0Q/JbkQ8PGsr1n7XOPnMknzt6DBkCeDBCwL\r\n"
"G/g9HtjCQGd6SsDNq1F3NO6urAlressgI7NEsX54oJVQWTaXBFeadmXgCHoJXmEW\r\n"
"WcI16+Ch/ZL11XbDV/NkGSX/qeNIWsm3rXfFgSQtx5nVpRUSZ2kAKs1OT0ZAUXg2\r\n"
"tSYVnHOc3L35/qxi3ArIoJ6qBunllMK9L0bUVAjX1phpH95j/Alw8pnIYyf3AJYe\r\n"
"rcPuzoDodc5Qa2xJyMSSBKAlfBlu1uBDRSrXKkRKA7lyF6THAblOiIyCYw+7womY\r\n"
"ho5t1V67C7+M0G+XFTn+EcnL3sVbLEdlByC2zwIDAQABAoIBAF1B/5hKiNuCV61w\r\n"
"GA0PNCSVqED440BvRVoBhftCPB/ufNjxxjRaw2uZmU3oPwBlmMXYj8vNd12OY4gV\r\n"
"GIEvh/qDorhQOsv0OAfJqPh4vStgDaQYwHBqhInVXZRfhqc0jQD/2Yvj7sB2qDPE\r\n"
"Teyk2Eiq8z+YfWc+gI+ZMMh6D7W0+mukxeBuhF/+W1p5lPiLpTilJ9QwveVzeH3/\r\n"
"Wn8V5DNKtHXrBXoygrXfzqZWiOWZUruSgZFSgRhspGT9R7fSy1HogUykJE62h6ei\r\n"
"wMvi9AdQxLEBadwMZjCuOLU1TnymHMX5GMno8Zq7TISX7PfKA7fj5xIuueP1kyFg\r\n"
"UOb7VPkCgYEA3mx/VLBIFteCwSd1zv5bGVUk/O0HXNKqd3WUjgtacxNIYVjqostL\r\n"
"CSyQGClNAHvVS/1ba38eAhY7BKazwX/kPJ3x+lo0tgCZQ5uqo/4amI5OJNlWTH1O\r\n"
"7Xw5woyyjI84nJ1rtUSjG9/SxMpK21ZeTNvl2/kYVEt9AsmQLu6ogrUCgYEAyq5f\r\n"
"lTulZJd4NpjLz+gCSqdA5qaoGJ5x+J49uMgAGAthKLD5vrWV1XEI6t4bOhku69sp\r\n"
"MhDmauq6HYlbvhEfkaDXKBwHis/LkGCrWQ2TlTWRo6iqCfgGGSdoEOd04Z/3tpbN\r\n"
"9JVwpUJU+qjz/BZnF3Kx4gNKGy95W7wUlRyIMfMCgYAxLxTJCWIniuhjBfLLHvvO\r\n"
"EkHnnBJwuDTxzZJYBrKtl6n9vMfFz+Z71NrYPOnGHZwA/bllf+qG05uhX6uIMlup\r\n"
"+9MyZRga1u8NQDLvqJUA/xbQly66I0t8wGeVWb9xzYnbOARFRTQ8SbY1xfXfoq2f\r\n"
"mVCu39o9aaPvJds4RZYFsQKBgQCTY16qvSc3EVcgDNkZpZQVCa+Oi17uGDq1Gw2z\r\n"
"U+2Njqjm2FulLZN6FarwcPfHtgyDA2rft5533Z3eYMbQXs9gLWCJEGkDrrxPj5zL\r\n"
"M65A8SWpp7uPaEe2/wsUT9yVPqj6pIu88vdpleUKKtbSWNA7IvLscovvXQSZixpE\r\n"
"nO0FtQKBgEDDqxchzGIpKfi0sPSdt9TfOZADdI7Tc28U7ktWcVnArtGGyecwatr7\r\n"
"nZUP68MPjezyldQPT0OYQgnIHm6smDbEEGVomIHuIPwFT8bFNX6fCh1NQWzTaNtv\r\n"
"alggV/is0bHz2sGVtWTy0N8jAyFmlDxCWBcqaQ2hVP2910rQgUVd\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
const char test_cli_crt[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
"MDkwMjA5MjExMjM1WhcNMTEwMjA5MjExMjM1WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n"
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAodfTDCz/vIWD4rI8wlsV/pJ8Cbh7\r\n"
"3pA5GU1RJhvIvdOfZKtmeS4eLD/YBwnwSTSe997dSme1lryeerxq5BXyRQw9JjIz\r\n"
"p+X+8Rng4x2GMKjksV9gZVZJGFVM7vILO2TOIrQt1hjh9ZYDUZz0/6gmI86aJ+Uh\r\n"
"gxazzKdb4W1nLF7hI7tWKR8u5P/CAUO0uVrkbSunMfvuC9uYSXVTN3UdknXV3Ncs\r\n"
"4ecqxL4V9v9OpDiHy2Z4q026SuCqFRZ0LpvIk5bqv8ZsQFQ527tUTNydU0oAhlvv\r\n"
"/UpZxh645GkBAzvxOgMK1J8mUGCbiz10Ewdu+c3n1uqX4Q+LCJnsxClwMwIDAQAB\r\n"
"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSMBjiT2RQGKd/MzXERQzeO8EM4GzAf\r\n"
"BgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQUFAAOC\r\n"
"AQEAZra5syKfgQmS8p8i7N9HPMUY5AGDT2lbEYhzcabvJZXRI+BNmiW71qyoiIbM\r\n"
"Bm6pyUcsBqXcskq2W2xMD/lcvLTo0kp51Sdnnyw471tUtLwTDrpyc1Q3PTn84Rfr\r\n"
"WT7suINW0csyzhMBiGFwjvnOl5VGOLqhd47upIajMBK3EN97dBhFPFeqVNrlxcC1\r\n"
"e01dwMLnDdDyqzZbAqg+H25KqrIFnzWq1ibxXyeil26cVpUeTvtbS09Y93uNVBzl\r\n"
"00p4klj1ol+YY1TX/W0UX0kSmdAy1SrAxpek0fXCndy0bPC6++c+9YZhu4bp5JkK\r\n"
"7e7c+oTqh+DDfnbkF6NYJQeCvw==\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_cli_key[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
"MIIEpAIBAAKCAQEAodfTDCz/vIWD4rI8wlsV/pJ8Cbh73pA5GU1RJhvIvdOfZKtm\r\n"
"eS4eLD/YBwnwSTSe997dSme1lryeerxq5BXyRQw9JjIzp+X+8Rng4x2GMKjksV9g\r\n"
"ZVZJGFVM7vILO2TOIrQt1hjh9ZYDUZz0/6gmI86aJ+UhgxazzKdb4W1nLF7hI7tW\r\n"
"KR8u5P/CAUO0uVrkbSunMfvuC9uYSXVTN3UdknXV3Ncs4ecqxL4V9v9OpDiHy2Z4\r\n"
"q026SuCqFRZ0LpvIk5bqv8ZsQFQ527tUTNydU0oAhlvv/UpZxh645GkBAzvxOgMK\r\n"
"1J8mUGCbiz10Ewdu+c3n1uqX4Q+LCJnsxClwMwIDAQABAoIBAQCepSN6QfoF4JMh\r\n"
"ezpYAlWTECCKns69on52MPYk9wNWIMWUNvfiPbTSB1tJuxJRkEVsEIi3UOYN9qMb\r\n"
"COt23ZR43sBqWreME8ZOrOFngB90P3q97BJgA67vLV6Ws6kS9YOjPR/ZSNbml8B1\r\n"
"FfiLS1bnrrQp+09YYr6pFDzawxVpxaCfr6mpfDbXhoBw0NGpf54V4rIm4eNIf9Ro\r\n"
"QS54g/d0thID9OhMrc2NIpfRs4GkebsxOIKZP+uKF6CoS8IujyKjab/Vb3XBSknD\r\n"
"ObmiDx+udh8gRRGSpIG8rgoMcM8JhPAYitjYo3AiRTPTAUb4nSgQVOVxnRRZX8C1\r\n"
"QhvKOntBAoGBANAmX4KzOncoELOZPAZpkBlAhLNEqKT6RrfVokR9JAz3Jqhe+3tF\r\n"
"a0taSHF0aDi7YI5PgRGsV2Bowf81IIS3z2UqHCf+Eo0745jPiY33V+KSQkydJruN\r\n"
"u/n89imdhcIZdvZoxoVB8aRFDarBlzVq/FozqcpbtiGNs2ogbf+xS1dRAoGBAMcM\r\n"
"Swc0S0G2ncec34beGNH9mloyseMVspGhUWy/3rKLLBVf7XtEM4eDMopgMeceWQw9\r\n"
"wZo4Hr9Ip8k3Z4Ue8wV+MxtSLuGaxHGnHVxJtEE9OarhKlvEqHVAeeWvK4Cr0+ip\r\n"
"/zxnWDAA7QulMuWiK0LBEYOvTUXFet4z/l27/rZDAoGAchjWufosziw0G36fnJQ4\r\n"
"3N603t9/4g8evJ5qOEiwfjrsAdcu2r+OtNtkYmyAxLhRkTCbe2iQ7NP/ozkn/hgT\r\n"
"o0yV6oYm/Swa8iSxLhSrJBMwLHboSF7E759uABnMvDzhLOj6CQnAv17qwvMjQ7DF\r\n"
"a1xucfIbwADAnCfyo/o3ZkECgYEApfbGCDe+GAif/fP7HITKxSxjKpniYKmSvoJ3\r\n"
"VemVUeFg3GGjrYfsPy1RUrdqZH6VWPOVHXV1jaCS5d9gXUq07vuOuVUI6esVqH3i\r\n"
"qTR7K3pVPvmHTATpQPqFqNEpwJuEkRZNTpwMl9ntzCvuCDHzSDGa3OWp1GcYT3Wi\r\n"
"vZ0mf+kCgYBEPLnXD1BH7BlzEsMfXCtw28VtTetixcHcZVKwzQ4UH035DFYHch3p\r\n"
"/rABUO+IwxfcHjrvUJyZgHTyzfhtjWV62SsTNrOa1JFhQ+frWxIU5VEA7rVnLeaO\r\n"
"3vMGjy6jnBSaKoktW8ikY+4FHq+t5z63UN3RF367Iz0dWzIVocbxAQ==\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
#endif

View File

@@ -0,0 +1,212 @@
/*
* Debugging routines
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_DEBUG_C)
#include "polarssl/debug.h"
#include <stdarg.h>
#include <stdlib.h>
#if defined _MSC_VER && !defined snprintf
#define snprintf _snprintf
#endif
#if defined _MSC_VER && !defined vsnprintf
#define vsnprintf _vsnprintf
#endif
char *debug_fmt( const char *format, ... )
{
va_list argp;
static char str[512];
int maxlen = sizeof( str ) - 1;
va_start( argp, format );
vsnprintf( str, maxlen, format, argp );
va_end( argp );
str[maxlen] = '\0';
return( str );
}
void debug_print_msg( const ssl_context *ssl, int level,
const char *file, int line, const char *text )
{
char str[512];
int maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL )
return;
snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
void debug_print_ret( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret )
{
char str[512];
int maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL )
return;
snprintf( str, maxlen, "%s(%04d): %s() returned %d (0x%x)\n",
file, line, text, ret, ret );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
void debug_print_buf( const ssl_context *ssl, int level,
const char *file, int line, const char *text,
unsigned char *buf, int len )
{
char str[512];
int i, maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL || len < 0 )
return;
snprintf( str, maxlen, "%s(%04d): dumping '%s' (%d bytes)\n",
file, line, text, len );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
for( i = 0; i < len; i++ )
{
if( i >= 4096 )
break;
if( i % 16 == 0 )
{
if( i > 0 )
ssl->f_dbg( ssl->p_dbg, level, "\n" );
snprintf( str, maxlen, "%s(%04d): %04x: ", file, line, i );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
snprintf( str, maxlen, " %02x", (unsigned int) buf[i] );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
if( len > 0 )
ssl->f_dbg( ssl->p_dbg, level, "\n" );
}
void debug_print_mpi( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mpi *X )
{
char str[512];
int i, j, k, n, maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL || X == NULL )
return;
for( n = X->n - 1; n >= 0; n-- )
if( X->p[n] != 0 )
break;
snprintf( str, maxlen, "%s(%04d): value of '%s' (%lu bits) is:\n",
file, line, text,
(unsigned long) ((n + 1) * sizeof( t_int )) << 3 );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
for( i = n, j = 0; i >= 0; i--, j++ )
{
if( j % ( 16 / sizeof( t_int ) ) == 0 )
{
if( j > 0 )
ssl->f_dbg( ssl->p_dbg, level, "\n" );
snprintf( str, maxlen, "%s(%04d): ", file, line );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
for( k = sizeof( t_int ) - 1; k >= 0; k-- )
{
snprintf( str, maxlen, " %02x", (unsigned int)
( X->p[i] >> (k << 3) ) & 0xFF );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
}
ssl->f_dbg( ssl->p_dbg, level, "\n" );
}
void debug_print_crt( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const x509_cert *crt )
{
char str[1024], prefix[64];
int i = 0, maxlen = sizeof( prefix ) - 1;
if( ssl->f_dbg == NULL || crt == NULL )
return;
snprintf( prefix, maxlen, "%s(%04d): ", file, line );
prefix[maxlen] = '\0';
maxlen = sizeof( str ) - 1;
while( crt != NULL )
{
char buf[1024];
x509parse_cert_info( buf, sizeof( buf ) - 1, prefix, crt );
snprintf( str, maxlen, "%s(%04d): %s #%d:\n%s",
file, line, text, ++i, buf );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
debug_print_mpi( ssl, level, file, line,
"crt->rsa.N", &crt->rsa.N );
debug_print_mpi( ssl, level, file, line,
"crt->rsa.E", &crt->rsa.E );
crt = crt->next;
}
}
#endif

View File

@@ -0,0 +1,895 @@
/*
* FIPS-46-3 compliant Triple-DES implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* DES, on which TDES is based, was originally designed by Horst Feistel
* at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
*
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_DES_C)
#include "polarssl/des.h"
#include <string.h>
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* Expanded DES S-boxes
*/
static const unsigned long SB1[64] =
{
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
static const unsigned long SB2[64] =
{
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
static const unsigned long SB3[64] =
{
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
static const unsigned long SB4[64] =
{
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
static const unsigned long SB5[64] =
{
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
static const unsigned long SB6[64] =
{
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
static const unsigned long SB7[64] =
{
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
static const unsigned long SB8[64] =
{
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/*
* PC1: left and right halves bit-swap
*/
static const unsigned long LHs[16] =
{
0x00000000, 0x00000001, 0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101,
0x01010000, 0x01010001, 0x01010100, 0x01010101
};
static const unsigned long RHs[16] =
{
0x00000000, 0x01000000, 0x00010000, 0x01010000,
0x00000100, 0x01000100, 0x00010100, 0x01010100,
0x00000001, 0x01000001, 0x00010001, 0x01010001,
0x00000101, 0x01000101, 0x00010101, 0x01010101,
};
/*
* Initial Permutation macro
*/
#define DES_IP(X,Y) \
{ \
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
}
/*
* Final Permutation macro
*/
#define DES_FP(X,Y) \
{ \
X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
}
/*
* DES round macro
*/
#define DES_ROUND(X,Y) \
{ \
T = *SK++ ^ X; \
Y ^= SB8[ (T ) & 0x3F ] ^ \
SB6[ (T >> 8) & 0x3F ] ^ \
SB4[ (T >> 16) & 0x3F ] ^ \
SB2[ (T >> 24) & 0x3F ]; \
\
T = *SK++ ^ ((X << 28) | (X >> 4)); \
Y ^= SB7[ (T ) & 0x3F ] ^ \
SB5[ (T >> 8) & 0x3F ] ^ \
SB3[ (T >> 16) & 0x3F ] ^ \
SB1[ (T >> 24) & 0x3F ]; \
}
#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
static void des_setkey( unsigned long SK[32], const unsigned char key[8] )
{
int i;
unsigned long X, Y, T;
GET_ULONG_BE( X, key, 0 );
GET_ULONG_BE( Y, key, 4 );
/*
* Permuted Choice 1
*/
T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
| (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
| (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
| (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
| (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
| (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
| (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
X &= 0x0FFFFFFF;
Y &= 0x0FFFFFFF;
/*
* calculate subkeys
*/
for( i = 0; i < 16; i++ )
{
if( i < 2 || i == 8 || i == 15 )
{
X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
}
else
{
X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
}
*SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
| ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
| ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
| ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
| ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
| ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
| ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
| ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
| ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
| ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
| ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
*SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
| ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
| ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
| ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
| ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
| ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
| ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
| ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
| ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
| ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
| ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
}
}
/*
* DES key schedule (56-bit, encryption)
*/
void des_setkey_enc( des_context *ctx, const unsigned char key[8] )
{
des_setkey( ctx->sk, key );
}
/*
* DES key schedule (56-bit, decryption)
*/
void des_setkey_dec( des_context *ctx, const unsigned char key[8] )
{
int i;
des_setkey( ctx->sk, key );
for( i = 0; i < 16; i += 2 )
{
SWAP( ctx->sk[i ], ctx->sk[30 - i] );
SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
}
}
static void des3_set2key( unsigned long esk[96],
unsigned long dsk[96],
const unsigned char key[16] )
{
int i;
des_setkey( esk, key );
des_setkey( dsk + 32, key + 8 );
for( i = 0; i < 32; i += 2 )
{
dsk[i ] = esk[30 - i];
dsk[i + 1] = esk[31 - i];
esk[i + 32] = dsk[62 - i];
esk[i + 33] = dsk[63 - i];
esk[i + 64] = esk[i ];
esk[i + 65] = esk[i + 1];
dsk[i + 64] = dsk[i ];
dsk[i + 65] = dsk[i + 1];
}
}
/*
* Triple-DES key schedule (112-bit, encryption)
*/
void des3_set2key_enc( des3_context *ctx, const unsigned char key[16] )
{
unsigned long sk[96];
des3_set2key( ctx->sk, sk, key );
memset( sk, 0, sizeof( sk ) );
}
/*
* Triple-DES key schedule (112-bit, decryption)
*/
void des3_set2key_dec( des3_context *ctx, const unsigned char key[16] )
{
unsigned long sk[96];
des3_set2key( sk, ctx->sk, key );
memset( sk, 0, sizeof( sk ) );
}
static void des3_set3key( unsigned long esk[96],
unsigned long dsk[96],
const unsigned char key[24] )
{
int i;
des_setkey( esk, key );
des_setkey( dsk + 32, key + 8 );
des_setkey( esk + 64, key + 16 );
for( i = 0; i < 32; i += 2 )
{
dsk[i ] = esk[94 - i];
dsk[i + 1] = esk[95 - i];
esk[i + 32] = dsk[62 - i];
esk[i + 33] = dsk[63 - i];
dsk[i + 64] = esk[30 - i];
dsk[i + 65] = esk[31 - i];
}
}
/*
* Triple-DES key schedule (168-bit, encryption)
*/
void des3_set3key_enc( des3_context *ctx, const unsigned char key[24] )
{
unsigned long sk[96];
des3_set3key( ctx->sk, sk, key );
memset( sk, 0, sizeof( sk ) );
}
/*
* Triple-DES key schedule (168-bit, decryption)
*/
void des3_set3key_dec( des3_context *ctx, const unsigned char key[24] )
{
unsigned long sk[96];
des3_set3key( sk, ctx->sk, key );
memset( sk, 0, sizeof( sk ) );
}
/*
* DES-ECB block encryption/decryption
*/
int des_crypt_ecb( des_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
int i;
unsigned long X, Y, T, *SK;
SK = ctx->sk;
GET_ULONG_BE( X, input, 0 );
GET_ULONG_BE( Y, input, 4 );
DES_IP( X, Y );
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
DES_FP( Y, X );
PUT_ULONG_BE( Y, output, 0 );
PUT_ULONG_BE( X, output, 4 );
return( 0 );
}
/*
* DES-CBC buffer encryption/decryption
*/
int des_crypt_cbc( des_context *ctx,
int mode,
int length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[8];
if( length % 8 )
return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
if( mode == DES_ENCRYPT )
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
des_crypt_ecb( ctx, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else /* DES_DECRYPT */
{
while( length > 0 )
{
memcpy( temp, input, 8 );
des_crypt_ecb( ctx, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
/*
* 3DES-ECB block encryption/decryption
*/
int des3_crypt_ecb( des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
int i;
unsigned long X, Y, T, *SK;
SK = ctx->sk;
GET_ULONG_BE( X, input, 0 );
GET_ULONG_BE( Y, input, 4 );
DES_IP( X, Y );
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
for( i = 0; i < 8; i++ )
{
DES_ROUND( X, Y );
DES_ROUND( Y, X );
}
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
DES_FP( Y, X );
PUT_ULONG_BE( Y, output, 0 );
PUT_ULONG_BE( X, output, 4 );
return( 0 );
}
/*
* 3DES-CBC buffer encryption/decryption
*/
int des3_crypt_cbc( des3_context *ctx,
int mode,
int length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[8];
if( length % 8 )
return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
if( mode == DES_ENCRYPT )
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
des3_crypt_ecb( ctx, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else /* DES_DECRYPT */
{
while( length > 0 )
{
memcpy( temp, input, 8 );
des3_crypt_ecb( ctx, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <stdio.h>
/*
* DES and 3DES test vectors from:
*
* http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
*/
static const unsigned char des3_test_keys[24] =
{
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
};
static const unsigned char des3_test_iv[8] =
{
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
};
static const unsigned char des3_test_buf[8] =
{
0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
};
static const unsigned char des3_test_ecb_dec[3][8] =
{
{ 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
{ 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
{ 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
};
static const unsigned char des3_test_ecb_enc[3][8] =
{
{ 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
{ 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
{ 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
};
static const unsigned char des3_test_cbc_dec[3][8] =
{
{ 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
{ 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
{ 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
};
static const unsigned char des3_test_cbc_enc[3][8] =
{
{ 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
{ 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
{ 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
};
/*
* Checkup routine
*/
int des_self_test( int verbose )
{
int i, j, u, v;
des_context ctx;
des3_context ctx3;
unsigned char key[24];
unsigned char buf[8];
unsigned char prv[8];
unsigned char iv[8];
memset( key, 0, 24 );
/*
* ECB mode
*/
for( i = 0; i < 6; i++ )
{
u = i >> 1;
v = i & 1;
if( verbose != 0 )
printf( " DES%c-ECB-%3d (%s): ",
( u == 0 ) ? ' ' : '3', 56 + u * 56,
( v == DES_DECRYPT ) ? "dec" : "enc" );
memcpy( buf, des3_test_buf, 8 );
switch( i )
{
case 0:
des_setkey_dec( &ctx, (unsigned char *) des3_test_keys );
break;
case 1:
des_setkey_enc( &ctx, (unsigned char *) des3_test_keys );
break;
case 2:
des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys );
break;
case 3:
des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys );
break;
case 4:
des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys );
break;
case 5:
des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys );
break;
default:
return( 1 );
}
for( j = 0; j < 10000; j++ )
{
if( u == 0 )
des_crypt_ecb( &ctx, buf, buf );
else
des3_crypt_ecb( &ctx3, buf, buf );
}
if( ( v == DES_DECRYPT &&
memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
( v != DES_DECRYPT &&
memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
/*
* CBC mode
*/
for( i = 0; i < 6; i++ )
{
u = i >> 1;
v = i & 1;
if( verbose != 0 )
printf( " DES%c-CBC-%3d (%s): ",
( u == 0 ) ? ' ' : '3', 56 + u * 56,
( v == DES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, des3_test_iv, 8 );
memcpy( prv, des3_test_iv, 8 );
memcpy( buf, des3_test_buf, 8 );
switch( i )
{
case 0:
des_setkey_dec( &ctx, (unsigned char *) des3_test_keys );
break;
case 1:
des_setkey_enc( &ctx, (unsigned char *) des3_test_keys );
break;
case 2:
des3_set2key_dec( &ctx3, (unsigned char *) des3_test_keys );
break;
case 3:
des3_set2key_enc( &ctx3, (unsigned char *) des3_test_keys );
break;
case 4:
des3_set3key_dec( &ctx3, (unsigned char *) des3_test_keys );
break;
case 5:
des3_set3key_enc( &ctx3, (unsigned char *) des3_test_keys );
break;
default:
return( 1 );
}
if( v == DES_DECRYPT )
{
for( j = 0; j < 10000; j++ )
{
if( u == 0 )
des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
else
des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
}
}
else
{
for( j = 0; j < 10000; j++ )
{
unsigned char tmp[8];
if( u == 0 )
des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
else
des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
memcpy( tmp, prv, 8 );
memcpy( prv, buf, 8 );
memcpy( buf, tmp, 8 );
}
memcpy( buf, prv, 8 );
}
if( ( v == DES_DECRYPT &&
memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
( v != DES_DECRYPT &&
memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,260 @@
/*
* Diffie-Hellman-Merkle key exchange
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Reference:
*
* http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12)
*/
#include "polarssl/config.h"
#if defined(POLARSSL_DHM_C)
#include "polarssl/dhm.h"
#include <string.h>
/*
* helper to validate the mpi size and import it
*/
static int dhm_read_bignum( mpi *X,
unsigned char **p,
const unsigned char *end )
{
int ret, n;
if( end - *p < 2 )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
n = ( (*p)[0] << 8 ) | (*p)[1];
(*p) += 2;
if( (int)( end - *p ) < n )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mpi_read_binary( X, *p, n ) ) != 0 )
return( POLARSSL_ERR_DHM_READ_PARAMS_FAILED | ret );
(*p) += n;
return( 0 );
}
/*
* Parse the ServerKeyExchange parameters
*/
int dhm_read_params( dhm_context *ctx,
unsigned char **p,
const unsigned char *end )
{
int ret, n;
memset( ctx, 0, sizeof( dhm_context ) );
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
return( ret );
ctx->len = mpi_size( &ctx->P );
if( end - *p < 2 )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
n = ( (*p)[0] << 8 ) | (*p)[1];
(*p) += 2;
if( end != *p + n )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
return( 0 );
}
/*
* Setup and write the ServerKeyExchange parameters
*/
int dhm_make_params( dhm_context *ctx, int x_size,
unsigned char *output, int *olen,
int (*f_rng)(void *), void *p_rng )
{
int i, ret, n, n1, n2, n3;
unsigned char *p;
/*
* Generate X as large as possible ( < P )
*/
n = x_size / sizeof( t_int );
MPI_CHK( mpi_grow( &ctx->X, n ) );
MPI_CHK( mpi_lset( &ctx->X, 0 ) );
p = (unsigned char *) ctx->X.p;
for( i = 0; i < x_size - 1; i++ )
*p++ = (unsigned char) f_rng( p_rng );
while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
mpi_shift_r( &ctx->X, 1 );
/*
* Calculate GX = G^X mod P
*/
MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
&ctx->P , &ctx->RP ) );
/*
* export P, G, GX
*/
#define DHM_MPI_EXPORT(X,n) \
MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \
*p++ = (unsigned char)( n >> 8 ); \
*p++ = (unsigned char)( n ); p += n;
n1 = mpi_size( &ctx->P );
n2 = mpi_size( &ctx->G );
n3 = mpi_size( &ctx->GX );
p = output;
DHM_MPI_EXPORT( &ctx->P , n1 );
DHM_MPI_EXPORT( &ctx->G , n2 );
DHM_MPI_EXPORT( &ctx->GX, n3 );
*olen = p - output;
ctx->len = n1;
cleanup:
if( ret != 0 )
return( ret | POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED );
return( 0 );
}
/*
* Import the peer's public value G^Y
*/
int dhm_read_public( dhm_context *ctx,
const unsigned char *input, int ilen )
{
int ret;
if( ctx == NULL || ilen < 1 || ilen > ctx->len )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
return( POLARSSL_ERR_DHM_READ_PUBLIC_FAILED | ret );
return( 0 );
}
/*
* Create own private value X and export G^X
*/
int dhm_make_public( dhm_context *ctx, int x_size,
unsigned char *output, int olen,
int (*f_rng)(void *), void *p_rng )
{
int ret, i, n;
unsigned char *p;
if( ctx == NULL || olen < 1 || olen > ctx->len )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
/*
* generate X and calculate GX = G^X mod P
*/
n = x_size / sizeof( t_int );
MPI_CHK( mpi_grow( &ctx->X, n ) );
MPI_CHK( mpi_lset( &ctx->X, 0 ) );
n = x_size - 1;
p = (unsigned char *) ctx->X.p;
for( i = 0; i < n; i++ )
*p++ = (unsigned char) f_rng( p_rng );
while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
mpi_shift_r( &ctx->X, 1 );
MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
&ctx->P , &ctx->RP ) );
MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) );
cleanup:
if( ret != 0 )
return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED | ret );
return( 0 );
}
/*
* Derive and export the shared secret (G^Y)^X mod P
*/
int dhm_calc_secret( dhm_context *ctx,
unsigned char *output, int *olen )
{
int ret;
if( ctx == NULL || *olen < ctx->len )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
MPI_CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X,
&ctx->P, &ctx->RP ) );
*olen = mpi_size( &ctx->K );
MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) );
cleanup:
if( ret != 0 )
return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED | ret );
return( 0 );
}
/*
* Free the components of a DHM key
*/
void dhm_free( dhm_context *ctx )
{
mpi_free( &ctx->RP, &ctx->K, &ctx->GY,
&ctx->GX, &ctx->X, &ctx->G,
&ctx->P, NULL );
}
#if defined(POLARSSL_SELF_TEST)
/*
* Checkup routine
*/
int dhm_self_test( int verbose )
{
return( verbose++ );
}
#endif
#endif

View File

@@ -0,0 +1,266 @@
/*
* HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The HAVEGE RNG was designed by Andre Seznec in 2002.
*
* http://www.irisa.fr/caps/projects/hipsor/publi.php
*
* Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
*/
#include <string.h>
#include <time.h>
#include "polarssl/config.h"
#if defined(POLARSSL_HAVEGE_C)
#include "polarssl/havege.h"
#include "polarssl/timing.h"
/* ------------------------------------------------------------------------
* On average, one iteration accesses two 8-word blocks in the havege WALK
* table, and generates 16 words in the RES array.
*
* The data read in the WALK table is updated and permuted after each use.
* The result of the hardware clock counter read is used for this update.
*
* 25 conditional tests are present. The conditional tests are grouped in
* two nested groups of 12 conditional tests and 1 test that controls the
* permutation; on average, there should be 6 tests executed and 3 of them
* should be mispredicted.
* ------------------------------------------------------------------------
*/
#define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST1_LEAVE U1++; }
#define TST2_LEAVE U2++; }
#define ONE_ITERATION \
\
PTEST = PT1 >> 20; \
\
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
\
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
\
PTX = (PT1 >> 18) & 7; \
PT1 &= 0x1FFF; \
PT2 &= 0x1FFF; \
CLK = (int) hardclock(); \
\
i = 0; \
A = &WALK[PT1 ]; RES[i++] ^= *A; \
B = &WALK[PT2 ]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
\
IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
*A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
*B = IN ^ U1; \
*C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
*D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
\
A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
\
if( PTEST & 1 ) SWAP( A, C ); \
\
IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
*A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
*B = IN; CLK = (int) hardclock(); \
*C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
*D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
\
A = &WALK[PT1 ^ 4]; \
B = &WALK[PT2 ^ 1]; \
\
PTEST = PT2 >> 1; \
\
PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
PTY = (PT2 >> 10) & 7; \
\
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
\
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
\
C = &WALK[PT1 ^ 5]; \
D = &WALK[PT2 ^ 5]; \
\
RES[i++] ^= *A; \
RES[i++] ^= *B; \
RES[i++] ^= *C; \
RES[i++] ^= *D; \
\
IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
*A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
*B = IN ^ U2; \
*C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
*D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
\
A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
\
IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
*A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
*B = IN; \
*C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
*D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
\
PT1 = ( RES[(i - 8) ^ PTX] ^ \
WALK[PT1 ^ PTX ^ 7] ) & (~1); \
PT1 ^= (PT2 ^ 0x10) & 0x10; \
\
for( n++, i = 0; i < 16; i++ ) \
hs->pool[n % COLLECT_SIZE] ^= RES[i];
/*
* Entropy gathering function
*/
static void havege_fill( havege_state *hs )
{
int i, n = 0;
int U1, U2, *A, *B, *C, *D;
int PT1, PT2, *WALK, RES[16];
int PTX, PTY, CLK, PTEST, IN;
WALK = hs->WALK;
PT1 = hs->PT1;
PT2 = hs->PT2;
PTX = U1 = 0;
PTY = U2 = 0;
memset( RES, 0, sizeof( RES ) );
while( n < COLLECT_SIZE * 4 )
{
ONE_ITERATION
ONE_ITERATION
ONE_ITERATION
ONE_ITERATION
}
hs->PT1 = PT1;
hs->PT2 = PT2;
hs->offset[0] = 0;
hs->offset[1] = COLLECT_SIZE / 2;
}
/*
* HAVEGE initialization
*/
void havege_init( havege_state *hs )
{
memset( hs, 0, sizeof( havege_state ) );
havege_fill( hs );
}
/*
* HAVEGE rand function
*/
int havege_rand( void *p_rng )
{
int ret;
havege_state *hs = (havege_state *) p_rng;
if( hs->offset[1] >= COLLECT_SIZE )
havege_fill( hs );
ret = hs->pool[hs->offset[0]++];
ret ^= hs->pool[hs->offset[1]++];
return( ret );
}
#if defined(POLARSSL_RAND_TEST)
#include <stdio.h>
int main( int argc, char *argv[] )
{
FILE *f;
time_t t;
int i, j, k;
havege_state hs;
unsigned char buf[1024];
if( argc < 2 )
{
fprintf( stderr, "usage: %s <output filename>\n", argv[0] );
return( 1 );
}
if( ( f = fopen( argv[1], "wb+" ) ) == NULL )
{
printf( "failed to open '%s' for writing.\n", argv[0] );
return( 1 );
}
havege_init( &hs );
t = time( NULL );
for( i = 0, k = 32768; i < k; i++ )
{
for( j = 0; j < sizeof( buf ); j++ )
buf[j] = havege_rand( &hs );
fwrite( buf, sizeof( buf ), 1, f );
printf( "Generating 32Mb of data in file '%s'... %04.1f" \
"%% done\r", argv[1], (100 * (float) (i + 1)) / k );
fflush( stdout );
}
if( t == time( NULL ) )
t--;
fclose( f );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,361 @@
/*
* RFC 1115/1319 compliant MD2 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD2 algorithm was designed by Ron Rivest in 1989.
*
* http://www.ietf.org/rfc/rfc1115.txt
* http://www.ietf.org/rfc/rfc1319.txt
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD2_C)
#include "polarssl/md2.h"
#include <string.h>
#include <stdio.h>
static const unsigned char PI_SUBST[256] =
{
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
};
/*
* MD2 context setup
*/
void md2_starts( md2_context *ctx )
{
memset( ctx->cksum, 0, 16 );
memset( ctx->state, 0, 46 );
memset( ctx->buffer, 0, 16 );
ctx->left = 0;
}
static void md2_process( md2_context *ctx )
{
int i, j;
unsigned char t = 0;
for( i = 0; i < 16; i++ )
{
ctx->state[i + 16] = ctx->buffer[i];
ctx->state[i + 32] =
(unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
}
for( i = 0; i < 18; i++ )
{
for( j = 0; j < 48; j++ )
{
ctx->state[j] = (unsigned char)
( ctx->state[j] ^ PI_SUBST[t] );
t = ctx->state[j];
}
t = (unsigned char)( t + i );
}
t = ctx->cksum[15];
for( i = 0; i < 16; i++ )
{
ctx->cksum[i] = (unsigned char)
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
t = ctx->cksum[i];
}
}
/*
* MD2 process buffer
*/
void md2_update( md2_context *ctx, const unsigned char *input, int ilen )
{
int fill;
while( ilen > 0 )
{
if( ctx->left + ilen > 16 )
fill = 16 - ctx->left;
else
fill = ilen;
memcpy( ctx->buffer + ctx->left, input, fill );
ctx->left += fill;
input += fill;
ilen -= fill;
if( ctx->left == 16 )
{
ctx->left = 0;
md2_process( ctx );
}
}
}
/*
* MD2 final digest
*/
void md2_finish( md2_context *ctx, unsigned char output[16] )
{
int i;
unsigned char x;
x = (unsigned char)( 16 - ctx->left );
for( i = ctx->left; i < 16; i++ )
ctx->buffer[i] = x;
md2_process( ctx );
memcpy( ctx->buffer, ctx->cksum, 16 );
md2_process( ctx );
memcpy( output, ctx->state, 16 );
}
/*
* output = MD2( input buffer )
*/
void md2( const unsigned char *input, int ilen, unsigned char output[16] )
{
md2_context ctx;
md2_starts( &ctx );
md2_update( &ctx, input, ilen );
md2_finish( &ctx, output );
memset( &ctx, 0, sizeof( md2_context ) );
}
/*
* output = MD2( file contents )
*/
int md2_file( const char *path, unsigned char output[16] )
{
FILE *f;
size_t n;
md2_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
md2_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md2_update( &ctx, buf, (int) n );
md2_finish( &ctx, output );
memset( &ctx, 0, sizeof( md2_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* MD2 HMAC context setup
*/
void md2_hmac_starts( md2_context *ctx, const unsigned char *key, int keylen )
{
int i;
unsigned char sum[16];
if( keylen > 64 )
{
md2( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md2_starts( ctx );
md2_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* MD2 HMAC process buffer
*/
void md2_hmac_update( md2_context *ctx, const unsigned char *input, int ilen )
{
md2_update( ctx, input, ilen );
}
/*
* MD2 HMAC final digest
*/
void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md2_finish( ctx, tmpbuf );
md2_starts( ctx );
md2_update( ctx, ctx->opad, 64 );
md2_update( ctx, tmpbuf, 16 );
md2_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* MD2 HMAC context reset
*/
void md2_hmac_reset( md2_context *ctx )
{
md2_starts( ctx );
md2_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-MD2( hmac key, input buffer )
*/
void md2_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[16] )
{
md2_context ctx;
md2_hmac_starts( &ctx, key, keylen );
md2_hmac_update( &ctx, input, ilen );
md2_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md2_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* RFC 1319 test vectors
*/
static const char md2_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const unsigned char md2_test_sum[7][16] =
{
{ 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
{ 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
{ 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
{ 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
{ 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
{ 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
{ 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
};
/*
* Checkup routine
*/
int md2_self_test( int verbose )
{
int i;
unsigned char md2sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD2 test #%d: ", i + 1 );
md2( (unsigned char *) md2_test_str[i],
strlen( md2_test_str[i] ), md2sum );
if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,457 @@
/*
* RFC 1186/1320 compliant MD4 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
*
* http://www.ietf.org/rfc/rfc1186.txt
* http://www.ietf.org/rfc/rfc1320.txt
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD4_C)
#include "polarssl/md4.h"
#include <string.h>
#include <stdio.h>
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_ULONG_LE
#define GET_ULONG_LE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] ) \
| ( (unsigned long) (b)[(i) + 1] << 8 ) \
| ( (unsigned long) (b)[(i) + 2] << 16 ) \
| ( (unsigned long) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_ULONG_LE
#define PUT_ULONG_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
#endif
/*
* MD4 context setup
*/
void md4_starts( md4_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
static void md4_process( md4_context *ctx, const unsigned char data[64] )
{
unsigned long X[16], A, B, C, D;
GET_ULONG_LE( X[ 0], data, 0 );
GET_ULONG_LE( X[ 1], data, 4 );
GET_ULONG_LE( X[ 2], data, 8 );
GET_ULONG_LE( X[ 3], data, 12 );
GET_ULONG_LE( X[ 4], data, 16 );
GET_ULONG_LE( X[ 5], data, 20 );
GET_ULONG_LE( X[ 6], data, 24 );
GET_ULONG_LE( X[ 7], data, 28 );
GET_ULONG_LE( X[ 8], data, 32 );
GET_ULONG_LE( X[ 9], data, 36 );
GET_ULONG_LE( X[10], data, 40 );
GET_ULONG_LE( X[11], data, 44 );
GET_ULONG_LE( X[12], data, 48 );
GET_ULONG_LE( X[13], data, 52 );
GET_ULONG_LE( X[14], data, 56 );
GET_ULONG_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x, y, z) ((x & y) | ((~x) & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 1], 7 );
P( C, D, A, B, X[ 2], 11 );
P( B, C, D, A, X[ 3], 19 );
P( A, B, C, D, X[ 4], 3 );
P( D, A, B, C, X[ 5], 7 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[ 7], 19 );
P( A, B, C, D, X[ 8], 3 );
P( D, A, B, C, X[ 9], 7 );
P( C, D, A, B, X[10], 11 );
P( B, C, D, A, X[11], 19 );
P( A, B, C, D, X[12], 3 );
P( D, A, B, C, X[13], 7 );
P( C, D, A, B, X[14], 11 );
P( B, C, D, A, X[15], 19 );
#undef P
#undef F
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 4], 5 );
P( C, D, A, B, X[ 8], 9 );
P( B, C, D, A, X[12], 13 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 5], 5 );
P( C, D, A, B, X[ 9], 9 );
P( B, C, D, A, X[13], 13 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[ 6], 5 );
P( C, D, A, B, X[10], 9 );
P( B, C, D, A, X[14], 13 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[ 7], 5 );
P( C, D, A, B, X[11], 9 );
P( B, C, D, A, X[15], 13 );
#undef P
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 8], 9 );
P( C, D, A, B, X[ 4], 11 );
P( B, C, D, A, X[12], 15 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[10], 9 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[14], 15 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 9], 9 );
P( C, D, A, B, X[ 5], 11 );
P( B, C, D, A, X[13], 15 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[11], 9 );
P( C, D, A, B, X[ 7], 11 );
P( B, C, D, A, X[15], 15 );
#undef F
#undef P
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
/*
* MD4 process buffer
*/
void md4_update( md4_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned long left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (unsigned long) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
md4_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
md4_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char md4_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD4 final digest
*/
void md4_finish( md4_context *ctx, unsigned char output[16] )
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_ULONG_LE( low, msglen, 0 );
PUT_ULONG_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
md4_update( ctx, (unsigned char *) md4_padding, padn );
md4_update( ctx, msglen, 8 );
PUT_ULONG_LE( ctx->state[0], output, 0 );
PUT_ULONG_LE( ctx->state[1], output, 4 );
PUT_ULONG_LE( ctx->state[2], output, 8 );
PUT_ULONG_LE( ctx->state[3], output, 12 );
}
/*
* output = MD4( input buffer )
*/
void md4( const unsigned char *input, int ilen, unsigned char output[16] )
{
md4_context ctx;
md4_starts( &ctx );
md4_update( &ctx, input, ilen );
md4_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
}
/*
* output = MD4( file contents )
*/
int md4_file( const char *path, unsigned char output[16] )
{
FILE *f;
size_t n;
md4_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
md4_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md4_update( &ctx, buf, (int) n );
md4_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* MD4 HMAC context setup
*/
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, int keylen )
{
int i;
unsigned char sum[16];
if( keylen > 64 )
{
md4( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md4_starts( ctx );
md4_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* MD4 HMAC process buffer
*/
void md4_hmac_update( md4_context *ctx, const unsigned char *input, int ilen )
{
md4_update( ctx, input, ilen );
}
/*
* MD4 HMAC final digest
*/
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md4_finish( ctx, tmpbuf );
md4_starts( ctx );
md4_update( ctx, ctx->opad, 64 );
md4_update( ctx, tmpbuf, 16 );
md4_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* MD4 HMAC context reset
*/
void md4_hmac_reset( md4_context *ctx )
{
md4_starts( ctx );
md4_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-MD4( hmac key, input buffer )
*/
void md4_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[16] )
{
md4_context ctx;
md4_hmac_starts( &ctx, key, keylen );
md4_hmac_update( &ctx, input, ilen );
md4_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* RFC 1320 test vectors
*/
static const char md4_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const unsigned char md4_test_sum[7][16] =
{
{ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
{ 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
{ 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
{ 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
{ 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
{ 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
{ 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
};
/*
* Checkup routine
*/
int md4_self_test( int verbose )
{
int i;
unsigned char md4sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD4 test #%d: ", i + 1 );
md4( (unsigned char *) md4_test_str[i],
strlen( md4_test_str[i] ), md4sum );
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,580 @@
/*
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
*
* http://www.ietf.org/rfc/rfc1321.txt
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD5_C)
#include "polarssl/md5.h"
#include <string.h>
#include <stdio.h>
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_ULONG_LE
#define GET_ULONG_LE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] ) \
| ( (unsigned long) (b)[(i) + 1] << 8 ) \
| ( (unsigned long) (b)[(i) + 2] << 16 ) \
| ( (unsigned long) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_ULONG_LE
#define PUT_ULONG_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
#endif
/*
* MD5 context setup
*/
void md5_starts( md5_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
static void md5_process( md5_context *ctx, const unsigned char data[64] )
{
unsigned long X[16], A, B, C, D;
GET_ULONG_LE( X[ 0], data, 0 );
GET_ULONG_LE( X[ 1], data, 4 );
GET_ULONG_LE( X[ 2], data, 8 );
GET_ULONG_LE( X[ 3], data, 12 );
GET_ULONG_LE( X[ 4], data, 16 );
GET_ULONG_LE( X[ 5], data, 20 );
GET_ULONG_LE( X[ 6], data, 24 );
GET_ULONG_LE( X[ 7], data, 28 );
GET_ULONG_LE( X[ 8], data, 32 );
GET_ULONG_LE( X[ 9], data, 36 );
GET_ULONG_LE( X[10], data, 40 );
GET_ULONG_LE( X[11], data, 44 );
GET_ULONG_LE( X[12], data, 48 );
GET_ULONG_LE( X[13], data, 52 );
GET_ULONG_LE( X[14], data, 56 );
GET_ULONG_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x,y,z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
P( C, D, A, B, 2, 17, 0x242070DB );
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
P( A, B, C, D, 4, 7, 0xF57C0FAF );
P( D, A, B, C, 5, 12, 0x4787C62A );
P( C, D, A, B, 6, 17, 0xA8304613 );
P( B, C, D, A, 7, 22, 0xFD469501 );
P( A, B, C, D, 8, 7, 0x698098D8 );
P( D, A, B, C, 9, 12, 0x8B44F7AF );
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
P( B, C, D, A, 11, 22, 0x895CD7BE );
P( A, B, C, D, 12, 7, 0x6B901122 );
P( D, A, B, C, 13, 12, 0xFD987193 );
P( C, D, A, B, 14, 17, 0xA679438E );
P( B, C, D, A, 15, 22, 0x49B40821 );
#undef F
#define F(x,y,z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
P( C, D, A, B, 11, 14, 0x265E5A51 );
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
P( A, B, C, D, 5, 5, 0xD62F105D );
P( D, A, B, C, 10, 9, 0x02441453 );
P( C, D, A, B, 15, 14, 0xD8A1E681 );
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
P( D, A, B, C, 14, 9, 0xC33707D6 );
P( C, D, A, B, 3, 14, 0xF4D50D87 );
P( B, C, D, A, 8, 20, 0x455A14ED );
P( A, B, C, D, 13, 5, 0xA9E3E905 );
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
P( C, D, A, B, 7, 14, 0x676F02D9 );
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
#undef F
#define F(x,y,z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
P( C, D, A, B, 11, 16, 0x6D9D6122 );
P( B, C, D, A, 14, 23, 0xFDE5380C );
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
P( A, B, C, D, 13, 4, 0x289B7EC6 );
P( D, A, B, C, 0, 11, 0xEAA127FA );
P( C, D, A, B, 3, 16, 0xD4EF3085 );
P( B, C, D, A, 6, 23, 0x04881D05 );
P( A, B, C, D, 9, 4, 0xD9D4D039 );
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
P( B, C, D, A, 2, 23, 0xC4AC5665 );
#undef F
#define F(x,y,z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
P( C, D, A, B, 14, 15, 0xAB9423A7 );
P( B, C, D, A, 5, 21, 0xFC93A039 );
P( A, B, C, D, 12, 6, 0x655B59C3 );
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
P( C, D, A, B, 10, 15, 0xFFEFF47D );
P( B, C, D, A, 1, 21, 0x85845DD1 );
P( A, B, C, D, 8, 6, 0x6FA87E4F );
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
P( C, D, A, B, 6, 15, 0xA3014314 );
P( B, C, D, A, 13, 21, 0x4E0811A1 );
P( A, B, C, D, 4, 6, 0xF7537E82 );
P( D, A, B, C, 11, 10, 0xBD3AF235 );
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
P( B, C, D, A, 9, 21, 0xEB86D391 );
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
/*
* MD5 process buffer
*/
void md5_update( md5_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned long left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (unsigned long) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
md5_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
md5_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char md5_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD5 final digest
*/
void md5_finish( md5_context *ctx, unsigned char output[16] )
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_ULONG_LE( low, msglen, 0 );
PUT_ULONG_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
md5_update( ctx, (unsigned char *) md5_padding, padn );
md5_update( ctx, msglen, 8 );
PUT_ULONG_LE( ctx->state[0], output, 0 );
PUT_ULONG_LE( ctx->state[1], output, 4 );
PUT_ULONG_LE( ctx->state[2], output, 8 );
PUT_ULONG_LE( ctx->state[3], output, 12 );
}
/*
* output = MD5( input buffer )
*/
void md5( const unsigned char *input, int ilen, unsigned char output[16] )
{
md5_context ctx;
md5_starts( &ctx );
md5_update( &ctx, input, ilen );
md5_finish( &ctx, output );
memset( &ctx, 0, sizeof( md5_context ) );
}
/*
* output = MD5( file contents )
*/
int md5_file( const char *path, unsigned char output[16] )
{
FILE *f;
size_t n;
md5_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
md5_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md5_update( &ctx, buf, (int) n );
md5_finish( &ctx, output );
memset( &ctx, 0, sizeof( md5_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* MD5 HMAC context setup
*/
void md5_hmac_starts( md5_context *ctx, const unsigned char *key, int keylen )
{
int i;
unsigned char sum[16];
if( keylen > 64 )
{
md5( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md5_starts( ctx );
md5_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* MD5 HMAC process buffer
*/
void md5_hmac_update( md5_context *ctx, const unsigned char *input, int ilen )
{
md5_update( ctx, input, ilen );
}
/*
* MD5 HMAC final digest
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md5_finish( ctx, tmpbuf );
md5_starts( ctx );
md5_update( ctx, ctx->opad, 64 );
md5_update( ctx, tmpbuf, 16 );
md5_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* MD5 HMAC context reset
*/
void md5_hmac_reset( md5_context *ctx )
{
md5_starts( ctx );
md5_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-MD5( hmac key, input buffer )
*/
void md5_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[16] )
{
md5_context ctx;
md5_hmac_starts( &ctx, key, keylen );
md5_hmac_update( &ctx, input, ilen );
md5_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md5_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* RFC 1321 test vectors
*/
static unsigned char md5_test_buf[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const int md5_test_buflen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md5_test_sum[7][16] =
{
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
};
/*
* RFC 2202 test vectors
*/
static unsigned char md5_hmac_test_key[7][26] =
{
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
{ "Jefe" },
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
{ "" }, /* 0xAA 80 times */
{ "" }
};
static const int md5_hmac_test_keylen[7] =
{
16, 4, 16, 25, 16, 80, 80
};
static unsigned char md5_hmac_test_buf[7][74] =
{
{ "Hi There" },
{ "what do ya want for nothing?" },
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
{ "Test With Truncation" },
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
{ "Test Using Larger Than Block-Size Key and Larger"
" Than One Block-Size Data" }
};
static const int md5_hmac_test_buflen[7] =
{
8, 28, 50, 50, 20, 54, 73
};
static const unsigned char md5_hmac_test_sum[7][16] =
{
{ 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
{ 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
{ 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
{ 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
{ 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
0xF9, 0xBA, 0xB9, 0x95 },
{ 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
{ 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
};
/*
* Checkup routine
*/
int md5_self_test( int verbose )
{
int i, buflen;
unsigned char buf[1024];
unsigned char md5sum[16];
md5_context ctx;
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD5 test #%d: ", i + 1 );
md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " HMAC-MD5 test #%d: ", i + 1 );
if( i == 5 || i == 6 )
{
memset( buf, '\xAA', buflen = 80 );
md5_hmac_starts( &ctx, buf, buflen );
}
else
md5_hmac_starts( &ctx, md5_hmac_test_key[i],
md5_hmac_test_keylen[i] );
md5_hmac_update( &ctx, md5_hmac_test_buf[i],
md5_hmac_test_buflen[i] );
md5_hmac_finish( &ctx, md5sum );
buflen = ( i == 4 ) ? 12 : 16;
if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,359 @@
/*
* TCP networking functions
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_NET_C)
#include "polarssl/net.h"
#if defined(_WIN32) || defined(_WIN32_WCE)
#include <winsock2.h>
#include <windows.h>
#if defined(_WIN32_WCE)
#pragma comment( lib, "ws2.lib" )
#else
#pragma comment( lib, "ws2_32.lib" )
#endif
#define read(fd,buf,len) recv(fd,buf,len,0)
#define write(fd,buf,len) send(fd,buf,len,0)
#define close(fd) closesocket(fd)
static int wsa_init_done = 0;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
#if defined(__FreeBSD__)
#include <sys/endian.h>
#elif defined(__APPLE__)
#include <machine/endian.h>
#else
#include <endian.h>
#endif
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/*
* htons() is not always available.
* By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN
* to help determine endianess.
*/
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
#define POLARSSL_HTONS(n) (n)
#else
#define POLARSSL_HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
#endif
unsigned short net_htons(unsigned short n);
#define net_htons(n) POLARSSL_HTONS(n)
/*
* Initiate a TCP connection with host:port
*/
int net_connect( int *fd, const char *host, int port )
{
struct sockaddr_in server_addr;
struct hostent *server_host;
#if defined(_WIN32) || defined(_WIN32_WCE)
WSADATA wsaData;
if( wsa_init_done == 0 )
{
if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
wsa_init_done = 1;
}
#else
signal( SIGPIPE, SIG_IGN );
#endif
if( ( server_host = gethostbyname( host ) ) == NULL )
return( POLARSSL_ERR_NET_UNKNOWN_HOST );
if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
memcpy( (void *) &server_addr.sin_addr,
(void *) server_host->h_addr,
server_host->h_length );
server_addr.sin_family = AF_INET;
server_addr.sin_port = net_htons( port );
if( connect( *fd, (struct sockaddr *) &server_addr,
sizeof( server_addr ) ) < 0 )
{
close( *fd );
return( POLARSSL_ERR_NET_CONNECT_FAILED );
}
return( 0 );
}
/*
* Create a listening socket on bind_ip:port
*/
int net_bind( int *fd, const char *bind_ip, int port )
{
int n, c[4];
struct sockaddr_in server_addr;
#if defined(_WIN32) || defined(_WIN32_WCE)
WSADATA wsaData;
if( wsa_init_done == 0 )
{
if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
wsa_init_done = 1;
}
#else
signal( SIGPIPE, SIG_IGN );
#endif
if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
n = 1;
setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof( n ) );
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_family = AF_INET;
server_addr.sin_port = net_htons( port );
if( bind_ip != NULL )
{
memset( c, 0, sizeof( c ) );
sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
for( n = 0; n < 4; n++ )
if( c[n] < 0 || c[n] > 255 )
break;
if( n == 4 )
server_addr.sin_addr.s_addr =
( (unsigned long) c[0] << 24 ) |
( (unsigned long) c[1] << 16 ) |
( (unsigned long) c[2] << 8 ) |
( (unsigned long) c[3] );
}
if( bind( *fd, (struct sockaddr *) &server_addr,
sizeof( server_addr ) ) < 0 )
{
close( *fd );
return( POLARSSL_ERR_NET_BIND_FAILED );
}
if( listen( *fd, 10 ) != 0 )
{
close( *fd );
return( POLARSSL_ERR_NET_LISTEN_FAILED );
}
return( 0 );
}
/*
* Check if the current operation is blocking
*/
static int net_is_blocking( void )
{
#if defined(_WIN32) || defined(_WIN32_WCE)
return( WSAGetLastError() == WSAEWOULDBLOCK );
#else
switch( errno )
{
#if defined EAGAIN
case EAGAIN:
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return( 1 );
}
return( 0 );
#endif
}
/*
* Accept a connection from a remote client
*/
int net_accept( int bind_fd, int *client_fd, void *client_ip )
{
struct sockaddr_in client_addr;
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T)
socklen_t n = (socklen_t) sizeof( client_addr );
#else
int n = (int) sizeof( client_addr );
#endif
*client_fd = accept( bind_fd, (struct sockaddr *)
&client_addr, &n );
if( *client_fd < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_TRY_AGAIN );
return( POLARSSL_ERR_NET_ACCEPT_FAILED );
}
if( client_ip != NULL )
memcpy( client_ip, &client_addr.sin_addr.s_addr,
sizeof( client_addr.sin_addr.s_addr ) );
return( 0 );
}
/*
* Set the socket blocking or non-blocking
*/
int net_set_block( int fd )
{
#if defined(_WIN32) || defined(_WIN32_WCE)
long n = 0;
return( ioctlsocket( fd, FIONBIO, &n ) );
#else
return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
#endif
}
int net_set_nonblock( int fd )
{
#if defined(_WIN32) || defined(_WIN32_WCE)
long n = 1;
return( ioctlsocket( fd, FIONBIO, &n ) );
#else
return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
#endif
}
/*
* Portable usleep helper
*/
void net_usleep( unsigned long usec )
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = usec;
select( 0, NULL, NULL, NULL, &tv );
}
/*
* Read at most 'len' characters
*/
int net_recv( void *ctx, unsigned char *buf, int len )
{
int ret = read( *((int *) ctx), buf, len );
if( len > 0 && ret == 0 )
return( POLARSSL_ERR_NET_CONN_RESET );
if( ret < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_TRY_AGAIN );
#if defined(_WIN32) || defined(_WIN32_WCE)
if( WSAGetLastError() == WSAECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
#else
if( errno == EPIPE || errno == ECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( POLARSSL_ERR_NET_TRY_AGAIN );
#endif
return( POLARSSL_ERR_NET_RECV_FAILED );
}
return( ret );
}
/*
* Write at most 'len' characters
*/
int net_send( void *ctx, unsigned char *buf, int len )
{
int ret = write( *((int *) ctx), buf, len );
if( ret < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_TRY_AGAIN );
#if defined(_WIN32) || defined(_WIN32_WCE)
if( WSAGetLastError() == WSAECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
#else
if( errno == EPIPE || errno == ECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( POLARSSL_ERR_NET_TRY_AGAIN );
#endif
return( POLARSSL_ERR_NET_SEND_FAILED );
}
return( ret );
}
/*
* Gracefully close the connection
*/
void net_close( int fd )
{
shutdown( fd, 2 );
close( fd );
}
#endif

View File

@@ -0,0 +1,164 @@
/*
* VIA PadLock support functions
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This implementation is based on the VIA PadLock Programming Guide:
*
* http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
* programming_guide.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_PADLOCK_C)
#include "polarssl/aes.h"
#include "polarssl/padlock.h"
#if defined(POLARSSL_HAVE_X86)
#include <string.h>
/*
* PadLock detection routine
*/
int padlock_supports( int feature )
{
static int flags = -1;
int ebx, edx;
if( flags == -1 )
{
asm( "movl %%ebx, %0 \n" \
"movl $0xC0000000, %%eax \n" \
"cpuid \n" \
"cmpl $0xC0000001, %%eax \n" \
"movl $0, %%edx \n" \
"jb unsupported \n" \
"movl $0xC0000001, %%eax \n" \
"cpuid \n" \
"unsupported: \n" \
"movl %%edx, %1 \n" \
"movl %2, %%ebx \n"
: "=m" (ebx), "=m" (edx)
: "m" (ebx)
: "eax", "ecx", "edx" );
flags = edx;
}
return( flags & feature );
}
/*
* PadLock AES-ECB block en(de)cryption
*/
int padlock_xcryptecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
int ebx;
unsigned long *rk;
unsigned long *blk;
unsigned long *ctrl;
unsigned char buf[256];
rk = ctx->rk;
blk = PADLOCK_ALIGN16( buf );
memcpy( blk, input, 16 );
ctrl = blk + 4;
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );
asm( "pushfl; popfl \n" \
"movl %%ebx, %0 \n" \
"movl $1, %%ecx \n" \
"movl %2, %%edx \n" \
"movl %3, %%ebx \n" \
"movl %4, %%esi \n" \
"movl %4, %%edi \n" \
".byte 0xf3,0x0f,0xa7,0xc8\n" \
"movl %1, %%ebx \n"
: "=m" (ebx)
: "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
: "ecx", "edx", "esi", "edi" );
memcpy( output, blk, 16 );
return( 0 );
}
/*
* PadLock AES-CBC buffer en(de)cryption
*/
int padlock_xcryptcbc( aes_context *ctx,
int mode,
int length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int ebx, count;
unsigned long *rk;
unsigned long *iw;
unsigned long *ctrl;
unsigned char buf[256];
if( ( (long) input & 15 ) != 0 ||
( (long) output & 15 ) != 0 )
return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED );
rk = ctx->rk;
iw = PADLOCK_ALIGN16( buf );
memcpy( iw, iv, 16 );
ctrl = iw + 4;
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 );
count = (length + 15) >> 4;
asm( "pushfl; popfl \n" \
"movl %%ebx, %0 \n" \
"movl %2, %%ecx \n" \
"movl %3, %%edx \n" \
"movl %4, %%ebx \n" \
"movl %5, %%esi \n" \
"movl %6, %%edi \n" \
"movl %7, %%eax \n" \
".byte 0xf3,0x0f,0xa7,0xd0\n" \
"movl %1, %%ebx \n"
: "=m" (ebx)
: "m" (ebx), "m" (count), "m" (ctrl),
"m" (rk), "m" (input), "m" (output), "m" (iw)
: "eax", "ecx", "edx", "esi", "edi" );
memcpy( iv, iw, 16 );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,823 @@
/*
* The RSA public-key cryptosystem
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
*
* http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
* Initialize an RSA context
*/
void rsa_init( rsa_context *ctx,
int padding,
int hash_id )
{
memset( ctx, 0, sizeof( rsa_context ) );
ctx->padding = padding;
ctx->hash_id = hash_id;
}
#if defined(POLARSSL_GENPRIME)
/*
* Generate an RSA keypair
*/
int rsa_gen_key( rsa_context *ctx,
int (*f_rng)(void *),
void *p_rng,
int nbits, int exponent )
{
int ret;
mpi P1, Q1, H, G;
if( f_rng == NULL || nbits < 128 || exponent < 3 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
mpi_init( &P1, &Q1, &H, &G, NULL );
/*
* find primes P and Q with Q < P so that:
* GCD( E, (P-1)*(Q-1) ) == 1
*/
MPI_CHK( mpi_lset( &ctx->E, exponent ) );
do
{
MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
f_rng, p_rng ) );
MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
f_rng, p_rng ) );
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
mpi_swap( &ctx->P, &ctx->Q );
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
continue;
MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
if( mpi_msb( &ctx->N ) != nbits )
continue;
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
}
while( mpi_cmp_int( &G, 1 ) != 0 );
/*
* D = E^-1 mod ((P-1)*(Q-1))
* DP = D mod (P - 1)
* DQ = D mod (Q - 1)
* QP = Q^-1 mod P
*/
MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
cleanup:
mpi_free( &G, &H, &Q1, &P1, NULL );
if( ret != 0 )
{
rsa_free( ctx );
return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
}
return( 0 );
}
#endif
/*
* Check a public RSA key
*/
int rsa_check_pubkey( const rsa_context *ctx )
{
if( !ctx->N.p || !ctx->E.p )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
if( ( ctx->N.p[0] & 1 ) == 0 ||
( ctx->E.p[0] & 1 ) == 0 )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
if( mpi_msb( &ctx->N ) < 128 ||
mpi_msb( &ctx->N ) > 4096 )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
if( mpi_msb( &ctx->E ) < 2 ||
mpi_msb( &ctx->E ) > 64 )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
return( 0 );
}
/*
* Check a private RSA key
*/
int rsa_check_privkey( const rsa_context *ctx )
{
int ret;
mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;
if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
return( ret );
if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );
MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
/*
* Check for a valid PKCS1v2 private key
*/
if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
mpi_cmp_int( &L2, 0 ) == 0 &&
mpi_cmp_int( &I, 1 ) == 0 &&
mpi_cmp_int( &G, 1 ) == 0 )
{
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
return( 0 );
}
cleanup:
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
}
/*
* Do an RSA public key operation
*/
int rsa_public( rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
int ret, olen;
mpi T;
mpi_init( &T, NULL );
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
{
mpi_free( &T, NULL );
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
olen = ctx->len;
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
MPI_CHK( mpi_write_binary( &T, output, olen ) );
cleanup:
mpi_free( &T, NULL );
if( ret != 0 )
return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
return( 0 );
}
/*
* Do an RSA private key operation
*/
int rsa_private( rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
int ret, olen;
mpi T, T1, T2;
mpi_init( &T, &T1, &T2, NULL );
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
{
mpi_free( &T, NULL );
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
#if 0
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
#else
/*
* faster decryption using the CRT
*
* T1 = input ^ dP mod P
* T2 = input ^ dQ mod Q
*/
MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
/*
* T = (T1 - T2) * (Q^-1 mod P) mod P
*/
MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
/*
* output = T2 + T * Q
*/
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
#endif
olen = ctx->len;
MPI_CHK( mpi_write_binary( &T, output, olen ) );
cleanup:
mpi_free( &T, &T1, &T2, NULL );
if( ret != 0 )
return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
return( 0 );
}
/*
* Add the message padding, then do an RSA operation
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
int (*f_rng)(void *),
void *p_rng,
int mode, int ilen,
const unsigned char *input,
unsigned char *output )
{
int nb_pad, olen;
unsigned char *p = output;
olen = ctx->len;
switch( ctx->padding )
{
case RSA_PKCS_V15:
if( ilen < 0 || olen < ilen + 11 || f_rng == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
nb_pad = olen - 3 - ilen;
*p++ = 0;
*p++ = RSA_CRYPT;
while( nb_pad-- > 0 )
{
int rng_dl = 100;
do {
*p = (unsigned char) f_rng( p_rng );
} while( *p == 0 && --rng_dl );
// Check if RNG failed to generate data
//
if( rng_dl == 0 )
return POLARSSL_ERR_RSA_RNG_FAILED;
p++;
}
*p++ = 0;
memcpy( p, input, ilen );
break;
default:
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
return( ( mode == RSA_PUBLIC )
? rsa_public( ctx, output, output )
: rsa_private( ctx, output, output ) );
}
/*
* Do an RSA operation, then remove the message padding
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen,
const unsigned char *input,
unsigned char *output,
int output_max_len)
{
int ret, ilen;
unsigned char *p;
unsigned char buf[1024];
ilen = ctx->len;
if( ilen < 16 || ilen > (int) sizeof( buf ) )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ret = ( mode == RSA_PUBLIC )
? rsa_public( ctx, input, buf )
: rsa_private( ctx, input, buf );
if( ret != 0 )
return( ret );
p = buf;
switch( ctx->padding )
{
case RSA_PKCS_V15:
if( *p++ != 0 || *p++ != RSA_CRYPT )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
while( *p != 0 )
{
if( p >= buf + ilen - 1 )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
p++;
}
p++;
break;
default:
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
if (ilen - (int)(p - buf) > output_max_len)
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
*olen = ilen - (int)(p - buf);
memcpy( output, p, *olen );
return( 0 );
}
/*
* Do an RSA operation to sign the message digest
*/
int rsa_pkcs1_sign( rsa_context *ctx,
int mode,
int hash_id,
int hashlen,
const unsigned char *hash,
unsigned char *sig )
{
int nb_pad, olen;
unsigned char *p = sig;
olen = ctx->len;
switch( ctx->padding )
{
case RSA_PKCS_V15:
switch( hash_id )
{
case SIG_RSA_RAW:
nb_pad = olen - 3 - hashlen;
break;
case SIG_RSA_MD2:
case SIG_RSA_MD4:
case SIG_RSA_MD5:
nb_pad = olen - 3 - 34;
break;
case SIG_RSA_SHA1:
nb_pad = olen - 3 - 35;
break;
case SIG_RSA_SHA224:
nb_pad = olen - 3 - 47;
break;
case SIG_RSA_SHA256:
nb_pad = olen - 3 - 51;
break;
case SIG_RSA_SHA384:
nb_pad = olen - 3 - 67;
break;
case SIG_RSA_SHA512:
nb_pad = olen - 3 - 83;
break;
default:
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
if( nb_pad < 8 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
*p++ = 0;
*p++ = RSA_SIGN;
memset( p, 0xFF, nb_pad );
p += nb_pad;
*p++ = 0;
break;
default:
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
switch( hash_id )
{
case SIG_RSA_RAW:
memcpy( p, hash, hashlen );
break;
case SIG_RSA_MD2:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 2; break;
case SIG_RSA_MD4:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 4; break;
case SIG_RSA_MD5:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 5; break;
case SIG_RSA_SHA1:
memcpy( p, ASN1_HASH_SHA1, 15 );
memcpy( p + 15, hash, 20 );
break;
case SIG_RSA_SHA224:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 28 );
p[1] += 28; p[14] = 4; p[18] += 28; break;
case SIG_RSA_SHA256:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 32 );
p[1] += 32; p[14] = 1; p[18] += 32; break;
case SIG_RSA_SHA384:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 48 );
p[1] += 48; p[14] = 2; p[18] += 48; break;
case SIG_RSA_SHA512:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 64 );
p[1] += 64; p[14] = 3; p[18] += 64; break;
default:
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
return( ( mode == RSA_PUBLIC )
? rsa_public( ctx, sig, sig )
: rsa_private( ctx, sig, sig ) );
}
/*
* Do an RSA operation and check the message digest
*/
int rsa_pkcs1_verify( rsa_context *ctx,
int mode,
int hash_id,
int hashlen,
const unsigned char *hash,
unsigned char *sig )
{
int ret, len, siglen;
unsigned char *p, c;
unsigned char buf[1024];
siglen = ctx->len;
if( siglen < 16 || siglen > (int) sizeof( buf ) )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ret = ( mode == RSA_PUBLIC )
? rsa_public( ctx, sig, buf )
: rsa_private( ctx, sig, buf );
if( ret != 0 )
return( ret );
p = buf;
switch( ctx->padding )
{
case RSA_PKCS_V15:
if( *p++ != 0 || *p++ != RSA_SIGN )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
while( *p != 0 )
{
if( p >= buf + siglen - 1 || *p != 0xFF )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
p++;
}
p++;
break;
default:
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
len = siglen - (int)( p - buf );
if( len == 34 )
{
c = p[13];
p[13] = 0;
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
( c == 4 && hash_id == SIG_RSA_MD4 ) ||
( c == 5 && hash_id == SIG_RSA_MD5 ) )
{
if( memcmp( p + 18, hash, 16 ) == 0 )
return( 0 );
else
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
}
if( len == 35 && hash_id == SIG_RSA_SHA1 )
{
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
memcmp( p + 15, hash, 20 ) == 0 )
return( 0 );
else
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
{
c = p[1] - 17;
p[1] = 17;
p[14] = 0;
if( p[18] == c &&
memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
memcmp( p + 19, hash, c ) == 0 )
return( 0 );
else
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
if( len == hashlen && hash_id == SIG_RSA_RAW )
{
if( memcmp( p, hash, hashlen ) == 0 )
return( 0 );
else
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
/*
* Free the components of an RSA key
*/
void rsa_free( rsa_context *ctx )
{
mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
&ctx->QP, &ctx->DQ, &ctx->DP,
&ctx->Q, &ctx->P, &ctx->D,
&ctx->E, &ctx->N, NULL );
}
#if defined(POLARSSL_SELF_TEST)
#include "polarssl/sha1.h"
/*
* Example RSA-1024 keypair, for test purposes
*/
#define KEY_LEN 128
#define RSA_N "9292758453063D803DD603D5E777D788" \
"8ED1D5BF35786190FA2F23EBC0848AEA" \
"DDA92CA6C3D80B32C4D109BE0F36D6AE" \
"7130B9CED7ACDF54CFC7555AC14EEBAB" \
"93A89813FBF3C4F8066D2D800F7C38A8" \
"1AE31942917403FF4946B0A83D3D3E05" \
"EE57C6F5F5606FB5D4BC6CD34EE0801A" \
"5E94BB77B07507233A0BC7BAC8F90F79"
#define RSA_E "10001"
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
"66CA472BC44D253102F8B4A9D3BFA750" \
"91386C0077937FE33FA3252D28855837" \
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
"DF79C5CE07EE72C7F123142198164234" \
"CABB724CF78B8173B9F880FC86322407" \
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
"071513A1E85B5DFA031F21ECAE91A34D"
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
"2C01CAD19EA484A87EA4377637E75500" \
"FCB2005C5C7DD6EC4AC023CDA285D796" \
"C3D9E75E1EFC42488BB4F1D13AC30A57"
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
"910E4168387E3C30AA1E00C339A79508" \
"8452DD96A9A5EA5D9DCA68DA636032AF"
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
"3C94D22288ACD763FD8E5600ED4A702D" \
"F84198A5F06C2E72236AE490C93F07F8" \
"3CC559CD27BC2D1CA488811730BB5725"
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
"D8AAEA56749EA28623272E4F7D0592AF" \
"7C1F1313CAC9471B5C523BFE592F517B" \
"407A1BD76C164B93DA2D32A383E58357"
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
"F38D18D2B2F0E2DD275AA977E2BF4411" \
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
"A74206CEC169D74BF5A8C50D6F48EA08"
#define PT_LEN 24
#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
"\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
static int myrand( void *rng_state )
{
if( rng_state != NULL )
rng_state = NULL;
return( rand() );
}
/*
* Checkup routine
*/
int rsa_self_test( int verbose )
{
int len;
rsa_context rsa;
unsigned char sha1sum[20];
unsigned char rsa_plaintext[PT_LEN];
unsigned char rsa_decrypted[PT_LEN];
unsigned char rsa_ciphertext[KEY_LEN];
rsa_init( &rsa, RSA_PKCS_V15, 0 );
rsa.len = KEY_LEN;
mpi_read_string( &rsa.N , 16, RSA_N );
mpi_read_string( &rsa.E , 16, RSA_E );
mpi_read_string( &rsa.D , 16, RSA_D );
mpi_read_string( &rsa.P , 16, RSA_P );
mpi_read_string( &rsa.Q , 16, RSA_Q );
mpi_read_string( &rsa.DP, 16, RSA_DP );
mpi_read_string( &rsa.DQ, 16, RSA_DQ );
mpi_read_string( &rsa.QP, 16, RSA_QP );
if( verbose != 0 )
printf( " RSA key validation: " );
if( rsa_check_pubkey( &rsa ) != 0 ||
rsa_check_privkey( &rsa ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n PKCS#1 encryption : " );
memcpy( rsa_plaintext, RSA_PT, PT_LEN );
if( rsa_pkcs1_encrypt( &rsa, &myrand, NULL, RSA_PUBLIC, PT_LEN,
rsa_plaintext, rsa_ciphertext ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n PKCS#1 decryption : " );
if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
rsa_ciphertext, rsa_decrypted,
sizeof(rsa_decrypted) ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n PKCS#1 data sign : " );
sha1( rsa_plaintext, PT_LEN, sha1sum );
if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20,
sha1sum, rsa_ciphertext ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n PKCS#1 sig. verify: " );
if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
sha1sum, rsa_ciphertext ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n\n" );
rsa_free( &rsa );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,621 @@
/*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#include "polarssl/config.h"
#if defined(POLARSSL_SHA1_C)
#include "polarssl/sha1.h"
#include <string.h>
#include <stdio.h>
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* SHA-1 context setup
*/
void sha1_starts( sha1_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
}
static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
{
unsigned long temp, W[16], A, B, C, D, E;
GET_ULONG_BE( W[ 0], data, 0 );
GET_ULONG_BE( W[ 1], data, 4 );
GET_ULONG_BE( W[ 2], data, 8 );
GET_ULONG_BE( W[ 3], data, 12 );
GET_ULONG_BE( W[ 4], data, 16 );
GET_ULONG_BE( W[ 5], data, 20 );
GET_ULONG_BE( W[ 6], data, 24 );
GET_ULONG_BE( W[ 7], data, 28 );
GET_ULONG_BE( W[ 8], data, 32 );
GET_ULONG_BE( W[ 9], data, 36 );
GET_ULONG_BE( W[10], data, 40 );
GET_ULONG_BE( W[11], data, 44 );
GET_ULONG_BE( W[12], data, 48 );
GET_ULONG_BE( W[13], data, 52 );
GET_ULONG_BE( W[14], data, 56 );
GET_ULONG_BE( W[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}
/*
* SHA-1 process buffer
*/
void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned long left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (unsigned long) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
sha1_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
sha1_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char sha1_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-1 final digest
*/
void sha1_finish( sha1_context *ctx, unsigned char output[20] )
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_ULONG_BE( high, msglen, 0 );
PUT_ULONG_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
sha1_update( ctx, (unsigned char *) sha1_padding, padn );
sha1_update( ctx, msglen, 8 );
PUT_ULONG_BE( ctx->state[0], output, 0 );
PUT_ULONG_BE( ctx->state[1], output, 4 );
PUT_ULONG_BE( ctx->state[2], output, 8 );
PUT_ULONG_BE( ctx->state[3], output, 12 );
PUT_ULONG_BE( ctx->state[4], output, 16 );
}
/*
* output = SHA-1( input buffer )
*/
void sha1( const unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
sha1_starts( &ctx );
sha1_update( &ctx, input, ilen );
sha1_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha1_context ) );
}
/*
* output = SHA-1( file contents )
*/
int sha1_file( const char *path, unsigned char output[20] )
{
FILE *f;
size_t n;
sha1_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
sha1_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha1_update( &ctx, buf, (int) n );
sha1_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha1_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* SHA-1 HMAC context setup
*/
void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen )
{
int i;
unsigned char sum[20];
if( keylen > 64 )
{
sha1( key, keylen, sum );
keylen = 20;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
sha1_starts( ctx );
sha1_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* SHA-1 HMAC process buffer
*/
void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen )
{
sha1_update( ctx, input, ilen );
}
/*
* SHA-1 HMAC final digest
*/
void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
{
unsigned char tmpbuf[20];
sha1_finish( ctx, tmpbuf );
sha1_starts( ctx );
sha1_update( ctx, ctx->opad, 64 );
sha1_update( ctx, tmpbuf, 20 );
sha1_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* SHA1 HMAC context reset
*/
void sha1_hmac_reset( sha1_context *ctx )
{
sha1_starts( ctx );
sha1_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-SHA-1( hmac key, input buffer )
*/
void sha1_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[20] )
{
sha1_context ctx;
sha1_hmac_starts( &ctx, key, keylen );
sha1_hmac_update( &ctx, input, ilen );
sha1_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha1_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* FIPS-180-1 test vectors
*/
static unsigned char sha1_test_buf[3][57] =
{
{ "abc" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
{ "" }
};
static const int sha1_test_buflen[3] =
{
3, 56, 1000
};
static const unsigned char sha1_test_sum[3][20] =
{
{ 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
{ 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
};
/*
* RFC 2202 test vectors
*/
static unsigned char sha1_hmac_test_key[7][26] =
{
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
"\x0B\x0B\x0B\x0B" },
{ "Jefe" },
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
"\xAA\xAA\xAA\xAA" },
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
"\x0C\x0C\x0C\x0C" },
{ "" }, /* 0xAA 80 times */
{ "" }
};
static const int sha1_hmac_test_keylen[7] =
{
20, 4, 20, 25, 20, 80, 80
};
static unsigned char sha1_hmac_test_buf[7][74] =
{
{ "Hi There" },
{ "what do ya want for nothing?" },
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
{ "Test With Truncation" },
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
{ "Test Using Larger Than Block-Size Key and Larger"
" Than One Block-Size Data" }
};
static const int sha1_hmac_test_buflen[7] =
{
8, 28, 50, 50, 20, 54, 73
};
static const unsigned char sha1_hmac_test_sum[7][20] =
{
{ 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
{ 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
{ 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
{ 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
{ 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
0x7B, 0xE1 },
{ 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
{ 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
};
/*
* Checkup routine
*/
int sha1_self_test( int verbose )
{
int i, j, buflen;
unsigned char buf[1024];
unsigned char sha1sum[20];
sha1_context ctx;
/*
* SHA-1
*/
for( i = 0; i < 3; i++ )
{
if( verbose != 0 )
printf( " SHA-1 test #%d: ", i + 1 );
sha1_starts( &ctx );
if( i == 2 )
{
memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ )
sha1_update( &ctx, buf, buflen );
}
else
sha1_update( &ctx, sha1_test_buf[i],
sha1_test_buflen[i] );
sha1_finish( &ctx, sha1sum );
if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " HMAC-SHA-1 test #%d: ", i + 1 );
if( i == 5 || i == 6 )
{
memset( buf, '\xAA', buflen = 80 );
sha1_hmac_starts( &ctx, buf, buflen );
}
else
sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
sha1_hmac_test_keylen[i] );
sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
sha1_hmac_test_buflen[i] );
sha1_hmac_finish( &ctx, sha1sum );
buflen = ( i == 4 ) ? 12 : 20;
if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,702 @@
/*
* FIPS-180-2 compliant SHA-256 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_SHA2_C)
#include "polarssl/sha2.h"
#include <string.h>
#include <stdio.h>
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* SHA-256 context setup
*/
void sha2_starts( sha2_context *ctx, int is224 )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is224 == 0 )
{
/* SHA-256 */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
else
{
/* SHA-224 */
ctx->state[0] = 0xC1059ED8;
ctx->state[1] = 0x367CD507;
ctx->state[2] = 0x3070DD17;
ctx->state[3] = 0xF70E5939;
ctx->state[4] = 0xFFC00B31;
ctx->state[5] = 0x68581511;
ctx->state[6] = 0x64F98FA7;
ctx->state[7] = 0xBEFA4FA4;
}
ctx->is224 = is224;
}
static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
{
unsigned long temp1, temp2, W[64];
unsigned long A, B, C, D, E, F, G, H;
GET_ULONG_BE( W[ 0], data, 0 );
GET_ULONG_BE( W[ 1], data, 4 );
GET_ULONG_BE( W[ 2], data, 8 );
GET_ULONG_BE( W[ 3], data, 12 );
GET_ULONG_BE( W[ 4], data, 16 );
GET_ULONG_BE( W[ 5], data, 20 );
GET_ULONG_BE( W[ 6], data, 24 );
GET_ULONG_BE( W[ 7], data, 28 );
GET_ULONG_BE( W[ 8], data, 32 );
GET_ULONG_BE( W[ 9], data, 36 );
GET_ULONG_BE( W[10], data, 40 );
GET_ULONG_BE( W[11], data, 44 );
GET_ULONG_BE( W[12], data, 48 );
GET_ULONG_BE( W[13], data, 52 );
GET_ULONG_BE( W[14], data, 56 );
GET_ULONG_BE( W[15], data, 60 );
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define R(t) \
( \
W[t] = S1(W[t - 2]) + W[t - 7] + \
S0(W[t - 15]) + W[t - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
F = ctx->state[5];
G = ctx->state[6];
H = ctx->state[7];
P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
ctx->state[5] += F;
ctx->state[6] += G;
ctx->state[7] += H;
}
/*
* SHA-256 process buffer
*/
void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned long left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (unsigned long) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
sha2_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
sha2_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char sha2_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-256 final digest
*/
void sha2_finish( sha2_context *ctx, unsigned char output[32] )
{
unsigned long last, padn;
unsigned long high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_ULONG_BE( high, msglen, 0 );
PUT_ULONG_BE( low, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
sha2_update( ctx, (unsigned char *) sha2_padding, padn );
sha2_update( ctx, msglen, 8 );
PUT_ULONG_BE( ctx->state[0], output, 0 );
PUT_ULONG_BE( ctx->state[1], output, 4 );
PUT_ULONG_BE( ctx->state[2], output, 8 );
PUT_ULONG_BE( ctx->state[3], output, 12 );
PUT_ULONG_BE( ctx->state[4], output, 16 );
PUT_ULONG_BE( ctx->state[5], output, 20 );
PUT_ULONG_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
PUT_ULONG_BE( ctx->state[7], output, 28 );
}
/*
* output = SHA-256( input buffer )
*/
void sha2( const unsigned char *input, int ilen,
unsigned char output[32], int is224 )
{
sha2_context ctx;
sha2_starts( &ctx, is224 );
sha2_update( &ctx, input, ilen );
sha2_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha2_context ) );
}
/*
* output = SHA-256( file contents )
*/
int sha2_file( const char *path, unsigned char output[32], int is224 )
{
FILE *f;
size_t n;
sha2_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
sha2_starts( &ctx, is224 );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha2_update( &ctx, buf, (int) n );
sha2_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha2_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* SHA-256 HMAC context setup
*/
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
int is224 )
{
int i;
unsigned char sum[32];
if( keylen > 64 )
{
sha2( key, keylen, sum, is224 );
keylen = ( is224 ) ? 28 : 32;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
sha2_starts( ctx, is224 );
sha2_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* SHA-256 HMAC process buffer
*/
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen )
{
sha2_update( ctx, input, ilen );
}
/*
* SHA-256 HMAC final digest
*/
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
{
int is224, hlen;
unsigned char tmpbuf[32];
is224 = ctx->is224;
hlen = ( is224 == 0 ) ? 32 : 28;
sha2_finish( ctx, tmpbuf );
sha2_starts( ctx, is224 );
sha2_update( ctx, ctx->opad, 64 );
sha2_update( ctx, tmpbuf, hlen );
sha2_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* SHA-256 HMAC context reset
*/
void sha2_hmac_reset( sha2_context *ctx )
{
sha2_starts( ctx, ctx->is224 );
sha2_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-SHA-256( hmac key, input buffer )
*/
void sha2_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[32], int is224 )
{
sha2_context ctx;
sha2_hmac_starts( &ctx, key, keylen, is224 );
sha2_hmac_update( &ctx, input, ilen );
sha2_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha2_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* FIPS-180-2 test vectors
*/
static unsigned char sha2_test_buf[3][57] =
{
{ "abc" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
{ "" }
};
static const int sha2_test_buflen[3] =
{
3, 56, 1000
};
static const unsigned char sha2_test_sum[6][32] =
{
/*
* SHA-224 test vectors
*/
{ 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
0xE3, 0x6C, 0x9D, 0xA7 },
{ 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
0x52, 0x52, 0x25, 0x25 },
{ 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
0x4E, 0xE7, 0xAD, 0x67 },
/*
* SHA-256 test vectors
*/
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
{ 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
};
/*
* RFC 4231 test vectors
*/
static unsigned char sha2_hmac_test_key[7][26] =
{
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
"\x0B\x0B\x0B\x0B" },
{ "Jefe" },
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
"\xAA\xAA\xAA\xAA" },
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
"\x0C\x0C\x0C\x0C" },
{ "" }, /* 0xAA 131 times */
{ "" }
};
static const int sha2_hmac_test_keylen[7] =
{
20, 4, 20, 25, 20, 131, 131
};
static unsigned char sha2_hmac_test_buf[7][153] =
{
{ "Hi There" },
{ "what do ya want for nothing?" },
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
{ "Test With Truncation" },
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
{ "This is a test using a larger than block-size key "
"and a larger than block-size data. The key needs to "
"be hashed before being used by the HMAC algorithm." }
};
static const int sha2_hmac_test_buflen[7] =
{
8, 28, 50, 50, 20, 54, 152
};
static const unsigned char sha2_hmac_test_sum[14][32] =
{
/*
* HMAC-SHA-224 test vectors
*/
{ 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
0x53, 0x68, 0x4B, 0x22 },
{ 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
0x8F, 0xD0, 0x5E, 0x44 },
{ 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
0xEC, 0x83, 0x33, 0xEA },
{ 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
0xE7, 0xAF, 0xEC, 0x5A },
{ 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
{ 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
0x3F, 0xA6, 0x87, 0x0E },
{ 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
0xF6, 0xF5, 0x65, 0xD1 },
/*
* HMAC-SHA-256 test vectors
*/
{ 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
{ 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
{ 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
{ 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
{ 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
{ 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
{ 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
};
/*
* Checkup routine
*/
int sha2_self_test( int verbose )
{
int i, j, k, buflen;
unsigned char buf[1024];
unsigned char sha2sum[32];
sha2_context ctx;
for( i = 0; i < 6; i++ )
{
j = i % 3;
k = i < 3;
if( verbose != 0 )
printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
sha2_starts( &ctx, k );
if( j == 2 )
{
memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ )
sha2_update( &ctx, buf, buflen );
}
else
sha2_update( &ctx, sha2_test_buf[j],
sha2_test_buflen[j] );
sha2_finish( &ctx, sha2sum );
if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
for( i = 0; i < 14; i++ )
{
j = i % 7;
k = i < 7;
if( verbose != 0 )
printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
if( j == 5 || j == 6 )
{
memset( buf, '\xAA', buflen = 131 );
sha2_hmac_starts( &ctx, buf, buflen, k );
}
else
sha2_hmac_starts( &ctx, sha2_hmac_test_key[j],
sha2_hmac_test_keylen[j], k );
sha2_hmac_update( &ctx, sha2_hmac_test_buf[j],
sha2_hmac_test_buflen[j] );
sha2_hmac_finish( &ctx, sha2sum );
buflen = ( j == 4 ) ? 16 : 32 - k * 4;
if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,757 @@
/*
* FIPS-180-2 compliant SHA-384/512 implementation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
*
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_SHA4_C)
#include "polarssl/sha4.h"
#include <string.h>
#include <stdio.h>
/*
* 64-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT64_BE
#define GET_UINT64_BE(n,b,i) \
{ \
(n) = ( (unsigned int64) (b)[(i) ] << 56 ) \
| ( (unsigned int64) (b)[(i) + 1] << 48 ) \
| ( (unsigned int64) (b)[(i) + 2] << 40 ) \
| ( (unsigned int64) (b)[(i) + 3] << 32 ) \
| ( (unsigned int64) (b)[(i) + 4] << 24 ) \
| ( (unsigned int64) (b)[(i) + 5] << 16 ) \
| ( (unsigned int64) (b)[(i) + 6] << 8 ) \
| ( (unsigned int64) (b)[(i) + 7] ); \
}
#endif
#ifndef PUT_UINT64_BE
#define PUT_UINT64_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 7] = (unsigned char) ( (n) ); \
}
#endif
/*
* Round constants
*/
static const unsigned int64 K[80] =
{
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
};
/*
* SHA-512 context setup
*/
void sha4_starts( sha4_context *ctx, int is384 )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
if( is384 == 0 )
{
/* SHA-512 */
ctx->state[0] = UL64(0x6A09E667F3BCC908);
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
ctx->state[4] = UL64(0x510E527FADE682D1);
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
ctx->state[7] = UL64(0x5BE0CD19137E2179);
}
else
{
/* SHA-384 */
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
ctx->state[1] = UL64(0x629A292A367CD507);
ctx->state[2] = UL64(0x9159015A3070DD17);
ctx->state[3] = UL64(0x152FECD8F70E5939);
ctx->state[4] = UL64(0x67332667FFC00B31);
ctx->state[5] = UL64(0x8EB44A8768581511);
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
}
ctx->is384 = is384;
}
static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
{
int i;
unsigned int64 temp1, temp2, W[80];
unsigned int64 A, B, C, D, E, F, G, H;
#define SHR(x,n) (x >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
for( i = 0; i < 16; i++ )
{
GET_UINT64_BE( W[i], data, i << 3 );
}
for( ; i < 80; i++ )
{
W[i] = S1(W[i - 2]) + W[i - 7] +
S0(W[i - 15]) + W[i - 16];
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
F = ctx->state[5];
G = ctx->state[6];
H = ctx->state[7];
i = 0;
do
{
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
}
while( i < 80 );
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
ctx->state[5] += F;
ctx->state[6] += G;
ctx->state[7] += H;
}
/*
* SHA-512 process buffer
*/
void sha4_update( sha4_context *ctx, const unsigned char *input, int ilen )
{
int fill;
unsigned int64 left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x7F;
fill = (int)( 128 - left );
ctx->total[0] += ilen;
if( ctx->total[0] < (unsigned int64) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
sha4_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 128 )
{
sha4_process( ctx, input );
input += 128;
ilen -= 128;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char sha4_padding[128] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* SHA-512 final digest
*/
void sha4_finish( sha4_context *ctx, unsigned char output[64] )
{
int last, padn;
unsigned int64 high, low;
unsigned char msglen[16];
high = ( ctx->total[0] >> 61 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT64_BE( high, msglen, 0 );
PUT_UINT64_BE( low, msglen, 8 );
last = (int)( ctx->total[0] & 0x7F );
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
sha4_update( ctx, (unsigned char *) sha4_padding, padn );
sha4_update( ctx, msglen, 16 );
PUT_UINT64_BE( ctx->state[0], output, 0 );
PUT_UINT64_BE( ctx->state[1], output, 8 );
PUT_UINT64_BE( ctx->state[2], output, 16 );
PUT_UINT64_BE( ctx->state[3], output, 24 );
PUT_UINT64_BE( ctx->state[4], output, 32 );
PUT_UINT64_BE( ctx->state[5], output, 40 );
if( ctx->is384 == 0 )
{
PUT_UINT64_BE( ctx->state[6], output, 48 );
PUT_UINT64_BE( ctx->state[7], output, 56 );
}
}
/*
* output = SHA-512( input buffer )
*/
void sha4( const unsigned char *input, int ilen,
unsigned char output[64], int is384 )
{
sha4_context ctx;
sha4_starts( &ctx, is384 );
sha4_update( &ctx, input, ilen );
sha4_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha4_context ) );
}
/*
* output = SHA-512( file contents )
*/
int sha4_file( const char *path, unsigned char output[64], int is384 )
{
FILE *f;
size_t n;
sha4_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( 1 );
sha4_starts( &ctx, is384 );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
sha4_update( &ctx, buf, (int) n );
sha4_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha4_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( 2 );
}
fclose( f );
return( 0 );
}
/*
* SHA-512 HMAC context setup
*/
void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, int keylen,
int is384 )
{
int i;
unsigned char sum[64];
if( keylen > 128 )
{
sha4( key, keylen, sum, is384 );
keylen = ( is384 ) ? 48 : 64;
key = sum;
}
memset( ctx->ipad, 0x36, 128 );
memset( ctx->opad, 0x5C, 128 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
sha4_starts( ctx, is384 );
sha4_update( ctx, ctx->ipad, 128 );
memset( sum, 0, sizeof( sum ) );
}
/*
* SHA-512 HMAC process buffer
*/
void sha4_hmac_update( sha4_context *ctx,
const unsigned char *input, int ilen )
{
sha4_update( ctx, input, ilen );
}
/*
* SHA-512 HMAC final digest
*/
void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] )
{
int is384, hlen;
unsigned char tmpbuf[64];
is384 = ctx->is384;
hlen = ( is384 == 0 ) ? 64 : 48;
sha4_finish( ctx, tmpbuf );
sha4_starts( ctx, is384 );
sha4_update( ctx, ctx->opad, 128 );
sha4_update( ctx, tmpbuf, hlen );
sha4_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* SHA-512 HMAC context reset
*/
void sha4_hmac_reset( sha4_context *ctx )
{
sha4_starts( ctx, ctx->is384 );
sha4_update( ctx, ctx->ipad, 128 );
}
/*
* output = HMAC-SHA-512( hmac key, input buffer )
*/
void sha4_hmac( const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
unsigned char output[64], int is384 )
{
sha4_context ctx;
sha4_hmac_starts( &ctx, key, keylen, is384 );
sha4_hmac_update( &ctx, input, ilen );
sha4_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( sha4_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* FIPS-180-2 test vectors
*/
static unsigned char sha4_test_buf[3][113] =
{
{ "abc" },
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
{ "" }
};
static const int sha4_test_buflen[3] =
{
3, 112, 1000
};
static const unsigned char sha4_test_sum[6][64] =
{
/*
* SHA-384 test vectors
*/
{ 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
{ 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
{ 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
/*
* SHA-512 test vectors
*/
{ 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
{ 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
{ 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
};
/*
* RFC 4231 test vectors
*/
static unsigned char sha4_hmac_test_key[7][26] =
{
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
"\x0B\x0B\x0B\x0B" },
{ "Jefe" },
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
"\xAA\xAA\xAA\xAA" },
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
"\x0C\x0C\x0C\x0C" },
{ "" }, /* 0xAA 131 times */
{ "" }
};
static const int sha4_hmac_test_keylen[7] =
{
20, 4, 20, 25, 20, 131, 131
};
static unsigned char sha4_hmac_test_buf[7][153] =
{
{ "Hi There" },
{ "what do ya want for nothing?" },
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
{ "Test With Truncation" },
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
{ "This is a test using a larger than block-size key "
"and a larger than block-size data. The key needs to "
"be hashed before being used by the HMAC algorithm." }
};
static const int sha4_hmac_test_buflen[7] =
{
8, 28, 50, 50, 20, 54, 152
};
static const unsigned char sha4_hmac_test_sum[14][64] =
{
/*
* HMAC-SHA-384 test vectors
*/
{ 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
{ 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
{ 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
{ 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
{ 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
{ 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
{ 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
/*
* HMAC-SHA-512 test vectors
*/
{ 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
{ 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
{ 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
{ 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
{ 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
{ 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
{ 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
};
/*
* Checkup routine
*/
int sha4_self_test( int verbose )
{
int i, j, k, buflen;
unsigned char buf[1024];
unsigned char sha4sum[64];
sha4_context ctx;
for( i = 0; i < 6; i++ )
{
j = i % 3;
k = i < 3;
if( verbose != 0 )
printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
sha4_starts( &ctx, k );
if( j == 2 )
{
memset( buf, 'a', buflen = 1000 );
for( j = 0; j < 1000; j++ )
sha4_update( &ctx, buf, buflen );
}
else
sha4_update( &ctx, sha4_test_buf[j],
sha4_test_buflen[j] );
sha4_finish( &ctx, sha4sum );
if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
for( i = 0; i < 14; i++ )
{
j = i % 7;
k = i < 7;
if( verbose != 0 )
printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
if( j == 5 || j == 6 )
{
memset( buf, '\xAA', buflen = 131 );
sha4_hmac_starts( &ctx, buf, buflen, k );
}
else
sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
sha4_hmac_test_keylen[j], k );
sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
sha4_hmac_test_buflen[j] );
sha4_hmac_finish( &ctx, sha4sum );
buflen = ( j == 4 ) ? 16 : 64 - k * 16;
if( memcmp( sha4sum, sha4_hmac_test_sum[i], buflen ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,789 @@
/*
* SSLv3/TLSv1 client-side functions
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_SSL_CLI_C)
#include "polarssl/debug.h"
#include "polarssl/ssl.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static int ssl_write_client_hello( ssl_context *ssl )
{
int ret, i, n;
unsigned char *buf;
unsigned char *p;
time_t t;
SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
ssl->major_ver = SSL_MAJOR_VERSION_3;
ssl->minor_ver = SSL_MINOR_VERSION_0;
ssl->max_major_ver = SSL_MAJOR_VERSION_3;
ssl->max_minor_ver = SSL_MINOR_VERSION_2;
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 highest version supported
* 6 . 9 current UNIX time
* 10 . 37 random bytes
*/
buf = ssl->out_msg;
p = buf + 4;
*p++ = (unsigned char) ssl->max_major_ver;
*p++ = (unsigned char) ssl->max_minor_ver;
SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
buf[4], buf[5] ) );
t = time( NULL );
*p++ = (unsigned char)( t >> 24 );
*p++ = (unsigned char)( t >> 16 );
*p++ = (unsigned char)( t >> 8 );
*p++ = (unsigned char)( t );
SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
for( i = 28; i > 0; i-- )
*p++ = (unsigned char) ssl->f_rng( ssl->p_rng );
memcpy( ssl->randbytes, buf + 6, 32 );
SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 );
/*
* 38 . 38 session id length
* 39 . 39+n session id
* 40+n . 41+n cipherlist length
* 42+n . .. cipherlist
* .. . .. compression alg. (0)
* .. . .. extensions (unused)
*/
n = ssl->session->length;
if( n < 16 || n > 32 || ssl->resume == 0 ||
( ssl->timeout != 0 && t - ssl->session->start > ssl->timeout ) )
n = 0;
*p++ = (unsigned char) n;
for( i = 0; i < n; i++ )
*p++ = ssl->session->id[i];
SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
for( n = 0; ssl->ciphers[n] != 0; n++ );
*p++ = (unsigned char)( n >> 7 );
*p++ = (unsigned char)( n << 1 );
SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphers", n ) );
for( i = 0; i < n; i++ )
{
SSL_DEBUG_MSG( 3, ( "client hello, add cipher: %2d",
ssl->ciphers[i] ) );
*p++ = (unsigned char)( ssl->ciphers[i] >> 8 );
*p++ = (unsigned char)( ssl->ciphers[i] );
}
SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", 0 ) );
*p++ = 1;
*p++ = SSL_COMPRESS_NULL;
if ( ssl->hostname != NULL )
{
SSL_DEBUG_MSG( 3, ( "client hello, server name extension: %s",
ssl->hostname ) );
*p++ = (unsigned char)( ( (ssl->hostname_len + 9) >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( (ssl->hostname_len + 9) ) & 0xFF );
*p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( TLS_EXT_SERVERNAME ) & 0xFF );
*p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( (ssl->hostname_len + 5) ) & 0xFF );
*p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( (ssl->hostname_len + 3) ) & 0xFF );
*p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
*p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( ssl->hostname_len ) & 0xFF );
memcpy( p, ssl->hostname, ssl->hostname_len );
p += ssl->hostname_len;
}
ssl->out_msglen = p - buf;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
ssl->state++;
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
}
SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
return( 0 );
}
static int ssl_parse_server_hello( ssl_context *ssl )
{
time_t t;
int ret, i, n;
int ext_len;
unsigned char *buf;
SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 protocol version
* 6 . 9 UNIX time()
* 10 . 37 random bytes
*/
buf = ssl->in_msg;
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
buf[4], buf[5] ) );
if( ssl->in_hslen < 42 ||
buf[0] != SSL_HS_SERVER_HELLO ||
buf[4] != SSL_MAJOR_VERSION_3 )
{
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
}
if( buf[5] > ssl->max_minor_ver )
{
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
}
ssl->minor_ver = buf[5];
t = ( (time_t) buf[6] << 24 )
| ( (time_t) buf[7] << 16 )
| ( (time_t) buf[8] << 8 )
| ( (time_t) buf[9] );
memcpy( ssl->randbytes + 32, buf + 6, 32 );
n = buf[38];
SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
/*
* 38 . 38 session id length
* 39 . 38+n session id
* 39+n . 40+n chosen cipher
* 41+n . 41+n chosen compression alg.
* 42+n . 43+n extensions length
* 44+n . 44+n+m extensions
*/
if( n < 0 || n > 32 || ssl->in_hslen > 42 + n )
{
ext_len = ( ( buf[42 + n] << 8 )
| ( buf[43 + n] ) ) + 2;
}
else
{
ext_len = 0;
}
if( n < 0 || n > 32 || ssl->in_hslen != 42 + n + ext_len )
{
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
}
i = ( buf[39 + n] << 8 ) | buf[40 + n];
SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
/*
* Check if the session can be resumed
*/
if( ssl->resume == 0 || n == 0 ||
ssl->session->cipher != i ||
ssl->session->length != n ||
memcmp( ssl->session->id, buf + 39, n ) != 0 )
{
ssl->state++;
ssl->resume = 0;
ssl->session->start = time( NULL );
ssl->session->cipher = i;
ssl->session->length = n;
memcpy( ssl->session->id, buf + 39, n );
}
else
{
ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
return( ret );
}
}
SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->resume ? "a" : "no" ) );
SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d", i ) );
SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
i = 0;
while( 1 )
{
if( ssl->ciphers[i] == 0 )
{
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
}
if( ssl->ciphers[i++] == ssl->session->cipher )
break;
}
if( buf[41 + n] != SSL_COMPRESS_NULL )
{
SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
}
/* TODO: Process extensions */
SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
return( 0 );
}
static int ssl_parse_server_key_exchange( ssl_context *ssl )
{
int ret, n;
unsigned char *p, *end;
unsigned char hash[36];
md5_context md5;
sha1_context sha1;
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
if( ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
ssl->session->cipher != SSL_EDH_RSA_AES_128_SHA &&
ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_128_SHA &&
ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA)
{
SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ssl->state++;
return( 0 );
}
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
p = ssl->in_msg + 4;
end = ssl->in_msg + ssl->in_hslen;
if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
if( (int)( end - p ) != ssl->peer_cert->rsa.len )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P );
SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G );
SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
/*
* digitally-signed struct {
* opaque md5_hash[16];
* opaque sha_hash[20];
* };
*
* md5_hash
* MD5(ClientHello.random + ServerHello.random
* + ServerParams);
* sha_hash
* SHA(ClientHello.random + ServerHello.random
* + ServerParams);
*/
n = ssl->in_hslen - ( end - p ) - 6;
md5_starts( &md5 );
md5_update( &md5, ssl->randbytes, 64 );
md5_update( &md5, ssl->in_msg + 4, n );
md5_finish( &md5, hash );
sha1_starts( &sha1 );
sha1_update( &sha1, ssl->randbytes, 64 );
sha1_update( &sha1, ssl->in_msg + 4, n );
sha1_finish( &sha1, hash + 16 );
SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
SIG_RSA_RAW, 36, hash, p ) ) != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
return( ret );
}
ssl->state++;
SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
return( 0 );
#endif
}
static int ssl_parse_certificate_request( ssl_context *ssl )
{
int ret;
SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 SSL version
* 6 . 6 cert type count
* 7 .. n-1 cert types
* n .. n+1 length of all DNs
* n+2 .. n+3 length of DN 1
* n+4 .. ... Distinguished Name #1
* ... .. ... length of DN 2, etc.
*/
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
ssl->client_auth = 0;
ssl->state++;
if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
ssl->client_auth++;
SSL_DEBUG_MSG( 3, ( "got %s certificate request",
ssl->client_auth ? "a" : "no" ) );
SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
return( 0 );
}
static int ssl_parse_server_hello_done( ssl_context *ssl )
{
int ret;
SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
if( ssl->client_auth != 0 )
{
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
}
}
if( ssl->in_hslen != 4 ||
ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
{
SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
}
ssl->state++;
SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
return( 0 );
}
static int ssl_write_client_key_exchange( ssl_context *ssl )
{
int ret, i, n;
SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
ssl->session->cipher == SSL_EDH_RSA_AES_128_SHA ||
ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_128_SHA ||
ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
{
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* DHM key exchange -- send G^X mod P
*/
n = ssl->dhm_ctx.len;
ssl->out_msg[4] = (unsigned char)( n >> 8 );
ssl->out_msg[5] = (unsigned char)( n );
i = 6;
ret = dhm_make_public( &ssl->dhm_ctx, 256,
&ssl->out_msg[i], n,
ssl->f_rng, ssl->p_rng );
if( ret != 0 )
{
SSL_DEBUG_RET( 1, "dhm_make_public", ret );
return( ret );
}
SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X );
SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
ssl->pmslen = ssl->dhm_ctx.len;
if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
ssl->premaster,
&ssl->pmslen ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
return( ret );
}
SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K );
#endif
}
else
{
/*
* RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
*/
ssl->premaster[0] = (unsigned char) ssl->max_major_ver;
ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
ssl->pmslen = 48;
for( i = 2; i < ssl->pmslen; i++ )
ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
i = 4;
n = ssl->peer_cert->rsa.len;
if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
{
i += 2;
ssl->out_msg[4] = (unsigned char)( n >> 8 );
ssl->out_msg[5] = (unsigned char)( n );
}
ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa,
ssl->f_rng, ssl->p_rng,
RSA_PUBLIC,
ssl->pmslen, ssl->premaster,
ssl->out_msg + i );
if( ret != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
return( ret );
}
}
if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
return( ret );
}
ssl->out_msglen = i + n;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
ssl->state++;
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
}
SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
return( 0 );
}
static int ssl_write_certificate_verify( ssl_context *ssl )
{
int ret, n;
unsigned char hash[36];
SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
if( ssl->client_auth == 0 )
{
SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
return( 0 );
}
if( ssl->rsa_key == NULL )
{
SSL_DEBUG_MSG( 1, ( "got no private key" ) );
return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
}
/*
* Make an RSA signature of the handshake digests
*/
ssl_calc_verify( ssl, hash );
n = ssl->rsa_key->len;
ssl->out_msg[4] = (unsigned char)( n >> 8 );
ssl->out_msg[5] = (unsigned char)( n );
if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW,
36, hash, ssl->out_msg + 6 ) ) != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret );
return( ret );
}
ssl->out_msglen = 6 + n;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
ssl->state++;
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
}
SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
return( 0 );
}
/*
* SSL handshake -- client side
*/
int ssl_handshake_client( ssl_context *ssl )
{
int ret = 0;
SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
while( ssl->state != SSL_HANDSHAKE_OVER )
{
SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
if( ( ret = ssl_flush_output( ssl ) ) != 0 )
break;
switch( ssl->state )
{
case SSL_HELLO_REQUEST:
ssl->state = SSL_CLIENT_HELLO;
break;
/*
* ==> ClientHello
*/
case SSL_CLIENT_HELLO:
ret = ssl_write_client_hello( ssl );
break;
/*
* <== ServerHello
* Certificate
* ( ServerKeyExchange )
* ( CertificateRequest )
* ServerHelloDone
*/
case SSL_SERVER_HELLO:
ret = ssl_parse_server_hello( ssl );
break;
case SSL_SERVER_CERTIFICATE:
ret = ssl_parse_certificate( ssl );
break;
case SSL_SERVER_KEY_EXCHANGE:
ret = ssl_parse_server_key_exchange( ssl );
break;
case SSL_CERTIFICATE_REQUEST:
ret = ssl_parse_certificate_request( ssl );
break;
case SSL_SERVER_HELLO_DONE:
ret = ssl_parse_server_hello_done( ssl );
break;
/*
* ==> ( Certificate/Alert )
* ClientKeyExchange
* ( CertificateVerify )
* ChangeCipherSpec
* Finished
*/
case SSL_CLIENT_CERTIFICATE:
ret = ssl_write_certificate( ssl );
break;
case SSL_CLIENT_KEY_EXCHANGE:
ret = ssl_write_client_key_exchange( ssl );
break;
case SSL_CERTIFICATE_VERIFY:
ret = ssl_write_certificate_verify( ssl );
break;
case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ret = ssl_write_change_cipher_spec( ssl );
break;
case SSL_CLIENT_FINISHED:
ret = ssl_write_finished( ssl );
break;
/*
* <== ChangeCipherSpec
* Finished
*/
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;
case SSL_SERVER_FINISHED:
ret = ssl_parse_finished( ssl );
break;
case SSL_FLUSH_BUFFERS:
SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
ssl->state = SSL_HANDSHAKE_OVER;
break;
default:
SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
if( ret != 0 )
break;
}
SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
return( ret );
}
#endif

View File

@@ -0,0 +1,951 @@
/*
* SSLv3/TLSv1 server-side functions
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_SSL_SRV_C)
#include "polarssl/debug.h"
#include "polarssl/ssl.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static int ssl_parse_client_hello( ssl_context *ssl )
{
int ret, i, j, n;
int ciph_len, sess_len;
int chal_len, comp_len;
unsigned char *buf, *p;
SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
return( ret );
}
buf = ssl->in_hdr;
if( ( buf[0] & 0x80 ) != 0 )
{
SSL_DEBUG_BUF( 4, "record header", buf, 5 );
SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d",
buf[2] ) );
SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d",
( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) );
SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]",
buf[3], buf[4] ) );
/*
* SSLv2 Client Hello
*
* Record layer:
* 0 . 1 message length
*
* SSL layer:
* 2 . 2 message type
* 3 . 4 protocol version
*/
if( buf[2] != SSL_HS_CLIENT_HELLO ||
buf[3] != SSL_MAJOR_VERSION_3 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF;
if( n < 17 || n > 512 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
ssl->max_major_ver = buf[3];
ssl->max_minor_ver = buf[4];
ssl->major_ver = SSL_MAJOR_VERSION_3;
ssl->minor_ver = ( buf[4] <= SSL_MINOR_VERSION_2 )
? buf[4] : SSL_MINOR_VERSION_2;
if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
return( ret );
}
md5_update( &ssl->fin_md5 , buf + 2, n );
sha1_update( &ssl->fin_sha1, buf + 2, n );
buf = ssl->in_msg;
n = ssl->in_left - 5;
/*
* 0 . 1 cipherlist length
* 2 . 3 session id length
* 4 . 5 challenge length
* 6 . .. cipherlist
* .. . .. session id
* .. . .. challenge
*/
SSL_DEBUG_BUF( 4, "record contents", buf, n );
ciph_len = ( buf[0] << 8 ) | buf[1];
sess_len = ( buf[2] << 8 ) | buf[3];
chal_len = ( buf[4] << 8 ) | buf[5];
SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
ciph_len, sess_len, chal_len ) );
/*
* Make sure each parameter length is valid
*/
if( ciph_len < 3 || ( ciph_len % 3 ) != 0 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( sess_len < 0 || sess_len > 32 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( chal_len < 8 || chal_len > 32 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( n != 6 + ciph_len + sess_len + chal_len )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
SSL_DEBUG_BUF( 3, "client hello, cipherlist",
buf + 6, ciph_len );
SSL_DEBUG_BUF( 3, "client hello, session id",
buf + 6 + ciph_len, sess_len );
SSL_DEBUG_BUF( 3, "client hello, challenge",
buf + 6 + ciph_len + sess_len, chal_len );
p = buf + 6 + ciph_len;
ssl->session->length = sess_len;
memset( ssl->session->id, 0, sizeof( ssl->session->id ) );
memcpy( ssl->session->id, p, ssl->session->length );
p += sess_len;
memset( ssl->randbytes, 0, 64 );
memcpy( ssl->randbytes + 32 - chal_len, p, chal_len );
for( i = 0; ssl->ciphers[i] != 0; i++ )
{
for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
{
if( p[0] == 0 &&
p[1] == 0 &&
p[2] == ssl->ciphers[i] )
goto have_cipher;
}
}
}
else
{
SSL_DEBUG_BUF( 4, "record header", buf, 5 );
SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d",
buf[0] ) );
SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d",
( buf[3] << 8 ) | buf[4] ) );
SSL_DEBUG_MSG( 3, ( "client hello v3, protocol ver: [%d:%d]",
buf[1], buf[2] ) );
/*
* SSLv3 Client Hello
*
* Record layer:
* 0 . 0 message type
* 1 . 2 protocol version
* 3 . 4 message length
*/
if( buf[0] != SSL_MSG_HANDSHAKE ||
buf[1] != SSL_MAJOR_VERSION_3 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
n = ( buf[3] << 8 ) | buf[4];
if( n < 45 || n > 512 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( ( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_fetch_input", ret );
return( ret );
}
buf = ssl->in_msg;
n = ssl->in_left - 5;
md5_update( &ssl->fin_md5 , buf, n );
sha1_update( &ssl->fin_sha1, buf, n );
/*
* SSL layer:
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 protocol version
* 6 . 9 UNIX time()
* 10 . 37 random bytes
* 38 . 38 session id length
* 39 . 38+x session id
* 39+x . 40+x cipherlist length
* 41+x . .. cipherlist
* .. . .. compression alg.
* .. . .. extensions
*/
SSL_DEBUG_BUF( 4, "record contents", buf, n );
SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d",
buf[0] ) );
SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) );
SSL_DEBUG_MSG( 3, ( "client hello v3, max. version: [%d:%d]",
buf[4], buf[5] ) );
/*
* Check the handshake type and protocol version
*/
if( buf[0] != SSL_HS_CLIENT_HELLO ||
buf[4] != SSL_MAJOR_VERSION_3 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
ssl->major_ver = SSL_MAJOR_VERSION_3;
ssl->minor_ver = ( buf[5] <= SSL_MINOR_VERSION_2 )
? buf[5] : SSL_MINOR_VERSION_2;
ssl->max_major_ver = buf[4];
ssl->max_minor_ver = buf[5];
memcpy( ssl->randbytes, buf + 6, 32 );
/*
* Check the handshake message length
*/
if( buf[1] != 0 || n != 4 + ( ( buf[2] << 8 ) | buf[3] ) )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
/*
* Check the session length
*/
sess_len = buf[38];
if( sess_len < 0 || sess_len > 32 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
ssl->session->length = sess_len;
memset( ssl->session->id, 0, sizeof( ssl->session->id ) );
memcpy( ssl->session->id, buf + 39 , ssl->session->length );
/*
* Check the cipherlist length
*/
ciph_len = ( buf[39 + sess_len] << 8 )
| ( buf[40 + sess_len] );
if( ciph_len < 2 || ciph_len > 256 || ( ciph_len % 2 ) != 0 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
/*
* Check the compression algorithms length
*/
comp_len = buf[41 + sess_len + ciph_len];
if( comp_len < 1 || comp_len > 16 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
SSL_DEBUG_BUF( 3, "client hello, random bytes",
buf + 6, 32 );
SSL_DEBUG_BUF( 3, "client hello, session id",
buf + 38, sess_len );
SSL_DEBUG_BUF( 3, "client hello, cipherlist",
buf + 41 + sess_len, ciph_len );
SSL_DEBUG_BUF( 3, "client hello, compression",
buf + 42 + sess_len + ciph_len, comp_len );
/*
* Search for a matching cipher
*/
for( i = 0; ssl->ciphers[i] != 0; i++ )
{
for( j = 0, p = buf + 41 + sess_len; j < ciph_len;
j += 2, p += 2 )
{
if( p[0] == 0 && p[1] == ssl->ciphers[i] )
goto have_cipher;
}
}
}
SSL_DEBUG_MSG( 1, ( "got no ciphers in common" ) );
return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
have_cipher:
ssl->session->cipher = ssl->ciphers[i];
ssl->in_left = 0;
ssl->state++;
SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
return( 0 );
}
static int ssl_write_server_hello( ssl_context *ssl )
{
time_t t;
int ret, i, n;
unsigned char *buf, *p;
SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 5 protocol version
* 6 . 9 UNIX time()
* 10 . 37 random bytes
*/
buf = ssl->out_msg;
p = buf + 4;
*p++ = (unsigned char) ssl->major_ver;
*p++ = (unsigned char) ssl->minor_ver;
SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
buf[4], buf[5] ) );
t = time( NULL );
*p++ = (unsigned char)( t >> 24 );
*p++ = (unsigned char)( t >> 16 );
*p++ = (unsigned char)( t >> 8 );
*p++ = (unsigned char)( t );
SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
for( i = 28; i > 0; i-- )
*p++ = (unsigned char) ssl->f_rng( ssl->p_rng );
memcpy( ssl->randbytes + 32, buf + 6, 32 );
SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
/*
* 38 . 38 session id length
* 39 . 38+n session id
* 39+n . 40+n chosen cipher
* 41+n . 41+n chosen compression alg.
*/
ssl->session->length = n = 32;
*p++ = (unsigned char) ssl->session->length;
if( ssl->s_get == NULL ||
ssl->s_get( ssl ) != 0 )
{
/*
* Not found, create a new session id
*/
ssl->resume = 0;
ssl->state++;
for( i = 0; i < n; i++ )
ssl->session->id[i] =
(unsigned char) ssl->f_rng( ssl->p_rng );
}
else
{
/*
* Found a matching session, resume it
*/
ssl->resume = 1;
ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
return( ret );
}
}
memcpy( p, ssl->session->id, ssl->session->length );
p += ssl->session->length;
SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->resume ? "a" : "no" ) );
*p++ = (unsigned char)( ssl->session->cipher >> 8 );
*p++ = (unsigned char)( ssl->session->cipher );
*p++ = SSL_COMPRESS_NULL;
SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d",
ssl->session->cipher ) );
SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", 0 ) );
ssl->out_msglen = p - buf;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_SERVER_HELLO;
ret = ssl_write_record( ssl );
SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
return( ret );
}
static int ssl_write_certificate_request( ssl_context *ssl )
{
int ret, n;
unsigned char *buf, *p;
const x509_cert *crt;
SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
ssl->state++;
if( ssl->authmode == SSL_VERIFY_NONE )
{
SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
return( 0 );
}
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
* 4 . 4 cert type count
* 5 .. n-1 cert types
* n .. n+1 length of all DNs
* n+2 .. n+3 length of DN 1
* n+4 .. ... Distinguished Name #1
* ... .. ... length of DN 2, etc.
*/
buf = ssl->out_msg;
p = buf + 4;
/*
* At the moment, only RSA certificates are supported
*/
*p++ = 1;
*p++ = 1;
p += 2;
crt = ssl->ca_chain;
while( crt != NULL )
{
if( p - buf > 4096 )
break;
n = crt->subject_raw.len;
*p++ = (unsigned char)( n >> 8 );
*p++ = (unsigned char)( n );
memcpy( p, crt->subject_raw.p, n );
SSL_DEBUG_BUF( 3, "requested DN", p, n );
p += n; crt = crt->next;
}
ssl->out_msglen = n = p - buf;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST;
ssl->out_msg[6] = (unsigned char)( ( n - 8 ) >> 8 );
ssl->out_msg[7] = (unsigned char)( ( n - 8 ) );
ret = ssl_write_record( ssl );
SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) );
return( ret );
}
static int ssl_write_server_key_exchange( ssl_context *ssl )
{
int ret, n;
unsigned char hash[36];
md5_context md5;
sha1_context sha1;
SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
if( ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
ssl->session->cipher != SSL_EDH_RSA_AES_128_SHA &&
ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_128_SHA &&
ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA)
{
SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm is not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
if( ( ret = dhm_make_params( &ssl->dhm_ctx, 256, ssl->out_msg + 4,
&n, ssl->f_rng, ssl->p_rng ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_make_params", ret );
return( ret );
}
SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X );
SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P );
SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G );
SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
/*
* digitally-signed struct {
* opaque md5_hash[16];
* opaque sha_hash[20];
* };
*
* md5_hash
* MD5(ClientHello.random + ServerHello.random
* + ServerParams);
* sha_hash
* SHA(ClientHello.random + ServerHello.random
* + ServerParams);
*/
md5_starts( &md5 );
md5_update( &md5, ssl->randbytes, 64 );
md5_update( &md5, ssl->out_msg + 4, n );
md5_finish( &md5, hash );
sha1_starts( &sha1 );
sha1_update( &sha1, ssl->randbytes, 64 );
sha1_update( &sha1, ssl->out_msg + 4, n );
sha1_finish( &sha1, hash + 16 );
SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
ssl->out_msg[4 + n] = (unsigned char)( ssl->rsa_key->len >> 8 );
ssl->out_msg[5 + n] = (unsigned char)( ssl->rsa_key->len );
ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE,
SIG_RSA_RAW, 36, hash, ssl->out_msg + 6 + n );
if( ret != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret );
return( ret );
}
SSL_DEBUG_BUF( 3, "my RSA sig", ssl->out_msg + 6 + n,
ssl->rsa_key->len );
ssl->out_msglen = 6 + n + ssl->rsa_key->len;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_SERVER_KEY_EXCHANGE;
ssl->state++;
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
}
SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
return( 0 );
#endif
}
static int ssl_write_server_hello_done( ssl_context *ssl )
{
int ret;
SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) );
ssl->out_msglen = 4;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_SERVER_HELLO_DONE;
ssl->state++;
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
}
SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) );
return( 0 );
}
static int ssl_parse_client_key_exchange( ssl_context *ssl )
{
int ret, i, n;
SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( ssl->in_msg[0] != SSL_HS_CLIENT_KEY_EXCHANGE )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
ssl->session->cipher == SSL_EDH_RSA_AES_128_SHA ||
ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_128_SHA ||
ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
{
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm is not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* Receive G^Y mod P, premaster = (G^Y)^X mod P
*/
n = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
if( n < 1 || n > ssl->dhm_ctx.len ||
n + 6 != ssl->in_hslen )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( ( ret = dhm_read_public( &ssl->dhm_ctx,
ssl->in_msg + 6, n ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_read_public", ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
}
SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
ssl->pmslen = ssl->dhm_ctx.len;
if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
ssl->premaster, &ssl->pmslen ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE | ret );
}
SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K );
#endif
}
else
{
/*
* Decrypt the premaster using own private RSA key
*/
i = 4;
n = ssl->rsa_key->len;
ssl->pmslen = 48;
if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
{
i += 2;
if( ssl->in_msg[4] != ( ( n >> 8 ) & 0xFF ) ||
ssl->in_msg[5] != ( ( n ) & 0xFF ) )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
}
if( ssl->in_hslen != i + n )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
ret = rsa_pkcs1_decrypt( ssl->rsa_key, RSA_PRIVATE, &ssl->pmslen,
ssl->in_msg + i, ssl->premaster,
sizeof(ssl->premaster) );
if( ret != 0 || ssl->pmslen != 48 ||
ssl->premaster[0] != ssl->max_major_ver ||
ssl->premaster[1] != ssl->max_minor_ver )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
/*
* Protection against Bleichenbacher's attack:
* invalid PKCS#1 v1.5 padding must not cause
* the connection to end immediately; instead,
* send a bad_record_mac later in the handshake.
*/
ssl->pmslen = 48;
for( i = 0; i < ssl->pmslen; i++ )
ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
}
}
if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
return( ret );
}
if( ssl->s_set != NULL )
ssl->s_set( ssl );
ssl->state++;
SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) );
return( 0 );
}
static int ssl_parse_certificate_verify( ssl_context *ssl )
{
int n1, n2, ret;
unsigned char hash[36];
SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
if( ssl->peer_cert == NULL )
{
SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
return( 0 );
}
ssl_calc_verify( ssl, hash );
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
ssl->state++;
if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
{
SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
}
if( ssl->in_msg[0] != SSL_HS_CERTIFICATE_VERIFY )
{
SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
}
n1 = ssl->peer_cert->rsa.len;
n2 = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
if( n1 + 6 != ssl->in_hslen || n1 != n2 )
{
SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
}
ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
SIG_RSA_RAW, 36, hash, ssl->in_msg + 6 );
if( ret != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
return( ret );
}
SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
return( 0 );
}
/*
* SSL handshake -- server side
*/
int ssl_handshake_server( ssl_context *ssl )
{
int ret = 0;
SSL_DEBUG_MSG( 2, ( "=> handshake server" ) );
while( ssl->state != SSL_HANDSHAKE_OVER )
{
SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
if( ( ret = ssl_flush_output( ssl ) ) != 0 )
break;
switch( ssl->state )
{
case SSL_HELLO_REQUEST:
ssl->state = SSL_CLIENT_HELLO;
break;
/*
* <== ClientHello
*/
case SSL_CLIENT_HELLO:
ret = ssl_parse_client_hello( ssl );
break;
/*
* ==> ServerHello
* Certificate
* ( ServerKeyExchange )
* ( CertificateRequest )
* ServerHelloDone
*/
case SSL_SERVER_HELLO:
ret = ssl_write_server_hello( ssl );
break;
case SSL_SERVER_CERTIFICATE:
ret = ssl_write_certificate( ssl );
break;
case SSL_SERVER_KEY_EXCHANGE:
ret = ssl_write_server_key_exchange( ssl );
break;
case SSL_CERTIFICATE_REQUEST:
ret = ssl_write_certificate_request( ssl );
break;
case SSL_SERVER_HELLO_DONE:
ret = ssl_write_server_hello_done( ssl );
break;
/*
* <== ( Certificate/Alert )
* ClientKeyExchange
* ( CertificateVerify )
* ChangeCipherSpec
* Finished
*/
case SSL_CLIENT_CERTIFICATE:
ret = ssl_parse_certificate( ssl );
break;
case SSL_CLIENT_KEY_EXCHANGE:
ret = ssl_parse_client_key_exchange( ssl );
break;
case SSL_CERTIFICATE_VERIFY:
ret = ssl_parse_certificate_verify( ssl );
break;
case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;
case SSL_CLIENT_FINISHED:
ret = ssl_parse_finished( ssl );
break;
/*
* ==> ChangeCipherSpec
* Finished
*/
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_write_change_cipher_spec( ssl );
break;
case SSL_SERVER_FINISHED:
ret = ssl_write_finished( ssl );
break;
case SSL_FLUSH_BUFFERS:
SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
ssl->state = SSL_HANDSHAKE_OVER;
break;
default:
SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
if( ret != 0 )
break;
}
SSL_DEBUG_MSG( 2, ( "<= handshake server" ) );
return( ret );
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,258 @@
/*
* Portable interface to the CPU cycle counter
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_TIMING_C)
#include "polarssl/timing.h"
#if defined(_WIN32)
#include <windows.h>
#include <winbase.h>
struct _hr_time
{
LARGE_INTEGER start;
};
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <time.h>
struct _hr_time
{
struct timeval start;
};
#endif
#if defined(POLARSSL_HAVE_ASM) && \
(defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
unsigned long hardclock( void )
{
unsigned long tsc;
__asm rdtsc
__asm mov [tsc], eax
return( tsc );
}
#else
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__)
unsigned long hardclock( void )
{
unsigned long tsc;
asm( "rdtsc" : "=a" (tsc) );
return( tsc );
}
#else
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && \
(defined(__amd64__) || defined(__x86_64__))
unsigned long hardclock( void )
{
unsigned long lo, hi;
asm( "rdtsc" : "=a" (lo), "=d" (hi) );
return( lo | (hi << 32) );
}
#else
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && \
(defined(__powerpc__) || defined(__ppc__))
unsigned long hardclock( void )
{
unsigned long tbl, tbu0, tbu1;
do
{
asm( "mftbu %0" : "=r" (tbu0) );
asm( "mftb %0" : "=r" (tbl ) );
asm( "mftbu %0" : "=r" (tbu1) );
}
while( tbu0 != tbu1 );
return( tbl );
}
#else
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__sparc__)
unsigned long hardclock( void )
{
unsigned long tick;
asm( ".byte 0x83, 0x41, 0x00, 0x00" );
asm( "mov %%g1, %0" : "=r" (tick) );
return( tick );
}
#else
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__alpha__)
unsigned long hardclock( void )
{
unsigned long cc;
asm( "rpcc %0" : "=r" (cc) );
return( cc & 0xFFFFFFFF );
}
#else
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__ia64__)
unsigned long hardclock( void )
{
unsigned long itc;
asm( "mov %0 = ar.itc" : "=r" (itc) );
return( itc );
}
#else
static int hardclock_init = 0;
static struct timeval tv_init;
unsigned long hardclock( void )
{
struct timeval tv_cur;
if( hardclock_init == 0 )
{
gettimeofday( &tv_init, NULL );
hardclock_init = 1;
}
gettimeofday( &tv_cur, NULL );
return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
+ ( tv_cur.tv_usec - tv_init.tv_usec ) );
}
#endif /* generic */
#endif /* IA-64 */
#endif /* Alpha */
#endif /* SPARC8 */
#endif /* PowerPC */
#endif /* AMD64 */
#endif /* i586+ */
int alarmed = 0;
#if defined(_WIN32)
unsigned long get_timer( struct hr_time *val, int reset )
{
unsigned long delta;
LARGE_INTEGER offset, hfreq;
struct _hr_time *t = (struct _hr_time *) val;
QueryPerformanceCounter( &offset );
QueryPerformanceFrequency( &hfreq );
delta = (unsigned long)( ( 1000 *
( offset.QuadPart - t->start.QuadPart ) ) /
hfreq.QuadPart );
if( reset )
QueryPerformanceCounter( &t->start );
return( delta );
}
DWORD WINAPI TimerProc( LPVOID uElapse )
{
Sleep( (DWORD) uElapse );
alarmed = 1;
return( TRUE );
}
void set_alarm( int seconds )
{
DWORD ThreadId;
alarmed = 0;
CloseHandle( CreateThread( NULL, 0, TimerProc,
(LPVOID) ( seconds * 1000 ), 0, &ThreadId ) );
}
void m_sleep( int milliseconds )
{
Sleep( milliseconds );
}
#else
unsigned long get_timer( struct hr_time *val, int reset )
{
unsigned long delta;
struct timeval offset;
struct _hr_time *t = (struct _hr_time *) val;
gettimeofday( &offset, NULL );
delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
+ ( offset.tv_usec - t->start.tv_usec ) / 1000;
if( reset )
{
t->start.tv_sec = offset.tv_sec;
t->start.tv_usec = offset.tv_usec;
}
return( delta );
}
static void sighandler( int signum )
{
alarmed = 1;
signal( signum, sighandler );
}
void set_alarm( int seconds )
{
alarmed = 0;
signal( SIGALRM, sighandler );
alarm( seconds );
}
void m_sleep( int milliseconds )
{
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
tv.tv_usec = milliseconds * 1000;
select( 0, NULL, NULL, NULL, &tv );
}
#endif
#endif

View File

@@ -0,0 +1,50 @@
/*
* Version information
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_VERSION_C)
#include "polarssl/version.h"
#include <string.h>
const char version[] = POLARSSL_VERSION_STRING;
unsigned int version_get_number()
{
return POLARSSL_VERSION_NUMBER;
}
void version_get_string( char *string )
{
memcpy( string, POLARSSL_VERSION_STRING, sizeof( POLARSSL_VERSION_STRING ) );
}
void version_get_string_full( char *string )
{
memcpy( string, POLARSSL_VERSION_STRING_FULL, sizeof( POLARSSL_VERSION_STRING_FULL ) );
}
#endif /* POLARSSL_VERSION_C */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,198 @@
/*
* An 32-bit implementation of the XTEA algorithm
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_XTEA_C)
#include "polarssl/xtea.h"
#include <string.h>
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* XTEA key schedule
*/
void xtea_setup( xtea_context *ctx, unsigned char key[16] )
{
int i;
memset(ctx, 0, sizeof(xtea_context));
for( i = 0; i < 4; i++ )
{
GET_ULONG_BE( ctx->k[i], key, i << 2 );
}
}
/*
* XTEA encrypt function
*/
int xtea_crypt_ecb( xtea_context *ctx, int mode, unsigned char input[8],
unsigned char output[8])
{
uint32_t *k, v0, v1, i;
k = ctx->k;
GET_ULONG_BE( v0, input, 0 );
GET_ULONG_BE( v1, input, 4 );
if( mode == XTEA_ENCRYPT )
{
uint32_t sum = 0, delta = 0x9E3779B9;
for( i = 0; i < 32; i++ )
{
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
}
}
else /* XTEA_DECRYPT */
{
uint32_t delta = 0x9E3779B9, sum = delta * 32;
for( i = 0; i < 32; i++ )
{
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
}
PUT_ULONG_BE( v0, output, 0 );
PUT_ULONG_BE( v1, output, 4 );
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
/*
* XTEA tests vectors (non-official)
*/
static const unsigned char xtea_test_key[6][16] =
{
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char xtea_test_pt[6][8] =
{
{ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
{ 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
{ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
{ 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
};
static const unsigned char xtea_test_ct[6][8] =
{
{ 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
{ 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
{ 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
{ 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
};
/*
* Checkup routine
*/
int xtea_self_test( int verbose )
{
int i;
unsigned char buf[8];
xtea_context ctx;
for( i = 0; i < 6; i++ )
{
if( verbose != 0 )
printf( " XTEA test #%d: ", i + 1 );
memcpy( buf, xtea_test_pt[i], 8 );
xtea_setup( &ctx, (unsigned char *) xtea_test_key[i] );
xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf );
if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,6 @@
add_subdirectory(aes)
add_subdirectory(hash)
add_subdirectory(pkey)
add_subdirectory(ssl)
add_subdirectory(test)
add_subdirectory(x509)

View File

@@ -0,0 +1,106 @@
# To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS
# To compile on MinGW: add "-lws2_32" to LDFLAGS
CFLAGS = -I../include -D_FILE_OFFSET_BITS=64 -Wall -Wdeclaration-after-statement
OFLAGS = -O
LDFLAGS = -L../library -lpolarssl
APPS = aes/aescrypt2 hash/hello \
hash/md5sum hash/sha1sum \
hash/sha2sum pkey/dh_client \
pkey/dh_genprime pkey/dh_server \
pkey/mpi_demo pkey/rsa_genkey \
pkey/rsa_sign pkey/rsa_verify \
ssl/ssl_client1 ssl/ssl_client2 \
ssl/ssl_server test/ssl_cert_test \
test/benchmark test/selftest \
test/ssl_test x509/cert_app
.SILENT:
all: $(APPS)
aes/aescrypt2: aes/aescrypt2.c ../library/libpolarssl.a
echo " CC aes/aescrypt2.c"
$(CC) $(CFLAGS) $(OFLAGS) aes/aescrypt2.c $(LDFLAGS) -o $@
hash/hello: hash/hello.c ../library/libpolarssl.a
echo " CC hash/hello.c"
$(CC) $(CFLAGS) $(OFLAGS) hash/hello.c $(LDFLAGS) -o $@
hash/md5sum: hash/md5sum.c ../library/libpolarssl.a
echo " CC hash/md5sum.c"
$(CC) $(CFLAGS) $(OFLAGS) hash/md5sum.c $(LDFLAGS) -o $@
hash/sha1sum: hash/sha1sum.c ../library/libpolarssl.a
echo " CC hash/sha1sum.c"
$(CC) $(CFLAGS) $(OFLAGS) hash/sha1sum.c $(LDFLAGS) -o $@
hash/sha2sum: hash/sha2sum.c ../library/libpolarssl.a
echo " CC hash/sha2sum.c"
$(CC) $(CFLAGS) $(OFLAGS) hash/sha2sum.c $(LDFLAGS) -o $@
pkey/dh_client: pkey/dh_client.c ../library/libpolarssl.a
echo " CC pkey/dh_client.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/dh_client.c $(LDFLAGS) -o $@
pkey/dh_genprime: pkey/dh_genprime.c ../library/libpolarssl.a
echo " CC pkey/dh_genprime.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/dh_genprime.c $(LDFLAGS) -o $@
pkey/dh_server: pkey/dh_server.c ../library/libpolarssl.a
echo " CC pkey/dh_server.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/dh_server.c $(LDFLAGS) -o $@
pkey/mpi_demo: pkey/mpi_demo.c ../library/libpolarssl.a
echo " CC pkey/mpi_demo.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/mpi_demo.c $(LDFLAGS) -o $@
pkey/rsa_genkey: pkey/rsa_genkey.c ../library/libpolarssl.a
echo " CC pkey/rsa_genkey.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/rsa_genkey.c $(LDFLAGS) -o $@
pkey/rsa_sign: pkey/rsa_sign.c ../library/libpolarssl.a
echo " CC pkey/rsa_sign.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/rsa_sign.c $(LDFLAGS) -o $@
pkey/rsa_verify: pkey/rsa_verify.c ../library/libpolarssl.a
echo " CC pkey/rsa_verify.c"
$(CC) $(CFLAGS) $(OFLAGS) pkey/rsa_verify.c $(LDFLAGS) -o $@
ssl/ssl_client1: ssl/ssl_client1.c ../library/libpolarssl.a
echo " CC ssl/ssl_client1.c"
$(CC) $(CFLAGS) $(OFLAGS) ssl/ssl_client1.c $(LDFLAGS) -o $@
ssl/ssl_client2: ssl/ssl_client2.c ../library/libpolarssl.a
echo " CC ssl/ssl_client2.c"
$(CC) $(CFLAGS) $(OFLAGS) ssl/ssl_client2.c $(LDFLAGS) -o $@
ssl/ssl_server: ssl/ssl_server.c ../library/libpolarssl.a
echo " CC ssl/ssl_server.c"
$(CC) $(CFLAGS) $(OFLAGS) ssl/ssl_server.c $(LDFLAGS) -o $@
test/ssl_cert_test: test/ssl_cert_test.c ../library/libpolarssl.a
echo " CC test/ssl_cert_test.c"
$(CC) $(CFLAGS) $(OFLAGS) test/ssl_cert_test.c $(LDFLAGS) -o $@
test/benchmark: test/benchmark.c ../library/libpolarssl.a
echo " CC test/benchmark.c"
$(CC) $(CFLAGS) $(OFLAGS) test/benchmark.c $(LDFLAGS) -o $@
test/selftest: test/selftest.c ../library/libpolarssl.a
echo " CC test/selftest.c"
$(CC) $(CFLAGS) $(OFLAGS) test/selftest.c $(LDFLAGS) -o $@
test/ssl_test: test/ssl_test.c ../library/libpolarssl.a
echo " CC test/ssl_test.c"
$(CC) $(CFLAGS) $(OFLAGS) test/ssl_test.c $(LDFLAGS) -o $@
x509/cert_app: x509/cert_app.c ../library/libpolarssl.a
echo " CC x509/cert_app.c"
$(CC) $(CFLAGS) $(OFLAGS) x509/cert_app.c $(LDFLAGS) -o $@
clean:
rm -f $(APPS)

View File

@@ -0,0 +1,2 @@
add_executable(aescrypt2 aescrypt2.c)
target_link_libraries(aescrypt2 polarssl)

View File

@@ -0,0 +1,401 @@
/*
* AES-256 file encryption program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#if defined(WIN32)
#include <windows.h>
#include <io.h>
#else
#include <sys/types.h>
#include <unistd.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "polarssl/aes.h"
#include "polarssl/sha2.h"
#define MODE_ENCRYPT 0
#define MODE_DECRYPT 1
#define USAGE \
"\n aescrypt2 <mode> <input filename> <output filename> <key>\n" \
"\n <mode>: 0 = encrypt, 1 = decrypt\n" \
"\n example: aescrypt2 0 file file.aes hex:E76B2413958B00E193\n" \
"\n"
int main( int argc, char *argv[] )
{
int ret = 1, i, n;
int keylen, mode, lastn;
FILE *fkey, *fin, *fout;
char *p;
unsigned char IV[16];
unsigned char key[512];
unsigned char digest[32];
unsigned char buffer[1024];
aes_context aes_ctx;
sha2_context sha_ctx;
#if defined(WIN32)
LARGE_INTEGER li_size;
__int64 filesize, offset;
#else
off_t filesize, offset;
#endif
/*
* Parse the command-line arguments.
*/
if( argc != 5 )
{
printf( USAGE );
#if defined(WIN32)
printf( "\n Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
goto exit;
}
mode = atoi( argv[1] );
if( mode != MODE_ENCRYPT && mode != MODE_DECRYPT )
{
fprintf( stderr, "invalide operation mode\n" );
goto exit;
}
if( strcmp( argv[2], argv[3] ) == 0 )
{
fprintf( stderr, "input and output filenames must differ\n" );
goto exit;
}
if( ( fin = fopen( argv[2], "rb" ) ) == NULL )
{
fprintf( stderr, "fopen(%s,rb) failed\n", argv[2] );
goto exit;
}
if( ( fout = fopen( argv[3], "wb+" ) ) == NULL )
{
fprintf( stderr, "fopen(%s,wb+) failed\n", argv[3] );
goto exit;
}
/*
* Read the secret key and clean the command line.
*/
if( ( fkey = fopen( argv[4], "rb" ) ) != NULL )
{
keylen = fread( key, 1, sizeof( key ), fkey );
fclose( fkey );
}
else
{
if( memcmp( argv[4], "hex:", 4 ) == 0 )
{
p = &argv[4][4];
keylen = 0;
while( sscanf( p, "%02X", &n ) > 0 &&
keylen < (int) sizeof( key ) )
{
key[keylen++] = (unsigned char) n;
p += 2;
}
}
else
{
keylen = strlen( argv[4] );
if( keylen > (int) sizeof( key ) )
keylen = (int) sizeof( key );
memcpy( key, argv[4], keylen );
}
}
memset( argv[4], 0, strlen( argv[4] ) );
#if defined(WIN32)
/*
* Support large files (> 2Gb) on Win32
*/
li_size.QuadPart = 0;
li_size.LowPart =
SetFilePointer( (HANDLE) _get_osfhandle( _fileno( fin ) ),
li_size.LowPart, &li_size.HighPart, FILE_END );
if( li_size.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR )
{
fprintf( stderr, "SetFilePointer(0,FILE_END) failed\n" );
goto exit;
}
filesize = li_size.QuadPart;
#else
if( ( filesize = lseek( fileno( fin ), 0, SEEK_END ) ) < 0 )
{
perror( "lseek" );
goto exit;
}
#endif
if( fseek( fin, 0, SEEK_SET ) < 0 )
{
fprintf( stderr, "fseek(0,SEEK_SET) failed\n" );
goto exit;
}
if( mode == MODE_ENCRYPT )
{
/*
* Generate the initialization vector as:
* IV = SHA-256( filesize || filename )[0..15]
*/
for( i = 0; i < 8; i++ )
buffer[i] = (unsigned char)( filesize >> ( i << 3 ) );
p = argv[2];
sha2_starts( &sha_ctx, 0 );
sha2_update( &sha_ctx, buffer, 8 );
sha2_update( &sha_ctx, (unsigned char *) p, strlen( p ) );
sha2_finish( &sha_ctx, digest );
memcpy( IV, digest, 16 );
/*
* The last four bits in the IV are actually used
* to store the file size modulo the AES block size.
*/
lastn = (int)( filesize & 0x0F );
IV[15] = (unsigned char)
( ( IV[15] & 0xF0 ) | lastn );
/*
* Append the IV at the beginning of the output.
*/
if( fwrite( IV, 1, 16, fout ) != 16 )
{
fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
goto exit;
}
/*
* Hash the IV and the secret key together 8192 times
* using the result to setup the AES context and HMAC.
*/
memset( digest, 0, 32 );
memcpy( digest, IV, 16 );
for( i = 0; i < 8192; i++ )
{
sha2_starts( &sha_ctx, 0 );
sha2_update( &sha_ctx, digest, 32 );
sha2_update( &sha_ctx, key, keylen );
sha2_finish( &sha_ctx, digest );
}
memset( key, 0, sizeof( key ) );
aes_setkey_enc( &aes_ctx, digest, 256 );
sha2_hmac_starts( &sha_ctx, digest, 32, 0 );
/*
* Encrypt and write the ciphertext.
*/
for( offset = 0; offset < filesize; offset += 16 )
{
n = ( filesize - offset > 16 ) ? 16 : (int)
( filesize - offset );
if( fread( buffer, 1, n, fin ) != (size_t) n )
{
fprintf( stderr, "fread(%d bytes) failed\n", n );
goto exit;
}
for( i = 0; i < 16; i++ )
buffer[i] = (unsigned char)( buffer[i] ^ IV[i] );
aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, buffer, buffer );
sha2_hmac_update( &sha_ctx, buffer, 16 );
if( fwrite( buffer, 1, 16, fout ) != 16 )
{
fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
goto exit;
}
memcpy( IV, buffer, 16 );
}
/*
* Finally write the HMAC.
*/
sha2_hmac_finish( &sha_ctx, digest );
if( fwrite( digest, 1, 32, fout ) != 32 )
{
fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
goto exit;
}
}
if( mode == MODE_DECRYPT )
{
unsigned char tmp[16];
/*
* The encrypted file must be structured as follows:
*
* 00 .. 15 Initialization Vector
* 16 .. 31 AES Encrypted Block #1
* ..
* N*16 .. (N+1)*16 - 1 AES Encrypted Block #N
* (N+1)*16 .. (N+1)*16 + 32 HMAC-SHA-256(ciphertext)
*/
if( filesize < 48 )
{
fprintf( stderr, "File too short to be encrypted.\n" );
goto exit;
}
if( ( filesize & 0x0F ) != 0 )
{
fprintf( stderr, "File size not a multiple of 16.\n" );
goto exit;
}
/*
* Substract the IV + HMAC length.
*/
filesize -= ( 16 + 32 );
/*
* Read the IV and original filesize modulo 16.
*/
if( fread( buffer, 1, 16, fin ) != 16 )
{
fprintf( stderr, "fread(%d bytes) failed\n", 16 );
goto exit;
}
memcpy( IV, buffer, 16 );
lastn = IV[15] & 0x0F;
/*
* Hash the IV and the secret key together 8192 times
* using the result to setup the AES context and HMAC.
*/
memset( digest, 0, 32 );
memcpy( digest, IV, 16 );
for( i = 0; i < 8192; i++ )
{
sha2_starts( &sha_ctx, 0 );
sha2_update( &sha_ctx, digest, 32 );
sha2_update( &sha_ctx, key, keylen );
sha2_finish( &sha_ctx, digest );
}
memset( key, 0, sizeof( key ) );
aes_setkey_dec( &aes_ctx, digest, 256 );
sha2_hmac_starts( &sha_ctx, digest, 32, 0 );
/*
* Decrypt and write the plaintext.
*/
for( offset = 0; offset < filesize; offset += 16 )
{
if( fread( buffer, 1, 16, fin ) != 16 )
{
fprintf( stderr, "fread(%d bytes) failed\n", 16 );
goto exit;
}
memcpy( tmp, buffer, 16 );
sha2_hmac_update( &sha_ctx, buffer, 16 );
aes_crypt_ecb( &aes_ctx, AES_DECRYPT, buffer, buffer );
for( i = 0; i < 16; i++ )
buffer[i] = (unsigned char)( buffer[i] ^ IV[i] );
memcpy( IV, tmp, 16 );
n = ( lastn > 0 && offset == filesize - 16 )
? lastn : 16;
if( fwrite( buffer, 1, n, fout ) != (size_t) n )
{
fprintf( stderr, "fwrite(%d bytes) failed\n", n );
goto exit;
}
}
/*
* Verify the message authentication code.
*/
sha2_hmac_finish( &sha_ctx, digest );
if( fread( buffer, 1, 32, fin ) != 32 )
{
fprintf( stderr, "fread(%d bytes) failed\n", 32 );
goto exit;
}
if( memcmp( digest, buffer, 32 ) != 0 )
{
fprintf( stderr, "HMAC check failed: wrong key, "
"or file corrupted.\n" );
goto exit;
}
}
ret = 0;
exit:
memset( buffer, 0, sizeof( buffer ) );
memset( digest, 0, sizeof( digest ) );
memset( &aes_ctx, 0, sizeof( aes_context ) );
memset( &sha_ctx, 0, sizeof( sha2_context ) );
return( ret );
}

View File

@@ -0,0 +1,11 @@
add_executable(hello hello.c)
target_link_libraries(hello polarssl)
add_executable(md5sum md5sum.c)
target_link_libraries(md5sum polarssl)
add_executable(sha1sum sha1sum.c)
target_link_libraries(sha1sum polarssl)
add_executable(sha2sum sha2sum.c)
target_link_libraries(sha2sum polarssl)

View File

@@ -0,0 +1,55 @@
/*
* Classic "Hello, world" demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <stdio.h>
#include "polarssl/md5.h"
int main( void )
{
int i;
unsigned char digest[16];
char str[] = "Hello, world!";
printf( "\n MD5('%s') = ", str );
md5( (unsigned char *) str, 13, digest );
for( i = 0; i < 16; i++ )
printf( "%02x", digest[i] );
printf( "\n\n" );
#ifdef WIN32
printf( " Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( 0 );
}

View File

@@ -0,0 +1,161 @@
/*
* md5sum demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/md5.h"
static int md5_wrapper( char *filename, unsigned char *sum )
{
int ret = md5_file( filename, sum );
if( ret == 1 )
fprintf( stderr, "failed to open: %s\n", filename );
if( ret == 2 )
fprintf( stderr, "failed to read: %s\n", filename );
return( ret );
}
static int md5_print( char *filename )
{
int i;
unsigned char sum[16];
if( md5_wrapper( filename, sum ) != 0 )
return( 1 );
for( i = 0; i < 16; i++ )
printf( "%02x", sum[i] );
printf( " %s\n", filename );
return( 0 );
}
static int md5_check( char *filename )
{
int i;
size_t n;
FILE *f;
int nb_err1, nb_err2;
int nb_tot1, nb_tot2;
unsigned char sum[16];
char buf[33], line[1024];
if( ( f = fopen( filename, "rb" ) ) == NULL )
{
printf( "failed to open: %s\n", filename );
return( 1 );
}
nb_err1 = nb_err2 = 0;
nb_tot1 = nb_tot2 = 0;
memset( line, 0, sizeof( line ) );
n = sizeof( line );
while( fgets( line, n - 1, f ) != NULL )
{
n = strlen( line );
if( n < 36 )
continue;
if( line[32] != ' ' || line[33] != ' ' )
continue;
if( line[n - 1] == '\n' ) { n--; line[n] = '\0'; }
if( line[n - 1] == '\r' ) { n--; line[n] = '\0'; }
nb_tot1++;
if( md5_wrapper( line + 34, sum ) != 0 )
{
nb_err1++;
continue;
}
nb_tot2++;
for( i = 0; i < 16; i++ )
sprintf( buf + i * 2, "%02x", sum[i] );
if( memcmp( line, buf, 32 ) != 0 )
{
nb_err2++;
fprintf( stderr, "wrong checksum: %s\n", line + 34 );
}
n = sizeof( line );
}
if( nb_err1 != 0 )
{
printf( "WARNING: %d (out of %d) input files could "
"not be read\n", nb_err1, nb_tot1 );
}
if( nb_err2 != 0 )
{
printf( "WARNING: %d (out of %d) computed checksums did "
"not match\n", nb_err2, nb_tot2 );
}
return( nb_err1 != 0 || nb_err2 != 0 );
}
int main( int argc, char *argv[] )
{
int ret, i;
if( argc == 1 )
{
printf( "print mode: md5sum <file> <file> ...\n" );
printf( "check mode: md5sum -c <checksum file>\n" );
#ifdef WIN32
printf( "\n Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( 1 );
}
if( argc == 3 && strcmp( "-c", argv[1] ) == 0 )
return( md5_check( argv[2] ) );
ret = 0;
for( i = 1; i < argc; i++ )
ret |= md5_print( argv[i] );
return( ret );
}

View File

@@ -0,0 +1,161 @@
/*
* sha1sum demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/sha1.h"
static int sha1_wrapper( char *filename, unsigned char *sum )
{
int ret = sha1_file( filename, sum );
if( ret == 1 )
fprintf( stderr, "failed to open: %s\n", filename );
if( ret == 2 )
fprintf( stderr, "failed to read: %s\n", filename );
return( ret );
}
static int sha1_print( char *filename )
{
int i;
unsigned char sum[20];
if( sha1_wrapper( filename, sum ) != 0 )
return( 1 );
for( i = 0; i < 20; i++ )
printf( "%02x", sum[i] );
printf( " %s\n", filename );
return( 0 );
}
static int sha1_check( char *filename )
{
int i;
size_t n;
FILE *f;
int nb_err1, nb_err2;
int nb_tot1, nb_tot2;
unsigned char sum[20];
char buf[41], line[1024];
if( ( f = fopen( filename, "rb" ) ) == NULL )
{
printf( "failed to open: %s\n", filename );
return( 1 );
}
nb_err1 = nb_err2 = 0;
nb_tot1 = nb_tot2 = 0;
memset( line, 0, sizeof( line ) );
n = sizeof( line );
while( fgets( line, n - 1, f ) != NULL )
{
n = strlen( line );
if( n < 44 )
continue;
if( line[40] != ' ' || line[41] != ' ' )
continue;
if( line[n - 1] == '\n' ) { n--; line[n] = '\0'; }
if( line[n - 1] == '\r' ) { n--; line[n] = '\0'; }
nb_tot1++;
if( sha1_wrapper( line + 42, sum ) != 0 )
{
nb_err1++;
continue;
}
nb_tot2++;
for( i = 0; i < 20; i++ )
sprintf( buf + i * 2, "%02x", sum[i] );
if( memcmp( line, buf, 40 ) != 0 )
{
nb_err2++;
fprintf( stderr, "wrong checksum: %s\n", line + 42 );
}
n = sizeof( line );
}
if( nb_err1 != 0 )
{
printf( "WARNING: %d (out of %d) input files could "
"not be read\n", nb_err1, nb_tot1 );
}
if( nb_err2 != 0 )
{
printf( "WARNING: %d (out of %d) computed checksums did "
"not match\n", nb_err2, nb_tot2 );
}
return( nb_err1 != 0 || nb_err2 != 0 );
}
int main( int argc, char *argv[] )
{
int ret, i;
if( argc == 1 )
{
printf( "print mode: sha1sum <file> <file> ...\n" );
printf( "check mode: sha1sum -c <checksum file>\n" );
#ifdef WIN32
printf( "\n Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( 1 );
}
if( argc == 3 && strcmp( "-c", argv[1] ) == 0 )
return( sha1_check( argv[2] ) );
ret = 0;
for( i = 1; i < argc; i++ )
ret |= sha1_print( argv[i] );
return( ret );
}

View File

@@ -0,0 +1,161 @@
/*
* sha2sum demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/sha2.h"
static int sha2_wrapper( char *filename, unsigned char *sum )
{
int ret = sha2_file( filename, sum, 0 );
if( ret == 1 )
fprintf( stderr, "failed to open: %s\n", filename );
if( ret == 2 )
fprintf( stderr, "failed to read: %s\n", filename );
return( ret );
}
static int sha2_print( char *filename )
{
int i;
unsigned char sum[32];
if( sha2_wrapper( filename, sum ) != 0 )
return( 1 );
for( i = 0; i < 32; i++ )
printf( "%02x", sum[i] );
printf( " %s\n", filename );
return( 0 );
}
static int sha2_check( char *filename )
{
int i;
size_t n;
FILE *f;
int nb_err1, nb_err2;
int nb_tot1, nb_tot2;
unsigned char sum[32];
char buf[65], line[1024];
if( ( f = fopen( filename, "rb" ) ) == NULL )
{
printf( "failed to open: %s\n", filename );
return( 1 );
}
nb_err1 = nb_err2 = 0;
nb_tot1 = nb_tot2 = 0;
memset( line, 0, sizeof( line ) );
n = sizeof( line );
while( fgets( line, n - 1, f ) != NULL )
{
n = strlen( line );
if( n < 68 )
continue;
if( line[64] != ' ' || line[65] != ' ' )
continue;
if( line[n - 1] == '\n' ) { n--; line[n] = '\0'; }
if( line[n - 1] == '\r' ) { n--; line[n] = '\0'; }
nb_tot1++;
if( sha2_wrapper( line + 66, sum ) != 0 )
{
nb_err1++;
continue;
}
nb_tot2++;
for( i = 0; i < 32; i++ )
sprintf( buf + i * 2, "%02x", sum[i] );
if( memcmp( line, buf, 64 ) != 0 )
{
nb_err2++;
fprintf( stderr, "wrong checksum: %s\n", line + 66 );
}
n = sizeof( line );
}
if( nb_err1 != 0 )
{
printf( "WARNING: %d (out of %d) input files could "
"not be read\n", nb_err1, nb_tot1 );
}
if( nb_err2 != 0 )
{
printf( "WARNING: %d (out of %d) computed checksums did "
"not match\n", nb_err2, nb_tot2 );
}
return( nb_err1 != 0 || nb_err2 != 0 );
}
int main( int argc, char *argv[] )
{
int ret, i;
if( argc == 1 )
{
printf( "print mode: sha2sum <file> <file> ...\n" );
printf( "check mode: sha2sum -c <checksum file>\n" );
#ifdef WIN32
printf( "\n Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( 1 );
}
if( argc == 3 && strcmp( "-c", argv[1] ) == 0 )
return( sha2_check( argv[2] ) );
ret = 0;
for( i = 1; i < argc; i++ )
ret |= sha2_print( argv[i] );
return( ret );
}

View File

@@ -0,0 +1,20 @@
add_executable(dh_client dh_client.c)
target_link_libraries(dh_client polarssl)
add_executable(dh_genprime dh_genprime.c)
target_link_libraries(dh_genprime polarssl)
add_executable(dh_server dh_server.c)
target_link_libraries(dh_server polarssl)
add_executable(mpi_demo mpi_demo.c)
target_link_libraries(mpi_demo polarssl)
add_executable(rsa_genkey rsa_genkey.c)
target_link_libraries(rsa_genkey polarssl)
add_executable(rsa_sign rsa_sign.c)
target_link_libraries(rsa_sign polarssl)
add_executable(rsa_verify rsa_verify.c)
target_link_libraries(rsa_verify polarssl)

View File

@@ -0,0 +1,254 @@
/*
* Diffie-Hellman-Merkle key exchange (client side)
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/net.h"
#include "polarssl/aes.h"
#include "polarssl/dhm.h"
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
#include "polarssl/havege.h"
#define SERVER_NAME "localhost"
#define SERVER_PORT 11999
int main( void )
{
FILE *f;
int ret, n, buflen;
int server_fd = -1;
unsigned char *p, *end;
unsigned char buf[1024];
unsigned char hash[20];
havege_state hs;
rsa_context rsa;
dhm_context dhm;
aes_context aes;
memset( &rsa, 0, sizeof( rsa ) );
memset( &dhm, 0, sizeof( dhm ) );
/*
* 1. Setup the RNG
*/
printf( "\n . Seeding the random number generator" );
fflush( stdout );
havege_init( &hs );
/*
* 2. Read the server's public RSA key
*/
printf( "\n . Reading public key from rsa_pub.txt" );
fflush( stdout );
if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
{
ret = 1;
printf( " failed\n ! Could not open rsa_pub.txt\n" \
" ! Please run rsa_genkey first\n\n" );
goto exit;
}
rsa_init( &rsa, RSA_PKCS_V15, 0 );
if( ( ret = mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.E, 16, f ) ) != 0 )
{
printf( " failed\n ! mpi_read_file returned %d\n\n", ret );
goto exit;
}
rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
fclose( f );
/*
* 3. Initiate the connection
*/
printf( "\n . Connecting to tcp/%s/%d", SERVER_NAME,
SERVER_PORT );
fflush( stdout );
if( ( ret = net_connect( &server_fd, SERVER_NAME,
SERVER_PORT ) ) != 0 )
{
printf( " failed\n ! net_connect returned %d\n\n", ret );
goto exit;
}
/*
* 4a. First get the buffer length
*/
printf( "\n . Receiving the server's DH parameters" );
fflush( stdout );
memset( buf, 0, sizeof( buf ) );
if( ( ret = net_recv( &server_fd, buf, 2 ) ) != 2 )
{
printf( " failed\n ! net_recv returned %d\n\n", ret );
goto exit;
}
n = buflen = ( buf[0] << 8 ) | buf[1];
if( buflen < 1 || buflen > (int) sizeof( buf ) )
{
printf( " failed\n ! Got an invalid buffer length\n\n" );
goto exit;
}
/*
* 4b. Get the DHM parameters: P, G and Ys = G^Xs mod P
*/
memset( buf, 0, sizeof( buf ) );
if( ( ret = net_recv( &server_fd, buf, n ) ) != n )
{
printf( " failed\n ! net_recv returned %d\n\n", ret );
goto exit;
}
p = buf, end = buf + buflen;
if( ( ret = dhm_read_params( &dhm, &p, end ) ) != 0 )
{
printf( " failed\n ! dhm_read_params returned %d\n\n", ret );
goto exit;
}
if( dhm.len < 64 || dhm.len > 256 )
{
ret = 1;
printf( " failed\n ! Invalid DHM modulus size\n\n" );
goto exit;
}
/*
* 5. Check that the server's RSA signature matches
* the SHA-1 hash of (P,G,Ys)
*/
printf( "\n . Verifying the server's RSA signature" );
fflush( stdout );
if( ( n = (int)( end - p ) ) != rsa.len )
{
ret = 1;
printf( " failed\n ! Invalid RSA signature size\n\n" );
goto exit;
}
sha1( buf, (int)( p - 2 - buf ), hash );
if( ( ret = rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1,
0, hash, p ) ) != 0 )
{
printf( " failed\n ! rsa_pkcs1_verify returned %d\n\n", ret );
goto exit;
}
/*
* 6. Send our public value: Yc = G ^ Xc mod P
*/
printf( "\n . Sending own public value to server" );
fflush( stdout );
n = dhm.len;
if( ( ret = dhm_make_public( &dhm, 256, buf, n,
havege_rand, &hs ) ) != 0 )
{
printf( " failed\n ! dhm_make_public returned %d\n\n", ret );
goto exit;
}
if( ( ret = net_send( &server_fd, buf, n ) ) != n )
{
printf( " failed\n ! net_send returned %d\n\n", ret );
goto exit;
}
/*
* 7. Derive the shared secret: K = Ys ^ Xc mod P
*/
printf( "\n . Shared secret: " );
fflush( stdout );
n = dhm.len;
if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 )
{
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
goto exit;
}
for( n = 0; n < 16; n++ )
printf( "%02x", buf[n] );
/*
* 8. Setup the AES-256 decryption key
*
* This is an overly simplified example; best practice is
* to hash the shared secret with a random value to derive
* the keying material for the encryption/decryption keys,
* IVs and MACs.
*/
printf( "...\n . Receiving and decrypting the ciphertext" );
fflush( stdout );
aes_setkey_dec( &aes, buf, 256 );
memset( buf, 0, sizeof( buf ) );
if( ( ret = net_recv( &server_fd, buf, 16 ) ) != 16 )
{
printf( " failed\n ! net_recv returned %d\n\n", ret );
goto exit;
}
aes_crypt_ecb( &aes, AES_DECRYPT, buf, buf );
buf[16] = '\0';
printf( "\n . Plaintext is \"%s\"\n\n", (char *) buf );
exit:
net_close( server_fd );
rsa_free( &rsa );
dhm_free( &dhm );
#ifdef WIN32
printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,127 @@
/*
* Diffie-Hellman-Merkle key exchange (prime generation)
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <stdio.h>
#include "polarssl/bignum.h"
#include "polarssl/config.h"
#include "polarssl/havege.h"
/*
* Note: G = 4 is always a quadratic residue mod P,
* so it is a generator of order Q (with P = 2*Q+1).
*/
#define DH_P_SIZE 1024
#define GENERATOR "4"
int main( void )
{
int ret = 1;
#if defined(POLARSSL_GENPRIME)
mpi G, P, Q;
havege_state hs;
FILE *fout;
mpi_init( &G, &P, &Q, NULL );
mpi_read_string( &G, 10, GENERATOR );
printf( "\n . Seeding the random number generator..." );
fflush( stdout );
havege_init( &hs );
printf( " ok\n . Generating the modulus, please wait..." );
fflush( stdout );
/*
* This can take a long time...
*/
if( ( ret = mpi_gen_prime( &P, DH_P_SIZE, 1,
havege_rand, &hs ) ) != 0 )
{
printf( " failed\n ! mpi_gen_prime returned %d\n\n", ret );
goto exit;
}
printf( " ok\n . Verifying that Q = (P-1)/2 is prime..." );
fflush( stdout );
if( ( ret = mpi_sub_int( &Q, &P, 1 ) ) != 0 )
{
printf( " failed\n ! mpi_sub_int returned %d\n\n", ret );
goto exit;
}
if( ( ret = mpi_div_int( &Q, NULL, &Q, 2 ) ) != 0 )
{
printf( " failed\n ! mpi_div_int returned %d\n\n", ret );
goto exit;
}
if( ( ret = mpi_is_prime( &Q, havege_rand, &hs ) ) != 0 )
{
printf( " failed\n ! mpi_is_prime returned %d\n\n", ret );
goto exit;
}
printf( " ok\n . Exporting the value in dh_prime.txt..." );
fflush( stdout );
if( ( fout = fopen( "dh_prime.txt", "wb+" ) ) == NULL )
{
ret = 1;
printf( " failed\n ! Could not create dh_prime.txt\n\n" );
goto exit;
}
if( ( ret = mpi_write_file( "P = ", &P, 16, fout ) != 0 ) ||
( ret = mpi_write_file( "G = ", &G, 16, fout ) != 0 ) )
{
printf( " failed\n ! mpi_write_file returned %d\n\n", ret );
goto exit;
}
printf( " ok\n\n" );
fclose( fout );
exit:
mpi_free( &Q, &P, &G, NULL );
#else
printf( "\n ! Prime-number generation is not available.\n\n" );
#endif
#ifdef WIN32
printf( " Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,2 @@
P = C3CF8BCFD9E88B0CC35EC526F3D63FA001DC9392E6CA81F3B414173955C582758B52038FAFBF402B8C29DC32F5231B0D2E25B252850C7DCDBFF46D0E7989E51DEA07A53BCF7947D4C95EBA28F9CBAFB0267EC3BCF57B15A49964236B56773851D6621E546F410D504F13827218CD14A1FDB69522DC72DD67D880E51B2E00894F
G = 04

View File

@@ -0,0 +1,257 @@
/*
* Diffie-Hellman-Merkle key exchange (server side)
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/net.h"
#include "polarssl/aes.h"
#include "polarssl/dhm.h"
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
#include "polarssl/havege.h"
#define SERVER_PORT 11999
#define PLAINTEXT "==Hello there!=="
int main( void )
{
FILE *f;
int ret, n, buflen;
int listen_fd = -1;
int client_fd = -1;
unsigned char buf[1024];
unsigned char hash[20];
unsigned char buf2[2];
havege_state hs;
rsa_context rsa;
dhm_context dhm;
aes_context aes;
memset( &rsa, 0, sizeof( rsa ) );
memset( &dhm, 0, sizeof( dhm ) );
/*
* 1. Setup the RNG
*/
printf( "\n . Seeding the random number generator" );
fflush( stdout );
havege_init( &hs );
/*
* 2a. Read the server's private RSA key
*/
printf( "\n . Reading private key from rsa_priv.txt" );
fflush( stdout );
if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL )
{
ret = 1;
printf( " failed\n ! Could not open rsa_priv.txt\n" \
" ! Please run rsa_genkey first\n\n" );
goto exit;
}
rsa_init( &rsa, RSA_PKCS_V15, 0 );
if( ( ret = mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.P , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.Q , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.DP, 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.DQ, 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
{
printf( " failed\n ! mpi_read_file returned %d\n\n", ret );
goto exit;
}
rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
fclose( f );
/*
* 2b. Get the DHM modulus and generator
*/
printf( "\n . Reading DH parameters from dh_prime.txt" );
fflush( stdout );
if( ( f = fopen( "dh_prime.txt", "rb" ) ) == NULL )
{
ret = 1;
printf( " failed\n ! Could not open dh_prime.txt\n" \
" ! Please run dh_genprime first\n\n" );
goto exit;
}
if( mpi_read_file( &dhm.P, 16, f ) != 0 ||
mpi_read_file( &dhm.G, 16, f ) != 0 )
{
printf( " failed\n ! Invalid DH parameter file\n\n" );
goto exit;
}
fclose( f );
/*
* 3. Wait for a client to connect
*/
printf( "\n . Waiting for a remote connection" );
fflush( stdout );
if( ( ret = net_bind( &listen_fd, NULL, SERVER_PORT ) ) != 0 )
{
printf( " failed\n ! net_bind returned %d\n\n", ret );
goto exit;
}
if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
{
printf( " failed\n ! net_accept returned %d\n\n", ret );
goto exit;
}
/*
* 4. Setup the DH parameters (P,G,Ys)
*/
printf( "\n . Sending the server's DH parameters" );
fflush( stdout );
memset( buf, 0, sizeof( buf ) );
if( ( ret = dhm_make_params( &dhm, 256, buf, &n,
havege_rand, &hs ) ) != 0 )
{
printf( " failed\n ! dhm_make_params returned %d\n\n", ret );
goto exit;
}
/*
* 5. Sign the parameters and send them
*/
sha1( buf, n, hash );
buf[n ] = (unsigned char)( rsa.len >> 8 );
buf[n + 1] = (unsigned char)( rsa.len );
if( ( ret = rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1,
0, hash, buf + n + 2 ) ) != 0 )
{
printf( " failed\n ! rsa_pkcs1_sign returned %d\n\n", ret );
goto exit;
}
buflen = n + 2 + rsa.len;
buf2[0] = (unsigned char)( buflen >> 8 );
buf2[1] = (unsigned char)( buflen );
if( ( ret = net_send( &client_fd, buf2, 2 ) ) != 2 ||
( ret = net_send( &client_fd, buf, buflen ) ) != buflen )
{
printf( " failed\n ! net_send returned %d\n\n", ret );
goto exit;
}
/*
* 6. Get the client's public value: Yc = G ^ Xc mod P
*/
printf( "\n . Receiving the client's public value" );
fflush( stdout );
memset( buf, 0, sizeof( buf ) );
n = dhm.len;
if( ( ret = net_recv( &client_fd, buf, n ) ) != n )
{
printf( " failed\n ! net_recv returned %d\n\n", ret );
goto exit;
}
if( ( ret = dhm_read_public( &dhm, buf, dhm.len ) ) != 0 )
{
printf( " failed\n ! dhm_read_public returned %d\n\n", ret );
goto exit;
}
/*
* 7. Derive the shared secret: K = Ys ^ Xc mod P
*/
printf( "\n . Shared secret: " );
fflush( stdout );
if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 )
{
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
goto exit;
}
for( n = 0; n < 16; n++ )
printf( "%02x", buf[n] );
/*
* 8. Setup the AES-256 encryption key
*
* This is an overly simplified example; best practice is
* to hash the shared secret with a random value to derive
* the keying material for the encryption/decryption keys
* and MACs.
*/
printf( "...\n . Encrypting and sending the ciphertext" );
fflush( stdout );
aes_setkey_enc( &aes, buf, 256 );
memcpy( buf, PLAINTEXT, 16 );
aes_crypt_ecb( &aes, AES_ENCRYPT, buf, buf );
if( ( ret = net_send( &client_fd, buf, 16 ) ) != 16 )
{
printf( " failed\n ! net_send returned %d\n\n", ret );
goto exit;
}
printf( "\n\n" );
exit:
net_close( client_fd );
rsa_free( &rsa );
dhm_free( &dhm );
#ifdef WIN32
printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,81 @@
/*
* Simple MPI demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <stdio.h>
#include "polarssl/bignum.h"
int main( void )
{
mpi E, P, Q, N, H, D, X, Y, Z;
mpi_init( &E, &P, &Q, &N, &H,
&D, &X, &Y, &Z, NULL );
mpi_read_string( &P, 10, "2789" );
mpi_read_string( &Q, 10, "3203" );
mpi_read_string( &E, 10, "257" );
mpi_mul_mpi( &N, &P, &Q );
printf( "\n Public key:\n\n" );
mpi_write_file( " N = ", &N, 10, NULL );
mpi_write_file( " E = ", &E, 10, NULL );
printf( "\n Private key:\n\n" );
mpi_write_file( " P = ", &P, 10, NULL );
mpi_write_file( " Q = ", &Q, 10, NULL );
mpi_sub_int( &P, &P, 1 );
mpi_sub_int( &Q, &Q, 1 );
mpi_mul_mpi( &H, &P, &Q );
mpi_inv_mod( &D, &E, &H );
mpi_write_file( " D = E^-1 mod (P-1)*(Q-1) = ",
&D, 10, NULL );
mpi_read_string( &X, 10, "55555" );
mpi_exp_mod( &Y, &X, &E, &N, NULL );
mpi_exp_mod( &Z, &Y, &D, &N, NULL );
printf( "\n RSA operation:\n\n" );
mpi_write_file( " X (plaintext) = ", &X, 10, NULL );
mpi_write_file( " Y (ciphertext) = X^E mod N = ", &Y, 10, NULL );
mpi_write_file( " Z (decrypted) = Y^D mod N = ", &Z, 10, NULL );
printf( "\n" );
mpi_free( &Z, &Y, &X, &D, &H,
&N, &Q, &P, &E, NULL );
#ifdef WIN32
printf( " Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( 0 );
}

View File

@@ -0,0 +1,134 @@
/*
* Example RSA key generation program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <stdio.h>
#include "polarssl/havege.h"
#include "polarssl/bignum.h"
#include "polarssl/x509.h"
#include "polarssl/rsa.h"
#define KEY_SIZE 1024
#define EXPONENT 65537
int main( void )
{
int ret;
rsa_context rsa;
havege_state hs;
FILE *fpub = NULL;
FILE *fpriv = NULL;
printf( "\n . Seeding the random number generator..." );
fflush( stdout );
havege_init( &hs );
printf( " ok\n . Generating the RSA key [ %d-bit ]...", KEY_SIZE );
fflush( stdout );
rsa_init( &rsa, RSA_PKCS_V15, 0 );
if( ( ret = rsa_gen_key( &rsa, havege_rand, &hs, KEY_SIZE, EXPONENT ) ) != 0 )
{
printf( " failed\n ! rsa_gen_key returned %d\n\n", ret );
goto exit;
}
printf( " ok\n . Exporting the public key in rsa_pub.txt...." );
fflush( stdout );
if( ( fpub = fopen( "rsa_pub.txt", "wb+" ) ) == NULL )
{
printf( " failed\n ! could not open rsa_pub.txt for writing\n\n" );
ret = 1;
goto exit;
}
if( ( ret = mpi_write_file( "N = ", &rsa.N, 16, fpub ) ) != 0 ||
( ret = mpi_write_file( "E = ", &rsa.E, 16, fpub ) ) != 0 )
{
printf( " failed\n ! mpi_write_file returned %d\n\n", ret );
goto exit;
}
printf( " ok\n . Exporting the private key in rsa_priv.txt..." );
fflush( stdout );
if( ( fpriv = fopen( "rsa_priv.txt", "wb+" ) ) == NULL )
{
printf( " failed\n ! could not open rsa_priv.txt for writing\n" );
ret = 1;
goto exit;
}
if( ( ret = mpi_write_file( "N = " , &rsa.N , 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "E = " , &rsa.E , 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "D = " , &rsa.D , 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "P = " , &rsa.P , 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "Q = " , &rsa.Q , 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "DP = ", &rsa.DP, 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "DQ = ", &rsa.DQ, 16, fpriv ) ) != 0 ||
( ret = mpi_write_file( "QP = ", &rsa.QP, 16, fpriv ) ) != 0 )
{
printf( " failed\n ! mpi_write_file returned %d\n\n", ret );
goto exit;
}
/*
printf( " ok\n . Generating the certificate..." );
x509write_init_raw( &cert );
x509write_add_pubkey( &cert, &rsa );
x509write_add_subject( &cert, "CN='localhost'" );
x509write_add_validity( &cert, "2007-09-06 17:00:32",
"2010-09-06 17:00:32" );
x509write_create_selfsign( &cert, &rsa );
x509write_crtfile( &cert, "cert.der", X509_OUTPUT_DER );
x509write_crtfile( &cert, "cert.pem", X509_OUTPUT_PEM );
x509write_free_raw( &cert );
*/
printf( " ok\n\n" );
exit:
if( fpub != NULL )
fclose( fpub );
if( fpriv != NULL )
fclose( fpriv );
rsa_free( &rsa );
#ifdef WIN32
printf( " Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,8 @@
N = 807E3526556FADF8D4CA64074ADA36862646D5ECB24E363821306588722AF2B58058CFB88E8C0BEA5C7084F3055D232F110E59C8837A0D132A4B907E91DB4A4924134A85E7445935E55A772C0B72E12C94501D9DF66B71BA030F842531721AEF43AE48F9505BF7504CDEEA3CAA6F94530835648D770AE2E6C628DD484D10AA57
E = 010001
D = 56B3D2AD612D10993D0CAC5E7755B340E6071A46B3322F47C4AD6175A683F06E2482C8F761C88229CBE268F38B0503BEB8A59453C6D3CE8AC6196310E4DEB1CA939DF7F7EE26C4697EEDD1E5122795BFC83861DE2E3EC9E3E84F42B3A9DD25EB09B30FDDFFACCE5091493BC5577530CE9CD9C8BA244EC5FD3DF91BCECFD73961
P = F8DAD6A5651CED9011D979A076D70C4FBD095AAE2E53EF51415832C63AD61618F0BB369F29D1363345FE481FE6C28F0830FE33A1C41F8743A4E02DD682A2E099
Q = 842EABF3171F972DE7D6B571B70F969F8F1C305851785BB042CDAE3B794014659A744EA7D16D881B7168463CEEAF52BA0F78755BBE89CFE1361076CE3E20886F
DP = B1C694047FE1548CD1538D21E703E595A933DF86032E8F0E7B21E8D3D8004CB4F074ADA6B296F4A35863395F20D8E8992F76C9A7CC95C169BF852EF9C9455631
DQ = 143C54E49D289FEB4E2FC78D461A23D3FF83B03F0511E8EF7DFAA0EEC7EC3073318716B7884F3D63FE239985208144A7E950669F09F76D14AC432EFCF9F3DF0F
QP = C2F98F412476BDA2B14F5882D929090C62BB24ED74E8B78A3BE287EABDB3FADC445D041F1DE04EBE2D39A8913DAF03C23FF632D1B3FB6CCBDD65B2A576F127F5

View File

@@ -0,0 +1,2 @@
N = 807E3526556FADF8D4CA64074ADA36862646D5ECB24E363821306588722AF2B58058CFB88E8C0BEA5C7084F3055D232F110E59C8837A0D132A4B907E91DB4A4924134A85E7445935E55A772C0B72E12C94501D9DF66B71BA030F842531721AEF43AE48F9505BF7504CDEEA3CAA6F94530835648D770AE2E6C628DD484D10AA57
E = 010001

View File

@@ -0,0 +1,135 @@
/*
* RSA/SHA-1 signature creation program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
int main( int argc, char *argv[] )
{
FILE *f;
int ret, i;
rsa_context rsa;
unsigned char hash[20];
unsigned char buf[512];
ret = 1;
if( argc != 2 )
{
printf( "usage: rsa_sign <filename>\n" );
#ifdef WIN32
printf( "\n" );
#endif
goto exit;
}
printf( "\n . Reading private key from rsa_priv.txt" );
fflush( stdout );
if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL )
{
ret = 1;
printf( " failed\n ! Could not open rsa_priv.txt\n" \
" ! Please run rsa_genkey first\n\n" );
goto exit;
}
rsa_init( &rsa, RSA_PKCS_V15, 0 );
if( ( ret = mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.P , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.Q , 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.DP, 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.DQ, 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
{
printf( " failed\n ! mpi_read_file returned %d\n\n", ret );
goto exit;
}
rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
fclose( f );
/*
* Compute the SHA-1 hash of the input file,
* then calculate the RSA signature of the hash.
*/
printf( "\n . Generating the RSA/SHA-1 signature" );
fflush( stdout );
if( ( ret = sha1_file( argv[1], hash ) ) != 0 )
{
printf( " failed\n ! Could not open or read %s\n\n", argv[1] );
goto exit;
}
if( ( ret = rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1,
20, hash, buf ) ) != 0 )
{
printf( " failed\n ! rsa_pkcs1_sign returned %d\n\n", ret );
goto exit;
}
/*
* Write the signature into <filename>-sig.txt
*/
memcpy( argv[1] + strlen( argv[1] ), ".sig", 5 );
if( ( f = fopen( argv[1], "wb+" ) ) == NULL )
{
ret = 1;
printf( " failed\n ! Could not create %s\n\n", argv[1] );
goto exit;
}
for( i = 0; i < rsa.len; i++ )
fprintf( f, "%02X%s", buf[i],
( i + 1 ) % 16 == 0 ? "\r\n" : " " );
fclose( f );
printf( "\n . Done (created \"%s\")\n\n", argv[1] );
exit:
#ifdef WIN32
printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,138 @@
/*
* RSA/SHA-1 signature verification program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
int main( int argc, char *argv[] )
{
FILE *f;
int ret, i, c;
rsa_context rsa;
unsigned char hash[20];
unsigned char buf[512];
ret = 1;
if( argc != 2 )
{
printf( "usage: rsa_verify <filename>\n" );
#ifdef WIN32
printf( "\n" );
#endif
goto exit;
}
printf( "\n . Reading public key from rsa_pub.txt" );
fflush( stdout );
if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
{
printf( " failed\n ! Could not open rsa_pub.txt\n" \
" ! Please run rsa_genkey first\n\n" );
goto exit;
}
rsa_init( &rsa, RSA_PKCS_V15, 0 );
if( ( ret = mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
( ret = mpi_read_file( &rsa.E, 16, f ) ) != 0 )
{
printf( " failed\n ! mpi_read_file returned %d\n\n", ret );
goto exit;
}
rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
fclose( f );
/*
* Extract the RSA signature from the text file
*/
ret = 1;
i = strlen( argv[1] );
memcpy( argv[1] + i, ".sig", 5 );
if( ( f = fopen( argv[1], "rb" ) ) == NULL )
{
printf( "\n ! Could not open %s\n\n", argv[1] );
goto exit;
}
argv[1][i] = '\0', i = 0;
while( fscanf( f, "%02X", &c ) > 0 &&
i < (int) sizeof( buf ) )
buf[i++] = (unsigned char) c;
fclose( f );
if( i != rsa.len )
{
printf( "\n ! Invalid RSA signature format\n\n" );
goto exit;
}
/*
* Compute the SHA-1 hash of the input file and compare
* it with the hash decrypted from the RSA signature.
*/
printf( "\n . Verifying the RSA/SHA-1 signature" );
fflush( stdout );
if( ( ret = sha1_file( argv[1], hash ) ) != 0 )
{
printf( " failed\n ! Could not open or read %s\n\n", argv[1] );
goto exit;
}
if( ( ret = rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1,
20, hash, buf ) ) != 0 )
{
printf( " failed\n ! rsa_pkcs1_verify returned %d\n\n", ret );
goto exit;
}
printf( "\n . OK (the decrypted SHA-1 hash matches)\n\n" );
ret = 0;
exit:
#ifdef WIN32
printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,144 @@
How to setup your own Certificate Authority
===========================================
Note: this howto requires the openssl binary, as well as classic
UNIX tools (cat, touch, echo). If you use Windows, please consider
installing Cygwin -- see http://cygwin.com/
1. Configure OpenSSL
--------------------
First of all, create sslconf.txt in the current directory
(a basic example is provided at the end of this file).
cat > sslconf.txt <<"EOF"
[paste contents here]
EOF
Then you need to create the database and a starting serial number:
touch index
echo "01" > serial
mkdir newcerts
2. Generate the CA certificate
------------------------------
openssl req -config sslconf.txt -days 3653 -x509 -newkey rsa:2048 \
-set_serial 0 -text -keyout test-ca.key -out test-ca.crt
3. Generate the private keys and certificate requests
-----------------------------------------------------
openssl genrsa -out server1.key 2048
openssl genrsa -out server2.key 2048
openssl genrsa -out client1.key 2048
openssl genrsa -out client2.key 2048
openssl req -config sslconf.txt -new -key server1.key -out server1.req
openssl req -config sslconf.txt -new -key server2.key -out server2.req
openssl req -config sslconf.txt -new -key client1.key -out client1.req
openssl req -config sslconf.txt -new -key client2.key -out client2.req
4. Issue and sign the certificates
----------------------------------
openssl ca -config sslconf.txt -in server1.req -out server1.crt
openssl ca -config sslconf.txt -in server2.req -out server2.crt
openssl ca -config sslconf.txt -in client1.req -out client1.crt
openssl ca -config sslconf.txt -in client2.req -out client2.crt
5. To revoke a certificate and update the CRL
---------------------------------------------
openssl ca -config sslconf.txt -revoke server1.crt
openssl ca -config sslconf.txt -revoke client1.crt
openssl ca -config sslconf.txt -gencrl -out crl.pem
6. To display a certificate and verify its validity
---------------------------------------------------
openssl x509 -in server2.crt -text -noout
cat test-ca.crt crl.pem > ca_crl.pem
openssl verify -CAfile ca_crl.pem -crl_check server2.crt
rm ca_crl.pem
7. To export a certificate into a .pfx file
-------------------------------------------
openssl pkcs12 -export -in client2.crt -inkey client2.key \
-out client2.pfx
##================================================================
##============== Example OpenSSL configuration file ==============
##================================================================
# References:
#
# /etc/ssl/openssl.conf
# http://www.openssl.org/docs/apps/config.html
# http://www.openssl.org/docs/apps/x509v3_config.html
[ ca ]
default_ca = my_ca
[ my_ca ]
certificate = test-ca.crt
private_key = test-ca.key
database = index
serial = serial
new_certs_dir = newcerts
default_crl_days = 60
default_days = 730
default_md = sha1
policy = my_policy
x509_extensions = v3_usr
[ my_policy ]
countryName = optional
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
distinguished_name = my_req_dn
x509_extensions = v3_ca
[ my_req_dn ]
countryName = Country Name..............
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name....
localityName = Locality Name.............
0.organizationName = Organization Name.........
organizationalUnitName = Org. Unit Name............
commonName = Common Name (required)....
commonName_max = 64
emailAddress = Email Address.............
emailAddress_max = 64
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_usr ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

View File

@@ -0,0 +1,8 @@
add_executable(ssl_client1 ssl_client1.c)
target_link_libraries(ssl_client1 polarssl)
add_executable(ssl_client2 ssl_client2.c)
target_link_libraries(ssl_client2 polarssl)
add_executable(ssl_server ssl_server.c)
target_link_libraries(ssl_server polarssl)

View File

@@ -0,0 +1,171 @@
/*
* SSL client demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdio.h>
#include "polarssl/net.h"
#include "polarssl/ssl.h"
#include "polarssl/havege.h"
#define SERVER_PORT 4433
#define SERVER_NAME "localhost"
#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
#define DEBUG_LEVEL 1
void my_debug( void *ctx, int level, const char *str )
{
if( level < DEBUG_LEVEL )
{
fprintf( (FILE *) ctx, "%s", str );
fflush( (FILE *) ctx );
}
}
int main( void )
{
int ret, len, server_fd;
unsigned char buf[1024];
havege_state hs;
ssl_context ssl;
ssl_session ssn;
/*
* 0. Initialize the RNG and the session data
*/
havege_init( &hs );
memset( &ssn, 0, sizeof( ssl_session ) );
/*
* 1. Start the connection
*/
printf( "\n . Connecting to tcp/%s/%4d...", SERVER_NAME,
SERVER_PORT );
fflush( stdout );
if( ( ret = net_connect( &server_fd, SERVER_NAME,
SERVER_PORT ) ) != 0 )
{
printf( " failed\n ! net_connect returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 2. Setup stuff
*/
printf( " . Setting up the SSL/TLS structure..." );
fflush( stdout );
if( ( ret = ssl_init( &ssl ) ) != 0 )
{
printf( " failed\n ! ssl_init returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
ssl_set_rng( &ssl, havege_rand, &hs );
ssl_set_dbg( &ssl, my_debug, stdout );
ssl_set_bio( &ssl, net_recv, &server_fd,
net_send, &server_fd );
ssl_set_ciphers( &ssl, ssl_default_ciphers );
ssl_set_session( &ssl, 1, 600, &ssn );
/*
* 3. Write the GET request
*/
printf( " > Write to server:" );
fflush( stdout );
len = sprintf( (char *) buf, GET_REQUEST );
while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
{
if( ret != POLARSSL_ERR_NET_TRY_AGAIN )
{
printf( " failed\n ! ssl_write returned %d\n\n", ret );
goto exit;
}
}
len = ret;
printf( " %d bytes written\n\n%s", len, (char *) buf );
/*
* 7. Read the HTTP response
*/
printf( " < Read from server:" );
fflush( stdout );
do
{
len = sizeof( buf ) - 1;
memset( buf, 0, sizeof( buf ) );
ret = ssl_read( &ssl, buf, len );
if( ret == POLARSSL_ERR_NET_TRY_AGAIN )
continue;
if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
break;
if( ret <= 0 )
{
printf( "failed\n ! ssl_read returned %d\n\n", ret );
break;
}
len = ret;
printf( " %d bytes read\n\n%s", len, (char *) buf );
}
while( 0 );
ssl_close_notify( &ssl );
exit:
net_close( server_fd );
ssl_free( &ssl );
memset( &ssl, 0, sizeof( ssl ) );
#ifdef WIN32
printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,374 @@
/*
* SSL client with certificate authentication
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "polarssl/net.h"
#include "polarssl/ssl.h"
#include "polarssl/havege.h"
#include "polarssl/certs.h"
#include "polarssl/x509.h"
#define DFL_SERVER_NAME "localhost"
#define DFL_SERVER_PORT 4433
#define DFL_REQUEST_PAGE "/"
#define DFL_DEBUG_LEVEL 0
#define DFL_CRT_FILE ""
#define DFL_KEY_FILE ""
#define GET_REQUEST "GET %s HTTP/1.0\r\n\r\n"
/*
* global options
*/
struct options
{
char *server_name; /* hostname of the server (client only) */
int server_port; /* port on which the ssl service runs */
int debug_level; /* level of debugging */
char *request_page; /* page on server to request */
char *crt_file; /* the file with the client certificate */
char *key_file; /* the file with the client key */
} opt;
void my_debug( void *ctx, int level, const char *str )
{
if( level < opt.debug_level )
{
fprintf( (FILE *) ctx, "%s", str );
fflush( (FILE *) ctx );
}
}
#define USAGE \
"\n usage: ssl_client2 param=<>...\n" \
"\n acceptable parameters:\n" \
" server_name=%%s default: localhost\n" \
" server_port=%%d default: 4433\n" \
" debug_level=%%d default: 0 (disabled)\n" \
" request_page=%%s default: \".\"\n" \
" crt_file=%%s default: \"\" (pre-loaded)\n" \
" key_file=%%s default: \"\" (pre-loaded)\n" \
"\n"
int main( int argc, char *argv[] )
{
int ret = 0, len, server_fd;
unsigned char buf[1024];
havege_state hs;
ssl_context ssl;
ssl_session ssn;
x509_cert cacert;
x509_cert clicert;
rsa_context rsa;
int i, j, n;
char *p, *q;
if( argc == 0 )
{
usage:
printf( USAGE );
goto exit;
}
opt.server_name = DFL_SERVER_NAME;
opt.server_port = DFL_SERVER_PORT;
opt.debug_level = DFL_DEBUG_LEVEL;
opt.request_page = DFL_REQUEST_PAGE;
opt.crt_file = DFL_CRT_FILE;
opt.key_file = DFL_KEY_FILE;
for( i = 1; i < argc; i++ )
{
n = strlen( argv[i] );
for( j = 0; j < n; j++ )
{
if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
argv[i][j] |= 0x20;
}
p = argv[i];
if( ( q = strchr( p, '=' ) ) == NULL )
goto usage;
*q++ = '\0';
if( strcmp( p, "server_name" ) == 0 )
opt.server_name = q;
else if( strcmp( p, "server_port" ) == 0 )
{
opt.server_port = atoi( q );
if( opt.server_port < 1 || opt.server_port > 65535 )
goto usage;
}
else if( strcmp( p, "debug_level" ) == 0 )
{
opt.debug_level = atoi( q );
if( opt.debug_level < 0 || opt.debug_level > 65535 )
goto usage;
}
else if( strcmp( p, "request_page" ) == 0 )
opt.request_page = q;
else if( strcmp( p, "crt_file" ) == 0 )
opt.crt_file = q;
else if( strcmp( p, "key_file" ) == 0 )
opt.key_file = q;
else
goto usage;
}
/*
* 0. Initialize the RNG and the session data
*/
havege_init( &hs );
memset( &ssn, 0, sizeof( ssl_session ) );
/*
* 1.1. Load the trusted CA
*/
printf( "\n . Loading the CA root certificate ..." );
fflush( stdout );
memset( &cacert, 0, sizeof( x509_cert ) );
/*
* Alternatively, you may load the CA certificates from a .pem or
* .crt file by calling x509parse_crtfile( &cacert, "myca.crt" ).
*/
ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
strlen( test_ca_crt ) );
if( ret != 0 )
{
printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 1.2. Load own certificate and private key
*
* (can be skipped if client authentication is not required)
*/
printf( " . Loading the client cert. and key..." );
fflush( stdout );
memset( &clicert, 0, sizeof( x509_cert ) );
if( strlen( opt.crt_file ) )
ret = x509parse_crtfile( &clicert, opt.crt_file );
else
ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
strlen( test_cli_crt ) );
if( ret != 0 )
{
printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
goto exit;
}
if( strlen( opt.key_file ) )
ret = x509parse_keyfile( &rsa, opt.key_file, "" );
else
ret = x509parse_key( &rsa, (unsigned char *) test_cli_key,
strlen( test_cli_key ), NULL, 0 );
if( ret != 0 )
{
printf( " failed\n ! x509parse_key returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 2. Start the connection
*/
printf( " . Connecting to tcp/%s/%-4d...", opt.server_name,
opt.server_port );
fflush( stdout );
if( ( ret = net_connect( &server_fd, opt.server_name,
opt.server_port ) ) != 0 )
{
printf( " failed\n ! net_connect returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 3. Setup stuff
*/
printf( " . Setting up the SSL/TLS structure..." );
fflush( stdout );
havege_init( &hs );
if( ( ret = ssl_init( &ssl ) ) != 0 )
{
printf( " failed\n ! ssl_init returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL );
ssl_set_rng( &ssl, havege_rand, &hs );
ssl_set_dbg( &ssl, my_debug, stdout );
ssl_set_bio( &ssl, net_recv, &server_fd,
net_send, &server_fd );
ssl_set_ciphers( &ssl, ssl_default_ciphers );
ssl_set_session( &ssl, 1, 600, &ssn );
ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
ssl_set_own_cert( &ssl, &clicert, &rsa );
ssl_set_hostname( &ssl, opt.server_name );
/*
* 4. Handshake
*/
printf( " . Performing the SSL/TLS handshake..." );
fflush( stdout );
while( ( ret = ssl_handshake( &ssl ) ) != 0 )
{
if( ret != POLARSSL_ERR_NET_TRY_AGAIN )
{
printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
goto exit;
}
}
printf( " ok\n [ Cipher is %s ]\n",
ssl_get_cipher( &ssl ) );
/*
* 5. Verify the server certificate
*/
printf( " . Verifying peer X.509 certificate..." );
if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
{
printf( " failed\n" );
if( ( ret & BADCERT_EXPIRED ) != 0 )
printf( " ! server certificate has expired\n" );
if( ( ret & BADCERT_REVOKED ) != 0 )
printf( " ! server certificate has been revoked\n" );
if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
printf( " ! CN mismatch (expected CN=%s)\n", opt.server_name );
if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
printf( " ! self-signed or not signed by a trusted CA\n" );
printf( "\n" );
}
else
printf( " ok\n" );
printf( " . Peer certificate information ...\n" );
x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", ssl.peer_cert );
printf( "%s\n", buf );
/*
* 6. Write the GET request
*/
printf( " > Write to server:" );
fflush( stdout );
len = sprintf( (char *) buf, GET_REQUEST, opt.request_page );
while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
{
if( ret != POLARSSL_ERR_NET_TRY_AGAIN )
{
printf( " failed\n ! ssl_write returned %d\n\n", ret );
goto exit;
}
}
len = ret;
printf( " %d bytes written\n\n%s", len, (char *) buf );
/*
* 7. Read the HTTP response
*/
printf( " < Read from server:" );
fflush( stdout );
do
{
len = sizeof( buf ) - 1;
memset( buf, 0, sizeof( buf ) );
ret = ssl_read( &ssl, buf, len );
if( ret == POLARSSL_ERR_NET_TRY_AGAIN )
continue;
if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
break;
if( ret <= 0 )
{
printf( "failed\n ! ssl_read returned %d\n\n", ret );
break;
}
len = ret;
printf( " %d bytes read\n\n%s", len, (char *) buf );
}
while( 0 );
ssl_close_notify( &ssl );
exit:
net_close( server_fd );
x509_free( &clicert );
x509_free( &cacert );
rsa_free( &rsa );
ssl_free( &ssl );
memset( &ssl, 0, sizeof( ssl ) );
#ifdef WIN32
printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,410 @@
/*
* SSL server demonstration program
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#ifdef WIN32
#include <windows.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "polarssl/havege.h"
#include "polarssl/certs.h"
#include "polarssl/x509.h"
#include "polarssl/ssl.h"
#include "polarssl/net.h"
#define HTTP_RESPONSE \
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
"<h2>PolarSSL Test Server</h2>\r\n" \
"<p>Successful connection using: %s</p>\r\n"
/*
* Computing a "safe" DH-1024 prime can take a very
* long time, so a precomputed value is provided below.
* You may run dh_genprime to generate a new value.
*/
char *my_dhm_P =
"E4004C1F94182000103D883A448B3F80" \
"2CE4B44A83301270002C20D0321CFD00" \
"11CCEF784C26A400F43DFB901BCA7538" \
"F2C6B176001CF5A0FD16D2C48B1D0C1C" \
"F6AC8E1DA6BCC3B4E1F96B0564965300" \
"FFA1D0B601EB2800F489AA512C4B248C" \
"01F76949A60BB7F00A40B1EAB64BDD48" \
"E8A700D60B7F1200FA8E77B0A979DABF";
char *my_dhm_G = "4";
/*
* Sorted by order of preference
*/
int my_ciphers[] =
{
SSL_EDH_RSA_AES_256_SHA,
SSL_EDH_RSA_CAMELLIA_256_SHA,
SSL_EDH_RSA_AES_128_SHA,
SSL_EDH_RSA_CAMELLIA_128_SHA,
SSL_EDH_RSA_DES_168_SHA,
SSL_RSA_AES_256_SHA,
SSL_RSA_CAMELLIA_256_SHA,
SSL_RSA_AES_128_SHA,
SSL_RSA_CAMELLIA_128_SHA,
SSL_RSA_DES_168_SHA,
SSL_RSA_RC4_128_SHA,
SSL_RSA_RC4_128_MD5,
0
};
#define DEBUG_LEVEL 0
void my_debug( void *ctx, int level, const char *str )
{
if( level < DEBUG_LEVEL )
{
fprintf( (FILE *) ctx, "%s", str );
fflush( (FILE *) ctx );
}
}
/*
* These session callbacks use a simple chained list
* to store and retrieve the session information.
*/
ssl_session *s_list_1st = NULL;
ssl_session *cur, *prv;
static int my_get_session( ssl_context *ssl )
{
time_t t = time( NULL );
if( ssl->resume == 0 )
return( 1 );
cur = s_list_1st;
prv = NULL;
while( cur != NULL )
{
prv = cur;
cur = cur->next;
if( ssl->timeout != 0 && t - prv->start > ssl->timeout )
continue;
if( ssl->session->cipher != prv->cipher ||
ssl->session->length != prv->length )
continue;
if( memcmp( ssl->session->id, prv->id, prv->length ) != 0 )
continue;
memcpy( ssl->session->master, prv->master, 48 );
return( 0 );
}
return( 1 );
}
static int my_set_session( ssl_context *ssl )
{
time_t t = time( NULL );
cur = s_list_1st;
prv = NULL;
while( cur != NULL )
{
if( ssl->timeout != 0 && t - cur->start > ssl->timeout )
break; /* expired, reuse this slot */
if( memcmp( ssl->session->id, cur->id, cur->length ) == 0 )
break; /* client reconnected */
prv = cur;
cur = cur->next;
}
if( cur == NULL )
{
cur = (ssl_session *) malloc( sizeof( ssl_session ) );
if( cur == NULL )
return( 1 );
if( prv == NULL )
s_list_1st = cur;
else prv->next = cur;
}
memcpy( cur, ssl->session, sizeof( ssl_session ) );
return( 0 );
}
int main( void )
{
int ret, len;
int listen_fd;
int client_fd;
unsigned char buf[1024];
havege_state hs;
ssl_context ssl;
ssl_session ssn;
x509_cert srvcert;
rsa_context rsa;
/*
* 1. Load the certificates and private RSA key
*/
printf( "\n . Loading the server cert. and key..." );
fflush( stdout );
memset( &srvcert, 0, sizeof( x509_cert ) );
/*
* This demonstration program uses embedded test certificates.
* Instead, you may want to use x509parse_crtfile() to read the
* server and CA certificates, as well as x509parse_keyfile().
*/
ret = x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,
strlen( test_srv_crt ) );
if( ret != 0 )
{
printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
goto exit;
}
ret = x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,
strlen( test_ca_crt ) );
if( ret != 0 )
{
printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
goto exit;
}
ret = x509parse_key( &rsa, (unsigned char *) test_srv_key,
strlen( test_srv_key ), NULL, 0 );
if( ret != 0 )
{
printf( " failed\n ! x509parse_key returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 2. Setup the listening TCP socket
*/
printf( " . Bind on https://localhost:4433/ ..." );
fflush( stdout );
if( ( ret = net_bind( &listen_fd, NULL, 4433 ) ) != 0 )
{
printf( " failed\n ! net_bind returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 3. Wait until a client connects
*/
#ifdef WIN32
ShellExecute( NULL, "open", "https://localhost:4433/",
NULL, NULL, SW_SHOWNORMAL );
#endif
client_fd = -1;
memset( &ssl, 0, sizeof( ssl ) );
accept:
net_close( client_fd );
ssl_free( &ssl );
printf( " . Waiting for a remote connection ..." );
fflush( stdout );
if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
{
printf( " failed\n ! net_accept returned %d\n\n", ret );
goto exit;
}
printf( " ok\n" );
/*
* 4. Setup stuff
*/
printf( " . Setting up the RNG and SSL data...." );
fflush( stdout );
havege_init( &hs );
if( ( ret = ssl_init( &ssl ) ) != 0 )
{
printf( " failed\n ! ssl_init returned %d\n\n", ret );
goto accept;
}
printf( " ok\n" );
ssl_set_endpoint( &ssl, SSL_IS_SERVER );
ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
ssl_set_rng( &ssl, havege_rand, &hs );
ssl_set_dbg( &ssl, my_debug, stdout );
ssl_set_bio( &ssl, net_recv, &client_fd,
net_send, &client_fd );
ssl_set_scb( &ssl, my_get_session,
my_set_session );
ssl_set_ciphers( &ssl, my_ciphers );
ssl_set_session( &ssl, 1, 0, &ssn );
memset( &ssn, 0, sizeof( ssl_session ) );
ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
ssl_set_own_cert( &ssl, &srvcert, &rsa );
ssl_set_dh_param( &ssl, my_dhm_P, my_dhm_G );
/*
* 5. Handshake
*/
printf( " . Performing the SSL/TLS handshake..." );
fflush( stdout );
while( ( ret = ssl_handshake( &ssl ) ) != 0 )
{
if( ret != POLARSSL_ERR_NET_TRY_AGAIN )
{
printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
goto accept;
}
}
printf( " ok\n" );
/*
* 6. Read the HTTP Request
*/
printf( " < Read from client:" );
fflush( stdout );
do
{
len = sizeof( buf ) - 1;
memset( buf, 0, sizeof( buf ) );
ret = ssl_read( &ssl, buf, len );
if( ret == POLARSSL_ERR_NET_TRY_AGAIN )
continue;
if( ret <= 0 )
{
switch( ret )
{
case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
printf( " connection was closed gracefully\n" );
break;
case POLARSSL_ERR_NET_CONN_RESET:
printf( " connection was reset by peer\n" );
break;
default:
printf( " ssl_read returned %d\n", ret );
break;
}
break;
}
len = ret;
printf( " %d bytes read\n\n%s", len, (char *) buf );
}
while( 0 );
/*
* 7. Write the 200 Response
*/
printf( " > Write to client:" );
fflush( stdout );
len = sprintf( (char *) buf, HTTP_RESPONSE,
ssl_get_cipher( &ssl ) );
while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
{
if( ret == POLARSSL_ERR_NET_CONN_RESET )
{
printf( " failed\n ! peer closed the connection\n\n" );
goto accept;
}
if( ret != POLARSSL_ERR_NET_TRY_AGAIN )
{
printf( " failed\n ! ssl_write returned %d\n\n", ret );
goto exit;
}
}
len = ret;
printf( " %d bytes written\n\n%s\n", len, (char *) buf );
ssl_close_notify( &ssl );
goto accept;
exit:
net_close( client_fd );
x509_free( &srvcert );
rsa_free( &rsa );
ssl_free( &ssl );
cur = s_list_1st;
while( cur != NULL )
{
prv = cur;
cur = cur->next;
memset( prv, 0, sizeof( ssl_session ) );
free( prv );
}
memset( &ssl, 0, sizeof( ssl_context ) );
#ifdef WIN32
printf( " Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( ret );
}

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA3BN0gcYS9mddoWZy7dx5tlhcMliz1BT9bAJhnguZRmOjCkHU
QjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtgYjGDJ39LlZIuoNbGhJRLs+Sm
zP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KHqHzaCYOYnXplXiBSBy5lpTH9
2XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP6zXJ8apGTnR//h2wkR+JSoTL
33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCeJF1yleCiBkGMYeRQV3SWsSm1
oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwIDAQABAoIBAAbw6iTJrYFuAyr7
AzbzVDdnFAlWeN2Ah/mnHZMRhJUOwW6qYtpvqGsTIqERu4uJWgBiWG7fHPXd342L
pUw7C0rsAf821o8hWa3u/V9/RqWZ08VpucUPa3MlGO3XDjlqWmmOI6RwiKbZAaaI
m+eX40PwzjyHK41PRDn7SUUtuciWJA8zz7f6mYqt3abRoaVpqEAs4OfreKvn60lN
SUgwrCVTVot7c+l+8QaXcvlH600um8Y/avLUbktxZMsSY47i0NIYmBGZahfvHLsE
MmJwlkTInSXPHvKjAoCA4Ny7QWLsx6+xdcig3ZjvFeHaus48hR9dohV1V488XtXP
u3ROIxkCgYEA8LpsoSjFCLL+6nz9Ca156UHD0oGUxVkxPH6ieHMnTCOT1ljl4WD2
pO26NxZI46eWkl48qNMvQujufRS6KUB59KfLK4Is7yYFLkacoxkRuiUT9r3sKhYs
MXU6ObiOA25gYCeu/OuRBbS6B/h03CuhVdkjbir28bbRUKuoi2fdLWsCgYEA6gmg
N2/e00G6YHdNIQRIcfoOvGKvZeEvwJCTwV1BxKKRNgCKMYUT6/50fJW7Nwo+Kfem
+4JCRz1/s9/N/F4pHo8DOHxRkQ+g55pi02S2kPJNYd4Mn1kxQ6s857PZkWCyyltD
y+WRXN3N9ZrAto7+5Etwr2d3tb5zNotdKAYtoTUCgYBeoqs53/E1rkiQnnpLZ6tZ
i8UT6GU4AAxfH9l3SK3WPNZNmb0lkRzlUZ+3MEePV77V474tEHiv8SpwecmFlhdb
mutAO3i2u1emDZReeeiCKTlj8t343aaZ+t/c+TS7HJU+t9sPCvyEJbxMjdxDAdP3
D9nh4XobJCe9cv5bb4V/6QKBgCLM1Z8Iqnh9UIphkv1y1pbkGObYQb6DcodOuDnL
dSkZB0ChaesdH646wvV3ikQP6Nhys8i4QMS5F1EW2VlKYxDhMRhoG/TW/xURNtq6
Ig+BiBIiY3waViH6x26oppRgbZV7ZqRd+XR2otZ/cWJz9uDZeuMKHpnOvPECXhLC
gGx1AoGAfYLKfsB9Im+x1+JwmRz1bMHV93XrQbt6OFt4MQhfcnZqebO7KT3E5/XF
NgjWiQcwTXPKzDxKE2YVpm/WKjh1ewypZ0eJa3PjbPG6aLlVtXGyNauQhyzlUwbZ
nmvjOi6uZv+U+hhvfsTcRIGMfwtohqSouG8wbz59ILXQoZNESaM=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 9 (0x9)
Signature Algorithm: md2WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert MD2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: md2WithRSAEncryption
28:5a:dd:48:fb:ec:80:fe:de:b7:20:c0:4c:05:a9:4b:51:e9:
a7:d1:4b:5e:76:42:d2:5d:9a:14:19:3b:cb:f9:91:d7:0f:11:
c9:cd:dd:00:8b:2c:76:73:22:a0:19:49:81:63:40:30:48:27:
62:90:ca:b8:dc:33:35:b3:4b:58:ca:dc:07:66:87:2e:ea:44:
2a:6a:13:67:7a:32:5e:48:1d:88:88:c5:70:e6:e7:ec:1b:2f:
a7:f4:61:71:29:f6:66:93:30:60:7e:b3:4c:01:c8:2c:53:ce:
00:11:ec:bf:f6:f2:ce:51:97:d8:ed:ed:dc:c9:6b:b8:19:15:
c8:9a:61:6d:12:9a:99:25:d8:03:1d:a6:4c:20:a5:f8:46:a3:
05:32:bb:1a:8e:1a:65:0d:f3:13:35:1d:6f:73:28:31:12:d7:
c4:9e:73:a0:a7:ce:82:25:d1:40:e8:1b:77:60:f3:3e:81:7f:
19:ee:cf:97:4d:c8:c3:35:9b:72:98:3b:c3:35:43:14:0a:04:
21:7b:f7:db:e6:5f:ce:21:d1:ce:bf:b7:ef:c1:63:21:c2:78:
e1:37:aa:b1:e0:31:b3:b6:63:4c:fd:66:c8:e6:cf:f8:d9:97:
2f:cf:92:81:3f:d4:bf:ec:e2:ad:6e:39:c7:a6:a8:e0:32:b0:
2e:0d:e1:30
-----BEGIN CERTIFICATE-----
MIIDPzCCAiegAwIBAgIBCTANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA8MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENlcnQgTUQyMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhcMliz
1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtgYjGD
J39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KHqHza
CYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP6zXJ
8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCeJF1y
leCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+btjAf
BgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQIFAAOC
AQEAKFrdSPvsgP7etyDATAWpS1Hpp9FLXnZC0l2aFBk7y/mR1w8Ryc3dAIssdnMi
oBlJgWNAMEgnYpDKuNwzNbNLWMrcB2aHLupEKmoTZ3oyXkgdiIjFcObn7Bsvp/Rh
cSn2ZpMwYH6zTAHILFPOABHsv/byzlGX2O3t3MlruBkVyJphbRKamSXYAx2mTCCl
+EajBTK7Go4aZQ3zEzUdb3MoMRLXxJ5zoKfOgiXRQOgbd2DzPoF/Ge7Pl03IwzWb
cpg7wzVDFAoEIXv32+ZfziHRzr+378FjIcJ44TeqseAxs7ZjTP1myObP+NmXL8+S
gT/Uv+zirW45x6ao4DKwLg3hMA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 10 (0xa)
Signature Algorithm: md4WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert MD4
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: md4WithRSAEncryption
3d:34:e7:aa:98:28:91:95:d4:df:be:66:4e:92:7f:25:f7:ce:
23:59:db:30:52:3f:67:a0:ab:06:18:be:32:ad:f9:d5:24:87:
90:c5:ac:42:a6:8f:2a:e3:b3:36:c4:9c:38:e4:2e:6a:64:26:
33:39:e0:46:4e:f5:09:a7:d2:cd:6a:16:30:49:80:81:4c:19:
43:2e:55:0d:b8:18:d6:db:8e:e0:3e:25:ca:a2:74:76:b7:1c:
97:13:db:21:83:50:38:eb:f7:36:d5:74:3d:fc:90:d8:7f:d6:
ad:2d:5d:ab:99:fc:45:41:c1:55:22:f7:57:c0:c5:24:a0:67:
a0:e8:03:f1:98:87:7a:be:d9:57:04:06:ba:57:29:ca:6e:33:
28:16:7d:fa:5c:2b:ae:40:78:01:6f:77:9f:54:94:fb:bb:73:
3f:f1:ca:81:4f:65:49:2c:1a:62:15:fe:0e:43:d3:81:10:b2:
b6:e9:92:f9:b8:be:cf:50:85:a4:65:af:ed:fa:58:6c:5c:90:
b1:ae:90:7a:a4:68:93:cf:85:6b:73:98:c0:a7:97:d7:03:59:
0c:97:33:1b:9d:5a:4a:9d:31:71:c3:e4:57:21:1e:9a:67:16:
89:ff:de:42:88:97:05:cf:ab:63:3b:a4:fc:7f:7b:4d:54:b7:
f5:bb:68:c4
-----BEGIN CERTIFICATE-----
MIIDPzCCAiegAwIBAgIBCjANBgkqhkiG9w0BAQMFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA8MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENlcnQgTUQ0MIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhcMliz
1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtgYjGD
J39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KHqHza
CYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP6zXJ
8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCeJF1y
leCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+btjAf
BgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQMFAAOC
AQEAPTTnqpgokZXU375mTpJ/JffOI1nbMFI/Z6CrBhi+Mq351SSHkMWsQqaPKuOz
NsScOOQuamQmMzngRk71CafSzWoWMEmAgUwZQy5VDbgY1tuO4D4lyqJ0drcclxPb
IYNQOOv3NtV0PfyQ2H/WrS1dq5n8RUHBVSL3V8DFJKBnoOgD8ZiHer7ZVwQGulcp
ym4zKBZ9+lwrrkB4AW93n1SU+7tzP/HKgU9lSSwaYhX+DkPTgRCytumS+bi+z1CF
pGWv7fpYbFyQsa6QeqRok8+Fa3OYwKeX1wNZDJczG51aSp0xccPkVyEemmcWif/e
QoiXBc+rYzuk/H97TVS39btoxA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 11 (0xb)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert MD5
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: md5WithRSAEncryption
7d:c7:ae:4b:1d:56:8c:c8:2a:40:13:24:91:38:b0:72:77:6a:
a3:fd:7e:0d:30:ca:96:7e:55:85:ff:fb:cd:a7:29:bd:a3:f8:
bc:df:e3:ee:f8:f0:5d:4b:91:0e:f6:e2:c5:9c:3f:74:26:d1:
d2:37:13:59:09:d6:39:43:ce:d7:67:70:92:c8:98:2b:5a:f5:
09:e1:ea:d9:43:f1:92:61:b8:43:74:d8:a9:f0:af:b6:df:11:
61:cd:8f:35:39:1f:d1:17:70:f9:2b:86:3e:df:4b:c6:81:0b:
f5:cc:de:62:dd:f7:7f:14:2a:1a:e7:98:3d:6e:db:1c:47:df:
8d:31:49:7b:78:b0:81:89:c8:b5:f5:e9:e4:9e:00:a5:20:70:
e5:32:56:e6:a7:be:68:ba:bf:d4:8e:8f:c8:42:31:30:b3:39:
fa:3e:9c:70:53:64:d6:96:af:f7:8a:e7:de:20:3a:f0:66:71:
98:ec:c0:f8:52:c9:07:be:29:0e:0d:6e:7e:4e:36:9c:bb:a1:
5a:ea:1e:6f:d9:8e:81:0c:58:88:1a:be:1b:01:14:ad:ad:4a:
58:7a:10:53:43:1b:6d:2d:17:44:94:ba:31:5d:09:4e:85:5c:
c7:f2:c2:53:a5:1d:58:dc:4e:de:3c:88:b3:13:5a:7f:5d:a5:
c6:e6:3a:f7
-----BEGIN CERTIFICATE-----
MIIDPzCCAiegAwIBAgIBCzANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA8MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENlcnQgTUQ1MIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhcMliz
1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtgYjGD
J39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KHqHza
CYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP6zXJ
8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCeJF1y
leCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+btjAf
BgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQQFAAOC
AQEAfceuSx1WjMgqQBMkkTiwcndqo/1+DTDKln5Vhf/7zacpvaP4vN/j7vjwXUuR
DvbixZw/dCbR0jcTWQnWOUPO12dwksiYK1r1CeHq2UPxkmG4Q3TYqfCvtt8RYc2P
NTkf0Rdw+SuGPt9LxoEL9czeYt33fxQqGueYPW7bHEffjTFJe3iwgYnItfXp5J4A
pSBw5TJW5qe+aLq/1I6PyEIxMLM5+j6ccFNk1pav94rn3iA68GZxmOzA+FLJB74p
Dg1ufk42nLuhWuoeb9mOgQxYiBq+GwEUra1KWHoQU0MbbS0XRJS6MV0JToVcx/LC
U6UdWNxO3jyIsxNaf12lxuY69w==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 12 (0xc)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert SHA1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha1WithRSAEncryption
0b:3d:49:a6:2a:23:fa:f1:5d:dd:c0:7e:b4:a4:47:cb:78:a8:
58:62:e5:80:e2:50:19:41:0e:22:98:fc:51:40:f1:64:88:4c:
2f:90:f9:eb:5e:93:51:bc:53:31:df:86:07:b0:bb:43:57:4d:
dc:0e:4d:6a:67:90:57:e1:3f:3c:df:a9:f6:fb:02:c8:fc:88:
91:35:c9:6c:a1:dd:2d:4f:0e:36:e9:d2:6b:1d:9b:3e:e9:01:
bd:11:cd:e0:fa:c3:8f:8d:07:ae:e4:aa:a2:80:3d:ad:10:02:
d9:f2:e8:c5:37:3f:95:f9:fa:b0:c6:57:b7:ad:16:a6:c8:ec:
f8:d5:46:d4:26:53:5e:33:52:ff:aa:c0:b8:c2:3c:b5:cb:30:
d9:6c:6f:6e:68:c8:5c:61:62:28:51:72:3b:57:17:1d:05:8c:
d8:4f:63:f4:51:25:e4:4d:37:3c:2e:dc:5e:d9:c9:e2:b0:16:
f9:25:cb:02:65:28:4f:b7:b6:16:c0:d9:04:1c:0e:b6:70:79:
3b:a6:aa:42:ee:37:97:3c:11:26:39:7b:b9:be:29:0c:06:e6:
f7:05:9f:38:19:22:d5:6e:44:52:1b:24:c8:6f:1f:8c:bc:71:
c2:7a:c3:17:ac:58:fd:c6:2e:5c:1c:83:c9:bc:a3:c7:81:1a:
09:d5:0d:49
-----BEGIN CERTIFICATE-----
MIIDQDCCAiigAwIBAgIBDDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA9MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxGzAZBgNVBAMTElBvbGFyU1NMIENlcnQgU0hBMTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANwTdIHGEvZnXaFmcu3cebZYXDJY
s9QU/WwCYZ4LmUZjowpB1EIzIebtQwdaHaI7ZCmoKsFmKABZ2AxJLTC3PYy7YGIx
gyd/S5WSLqDWxoSUS7Pkpsz/MjrF7EzJJFi/szN3arUXiwIQKY6VqpFgF0NCh6h8
2gmDmJ16ZV4gUgcuZaUx/dl0HgDJrp2BVosICvUenNyiXmzb/xGDFfTRJFebD+s1
yfGqRk50f/4dsJEfiUqEy9914813gmIJ5Z9tKd4uJdhItiC+UZdMLSBlLSpQniRd
cpXgogZBjGHkUFd0lrEptaGIN/FcnrKejoONcju1XP67EolyXKH52BgpsicCAwEA
AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUt1HU5SDVRVT0xVEb4IK1YQWvm7Yw
HwYDVR0jBBgwFoAUzyIxJ5HYwlT/HtrZ7orFiTKtDCEwDQYJKoZIhvcNAQEFBQAD
ggEBAAs9SaYqI/rxXd3AfrSkR8t4qFhi5YDiUBlBDiKY/FFA8WSITC+Q+etek1G8
UzHfhgewu0NXTdwOTWpnkFfhPzzfqfb7Asj8iJE1yWyh3S1PDjbp0msdmz7pAb0R
zeD6w4+NB67kqqKAPa0QAtny6MU3P5X5+rDGV7etFqbI7PjVRtQmU14zUv+qwLjC
PLXLMNlsb25oyFxhYihRcjtXFx0FjNhPY/RRJeRNNzwu3F7ZyeKwFvklywJlKE+3
thbA2QQcDrZweTumqkLuN5c8ESY5e7m+KQwG5vcFnzgZItVuRFIbJMhvH4y8ccJ6
wxesWP3GLlwcg8m8o8eBGgnVDUk=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 13 (0xd)
Signature Algorithm: sha224WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert SHA224
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha224WithRSAEncryption
81:8e:2e:bb:77:a3:7c:53:02:9e:9c:d7:66:e3:f5:3f:a6:19:
ff:09:8c:7d:4b:10:5f:c3:bd:ad:fc:cc:5c:dc:92:ef:1e:c3:
74:70:a6:88:0d:4c:4d:2c:45:0b:76:90:b5:2f:13:93:ee:79:
ea:2a:91:f5:ab:6c:dc:5d:3d:f1:b8:3d:bb:d1:a8:40:3d:16:
11:97:50:59:39:41:54:9f:c3:a6:d9:81:36:6d:85:90:a1:fb:
c3:6b:3d:5f:24:95:c5:1e:e4:bc:bc:22:b6:9d:6b:60:c1:3a:
35:21:13:19:ff:82:0e:4f:e5:50:53:db:cc:51:1b:bc:4d:12:
ca:79:cc:cc:a0:6e:b5:9a:5a:25:c2:c6:e3:e2:fb:04:ba:d4:
0d:69:ce:d3:8c:60:54:d2:32:75:8a:4d:08:ee:b0:01:15:ef:
80:9a:ae:dd:e5:47:5a:a3:99:e8:eb:aa:38:51:6c:5a:94:6f:
7b:6c:c6:34:eb:66:5a:da:83:53:eb:32:6c:1e:8d:7e:20:09:
4c:9b:05:57:e8:27:71:84:53:5f:be:c3:e9:87:9f:8a:a0:41:
67:5e:c5:7e:a8:c4:31:31:aa:f4:4b:95:c7:eb:83:01:da:8a:
7f:0c:f3:07:b2:5f:8e:28:2e:85:a0:d8:ef:d8:35:6b:cd:42:
92:cc:44:0e
-----BEGIN CERTIFICATE-----
MIIDQjCCAiqgAwIBAgIBDTANBgkqhkiG9w0BAQ4FADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA/MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxHTAbBgNVBAMTFFBvbGFyU1NMIENlcnQgU0hBMjI0MIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhc
Mliz1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtg
YjGDJ39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KH
qHzaCYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP
6zXJ8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCe
JF1yleCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+b
tjAfBgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQ4F
AAOCAQEAgY4uu3ejfFMCnpzXZuP1P6YZ/wmMfUsQX8O9rfzMXNyS7x7DdHCmiA1M
TSxFC3aQtS8Tk+556iqR9ats3F098bg9u9GoQD0WEZdQWTlBVJ/DptmBNm2FkKH7
w2s9XySVxR7kvLwitp1rYME6NSETGf+CDk/lUFPbzFEbvE0SynnMzKButZpaJcLG
4+L7BLrUDWnO04xgVNIydYpNCO6wARXvgJqu3eVHWqOZ6OuqOFFsWpRve2zGNOtm
WtqDU+sybB6NfiAJTJsFV+gncYRTX77D6YefiqBBZ17FfqjEMTGq9EuVx+uDAdqK
fwzzB7JfjiguhaDY79g1a81CksxEDg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14 (0xe)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert SHA256
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha256WithRSAEncryption
0f:4c:70:2a:ad:b8:43:ea:97:3d:5d:d6:0a:d8:e1:42:b9:3d:
42:42:a1:dd:df:37:e3:0c:ab:40:aa:10:3c:f6:88:c1:e9:82:
ac:35:f6:f7:66:d1:ee:71:bd:b5:9f:48:dc:e2:09:8a:3e:0e:
1d:da:12:e4:f3:53:a1:a1:d9:b2:32:df:e2:83:5d:c8:df:fa:
1a:6c:f4:c0:94:cc:20:6b:2b:74:9e:c1:35:d7:2a:ea:99:f8:
31:50:e9:c1:5d:3b:14:d4:12:96:b2:06:a3:4d:0f:f5:a9:8f:
44:08:61:15:0a:92:bd:29:0b:8d:c1:87:0a:40:de:29:b8:4f:
92:e4:b8:fa:d3:ec:5f:55:5e:32:69:57:60:6b:6a:02:89:2a:
d4:8e:91:5e:fd:45:d0:21:07:92:d6:c0:9b:ed:d0:d1:07:b9:
84:65:01:47:ed:95:03:a5:67:66:30:83:21:87:bb:4c:08:1b:
79:97:ec:ad:f8:89:7f:01:29:07:6a:d4:58:c6:11:d4:bc:1d:
4f:03:3b:ef:11:a5:e7:8b:4b:29:b5:c5:7d:57:8a:6b:e5:11:
0a:39:aa:ef:bf:53:82:ea:34:24:42:84:11:91:ba:cb:71:7e:
fa:f7:d3:1e:2b:c4:14:10:0a:16:0a:b7:a5:e2:89:ca:79:dd:
d1:ad:d2:00
-----BEGIN CERTIFICATE-----
MIIDQjCCAiqgAwIBAgIBDjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA/MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxHTAbBgNVBAMTFFBvbGFyU1NMIENlcnQgU0hBMjU2MIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhc
Mliz1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtg
YjGDJ39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KH
qHzaCYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP
6zXJ8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCe
JF1yleCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+b
tjAfBgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQsF
AAOCAQEAD0xwKq24Q+qXPV3WCtjhQrk9QkKh3d834wyrQKoQPPaIwemCrDX292bR
7nG9tZ9I3OIJij4OHdoS5PNToaHZsjLf4oNdyN/6Gmz0wJTMIGsrdJ7BNdcq6pn4
MVDpwV07FNQSlrIGo00P9amPRAhhFQqSvSkLjcGHCkDeKbhPkuS4+tPsX1VeMmlX
YGtqAokq1I6RXv1F0CEHktbAm+3Q0Qe5hGUBR+2VA6VnZjCDIYe7TAgbeZfsrfiJ
fwEpB2rUWMYR1LwdTwM77xGl54tLKbXFfVeKa+URCjmq779Tguo0JEKEEZG6y3F+
+vfTHivEFBAKFgq3peKJynnd0a3SAA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15 (0xf)
Signature Algorithm: sha384WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:56:59 2009 GMT
Not After : Jul 12 10:56:59 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert SHA384
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha384WithRSAEncryption
21:92:8d:39:05:a4:16:00:35:0b:de:ce:a8:17:9f:b8:a1:8b:
ad:5c:17:40:a8:5a:3b:c9:e5:5a:48:0d:e4:c3:6f:22:5a:eb:
19:85:10:a2:af:8f:71:e7:ca:a9:4f:be:01:3d:ba:8b:91:40:
25:f3:51:b6:d9:54:ae:4a:1d:2a:da:dd:9f:f8:70:07:31:35:
c0:ea:5e:ca:c5:76:38:08:f1:63:0d:8d:f7:96:3a:97:cb:a0:
f0:33:0f:2a:91:e4:13:30:73:68:74:92:e5:08:af:27:b8:14:
8e:b5:f6:a8:95:f2:52:c9:d1:bc:35:fa:97:ef:74:9e:dc:cc:
df:b3:d2:cd:8e:f1:fa:81:6d:b0:38:37:10:4a:1d:f7:ed:10:
33:da:e0:2f:ae:bb:a8:6a:02:f9:44:d7:46:a6:fb:89:b3:d7:
5b:dc:55:7d:a9:51:c5:f2:79:d8:60:b7:52:7c:9d:e5:13:ed:
98:1d:39:1b:fa:da:b9:70:53:51:22:22:03:1c:6e:f6:5d:88:
d8:a8:5e:95:8d:27:69:97:d5:a6:3f:ae:83:9b:02:e9:45:21:
e6:df:d5:84:ec:78:3a:e2:e7:a9:8a:e9:62:fa:fc:dc:94:86:
66:30:48:ea:dc:e2:5f:c0:52:d1:be:d0:03:c4:e3:7c:52:ce:
79:f1:26:84
-----BEGIN CERTIFICATE-----
MIIDQjCCAiqgAwIBAgIBDzANBgkqhkiG9w0BAQwFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NjU5WhcNMTEwNzEyMTA1NjU5WjA/MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxHTAbBgNVBAMTFFBvbGFyU1NMIENlcnQgU0hBMzg0MIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhc
Mliz1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtg
YjGDJ39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KH
qHzaCYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP
6zXJ8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCe
JF1yleCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+b
tjAfBgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQwF
AAOCAQEAIZKNOQWkFgA1C97OqBefuKGLrVwXQKhaO8nlWkgN5MNvIlrrGYUQoq+P
cefKqU++AT26i5FAJfNRttlUrkodKtrdn/hwBzE1wOpeysV2OAjxYw2N95Y6l8ug
8DMPKpHkEzBzaHSS5QivJ7gUjrX2qJXyUsnRvDX6l+90ntzM37PSzY7x+oFtsDg3
EEod9+0QM9rgL667qGoC+UTXRqb7ibPXW9xVfalRxfJ52GC3Unyd5RPtmB05G/ra
uXBTUSIiAxxu9l2I2KhelY0naZfVpj+ug5sC6UUh5t/VhOx4OuLnqYrpYvr83JSG
ZjBI6tziX8BS0b7QA8TjfFLOefEmhA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 16 (0x10)
Signature Algorithm: sha512WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Jul 12 10:57:00 2009 GMT
Not After : Jul 12 10:57:00 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Cert SHA512
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:dc:13:74:81:c6:12:f6:67:5d:a1:66:72:ed:dc:
79:b6:58:5c:32:58:b3:d4:14:fd:6c:02:61:9e:0b:
99:46:63:a3:0a:41:d4:42:33:21:e6:ed:43:07:5a:
1d:a2:3b:64:29:a8:2a:c1:66:28:00:59:d8:0c:49:
2d:30:b7:3d:8c:bb:60:62:31:83:27:7f:4b:95:92:
2e:a0:d6:c6:84:94:4b:b3:e4:a6:cc:ff:32:3a:c5:
ec:4c:c9:24:58:bf:b3:33:77:6a:b5:17:8b:02:10:
29:8e:95:aa:91:60:17:43:42:87:a8:7c:da:09:83:
98:9d:7a:65:5e:20:52:07:2e:65:a5:31:fd:d9:74:
1e:00:c9:ae:9d:81:56:8b:08:0a:f5:1e:9c:dc:a2:
5e:6c:db:ff:11:83:15:f4:d1:24:57:9b:0f:eb:35:
c9:f1:aa:46:4e:74:7f:fe:1d:b0:91:1f:89:4a:84:
cb:df:75:e3:cd:77:82:62:09:e5:9f:6d:29:de:2e:
25:d8:48:b6:20:be:51:97:4c:2d:20:65:2d:2a:50:
9e:24:5d:72:95:e0:a2:06:41:8c:61:e4:50:57:74:
96:b1:29:b5:a1:88:37:f1:5c:9e:b2:9e:8e:83:8d:
72:3b:b5:5c:fe:bb:12:89:72:5c:a1:f9:d8:18:29:
b2:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B7:51:D4:E5:20:D5:45:54:F4:C5:51:1B:E0:82:B5:61:05:AF:9B:B6
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha512WithRSAEncryption
19:13:61:13:81:ff:a2:c4:cf:45:dc:4f:40:e5:ce:a6:78:fb:
ff:49:a2:f7:58:d5:36:c0:e4:78:2a:0c:68:97:21:62:76:5e:
7f:4c:11:aa:31:13:17:22:d9:26:93:14:5e:60:6a:48:dd:56:
d2:b5:5d:9b:9a:d8:e0:c4:4a:42:53:de:43:2b:3e:82:0c:b7:
dd:f7:c5:5c:89:63:28:a9:8d:96:40:3a:0b:5b:df:7d:1e:4d:
b2:84:d8:38:1b:80:b6:28:d0:48:d0:42:30:f1:31:ec:ed:2e:
a2:e3:9d:e2:88:3f:b9:27:8d:34:76:dd:a7:de:71:5e:05:da:
78:9b:2b:51:f4:d2:f5:81:a5:f8:d4:78:d8:42:ba:91:24:30:
67:18:3c:ba:03:4f:ac:98:2c:ee:15:50:25:33:be:bb:4f:64:
54:28:51:9a:d1:9b:b6:8e:5a:db:4c:3f:89:0c:c6:e7:d4:27:
e4:4a:8d:55:11:df:46:23:9e:8a:cb:79:f3:bb:f1:1b:c0:2c:
5f:bd:31:09:e6:f7:31:c8:9d:4c:7a:99:74:38:78:39:d5:c1:
e5:d0:48:f7:fd:00:a5:1b:c2:bb:e9:9a:a3:1f:3f:fd:47:eb:
78:ed:3e:59:bb:16:65:1c:62:e0:a2:78:b5:bd:50:79:b9:5d:
4f:79:a6:37
-----BEGIN CERTIFICATE-----
MIIDQjCCAiqgAwIBAgIBEDANBgkqhkiG9w0BAQ0FADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwNzEyMTA1NzAwWhcNMTEwNzEyMTA1NzAwWjA/MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxHTAbBgNVBAMTFFBvbGFyU1NMIENlcnQgU0hBNTEyMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BN0gcYS9mddoWZy7dx5tlhc
Mliz1BT9bAJhnguZRmOjCkHUQjMh5u1DB1odojtkKagqwWYoAFnYDEktMLc9jLtg
YjGDJ39LlZIuoNbGhJRLs+SmzP8yOsXsTMkkWL+zM3dqtReLAhApjpWqkWAXQ0KH
qHzaCYOYnXplXiBSBy5lpTH92XQeAMmunYFWiwgK9R6c3KJebNv/EYMV9NEkV5sP
6zXJ8apGTnR//h2wkR+JSoTL33XjzXeCYgnln20p3i4l2Ei2IL5Rl0wtIGUtKlCe
JF1yleCiBkGMYeRQV3SWsSm1oYg38Vyesp6Og41yO7Vc/rsSiXJcofnYGCmyJwID
AQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS3UdTlINVFVPTFURvggrVhBa+b
tjAfBgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQ0F
AAOCAQEAGRNhE4H/osTPRdxPQOXOpnj7/0mi91jVNsDkeCoMaJchYnZef0wRqjET
FyLZJpMUXmBqSN1W0rVdm5rY4MRKQlPeQys+ggy33ffFXIljKKmNlkA6C1vffR5N
soTYOBuAtijQSNBCMPEx7O0uouOd4og/uSeNNHbdp95xXgXaeJsrUfTS9YGl+NR4
2EK6kSQwZxg8ugNPrJgs7hVQJTO+u09kVChRmtGbto5a20w/iQzG59Qn5EqNVRHf
RiOeist587vxG8AsX70xCeb3McidTHqZdDh4OdXB5dBI9/0ApRvCu+maox8//Ufr
eO0+WbsWZRxi4KJ4tb1QebldT3mmNw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Feb 9 21:12:35 2009 GMT
Not After : Feb 9 21:12:35 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Client 1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:cc:e9:b3:06:08:93:8e:83:e4:e8:d0:35:a4:81:
1d:a2:f0:f4:0a:33:46:dd:93:92:1b:da:51:5d:2e:
62:5d:36:78:c4:72:22:86:08:f4:a6:51:3e:02:de:
da:86:82:d4:65:2a:4e:2a:80:c7:dd:f8:ed:79:f8:
17:39:79:4b:1a:c6:0d:e5:b0:9b:f5:cc:4e:76:64:
2c:e6:47:ec:76:d6:cd:36:e0:f5:1b:24:36:21:a6:
72:71:39:0f:7a:d8:af:90:e8:3f:5d:19:ab:d3:f2:
1b:4a:fa:69:4b:7c:12:42:26:44:c3:46:27:6d:f7:
e2:66:59:56:fa:ec:a8:e7:dd:76:d5:36:6e:13:a0:
1f:9d:9e:29:ce:b5:bc:30:45:fb:d1:76:e0:3c:d4:
7b:ce:7a:32:a6:0e:63:aa:63:44:57:91:41:e9:2f:
c4:e8:5d:ad:d0:cf:1b:4b:8d:68:30:f2:7e:50:bc:
86:c1:cd:6c:10:28:7c:a5:d7:c2:f8:90:ce:6d:f7:
69:a6:25:50:a2:28:ad:57:75:82:23:ed:af:27:ea:
32:1e:89:b0:9d:07:0c:6a:f9:98:14:8b:8c:6d:fb:
15:83:7f:42:98:5f:4e:82:b0:1a:cc:c0:ce:6a:61:
e0:a8:a6:e0:d5:ec:17:16:9d:ce:41:ef:27:e3:e4:
8e:fb
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
F3:A4:F7:F2:0C:11:57:C9:D8:29:46:80:72:CA:23:87:7E:EA:90:27
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha1WithRSAEncryption
76:09:20:d6:88:9c:e7:ee:ae:bb:82:57:1e:ee:bf:bc:71:47:
79:04:49:84:5d:f3:99:3f:de:86:da:a4:0c:e4:47:63:9c:d8:
dd:2f:b8:d6:0f:4d:67:e7:04:c2:83:82:ce:6e:4c:ed:1a:1c:
70:27:b2:9b:da:7a:12:a1:1c:d3:dc:e4:ac:60:ae:21:71:f5:
dc:cc:01:c9:2f:c0:4c:51:fc:8e:c4:de:ac:c0:01:e0:82:b5:
80:f4:38:7d:21:ea:9c:92:46:cd:f6:1d:f9:60:3d:cb:0a:00:
88:6d:aa:5a:c1:08:50:d1:36:04:0a:ee:07:9a:6d:0d:ff:4d:
9e:af:97:d3:eb:88:5b:c8:0d:ed:0a:5c:6b:4b:b7:0b:ca:d5:
fd:9b:34:f4:be:d0:e0:6c:01:0d:6b:bc:41:f2:a3:13:05:0b:
cd:34:59:ba:15:7f:6e:a8:00:53:2a:d5:b7:3a:51:e5:cf:16:
04:66:ba:6b:73:4c:bd:4f:14:0f:64:30:00:7b:12:25:eb:73:
c5:2d:03:7c:37:91:3e:12:53:ad:a4:f4:fa:73:7b:b7:67:fa:
a5:9c:bd:2e:32:87:7b:8f:54:97:28:b8:5e:80:7d:6f:8a:47:
e1:f9:b9:61:ef:91:e6:74:54:af:e9:43:03:8f:8b:b6:f7:b5:
8d:24:5e:01
-----BEGIN CERTIFICATE-----
MIIDPzCCAiegAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwMjA5MjExMjM1WhcNMTEwMjA5MjExMjM1WjA8MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAxMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzOmzBgiTjoPk6NA1pIEdovD0CjNG
3ZOSG9pRXS5iXTZ4xHIihgj0plE+At7ahoLUZSpOKoDH3fjtefgXOXlLGsYN5bCb
9cxOdmQs5kfsdtbNNuD1GyQ2IaZycTkPetivkOg/XRmr0/IbSvppS3wSQiZEw0Yn
bffiZllW+uyo59121TZuE6AfnZ4pzrW8MEX70XbgPNR7znoypg5jqmNEV5FB6S/E
6F2t0M8bS41oMPJ+ULyGwc1sECh8pdfC+JDObfdppiVQoiitV3WCI+2vJ+oyHomw
nQcMavmYFIuMbfsVg39CmF9OgrAazMDOamHgqKbg1ewXFp3OQe8n4+SO+wIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTzpPfyDBFXydgpRoByyiOHfuqQJzAf
BgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQUFAAOC
AQEAdgkg1oic5+6uu4JXHu6/vHFHeQRJhF3zmT/ehtqkDORHY5zY3S+41g9NZ+cE
woOCzm5M7RoccCeym9p6EqEc09zkrGCuIXH13MwByS/ATFH8jsTerMAB4IK1gPQ4
fSHqnJJGzfYd+WA9ywoAiG2qWsEIUNE2BAruB5ptDf9Nnq+X0+uIW8gN7Qpca0u3
C8rV/Zs09L7Q4GwBDWu8QfKjEwULzTRZuhV/bqgAUyrVtzpR5c8WBGa6a3NMvU8U
D2QwAHsSJetzxS0DfDeRPhJTraT0+nN7t2f6pZy9LjKHe49Ulyi4XoB9b4pH4fm5
Ye+R5nRUr+lDA4+Ltve1jSReAQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzOmzBgiTjoPk6NA1pIEdovD0CjNG3ZOSG9pRXS5iXTZ4xHIi
hgj0plE+At7ahoLUZSpOKoDH3fjtefgXOXlLGsYN5bCb9cxOdmQs5kfsdtbNNuD1
GyQ2IaZycTkPetivkOg/XRmr0/IbSvppS3wSQiZEw0YnbffiZllW+uyo59121TZu
E6AfnZ4pzrW8MEX70XbgPNR7znoypg5jqmNEV5FB6S/E6F2t0M8bS41oMPJ+ULyG
wc1sECh8pdfC+JDObfdppiVQoiitV3WCI+2vJ+oyHomwnQcMavmYFIuMbfsVg39C
mF9OgrAazMDOamHgqKbg1ewXFp3OQe8n4+SO+wIDAQABAoIBAEVCTB8i8PS/gbRr
A2aJuYGkXWfBMxebVEwTu2J6VgbZbXJAfYi+KCq61PHVbxj9yVo0NV1KT8On6mRK
RVdItujivjm/OseWeYKskzx2XOdB7PS6jj3RPHadMpswRRopeRXKWfhWv+wQLcdm
4gYAdo9jLeSupo8VtLERS0Pej6xmZBrk/SKpFswXa7K4ddpHLN9Jzfo+4TRF/1n5
wmjHhUzi9yhJcVbfV7/EqUItDnmpFauBul//Qx7syQCJ7yGVIc0aJ3ESvQl3qQvD
inxcwiS+myRiilolFqiRf4Q4OCYfsoa1gSxz+Ohl9sv3PeDXKwvppG1Ch4FO3yH3
idRxT4kCgYEA9Y6fsEEnStmPlRB7Ru9jJCtarlkBpM/dk1rS6cEtGe1XKqaZI9m5
fmI8W5C3L5Q0c5FiqzOVIOT14x0SFrWewIQOnpJfH12ULJ3CuwXaDXWHKb1JBpj8
Yt/stgwdDdqdbSWmVhbYW/eHH3iXz/SAgmr4x0WpbMDacqSegc6wrCUCgYEA1aCV
GZy6qpGqbh4pWNN/lrpE9BgHRNesfpCM2EqFzehecuSZf+V6lZVUr/TTjjT9AzGi
TGy+S9BTY04NNAcTty/dWHOvGaeL6PcJTW89LGAgcT+jB3VFvoAC9FexXuq9JV/Y
q8OP+CT8W5aRAle6PL9pVOAY0e5qa92WaM6/1J8CgYEAvzw+0wY6sokyz/VQ/JJs
VHvLGGLK6+7ScfLWtSMzm7CCJP4v34KtembI+MqAT3aNTr+X5xq59i8565D1SGhT
ZTyzIf1+RTAcuI54XCyXf8na5L+8Qn4ceGhJshFHA0YROjKLExqhjyX7vp+tI1AY
UPk8G/z9kGu09HmN1CwC3V0CgYEAyJ8NR0dcOpGgF9g1hljhqsD1vrLOKMXPFfFU
hE/ARzahdI7g5S6yp8XdCX4IK7Xxos07GUDKmdJkbY9AcQrwZgoKemXyHEqv5zIQ
x2rfbUw9S32y8m8c96GqpKOyTGxxA6d2iSCYlTbO1IibWDLhEOnF1tK6HHUl9nTc
K0N2/gsCgYEAh8ZztJznIBzBAI4oplSd2XwFrCRh2y+ZcLTA6+G9E3Kux8Qngh/i
X22q/ekzdd7fk3wBKjSprfkJ635UnroH/X/6OzMZvAs6JeTSQuc2p4xHHt88fIL8
4Y/vd9vztAAnMj1NvLuWI6ZmtKfzZ76cTQVfwpQykzXl+P64U8IF1Ds=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,77 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4 (0x4)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
Validity
Not Before: Feb 9 21:12:35 2009 GMT
Not After : Feb 9 21:12:35 2011 GMT
Subject: C=NL, O=PolarSSL, CN=PolarSSL Client 2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:a1:d7:d3:0c:2c:ff:bc:85:83:e2:b2:3c:c2:5b:
15:fe:92:7c:09:b8:7b:de:90:39:19:4d:51:26:1b:
c8:bd:d3:9f:64:ab:66:79:2e:1e:2c:3f:d8:07:09:
f0:49:34:9e:f7:de:dd:4a:67:b5:96:bc:9e:7a:bc:
6a:e4:15:f2:45:0c:3d:26:32:33:a7:e5:fe:f1:19:
e0:e3:1d:86:30:a8:e4:b1:5f:60:65:56:49:18:55:
4c:ee:f2:0b:3b:64:ce:22:b4:2d:d6:18:e1:f5:96:
03:51:9c:f4:ff:a8:26:23:ce:9a:27:e5:21:83:16:
b3:cc:a7:5b:e1:6d:67:2c:5e:e1:23:bb:56:29:1f:
2e:e4:ff:c2:01:43:b4:b9:5a:e4:6d:2b:a7:31:fb:
ee:0b:db:98:49:75:53:37:75:1d:92:75:d5:dc:d7:
2c:e1:e7:2a:c4:be:15:f6:ff:4e:a4:38:87:cb:66:
78:ab:4d:ba:4a:e0:aa:15:16:74:2e:9b:c8:93:96:
ea:bf:c6:6c:40:54:39:db:bb:54:4c:dc:9d:53:4a:
00:86:5b:ef:fd:4a:59:c6:1e:b8:e4:69:01:03:3b:
f1:3a:03:0a:d4:9f:26:50:60:9b:8b:3d:74:13:07:
6e:f9:cd:e7:d6:ea:97:e1:0f:8b:08:99:ec:c4:29:
70:33
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
8C:06:38:93:D9:14:06:29:DF:CC:CD:71:11:43:37:8E:F0:43:38:1B
X509v3 Authority Key Identifier:
keyid:CF:22:31:27:91:D8:C2:54:FF:1E:DA:D9:EE:8A:C5:89:32:AD:0C:21
Signature Algorithm: sha1WithRSAEncryption
66:b6:b9:b3:22:9f:81:09:92:f2:9f:22:ec:df:47:3c:c5:18:
e4:01:83:4f:69:5b:11:88:73:71:a6:ef:25:95:d1:23:e0:4d:
9a:25:bb:d6:ac:a8:88:86:cc:06:6e:a9:c9:47:2c:06:a5:dc:
b2:4a:b6:5b:6c:4c:0f:f9:5c:bc:b4:e8:d2:4a:79:d5:27:67:
9f:2c:38:ef:5b:54:b4:bc:13:0e:ba:72:73:54:37:3d:39:fc:
e1:17:eb:59:3e:ec:b8:83:56:d1:cb:32:ce:13:01:88:61:70:
8e:f9:ce:97:95:46:38:ba:a1:77:8e:ee:a4:86:a3:30:12:b7:
10:df:7b:74:18:45:3c:57:aa:54:da:e5:c5:c0:b5:7b:4d:5d:
c0:c2:e7:0d:d0:f2:ab:36:5b:02:a8:3e:1f:6e:4a:aa:b2:05:
9f:35:aa:d6:26:f1:5f:27:a2:97:6e:9c:56:95:1e:4e:fb:5b:
4b:4f:58:f7:7b:8d:54:1c:e5:d3:4a:78:92:58:f5:a2:5f:98:
63:54:d7:fd:6d:14:5f:49:12:99:d0:32:d5:2a:c0:c6:97:a4:
d1:f5:c2:9d:dc:b4:6c:f0:ba:fb:e7:3e:f5:86:61:bb:86:e9:
e4:99:0a:ed:ee:dc:fa:84:ea:87:e0:c3:7e:76:e4:17:a3:58:
25:07:82:bf
-----BEGIN CERTIFICATE-----
MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
MDkwMjA5MjExMjM1WhcNMTEwMjA5MjExMjM1WjA8MQswCQYDVQQGEwJOTDERMA8G
A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAodfTDCz/vIWD4rI8wlsV/pJ8Cbh7
3pA5GU1RJhvIvdOfZKtmeS4eLD/YBwnwSTSe997dSme1lryeerxq5BXyRQw9JjIz
p+X+8Rng4x2GMKjksV9gZVZJGFVM7vILO2TOIrQt1hjh9ZYDUZz0/6gmI86aJ+Uh
gxazzKdb4W1nLF7hI7tWKR8u5P/CAUO0uVrkbSunMfvuC9uYSXVTN3UdknXV3Ncs
4ecqxL4V9v9OpDiHy2Z4q026SuCqFRZ0LpvIk5bqv8ZsQFQ527tUTNydU0oAhlvv
/UpZxh645GkBAzvxOgMK1J8mUGCbiz10Ewdu+c3n1uqX4Q+LCJnsxClwMwIDAQAB
o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSMBjiT2RQGKd/MzXERQzeO8EM4GzAf
BgNVHSMEGDAWgBTPIjEnkdjCVP8e2tnuisWJMq0MITANBgkqhkiG9w0BAQUFAAOC
AQEAZra5syKfgQmS8p8i7N9HPMUY5AGDT2lbEYhzcabvJZXRI+BNmiW71qyoiIbM
Bm6pyUcsBqXcskq2W2xMD/lcvLTo0kp51Sdnnyw471tUtLwTDrpyc1Q3PTn84Rfr
WT7suINW0csyzhMBiGFwjvnOl5VGOLqhd47upIajMBK3EN97dBhFPFeqVNrlxcC1
e01dwMLnDdDyqzZbAqg+H25KqrIFnzWq1ibxXyeil26cVpUeTvtbS09Y93uNVBzl
00p4klj1ol+YY1TX/W0UX0kSmdAy1SrAxpek0fXCndy0bPC6++c+9YZhu4bp5JkK
7e7c+oTqh+DDfnbkF6NYJQeCvw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAodfTDCz/vIWD4rI8wlsV/pJ8Cbh73pA5GU1RJhvIvdOfZKtm
eS4eLD/YBwnwSTSe997dSme1lryeerxq5BXyRQw9JjIzp+X+8Rng4x2GMKjksV9g
ZVZJGFVM7vILO2TOIrQt1hjh9ZYDUZz0/6gmI86aJ+UhgxazzKdb4W1nLF7hI7tW
KR8u5P/CAUO0uVrkbSunMfvuC9uYSXVTN3UdknXV3Ncs4ecqxL4V9v9OpDiHy2Z4
q026SuCqFRZ0LpvIk5bqv8ZsQFQ527tUTNydU0oAhlvv/UpZxh645GkBAzvxOgMK
1J8mUGCbiz10Ewdu+c3n1uqX4Q+LCJnsxClwMwIDAQABAoIBAQCepSN6QfoF4JMh
ezpYAlWTECCKns69on52MPYk9wNWIMWUNvfiPbTSB1tJuxJRkEVsEIi3UOYN9qMb
COt23ZR43sBqWreME8ZOrOFngB90P3q97BJgA67vLV6Ws6kS9YOjPR/ZSNbml8B1
FfiLS1bnrrQp+09YYr6pFDzawxVpxaCfr6mpfDbXhoBw0NGpf54V4rIm4eNIf9Ro
QS54g/d0thID9OhMrc2NIpfRs4GkebsxOIKZP+uKF6CoS8IujyKjab/Vb3XBSknD
ObmiDx+udh8gRRGSpIG8rgoMcM8JhPAYitjYo3AiRTPTAUb4nSgQVOVxnRRZX8C1
QhvKOntBAoGBANAmX4KzOncoELOZPAZpkBlAhLNEqKT6RrfVokR9JAz3Jqhe+3tF
a0taSHF0aDi7YI5PgRGsV2Bowf81IIS3z2UqHCf+Eo0745jPiY33V+KSQkydJruN
u/n89imdhcIZdvZoxoVB8aRFDarBlzVq/FozqcpbtiGNs2ogbf+xS1dRAoGBAMcM
Swc0S0G2ncec34beGNH9mloyseMVspGhUWy/3rKLLBVf7XtEM4eDMopgMeceWQw9
wZo4Hr9Ip8k3Z4Ue8wV+MxtSLuGaxHGnHVxJtEE9OarhKlvEqHVAeeWvK4Cr0+ip
/zxnWDAA7QulMuWiK0LBEYOvTUXFet4z/l27/rZDAoGAchjWufosziw0G36fnJQ4
3N603t9/4g8evJ5qOEiwfjrsAdcu2r+OtNtkYmyAxLhRkTCbe2iQ7NP/ozkn/hgT
o0yV6oYm/Swa8iSxLhSrJBMwLHboSF7E759uABnMvDzhLOj6CQnAv17qwvMjQ7DF
a1xucfIbwADAnCfyo/o3ZkECgYEApfbGCDe+GAif/fP7HITKxSxjKpniYKmSvoJ3
VemVUeFg3GGjrYfsPy1RUrdqZH6VWPOVHXV1jaCS5d9gXUq07vuOuVUI6esVqH3i
qTR7K3pVPvmHTATpQPqFqNEpwJuEkRZNTpwMl9ntzCvuCDHzSDGa3OWp1GcYT3Wi
vZ0mf+kCgYBEPLnXD1BH7BlzEsMfXCtw28VtTetixcHcZVKwzQ4UH035DFYHch3p
/rABUO+IwxfcHjrvUJyZgHTyzfhtjWV62SsTNrOa1JFhQ+frWxIU5VEA7rVnLeaO
3vMGjy6jnBSaKoktW8ikY+4FHq+t5z63UN3RF367Iz0dWzIVocbxAQ==
-----END RSA PRIVATE KEY-----

Some files were not shown because too many files have changed in this diff Show More