/programs/develop/libraries/kos_mbedtls/README.md |
---|
0,0 → 1,0 |
#### port of mbedtls-2.16.6 library for KolibriOS |
/programs/develop/libraries/kos_mbedtls/gpl-2.0.txt |
---|
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. |
/programs/develop/libraries/kos_mbedtls/howto.md |
---|
0,0 → 1,5 |
on windows: |
- how to build mdebtls static library: |
- cd to library/ |
- to build: mingw32-make |
- to clean: mingw32-make clean WINDOWS=1 |
/programs/develop/libraries/kos_mbedtls/include/.gitignore |
---|
0,0 → 1,4 |
Makefile |
*.sln |
*.vcxproj |
mbedtls/check_config |
/programs/develop/libraries/kos_mbedtls/include/CMakeLists.txt |
---|
0,0 → 1,16 |
option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON) |
if(INSTALL_MBEDTLS_HEADERS) |
file(GLOB headers "mbedtls/*.h") |
install(FILES ${headers} |
DESTINATION include/mbedtls |
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) |
endif(INSTALL_MBEDTLS_HEADERS) |
# Make config.h available in an out-of-source build. ssl-opt.sh requires it. |
if (ENABLE_TESTING AND NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) |
link_to_source(mbedtls) |
endif() |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/aes.h |
---|
0,0 → 1,676 |
/** |
* \file aes.h |
* |
* \brief This file contains AES definitions and functions. |
* |
* The Advanced Encryption Standard (AES) specifies a FIPS-approved |
* cryptographic algorithm that can be used to protect electronic |
* data. |
* |
* The AES algorithm is a symmetric block cipher that can |
* encrypt and decrypt information. For more information, see |
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and |
* <em>ISO/IEC 18033-2:2006: Information technology -- Security |
* techniques -- Encryption algorithms -- Part 2: Asymmetric |
* ciphers</em>. |
* |
* The AES-XTS block mode is standardized by NIST SP 800-38E |
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf> |
* and described in detail by IEEE P1619 |
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>. |
*/ |
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_AES_H |
#define MBEDTLS_AES_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* padlock.c and aesni.c rely on these values! */ |
#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ |
#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ |
/* Error codes in range 0x0020-0x0022 */ |
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ |
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ |
/* Error codes in range 0x0021-0x0025 */ |
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */ |
/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */ |
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */ |
/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */ |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_AES_ALT) |
// Regular implementation |
// |
/** |
* \brief The AES context-type definition. |
*/ |
typedef struct mbedtls_aes_context |
{ |
int nr; /*!< The number of rounds. */ |
uint32_t *rk; /*!< AES round keys. */ |
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can |
hold 32 extra Bytes, which can be used for |
one of the following purposes: |
<ul><li>Alignment if VIA padlock is |
used.</li> |
<li>Simplifying key expansion in the 256-bit |
case by generating an extra round key. |
</li></ul> */ |
} |
mbedtls_aes_context; |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/** |
* \brief The AES XTS context-type definition. |
*/ |
typedef struct mbedtls_aes_xts_context |
{ |
mbedtls_aes_context crypt; /*!< The AES context to use for AES block |
encryption or decryption. */ |
mbedtls_aes_context tweak; /*!< The AES context used for tweak |
computation. */ |
} mbedtls_aes_xts_context; |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#else /* MBEDTLS_AES_ALT */ |
#include "aes_alt.h" |
#endif /* MBEDTLS_AES_ALT */ |
/** |
* \brief This function initializes the specified AES context. |
* |
* It must be the first API called before using |
* the context. |
* |
* \param ctx The AES context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_aes_init( mbedtls_aes_context *ctx ); |
/** |
* \brief This function releases and clears the specified AES context. |
* |
* \param ctx The AES context to clear. |
* If this is \c NULL, this function does nothing. |
* Otherwise, the context must have been at least initialized. |
*/ |
void mbedtls_aes_free( mbedtls_aes_context *ctx ); |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/** |
* \brief This function initializes the specified AES XTS context. |
* |
* It must be the first API called before using |
* the context. |
* |
* \param ctx The AES XTS context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); |
/** |
* \brief This function releases and clears the specified AES XTS context. |
* |
* \param ctx The AES XTS context to clear. |
* If this is \c NULL, this function does nothing. |
* Otherwise, the context must have been at least initialized. |
*/ |
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
/** |
* \brief This function sets the encryption key. |
* |
* \param ctx The AES context to which the key should be bound. |
* It must be initialized. |
* \param key The encryption key. |
* This must be a readable buffer of size \p keybits bits. |
* \param keybits The size of data passed in bits. Valid options are: |
* <ul><li>128 bits</li> |
* <li>192 bits</li> |
* <li>256 bits</li></ul> |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. |
*/ |
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief This function sets the decryption key. |
* |
* \param ctx The AES context to which the key should be bound. |
* It must be initialized. |
* \param key The decryption key. |
* This must be a readable buffer of size \p keybits bits. |
* \param keybits The size of data passed. Valid options are: |
* <ul><li>128 bits</li> |
* <li>192 bits</li> |
* <li>256 bits</li></ul> |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. |
*/ |
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, |
unsigned int keybits ); |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/** |
* \brief This function prepares an XTS context for encryption and |
* sets the encryption key. |
* |
* \param ctx The AES XTS context to which the key should be bound. |
* It must be initialized. |
* \param key The encryption key. This is comprised of the XTS key1 |
* concatenated with the XTS key2. |
* This must be a readable buffer of size \p keybits bits. |
* \param keybits The size of \p key passed in bits. Valid options are: |
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li> |
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul> |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. |
*/ |
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief This function prepares an XTS context for decryption and |
* sets the decryption key. |
* |
* \param ctx The AES XTS context to which the key should be bound. |
* It must be initialized. |
* \param key The decryption key. This is comprised of the XTS key1 |
* concatenated with the XTS key2. |
* This must be a readable buffer of size \p keybits bits. |
* \param keybits The size of \p key passed in bits. Valid options are: |
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li> |
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul> |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. |
*/ |
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, |
const unsigned char *key, |
unsigned int keybits ); |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
/** |
* \brief This function performs an AES single-block encryption or |
* decryption operation. |
* |
* It performs the operation defined in the \p mode parameter |
* (encrypt or decrypt), on the input data buffer defined in |
* the \p input parameter. |
* |
* mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or |
* mbedtls_aes_setkey_dec() must be called before the first |
* call to this API with the same context. |
* |
* \param ctx The AES context to use for encryption or decryption. |
* It must be initialized and bound to a key. |
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or |
* #MBEDTLS_AES_DECRYPT. |
* \param input The buffer holding the input data. |
* It must be readable and at least \c 16 Bytes long. |
* \param output The buffer where the output data will be written. |
* It must be writeable and at least \c 16 Bytes long. |
* \return \c 0 on success. |
*/ |
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief This function performs an AES-CBC encryption or decryption operation |
* on full blocks. |
* |
* It performs the operation defined in the \p mode |
* parameter (encrypt/decrypt), on the input data buffer defined in |
* the \p input parameter. |
* |
* It can be called as many times as needed, until all the input |
* data is processed. mbedtls_aes_init(), and either |
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called |
* before the first call to this API with the same context. |
* |
* \note This function operates on full blocks, that is, the input size |
* must be a multiple of the AES block size of \c 16 Bytes. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the same function again on the next |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If you need to retain the contents of the IV, you should |
* either save it manually or use the cipher module instead. |
* |
* |
* \param ctx The AES context to use for encryption or decryption. |
* It must be initialized and bound to a key. |
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or |
* #MBEDTLS_AES_DECRYPT. |
* \param length The length of the input data in Bytes. This must be a |
* multiple of the block size (\c 16 Bytes). |
* \param iv Initialization vector (updated after use). |
* It must be a readable and writeable buffer of \c 16 Bytes. |
* \param input The buffer holding the input data. |
* It must be readable and of size \p length Bytes. |
* \param output The buffer holding the output data. |
* It must be writeable and of size \p length Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH |
* on failure. |
*/ |
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/** |
* \brief This function performs an AES-XTS encryption or decryption |
* operation for an entire XTS data unit. |
* |
* AES-XTS encrypts or decrypts blocks based on their location as |
* defined by a data unit number. The data unit number must be |
* provided by \p data_unit. |
* |
* NIST SP 800-38E limits the maximum size of a data unit to 2^20 |
* AES blocks. If the data unit is larger than this, this function |
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. |
* |
* \param ctx The AES XTS context to use for AES XTS operations. |
* It must be initialized and bound to a key. |
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or |
* #MBEDTLS_AES_DECRYPT. |
* \param length The length of a data unit in Bytes. This can be any |
* length between 16 bytes and 2^24 bytes inclusive |
* (between 1 and 2^20 block cipher blocks). |
* \param data_unit The address of the data unit encoded as an array of 16 |
* bytes in little-endian format. For disk encryption, this |
* is typically the index of the block device sector that |
* contains the data. |
* \param input The buffer holding the input data (which is an entire |
* data unit). This function reads \p length Bytes from \p |
* input. |
* \param output The buffer holding the output data (which is an entire |
* data unit). This function writes \p length Bytes to \p |
* output. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is |
* smaller than an AES block in size (16 Bytes) or if \p |
* length is larger than 2^20 blocks (16 MiB). |
*/ |
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, |
int mode, |
size_t length, |
const unsigned char data_unit[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/** |
* \brief This function performs an AES-CFB128 encryption or decryption |
* operation. |
* |
* It performs the operation defined in the \p mode |
* parameter (encrypt or decrypt), on the input data buffer |
* defined in the \p input parameter. |
* |
* For CFB, you must set up the context with mbedtls_aes_setkey_enc(), |
* regardless of whether you are performing an encryption or decryption |
* operation, that is, regardless of the \p mode parameter. This is |
* because CFB mode uses the same key schedule for encryption and |
* decryption. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the same function again on the next |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If you need to retain the contents of the |
* IV, you must either save it manually or use the cipher |
* module instead. |
* |
* |
* \param ctx The AES context to use for encryption or decryption. |
* It must be initialized and bound to a key. |
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or |
* #MBEDTLS_AES_DECRYPT. |
* \param length The length of the input data in Bytes. |
* \param iv_off The offset in IV (updated after use). |
* It must point to a valid \c size_t. |
* \param iv The initialization vector (updated after use). |
* It must be a readable and writeable buffer of \c 16 Bytes. |
* \param input The buffer holding the input data. |
* It must be readable and of size \p length Bytes. |
* \param output The buffer holding the output data. |
* It must be writeable and of size \p length Bytes. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function performs an AES-CFB8 encryption or decryption |
* operation. |
* |
* It performs the operation defined in the \p mode |
* parameter (encrypt/decrypt), on the input data buffer defined |
* in the \p input parameter. |
* |
* Due to the nature of CFB, you must use the same key schedule for |
* both encryption and decryption operations. Therefore, you must |
* use the context initialized with mbedtls_aes_setkey_enc() for |
* both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the same function again on the next |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* |
* \param ctx The AES context to use for encryption or decryption. |
* It must be initialized and bound to a key. |
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or |
* #MBEDTLS_AES_DECRYPT |
* \param length The length of the input data. |
* \param iv The initialization vector (updated after use). |
* It must be a readable and writeable buffer of \c 16 Bytes. |
* \param input The buffer holding the input data. |
* It must be readable and of size \p length Bytes. |
* \param output The buffer holding the output data. |
* It must be writeable and of size \p length Bytes. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /*MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
/** |
* \brief This function performs an AES-OFB (Output Feedback Mode) |
* encryption or decryption operation. |
* |
* For OFB, you must set up the context with |
* mbedtls_aes_setkey_enc(), regardless of whether you are |
* performing an encryption or decryption operation. This is |
* because OFB mode uses the same key schedule for encryption and |
* decryption. |
* |
* The OFB operation is identical for encryption or decryption, |
* therefore no operation mode needs to be specified. |
* |
* \note Upon exit, the content of iv, the Initialisation Vector, is |
* updated so that you can call the same function again on the next |
* block(s) of data and get the same result as if it was encrypted |
* in one call. This allows a "streaming" usage, by initialising |
* iv_off to 0 before the first call, and preserving its value |
* between calls. |
* |
* For non-streaming use, the iv should be initialised on each call |
* to a unique value, and iv_off set to 0 on each call. |
* |
* If you need to retain the contents of the initialisation vector, |
* you must either save it manually or use the cipher module |
* instead. |
* |
* \warning For the OFB mode, the initialisation vector must be unique |
* every encryption operation. Reuse of an initialisation vector |
* will compromise security. |
* |
* \param ctx The AES context to use for encryption or decryption. |
* It must be initialized and bound to a key. |
* \param length The length of the input data. |
* \param iv_off The offset in IV (updated after use). |
* It must point to a valid \c size_t. |
* \param iv The initialization vector (updated after use). |
* It must be a readable and writeable buffer of \c 16 Bytes. |
* \param input The buffer holding the input data. |
* It must be readable and of size \p length Bytes. |
* \param output The buffer holding the output data. |
* It must be writeable and of size \p length Bytes. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, |
size_t length, |
size_t *iv_off, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/** |
* \brief This function performs an AES-CTR encryption or decryption |
* operation. |
* |
* This function performs the operation defined in the \p mode |
* parameter (encrypt/decrypt), on the input data buffer |
* defined in the \p input parameter. |
* |
* Due to the nature of CTR, you must use the same key schedule |
* for both encryption and decryption operations. Therefore, you |
* must use the context initialized with mbedtls_aes_setkey_enc() |
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. |
* |
* \warning You must never reuse a nonce value with the same key. Doing so |
* would void the encryption for the two messages encrypted with |
* the same nonce and key. |
* |
* There are two common strategies for managing nonces with CTR: |
* |
* 1. You can handle everything as a single message processed over |
* successive calls to this function. In that case, you want to |
* set \p nonce_counter and \p nc_off to 0 for the first call, and |
* then preserve the values of \p nonce_counter, \p nc_off and \p |
* stream_block across calls to this function as they will be |
* updated by this function. |
* |
* With this strategy, you must not encrypt more than 2**128 |
* blocks of data with the same key. |
* |
* 2. You can encrypt separate messages by dividing the \p |
* nonce_counter buffer in two areas: the first one used for a |
* per-message nonce, handled by yourself, and the second one |
* updated by this function internally. |
* |
* For example, you might reserve the first 12 bytes for the |
* per-message nonce, and the last 4 bytes for internal use. In that |
* case, before calling this function on a new message you need to |
* set the first 12 bytes of \p nonce_counter to your chosen nonce |
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p |
* stream_block to be ignored). That way, you can encrypt at most |
* 2**96 messages of up to 2**32 blocks each with the same key. |
* |
* The per-message nonce (or information sufficient to reconstruct |
* it) needs to be communicated with the ciphertext and must be unique. |
* The recommended way to ensure uniqueness is to use a message |
* counter. An alternative is to generate random nonces, but this |
* limits the number of messages that can be securely encrypted: |
* for example, with 96-bit random nonces, you should not encrypt |
* more than 2**32 messages with the same key. |
* |
* Note that for both stategies, sizes are measured in blocks and |
* that an AES block is 16 bytes. |
* |
* \warning Upon return, \p stream_block contains sensitive data. Its |
* content must not be written to insecure storage and should be |
* securely discarded as soon as it's no longer needed. |
* |
* \param ctx The AES context to use for encryption or decryption. |
* It must be initialized and bound to a key. |
* \param length The length of the input data. |
* \param nc_off The offset in the current \p stream_block, for |
* resuming within the current cipher stream. The |
* offset pointer should be 0 at the start of a stream. |
* It must point to a valid \c size_t. |
* \param nonce_counter The 128-bit nonce and counter. |
* It must be a readable-writeable buffer of \c 16 Bytes. |
* \param stream_block The saved stream block for resuming. This is |
* overwritten by the function. |
* It must be a readable-writeable buffer of \c 16 Bytes. |
* \param input The buffer holding the input data. |
* It must be readable and of size \p length Bytes. |
* \param output The buffer holding the output data. |
* It must be writeable and of size \p length Bytes. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[16], |
unsigned char stream_block[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
/** |
* \brief Internal AES block encryption function. This is only |
* exposed to allow overriding it using |
* \c MBEDTLS_AES_ENCRYPT_ALT. |
* |
* \param ctx The AES context to use for encryption. |
* \param input The plaintext block. |
* \param output The output (ciphertext) block. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ); |
/** |
* \brief Internal AES block decryption function. This is only |
* exposed to allow overriding it using see |
* \c MBEDTLS_AES_DECRYPT_ALT. |
* |
* \param ctx The AES context to use for decryption. |
* \param input The ciphertext block. |
* \param output The output (plaintext) block. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Deprecated internal AES block encryption function |
* without return value. |
* |
* \deprecated Superseded by mbedtls_internal_aes_encrypt() |
* |
* \param ctx The AES context to use for encryption. |
* \param input Plaintext block. |
* \param output Output (ciphertext) block. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ); |
/** |
* \brief Deprecated internal AES block decryption function |
* without return value. |
* |
* \deprecated Superseded by mbedtls_internal_aes_decrypt() |
* |
* \param ctx The AES context to use for decryption. |
* \param input Ciphertext block. |
* \param output Output (plaintext) block. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_aes_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* aes.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/aesni.h |
---|
0,0 → 1,140 |
/** |
* \file aesni.h |
* |
* \brief AES-NI for hardware AES acceleration on some Intel processors |
* |
* \warning These functions are only for internal use by other library |
* functions; you must not call them directly. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_AESNI_H |
#define MBEDTLS_AESNI_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "aes.h" |
#define MBEDTLS_AESNI_AES 0x02000000u |
#define MBEDTLS_AESNI_CLMUL 0x00000002u |
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \ |
( defined(__amd64__) || defined(__x86_64__) ) && \ |
! defined(MBEDTLS_HAVE_X86_64) |
#define MBEDTLS_HAVE_X86_64 |
#endif |
#if defined(MBEDTLS_HAVE_X86_64) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Internal function to detect the AES-NI feature in CPUs. |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param what The feature to detect |
* (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) |
* |
* \return 1 if CPU has support for the feature, 0 otherwise |
*/ |
int mbedtls_aesni_has_support( unsigned int what ); |
/** |
* \brief Internal AES-NI AES-ECB block encryption and decryption |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param ctx AES context |
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT |
* \param input 16-byte input block |
* \param output 16-byte output block |
* |
* \return 0 on success (cannot fail) |
*/ |
int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ); |
/** |
* \brief Internal GCM multiplication: c = a * b in GF(2^128) |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param c Result |
* \param a First operand |
* \param b Second operand |
* |
* \note Both operands and result are bit strings interpreted as |
* elements of GF(2^128) as per the GCM spec. |
*/ |
void mbedtls_aesni_gcm_mult( unsigned char c[16], |
const unsigned char a[16], |
const unsigned char b[16] ); |
/** |
* \brief Internal round key inversion. This function computes |
* decryption round keys from the encryption round keys. |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param invkey Round keys for the equivalent inverse cipher |
* \param fwdkey Original round keys (for encryption) |
* \param nr Number of rounds (that is, number of round keys minus one) |
*/ |
void mbedtls_aesni_inverse_key( unsigned char *invkey, |
const unsigned char *fwdkey, |
int nr ); |
/** |
* \brief Internal key expansion for encryption |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param rk Destination buffer where the round keys are written |
* \param key Encryption key |
* \param bits Key size in bits (must be 128, 192 or 256) |
* |
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH |
*/ |
int mbedtls_aesni_setkey_enc( unsigned char *rk, |
const unsigned char *key, |
size_t bits ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_HAVE_X86_64 */ |
#endif /* MBEDTLS_AESNI_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/arc4.h |
---|
0,0 → 1,148 |
/** |
* \file arc4.h |
* |
* \brief The ARCFOUR stream cipher |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers instead. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
* |
*/ |
#ifndef MBEDTLS_ARC4_H |
#define MBEDTLS_ARC4_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_ARC4_ALT) |
// Regular implementation |
// |
/** |
* \brief ARC4 context structure |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers instead. |
* |
*/ |
typedef struct mbedtls_arc4_context |
{ |
int x; /*!< permutation index */ |
int y; /*!< permutation index */ |
unsigned char m[256]; /*!< permutation table */ |
} |
mbedtls_arc4_context; |
#else /* MBEDTLS_ARC4_ALT */ |
#include "arc4_alt.h" |
#endif /* MBEDTLS_ARC4_ALT */ |
/** |
* \brief Initialize ARC4 context |
* |
* \param ctx ARC4 context to be initialized |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
* |
*/ |
void mbedtls_arc4_init( mbedtls_arc4_context *ctx ); |
/** |
* \brief Clear ARC4 context |
* |
* \param ctx ARC4 context to be cleared |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
* |
*/ |
void mbedtls_arc4_free( mbedtls_arc4_context *ctx ); |
/** |
* \brief ARC4 key schedule |
* |
* \param ctx ARC4 context to be setup |
* \param key the secret key |
* \param keylen length of the key, in bytes |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
* |
*/ |
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, |
unsigned 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 |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
* |
*/ |
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, |
unsigned char *output ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
* |
*/ |
int mbedtls_arc4_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* arc4.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/aria.h |
---|
0,0 → 1,372 |
/** |
* \file aria.h |
* |
* \brief ARIA block cipher |
* |
* The ARIA algorithm is a symmetric block cipher that can encrypt and |
* decrypt information. It is defined by the Korean Agency for |
* Technology and Standards (KATS) in <em>KS X 1213:2004</em> (in |
* Korean, but see http://210.104.33.10/ARIA/index-e.html in English) |
* and also described by the IETF in <em>RFC 5794</em>. |
*/ |
/* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ARIA_H |
#define MBEDTLS_ARIA_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
#include "platform_util.h" |
#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */ |
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */ |
#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */ |
#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maxiumum number of rounds in ARIA. */ |
#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */ |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C ) |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */ |
#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */ |
/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, an unsupported ARIA key size. */ |
/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED -0x0058 /**< ARIA hardware accelerator failed. */ |
#if !defined(MBEDTLS_ARIA_ALT) |
// Regular implementation |
// |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief The ARIA context-type definition. |
*/ |
typedef struct mbedtls_aria_context |
{ |
unsigned char nr; /*!< The number of rounds (12, 14 or 16) */ |
/*! The ARIA round keys. */ |
uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4]; |
} |
mbedtls_aria_context; |
#else /* MBEDTLS_ARIA_ALT */ |
#include "aria_alt.h" |
#endif /* MBEDTLS_ARIA_ALT */ |
/** |
* \brief This function initializes the specified ARIA context. |
* |
* It must be the first API called before using |
* the context. |
* |
* \param ctx The ARIA context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_aria_init( mbedtls_aria_context *ctx ); |
/** |
* \brief This function releases and clears the specified ARIA context. |
* |
* \param ctx The ARIA context to clear. This may be \c NULL, in which |
* case this function returns immediately. If it is not \c NULL, |
* it must point to an initialized ARIA context. |
*/ |
void mbedtls_aria_free( mbedtls_aria_context *ctx ); |
/** |
* \brief This function sets the encryption key. |
* |
* \param ctx The ARIA context to which the key should be bound. |
* This must be initialized. |
* \param key The encryption key. This must be a readable buffer |
* of size \p keybits Bits. |
* \param keybits The size of \p key in Bits. Valid options are: |
* <ul><li>128 bits</li> |
* <li>192 bits</li> |
* <li>256 bits</li></ul> |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief This function sets the decryption key. |
* |
* \param ctx The ARIA context to which the key should be bound. |
* This must be initialized. |
* \param key The decryption key. This must be a readable buffer |
* of size \p keybits Bits. |
* \param keybits The size of data passed. Valid options are: |
* <ul><li>128 bits</li> |
* <li>192 bits</li> |
* <li>256 bits</li></ul> |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief This function performs an ARIA single-block encryption or |
* decryption operation. |
* |
* It performs encryption or decryption (depending on whether |
* the key was set for encryption on decryption) on the input |
* data buffer defined in the \p input parameter. |
* |
* mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or |
* mbedtls_aria_setkey_dec() must be called before the first |
* call to this API with the same context. |
* |
* \param ctx The ARIA context to use for encryption or decryption. |
* This must be initialized and bound to a key. |
* \param input The 16-Byte buffer holding the input data. |
* \param output The 16-Byte buffer holding the output data. |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, |
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], |
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief This function performs an ARIA-CBC encryption or decryption operation |
* on full blocks. |
* |
* It performs the operation defined in the \p mode |
* parameter (encrypt/decrypt), on the input data buffer defined in |
* the \p input parameter. |
* |
* It can be called as many times as needed, until all the input |
* data is processed. mbedtls_aria_init(), and either |
* mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called |
* before the first call to this API with the same context. |
* |
* \note This function operates on aligned blocks, that is, the input size |
* must be a multiple of the ARIA block size of 16 Bytes. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the same function again on the next |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If you need to retain the contents of the IV, you should |
* either save it manually or use the cipher module instead. |
* |
* |
* \param ctx The ARIA context to use for encryption or decryption. |
* This must be initialized and bound to a key. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_ARIA_ENCRYPT for encryption, or |
* #MBEDTLS_ARIA_DECRYPT for decryption. |
* \param length The length of the input data in Bytes. This must be a |
* multiple of the block size (16 Bytes). |
* \param iv Initialization vector (updated after use). |
* This must be a readable buffer of size 16 Bytes. |
* \param input The buffer holding the input data. This must |
* be a readable buffer of length \p length Bytes. |
* \param output The buffer holding the output data. This must |
* be a writable buffer of length \p length Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/** |
* \brief This function performs an ARIA-CFB128 encryption or decryption |
* operation. |
* |
* It performs the operation defined in the \p mode |
* parameter (encrypt or decrypt), on the input data buffer |
* defined in the \p input parameter. |
* |
* For CFB, you must set up the context with mbedtls_aria_setkey_enc(), |
* regardless of whether you are performing an encryption or decryption |
* operation, that is, regardless of the \p mode parameter. This is |
* because CFB mode uses the same key schedule for encryption and |
* decryption. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the same function again on the next |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If you need to retain the contents of the |
* IV, you must either save it manually or use the cipher |
* module instead. |
* |
* |
* \param ctx The ARIA context to use for encryption or decryption. |
* This must be initialized and bound to a key. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_ARIA_ENCRYPT for encryption, or |
* #MBEDTLS_ARIA_DECRYPT for decryption. |
* \param length The length of the input data \p input in Bytes. |
* \param iv_off The offset in IV (updated after use). |
* This must not be larger than 15. |
* \param iv The initialization vector (updated after use). |
* This must be a readable buffer of size 16 Bytes. |
* \param input The buffer holding the input data. This must |
* be a readable buffer of length \p length Bytes. |
* \param output The buffer holding the output data. This must |
* be a writable buffer of length \p length Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/** |
* \brief This function performs an ARIA-CTR encryption or decryption |
* operation. |
* |
* This function performs the operation defined in the \p mode |
* parameter (encrypt/decrypt), on the input data buffer |
* defined in the \p input parameter. |
* |
* Due to the nature of CTR, you must use the same key schedule |
* for both encryption and decryption operations. Therefore, you |
* must use the context initialized with mbedtls_aria_setkey_enc() |
* for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT. |
* |
* \warning You must never reuse a nonce value with the same key. Doing so |
* would void the encryption for the two messages encrypted with |
* the same nonce and key. |
* |
* There are two common strategies for managing nonces with CTR: |
* |
* 1. You can handle everything as a single message processed over |
* successive calls to this function. In that case, you want to |
* set \p nonce_counter and \p nc_off to 0 for the first call, and |
* then preserve the values of \p nonce_counter, \p nc_off and \p |
* stream_block across calls to this function as they will be |
* updated by this function. |
* |
* With this strategy, you must not encrypt more than 2**128 |
* blocks of data with the same key. |
* |
* 2. You can encrypt separate messages by dividing the \p |
* nonce_counter buffer in two areas: the first one used for a |
* per-message nonce, handled by yourself, and the second one |
* updated by this function internally. |
* |
* For example, you might reserve the first 12 bytes for the |
* per-message nonce, and the last 4 bytes for internal use. In that |
* case, before calling this function on a new message you need to |
* set the first 12 bytes of \p nonce_counter to your chosen nonce |
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p |
* stream_block to be ignored). That way, you can encrypt at most |
* 2**96 messages of up to 2**32 blocks each with the same key. |
* |
* The per-message nonce (or information sufficient to reconstruct |
* it) needs to be communicated with the ciphertext and must be unique. |
* The recommended way to ensure uniqueness is to use a message |
* counter. An alternative is to generate random nonces, but this |
* limits the number of messages that can be securely encrypted: |
* for example, with 96-bit random nonces, you should not encrypt |
* more than 2**32 messages with the same key. |
* |
* Note that for both stategies, sizes are measured in blocks and |
* that an ARIA block is 16 bytes. |
* |
* \warning Upon return, \p stream_block contains sensitive data. Its |
* content must not be written to insecure storage and should be |
* securely discarded as soon as it's no longer needed. |
* |
* \param ctx The ARIA context to use for encryption or decryption. |
* This must be initialized and bound to a key. |
* \param length The length of the input data \p input in Bytes. |
* \param nc_off The offset in Bytes in the current \p stream_block, |
* for resuming within the current cipher stream. The |
* offset pointer should be \c 0 at the start of a |
* stream. This must not be larger than \c 15 Bytes. |
* \param nonce_counter The 128-bit nonce and counter. This must point to |
* a read/write buffer of length \c 16 bytes. |
* \param stream_block The saved stream block for resuming. This must |
* point to a read/write buffer of length \c 16 bytes. |
* This is overwritten by the function. |
* \param input The buffer holding the input data. This must |
* be a readable buffer of length \p length Bytes. |
* \param output The buffer holding the output data. This must |
* be a writable buffer of length \p length Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], |
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine. |
* |
* \return \c 0 on success, or \c 1 on failure. |
*/ |
int mbedtls_aria_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* aria.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/asn1.h |
---|
0,0 → 1,360 |
/** |
* \file asn1.h |
* |
* \brief Generic ASN.1 parsing |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ASN1_H |
#define MBEDTLS_ASN1_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#if defined(MBEDTLS_BIGNUM_C) |
#include "bignum.h" |
#endif |
/** |
* \addtogroup asn1_module |
* \{ |
*/ |
/** |
* \name ASN1 Error codes |
* These error codes are OR'ed to X509 error codes for |
* higher error granularity. |
* ASN1 is a standard to specify data structures. |
* \{ |
*/ |
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */ |
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */ |
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */ |
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */ |
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */ |
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */ |
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */ |
/* \} name */ |
/** |
* \name DER constants |
* These constants comply with the DER encoded ASN.1 type tags. |
* DER encoding uses hexadecimal representation. |
* An example DER sequence is:\n |
* - 0x02 -- tag indicating INTEGER |
* - 0x01 -- length in octets |
* - 0x05 -- value |
* Such sequences are typically read into \c ::mbedtls_x509_buf. |
* \{ |
*/ |
#define MBEDTLS_ASN1_BOOLEAN 0x01 |
#define MBEDTLS_ASN1_INTEGER 0x02 |
#define MBEDTLS_ASN1_BIT_STRING 0x03 |
#define MBEDTLS_ASN1_OCTET_STRING 0x04 |
#define MBEDTLS_ASN1_NULL 0x05 |
#define MBEDTLS_ASN1_OID 0x06 |
#define MBEDTLS_ASN1_UTF8_STRING 0x0C |
#define MBEDTLS_ASN1_SEQUENCE 0x10 |
#define MBEDTLS_ASN1_SET 0x11 |
#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13 |
#define MBEDTLS_ASN1_T61_STRING 0x14 |
#define MBEDTLS_ASN1_IA5_STRING 0x16 |
#define MBEDTLS_ASN1_UTC_TIME 0x17 |
#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18 |
#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C |
#define MBEDTLS_ASN1_BMP_STRING 0x1E |
#define MBEDTLS_ASN1_PRIMITIVE 0x00 |
#define MBEDTLS_ASN1_CONSTRUCTED 0x20 |
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 |
/* |
* Bit masks for each of the components of an ASN.1 tag as specified in |
* ITU X.690 (08/2015), section 8.1 "General rules for encoding", |
* paragraph 8.1.2.2: |
* |
* Bit 8 7 6 5 1 |
* +-------+-----+------------+ |
* | Class | P/C | Tag number | |
* +-------+-----+------------+ |
*/ |
#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0 |
#define MBEDTLS_ASN1_TAG_PC_MASK 0x20 |
#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F |
/* \} name */ |
/* \} addtogroup asn1_module */ |
/** Returns the size of the binary string, without the trailing \\0 */ |
#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1) |
/** |
* Compares an mbedtls_asn1_buf structure to a reference OID. |
* |
* Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a |
* 'unsigned char *oid' here! |
*/ |
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \ |
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \ |
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 ) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \name Functions to parse ASN.1 data structures |
* \{ |
*/ |
/** |
* Type-length-value structure that allows for ASN1 using DER. |
*/ |
typedef struct mbedtls_asn1_buf |
{ |
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */ |
size_t len; /**< ASN1 length, in octets. */ |
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */ |
} |
mbedtls_asn1_buf; |
/** |
* Container for ASN1 bit strings. |
*/ |
typedef struct mbedtls_asn1_bitstring |
{ |
size_t len; /**< ASN1 length, in octets. */ |
unsigned char unused_bits; /**< Number of unused bits at the end of the string */ |
unsigned char *p; /**< Raw ASN1 data for the bit string */ |
} |
mbedtls_asn1_bitstring; |
/** |
* Container for a sequence of ASN.1 items |
*/ |
typedef struct mbedtls_asn1_sequence |
{ |
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */ |
struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */ |
} |
mbedtls_asn1_sequence; |
/** |
* Container for a sequence or list of 'named' ASN.1 data items |
*/ |
typedef struct mbedtls_asn1_named_data |
{ |
mbedtls_asn1_buf oid; /**< The object identifier. */ |
mbedtls_asn1_buf val; /**< The named value. */ |
struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */ |
unsigned char next_merged; /**< Merge next item into the current one? */ |
} |
mbedtls_asn1_named_data; |
/** |
* \brief Get the length of an ASN.1 element. |
* Updates the pointer to immediately behind the length. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param len The variable that will receive the value |
* |
* \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching |
* end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is |
* unparseable. |
*/ |
int mbedtls_asn1_get_len( unsigned char **p, |
const unsigned char *end, |
size_t *len ); |
/** |
* \brief Get the tag and length of the tag. Check for the requested tag. |
* Updates the pointer to immediately behind the tag and length. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param len The variable that will receive the length |
* \param tag The expected tag |
* |
* \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did |
* not match requested tag, or another specific ASN.1 error code. |
*/ |
int mbedtls_asn1_get_tag( unsigned char **p, |
const unsigned char *end, |
size_t *len, int tag ); |
/** |
* \brief Retrieve a boolean ASN.1 tag and its value. |
* Updates the pointer to immediately behind the full tag. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param val The variable that will receive the value |
* |
* \return 0 if successful or a specific ASN.1 error code. |
*/ |
int mbedtls_asn1_get_bool( unsigned char **p, |
const unsigned char *end, |
int *val ); |
/** |
* \brief Retrieve an integer ASN.1 tag and its value. |
* Updates the pointer to immediately behind the full tag. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param val The variable that will receive the value |
* |
* \return 0 if successful or a specific ASN.1 error code. |
*/ |
int mbedtls_asn1_get_int( unsigned char **p, |
const unsigned char *end, |
int *val ); |
/** |
* \brief Retrieve a bitstring ASN.1 tag and its value. |
* Updates the pointer to immediately behind the full tag. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param bs The variable that will receive the value |
* |
* \return 0 if successful or a specific ASN.1 error code. |
*/ |
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, |
mbedtls_asn1_bitstring *bs); |
/** |
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its |
* value. |
* Updates the pointer to the beginning of the bit/octet string. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param len Length of the actual bit/octect string in bytes |
* |
* \return 0 if successful or a specific ASN.1 error code. |
*/ |
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, |
size_t *len ); |
/** |
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>" |
* Updated the pointer to immediately behind the full sequence tag. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param cur First variable in the chain to fill |
* \param tag Type of sequence |
* |
* \return 0 if successful or a specific ASN.1 error code. |
*/ |
int mbedtls_asn1_get_sequence_of( unsigned char **p, |
const unsigned char *end, |
mbedtls_asn1_sequence *cur, |
int tag); |
#if defined(MBEDTLS_BIGNUM_C) |
/** |
* \brief Retrieve a MPI value from an integer ASN.1 tag. |
* Updates the pointer to immediately behind the full tag. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param X The MPI that will receive the value |
* |
* \return 0 if successful or a specific ASN.1 or MPI error code. |
*/ |
int mbedtls_asn1_get_mpi( unsigned char **p, |
const unsigned char *end, |
mbedtls_mpi *X ); |
#endif /* MBEDTLS_BIGNUM_C */ |
/** |
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. |
* Updates the pointer to immediately behind the full |
* AlgorithmIdentifier. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param alg The buffer to receive the OID |
* \param params The buffer to receive the params (if any) |
* |
* \return 0 if successful or a specific ASN.1 or MPI error code. |
*/ |
int mbedtls_asn1_get_alg( unsigned char **p, |
const unsigned char *end, |
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ); |
/** |
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no |
* params. |
* Updates the pointer to immediately behind the full |
* AlgorithmIdentifier. |
* |
* \param p The position in the ASN.1 data |
* \param end End of data |
* \param alg The buffer to receive the OID |
* |
* \return 0 if successful or a specific ASN.1 or MPI error code. |
*/ |
int mbedtls_asn1_get_alg_null( unsigned char **p, |
const unsigned char *end, |
mbedtls_asn1_buf *alg ); |
/** |
* \brief Find a specific named_data entry in a sequence or list based on |
* the OID. |
* |
* \param list The list to seek through |
* \param oid The OID to look for |
* \param len Size of the OID |
* |
* \return NULL if not found, or a pointer to the existing entry. |
*/ |
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, |
const char *oid, size_t len ); |
/** |
* \brief Free a mbedtls_asn1_named_data entry |
* |
* \param entry The named data entry to free |
*/ |
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry ); |
/** |
* \brief Free all entries in a mbedtls_asn1_named_data list |
* Head will be set to NULL |
* |
* \param head Pointer to the head of the list of named data entries to free |
*/ |
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* asn1.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/asn1write.h |
---|
0,0 → 1,331 |
/** |
* \file asn1write.h |
* |
* \brief ASN.1 buffer writing functionality |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ASN1_WRITE_H |
#define MBEDTLS_ASN1_WRITE_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "asn1.h" |
#define MBEDTLS_ASN1_CHK_ADD(g, f) \ |
do \ |
{ \ |
if( ( ret = (f) ) < 0 ) \ |
return( ret ); \ |
else \ |
(g) += ret; \ |
} while( 0 ) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Write a length field in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param len The length value to write. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, |
size_t len ); |
/** |
* \brief Write an ASN.1 tag in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param tag The tag to write. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, |
unsigned char tag ); |
/** |
* \brief Write raw buffer data. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param buf The data buffer to write. |
* \param size The length of the data buffer. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, |
const unsigned char *buf, size_t size ); |
#if defined(MBEDTLS_BIGNUM_C) |
/** |
* \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) |
* in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param X The MPI to write. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, |
const mbedtls_mpi *X ); |
#endif /* MBEDTLS_BIGNUM_C */ |
/** |
* \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data |
* in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ); |
/** |
* \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data |
* in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param oid The OID to write. |
* \param oid_len The length of the OID. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, |
const char *oid, size_t oid_len ); |
/** |
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param oid The OID of the algorithm to write. |
* \param oid_len The length of the algorithm's OID. |
* \param par_len The length of the parameters, which must be already written. |
* If 0, NULL parameters are added |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, |
unsigned char *start, |
const char *oid, size_t oid_len, |
size_t par_len ); |
/** |
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value |
* in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param boolean The boolean value to write, either \c 0 or \c 1. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, |
int boolean ); |
/** |
* \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value |
* in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param val The integer value to write. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ); |
/** |
* \brief Write a string in ASN.1 format using a specific |
* string encoding tag. |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param tag The string encoding tag to write, e.g. |
* #MBEDTLS_ASN1_UTF8_STRING. |
* \param text The string to write. |
* \param text_len The length of \p text in bytes (which might |
* be strictly larger than the number of characters). |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, |
int tag, const char *text, |
size_t text_len ); |
/** |
* \brief Write a string in ASN.1 format using the PrintableString |
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param text The string to write. |
* \param text_len The length of \p text in bytes (which might |
* be strictly larger than the number of characters). |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_asn1_write_printable_string( unsigned char **p, |
unsigned char *start, |
const char *text, size_t text_len ); |
/** |
* \brief Write a UTF8 string in ASN.1 format using the UTF8String |
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param text The string to write. |
* \param text_len The length of \p text in bytes (which might |
* be strictly larger than the number of characters). |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, |
const char *text, size_t text_len ); |
/** |
* \brief Write a string in ASN.1 format using the IA5String |
* string encoding tag (#MBEDTLS_ASN1_IA5_STRING). |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param text The string to write. |
* \param text_len The length of \p text in bytes (which might |
* be strictly larger than the number of characters). |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, |
const char *text, size_t text_len ); |
/** |
* \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and |
* value in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param buf The bitstring to write. |
* \param bits The total number of bits in the bitstring. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, |
const unsigned char *buf, size_t bits ); |
/** |
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING) |
* and value in ASN.1 format. |
* |
* \note This function works backwards in data buffer. |
* |
* \param p The reference to the current position pointer. |
* \param start The start of the buffer, for bounds-checking. |
* \param buf The buffer holding the data to write. |
* \param size The length of the data buffer \p buf. |
* |
* \return The number of bytes written to \p p on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, |
const unsigned char *buf, size_t size ); |
/** |
* \brief Create or find a specific named_data entry for writing in a |
* sequence or list based on the OID. If not already in there, |
* a new entry is added to the head of the list. |
* Warning: Destructive behaviour for the val data! |
* |
* \param list The pointer to the location of the head of the list to seek |
* through (will be updated in case of a new entry). |
* \param oid The OID to look for. |
* \param oid_len The size of the OID. |
* \param val The data to store (can be \c NULL if you want to fill |
* it by hand). |
* \param val_len The minimum length of the data buffer needed. |
* |
* \return A pointer to the new / existing entry on success. |
* \return \c NULL if if there was a memory allocation error. |
*/ |
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list, |
const char *oid, size_t oid_len, |
const unsigned char *val, |
size_t val_len ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_ASN1_WRITE_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/base64.h |
---|
0,0 → 1,100 |
/** |
* \file base64.h |
* |
* \brief RFC 1521 base64 encoding/decoding |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_BASE64_H |
#define MBEDTLS_BASE64_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ |
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Encode a buffer into base64 format |
* |
* \param dst destination buffer |
* \param dlen size of the destination buffer |
* \param olen number of bytes written |
* \param src source buffer |
* \param slen amount of data to be encoded |
* |
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. |
* *olen is always updated to reflect the amount |
* of data that has (or would have) been written. |
* If that length cannot be represented, then no data is |
* written to the buffer and *olen is set to the maximum |
* length representable as a size_t. |
* |
* \note Call this function with dlen = 0 to obtain the |
* required buffer size in *olen |
*/ |
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, |
const unsigned char *src, size_t slen ); |
/** |
* \brief Decode a base64-formatted buffer |
* |
* \param dst destination buffer (can be NULL for checking size) |
* \param dlen size of the destination buffer |
* \param olen number of bytes written |
* \param src source buffer |
* \param slen amount of data to be decoded |
* |
* \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or |
* MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is |
* not correct. *olen is always updated to reflect the amount |
* of data that has (or would have) been written. |
* |
* \note Call this function with *dst = NULL or dlen = 0 to obtain |
* the required buffer size in *olen |
*/ |
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, |
const unsigned char *src, size_t slen ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_base64_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* base64.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/bignum.h |
---|
0,0 → 1,986 |
/** |
* \file bignum.h |
* |
* \brief Multi-precision integer library |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_BIGNUM_H |
#define MBEDTLS_BIGNUM_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
#if defined(MBEDTLS_FS_IO) |
#include <stdio.h> |
#endif |
#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ |
#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ |
#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */ |
#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ |
#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ |
#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ |
#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */ |
#define MBEDTLS_MPI_CHK(f) \ |
do \ |
{ \ |
if( ( ret = (f) ) != 0 ) \ |
goto cleanup; \ |
} while( 0 ) |
/* |
* Maximum size MPIs are allowed to grow to in number of limbs. |
*/ |
#define MBEDTLS_MPI_MAX_LIMBS 10000 |
#if !defined(MBEDTLS_MPI_WINDOW_SIZE) |
/* |
* Maximum window size used for modular exponentiation. Default: 6 |
* Minimum value: 1. Maximum value: 6. |
* |
* Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used |
* for the sliding window calculation. (So 64 by default) |
* |
* Reduction in size, reduces speed. |
*/ |
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ |
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */ |
#if !defined(MBEDTLS_MPI_MAX_SIZE) |
/* |
* Maximum size of MPIs allowed in bits and bytes for user-MPIs. |
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) |
* |
* Note: Calculations can temporarily result in larger MPIs. So the number |
* of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. |
*/ |
#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ |
#endif /* !MBEDTLS_MPI_MAX_SIZE */ |
#define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ |
/* |
* When reading from files with mbedtls_mpi_read_file() and writing to files with |
* mbedtls_mpi_write_file() the buffer should have space |
* for a (short) label, the MPI (in the provided radix), the newline |
* characters and the '\0'. |
* |
* By default we assume at least a 10 char label, a minimum radix of 10 |
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). |
* Autosized at compile time for at least a 10 char label, a minimum radix |
* of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size. |
* |
* This used to be statically sized to 1250 for a maximum of 4096 bit |
* numbers (1234 decimal chars). |
* |
* Calculate using the formula: |
* MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) + |
* LabelSize + 6 |
*/ |
#define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS ) |
#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332 |
#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) |
/* |
* Define the base integer type, architecture-wise. |
* |
* 32 or 64-bit integer types can be forced regardless of the underlying |
* architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 |
* respectively and undefining MBEDTLS_HAVE_ASM. |
* |
* Double-width integers (e.g. 128-bit in 64-bit architectures) can be |
* disabled by defining MBEDTLS_NO_UDBL_DIVISION. |
*/ |
#if !defined(MBEDTLS_HAVE_INT32) |
#if defined(_MSC_VER) && defined(_M_AMD64) |
/* Always choose 64-bit when using MSC */ |
#if !defined(MBEDTLS_HAVE_INT64) |
#define MBEDTLS_HAVE_INT64 |
#endif /* !MBEDTLS_HAVE_INT64 */ |
typedef int64_t mbedtls_mpi_sint; |
typedef uint64_t mbedtls_mpi_uint; |
#elif defined(__GNUC__) && ( \ |
defined(__amd64__) || defined(__x86_64__) || \ |
defined(__ppc64__) || defined(__powerpc64__) || \ |
defined(__ia64__) || defined(__alpha__) || \ |
( defined(__sparc__) && defined(__arch64__) ) || \ |
defined(__s390x__) || defined(__mips64) ) |
#if !defined(MBEDTLS_HAVE_INT64) |
#define MBEDTLS_HAVE_INT64 |
#endif /* MBEDTLS_HAVE_INT64 */ |
typedef int64_t mbedtls_mpi_sint; |
typedef uint64_t mbedtls_mpi_uint; |
#if !defined(MBEDTLS_NO_UDBL_DIVISION) |
/* mbedtls_t_udbl defined as 128-bit unsigned int */ |
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); |
#define MBEDTLS_HAVE_UDBL |
#endif /* !MBEDTLS_NO_UDBL_DIVISION */ |
#elif defined(__ARMCC_VERSION) && defined(__aarch64__) |
/* |
* __ARMCC_VERSION is defined for both armcc and armclang and |
* __aarch64__ is only defined by armclang when compiling 64-bit code |
*/ |
#if !defined(MBEDTLS_HAVE_INT64) |
#define MBEDTLS_HAVE_INT64 |
#endif /* !MBEDTLS_HAVE_INT64 */ |
typedef int64_t mbedtls_mpi_sint; |
typedef uint64_t mbedtls_mpi_uint; |
#if !defined(MBEDTLS_NO_UDBL_DIVISION) |
/* mbedtls_t_udbl defined as 128-bit unsigned int */ |
typedef __uint128_t mbedtls_t_udbl; |
#define MBEDTLS_HAVE_UDBL |
#endif /* !MBEDTLS_NO_UDBL_DIVISION */ |
#elif defined(MBEDTLS_HAVE_INT64) |
/* Force 64-bit integers with unknown compiler */ |
typedef int64_t mbedtls_mpi_sint; |
typedef uint64_t mbedtls_mpi_uint; |
#endif |
#endif /* !MBEDTLS_HAVE_INT32 */ |
#if !defined(MBEDTLS_HAVE_INT64) |
/* Default to 32-bit compilation */ |
#if !defined(MBEDTLS_HAVE_INT32) |
#define MBEDTLS_HAVE_INT32 |
#endif /* !MBEDTLS_HAVE_INT32 */ |
typedef int32_t mbedtls_mpi_sint; |
typedef uint32_t mbedtls_mpi_uint; |
#if !defined(MBEDTLS_NO_UDBL_DIVISION) |
typedef uint64_t mbedtls_t_udbl; |
#define MBEDTLS_HAVE_UDBL |
#endif /* !MBEDTLS_NO_UDBL_DIVISION */ |
#endif /* !MBEDTLS_HAVE_INT64 */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief MPI structure |
*/ |
typedef struct mbedtls_mpi |
{ |
int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */ |
size_t n; /*!< total # of limbs */ |
mbedtls_mpi_uint *p; /*!< pointer to limbs */ |
} |
mbedtls_mpi; |
/** |
* \brief Initialize an MPI context. |
* |
* This makes the MPI ready to be set or freed, |
* but does not define a value for the MPI. |
* |
* \param X The MPI context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_mpi_init( mbedtls_mpi *X ); |
/** |
* \brief This function frees the components of an MPI context. |
* |
* \param X The MPI context to be cleared. This may be \c NULL, |
* in which case this function is a no-op. If it is |
* not \c NULL, it must point to an initialized MPI. |
*/ |
void mbedtls_mpi_free( mbedtls_mpi *X ); |
/** |
* \brief Enlarge an MPI to the specified number of limbs. |
* |
* \note This function does nothing if the MPI is |
* already large enough. |
* |
* \param X The MPI to grow. It must be initialized. |
* \param nblimbs The target number of limbs. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ); |
/** |
* \brief This function resizes an MPI downwards, keeping at least the |
* specified number of limbs. |
* |
* If \c X is smaller than \c nblimbs, it is resized up |
* instead. |
* |
* \param X The MPI to shrink. This must point to an initialized MPI. |
* \param nblimbs The minimum number of limbs to keep. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed |
* (this can only happen when resizing up). |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ); |
/** |
* \brief Make a copy of an MPI. |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param Y The source MPI. This must point to an initialized MPI. |
* |
* \note The limb-buffer in the destination MPI is enlarged |
* if necessary to hold the value in the source MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ); |
/** |
* \brief Swap the contents of two MPIs. |
* |
* \param X The first MPI. It must be initialized. |
* \param Y The second MPI. It must be initialized. |
*/ |
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); |
/** |
* \brief Perform a safe conditional copy of MPI which doesn't |
* reveal whether the condition was true or not. |
* |
* \param X The MPI to conditionally assign to. This must point |
* to an initialized MPI. |
* \param Y The MPI to be assigned from. This must point to an |
* initialized MPI. |
* \param assign The condition deciding whether to perform the |
* assignment or not. Possible values: |
* * \c 1: Perform the assignment `X = Y`. |
* * \c 0: Keep the original value of \p X. |
* |
* \note This function is equivalent to |
* `if( assign ) mbedtls_mpi_copy( X, Y );` |
* except that it avoids leaking any information about whether |
* the assignment was done or not (the above code may leak |
* information through branch prediction and/or memory access |
* patterns analysis). |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ); |
/** |
* \brief Perform a safe conditional swap which doesn't |
* reveal whether the condition was true or not. |
* |
* \param X The first MPI. This must be initialized. |
* \param Y The second MPI. This must be initialized. |
* \param assign The condition deciding whether to perform |
* the swap or not. Possible values: |
* * \c 1: Swap the values of \p X and \p Y. |
* * \c 0: Keep the original values of \p X and \p Y. |
* |
* \note This function is equivalent to |
* if( assign ) mbedtls_mpi_swap( X, Y ); |
* except that it avoids leaking any information about whether |
* the assignment was done or not (the above code may leak |
* information through branch prediction and/or memory access |
* patterns analysis). |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on other kinds of failure. |
* |
*/ |
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); |
/** |
* \brief Store integer value in MPI. |
* |
* \param X The MPI to set. This must be initialized. |
* \param z The value to use. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ); |
/** |
* \brief Get a specific bit from an MPI. |
* |
* \param X The MPI to query. This must be initialized. |
* \param pos Zero-based index of the bit to query. |
* |
* \return \c 0 or \c 1 on success, depending on whether bit \c pos |
* of \c X is unset or set. |
* \return A negative error code on failure. |
*/ |
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ); |
/** |
* \brief Modify a specific bit in an MPI. |
* |
* \note This function will grow the target MPI if necessary to set a |
* bit to \c 1 in a not yet existing limb. It will not grow if |
* the bit should be set to \c 0. |
* |
* \param X The MPI to modify. This must be initialized. |
* \param pos Zero-based index of the bit to modify. |
* \param val The desired value of bit \c pos: \c 0 or \c 1. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ); |
/** |
* \brief Return the number of bits of value \c 0 before the |
* least significant bit of value \c 1. |
* |
* \note This is the same as the zero-based index of |
* the least significant bit of value \c 1. |
* |
* \param X The MPI to query. |
* |
* \return The number of bits of value \c 0 before the least significant |
* bit of value \c 1 in \p X. |
*/ |
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ); |
/** |
* \brief Return the number of bits up to and including the most |
* significant bit of value \c 1. |
* |
* * \note This is same as the one-based index of the most |
* significant bit of value \c 1. |
* |
* \param X The MPI to query. This must point to an initialized MPI. |
* |
* \return The number of bits up to and including the most |
* significant bit of value \c 1. |
*/ |
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ); |
/** |
* \brief Return the total size of an MPI value in bytes. |
* |
* \param X The MPI to use. This must point to an initialized MPI. |
* |
* \note The value returned by this function may be less than |
* the number of bytes used to store \p X internally. |
* This happens if and only if there are trailing bytes |
* of value zero. |
* |
* \return The least number of bytes capable of storing |
* the absolute value of \p X. |
*/ |
size_t mbedtls_mpi_size( const mbedtls_mpi *X ); |
/** |
* \brief Import an MPI from an ASCII string. |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param radix The numeric base of the input string. |
* \param s Null-terminated string buffer. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ); |
/** |
* \brief Export an MPI to an ASCII string. |
* |
* \param X The source MPI. This must point to an initialized MPI. |
* \param radix The numeric base of the output string. |
* \param buf The buffer to write the string to. This must be writable |
* buffer of length \p buflen Bytes. |
* \param buflen The available size in Bytes of \p buf. |
* \param olen The address at which to store the length of the string |
* written, including the final \c NULL byte. This must |
* not be \c NULL. |
* |
* \note You can call this function with `buflen == 0` to obtain the |
* minimum required buffer size in `*olen`. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf |
* is too small to hold the value of \p X in the desired base. |
* In this case, `*olen` is nonetheless updated to contain the |
* size of \p buf required for a successful call. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, |
char *buf, size_t buflen, size_t *olen ); |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief Read an MPI from a line in an opened file. |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param radix The numeric base of the string representation used |
* in the source line. |
* \param fin The input file handle to use. This must not be \c NULL. |
* |
* \note On success, this function advances the file stream |
* to the end of the current line or to EOF. |
* |
* The function returns \c 0 on an empty line. |
* |
* Leading whitespaces are ignored, as is a |
* '0x' prefix for radix \c 16. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer |
* is too small. |
* \return Another negative error code on failure. |
*/ |
int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ); |
/** |
* \brief Export an MPI into an opened file. |
* |
* \param p A string prefix to emit prior to the MPI data. |
* For example, this might be a label, or "0x" when |
* printing in base \c 16. This may be \c NULL if no prefix |
* is needed. |
* \param X The source MPI. This must point to an initialized MPI. |
* \param radix The numeric base to be used in the emitted string. |
* \param fout The output file handle. This may be \c NULL, in which case |
* the output is written to \c stdout. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, |
int radix, FILE *fout ); |
#endif /* MBEDTLS_FS_IO */ |
/** |
* \brief Import an MPI from unsigned big endian binary data. |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param buf The input buffer. This must be a readable buffer of length |
* \p buflen Bytes. |
* \param buflen The length of the input buffer \p p in Bytes. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, |
size_t buflen ); |
/** |
* \brief Export an MPI into unsigned big endian binary data |
* of fixed size. |
* |
* \param X The source MPI. This must point to an initialized MPI. |
* \param buf The output buffer. This must be a writable buffer of length |
* \p buflen Bytes. |
* \param buflen The size of the output buffer \p buf in Bytes. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't |
* large enough to hold the value of \p X. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, |
size_t buflen ); |
/** |
* \brief Perform a left-shift on an MPI: X <<= count |
* |
* \param X The MPI to shift. This must point to an initialized MPI. |
* \param count The number of bits to shift by. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ); |
/** |
* \brief Perform a right-shift on an MPI: X >>= count |
* |
* \param X The MPI to shift. This must point to an initialized MPI. |
* \param count The number of bits to shift by. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ); |
/** |
* \brief Compare the absolute values of two MPIs. |
* |
* \param X The left-hand MPI. This must point to an initialized MPI. |
* \param Y The right-hand MPI. This must point to an initialized MPI. |
* |
* \return \c 1 if `|X|` is greater than `|Y|`. |
* \return \c -1 if `|X|` is lesser than `|Y|`. |
* \return \c 0 if `|X|` is equal to `|Y|`. |
*/ |
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ); |
/** |
* \brief Compare two MPIs. |
* |
* \param X The left-hand MPI. This must point to an initialized MPI. |
* \param Y The right-hand MPI. This must point to an initialized MPI. |
* |
* \return \c 1 if \p X is greater than \p Y. |
* \return \c -1 if \p X is lesser than \p Y. |
* \return \c 0 if \p X is equal to \p Y. |
*/ |
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); |
/** |
* \brief Check if an MPI is less than the other in constant time. |
* |
* \param X The left-hand MPI. This must point to an initialized MPI |
* with the same allocated length as Y. |
* \param Y The right-hand MPI. This must point to an initialized MPI |
* with the same allocated length as X. |
* \param ret The result of the comparison: |
* \c 1 if \p X is less than \p Y. |
* \c 0 if \p X is greater than or equal to \p Y. |
* |
* \return 0 on success. |
* \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of |
* the two input MPIs is not the same. |
*/ |
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, |
unsigned *ret ); |
/** |
* \brief Compare an MPI with an integer. |
* |
* \param X The left-hand MPI. This must point to an initialized MPI. |
* \param z The integer value to compare \p X to. |
* |
* \return \c 1 if \p X is greater than \p z. |
* \return \c -1 if \p X is lesser than \p z. |
* \return \c 0 if \p X is equal to \p z. |
*/ |
int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ); |
/** |
* \brief Perform an unsigned addition of MPIs: X = |A| + |B| |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The first summand. This must point to an initialized MPI. |
* \param B The second summand. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform an unsigned subtraction of MPIs: X = |A| - |B| |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The minuend. This must point to an initialized MPI. |
* \param B The subtrahend. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A. |
* \return Another negative error code on different kinds of failure. |
* |
*/ |
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform a signed addition of MPIs: X = A + B |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The first summand. This must point to an initialized MPI. |
* \param B The second summand. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform a signed subtraction of MPIs: X = A - B |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The minuend. This must point to an initialized MPI. |
* \param B The subtrahend. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform a signed addition of an MPI and an integer: X = A + b |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The first summand. This must point to an initialized MPI. |
* \param b The second summand. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, |
mbedtls_mpi_sint b ); |
/** |
* \brief Perform a signed subtraction of an MPI and an integer: |
* X = A - b |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The minuend. This must point to an initialized MPI. |
* \param b The subtrahend. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, |
mbedtls_mpi_sint b ); |
/** |
* \brief Perform a multiplication of two MPIs: X = A * B |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The first factor. This must point to an initialized MPI. |
* \param B The second factor. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
* |
*/ |
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform a multiplication of an MPI with an unsigned integer: |
* X = A * b |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The first factor. This must point to an initialized MPI. |
* \param b The second factor. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
* |
*/ |
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, |
mbedtls_mpi_uint b ); |
/** |
* \brief Perform a division with remainder of two MPIs: |
* A = Q * B + R |
* |
* \param Q The destination MPI for the quotient. |
* This may be \c NULL if the value of the |
* quotient is not needed. |
* \param R The destination MPI for the remainder value. |
* This may be \c NULL if the value of the |
* remainder is not needed. |
* \param A The dividend. This must point to an initialized MPi. |
* \param B The divisor. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform a division with remainder of an MPI by an integer: |
* A = Q * b + R |
* |
* \param Q The destination MPI for the quotient. |
* This may be \c NULL if the value of the |
* quotient is not needed. |
* \param R The destination MPI for the remainder value. |
* This may be \c NULL if the value of the |
* remainder is not needed. |
* \param A The dividend. This must point to an initialized MPi. |
* \param b The divisor. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, |
mbedtls_mpi_sint b ); |
/** |
* \brief Perform a modular reduction. R = A mod B |
* |
* \param R The destination MPI for the residue value. |
* This must point to an initialized MPI. |
* \param A The MPI to compute the residue of. |
* This must point to an initialized MPI. |
* \param B The base of the modular reduction. |
* This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. |
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative. |
* \return Another negative error code on different kinds of failure. |
* |
*/ |
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Perform a modular reduction with respect to an integer. |
* r = A mod b |
* |
* \param r The address at which to store the residue. |
* This must not be \c NULL. |
* \param A The MPI to compute the residue of. |
* This must point to an initialized MPi. |
* \param b The integer base of the modular reduction. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. |
* \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, |
mbedtls_mpi_sint b ); |
/** |
* \brief Perform a sliding-window exponentiation: X = A^E mod N |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The base of the exponentiation. |
* This must point to an initialized MPI. |
* \param E The exponent MPI. This must point to an initialized MPI. |
* \param N The base for the modular reduction. This must point to an |
* initialized MPI. |
* \param _RR A helper MPI depending solely on \p N which can be used to |
* speed-up multiple modular exponentiations for the same value |
* of \p N. This may be \c NULL. If it is not \c NULL, it must |
* point to an initialized MPI. If it hasn't been used after |
* the call to mbedtls_mpi_init(), this function will compute |
* the helper value and store it in \p _RR for reuse on |
* subsequent calls to this function. Otherwise, the function |
* will assume that \p _RR holds the helper value set by a |
* previous call to mbedtls_mpi_exp_mod(), and reuse it. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or |
* even, or if \c E is negative. |
* \return Another negative error code on different kinds of failures. |
* |
*/ |
int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *E, const mbedtls_mpi *N, |
mbedtls_mpi *_RR ); |
/** |
* \brief Fill an MPI with a number of random bytes. |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param size The number of random bytes to generate. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on failure. |
* |
* \note The bytes obtained from the RNG are interpreted |
* as a big-endian representation of an MPI; this can |
* be relevant in applications like deterministic ECDSA. |
*/ |
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Compute the greatest common divisor: G = gcd(A, B) |
* |
* \param G The destination MPI. This must point to an initialized MPI. |
* \param A The first operand. This must point to an initialized MPI. |
* \param B The second operand. This must point to an initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return Another negative error code on different kinds of failure. |
*/ |
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, |
const mbedtls_mpi *B ); |
/** |
* \brief Compute the modular inverse: X = A^-1 mod N |
* |
* \param X The destination MPI. This must point to an initialized MPI. |
* \param A The MPI to calculate the modular inverse of. This must point |
* to an initialized MPI. |
* \param N The base of the modular inversion. This must point to an |
* initialized MPI. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than |
* or equal to one. |
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse |
* with respect to \p N. |
*/ |
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *N ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Perform a Miller-Rabin primality test with error |
* probability of 2<sup>-80</sup>. |
* |
* \deprecated Superseded by mbedtls_mpi_is_prime_ext() which allows |
* specifying the number of Miller-Rabin rounds. |
* |
* \param X The MPI to check for primality. |
* This must point to an initialized MPI. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. |
* This may be \c NULL if \p f_rng doesn't use a |
* context parameter. |
* |
* \return \c 0 if successful, i.e. \p X is probably prime. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. |
* \return Another negative error code on other kinds of failure. |
*/ |
MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Miller-Rabin primality test. |
* |
* \warning If \p X is potentially generated by an adversary, for example |
* when validating cryptographic parameters that you didn't |
* generate yourself and that are supposed to be prime, then |
* \p rounds should be at least the half of the security |
* strength of the cryptographic algorithm. On the other hand, |
* if \p X is chosen uniformly or non-adversially (as is the |
* case when mbedtls_mpi_gen_prime calls this function), then |
* \p rounds can be much lower. |
* |
* \param X The MPI to check for primality. |
* This must point to an initialized MPI. |
* \param rounds The number of bases to perform the Miller-Rabin primality |
* test for. The probability of returning 0 on a composite is |
* at most 2<sup>-2*\p rounds</sup>. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. |
* This may be \c NULL if \p f_rng doesn't use |
* a context parameter. |
* |
* \return \c 0 if successful, i.e. \p X is probably prime. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Flags for mbedtls_mpi_gen_prime() |
* |
* Each of these flags is a constraint on the result X returned by |
* mbedtls_mpi_gen_prime(). |
*/ |
typedef enum { |
MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */ |
MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2<sup>-80</sup> to 2<sup>-128</sup> */ |
} mbedtls_mpi_gen_prime_flag_t; |
/** |
* \brief Generate a prime number. |
* |
* \param X The destination MPI to store the generated prime in. |
* This must point to an initialized MPi. |
* \param nbits The required size of the destination MPI in bits. |
* This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS. |
* \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. |
* This may be \c NULL if \p f_rng doesn't use |
* a context parameter. |
* |
* \return \c 0 if successful, in which case \p X holds a |
* probably prime number. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. |
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between |
* \c 3 and #MBEDTLS_MPI_MAX_BITS. |
*/ |
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_mpi_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* bignum.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/blowfish.h |
---|
0,0 → 1,289 |
/** |
* \file blowfish.h |
* |
* \brief Blowfish block cipher |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_BLOWFISH_H |
#define MBEDTLS_BLOWFISH_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
#include "platform_util.h" |
#define MBEDTLS_BLOWFISH_ENCRYPT 1 |
#define MBEDTLS_BLOWFISH_DECRYPT 0 |
#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448 |
#define MBEDTLS_BLOWFISH_MIN_KEY_BITS 32 |
#define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */ |
#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */ |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 ) |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */ |
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */ |
/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_BLOWFISH_ALT) |
// Regular implementation |
// |
/** |
* \brief Blowfish context structure |
*/ |
typedef struct mbedtls_blowfish_context |
{ |
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */ |
uint32_t S[4][256]; /*!< key dependent S-boxes */ |
} |
mbedtls_blowfish_context; |
#else /* MBEDTLS_BLOWFISH_ALT */ |
#include "blowfish_alt.h" |
#endif /* MBEDTLS_BLOWFISH_ALT */ |
/** |
* \brief Initialize a Blowfish context. |
* |
* \param ctx The Blowfish context to be initialized. |
* This must not be \c NULL. |
*/ |
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ); |
/** |
* \brief Clear a Blowfish context. |
* |
* \param ctx The Blowfish context to be cleared. |
* This may be \c NULL, in which case this function |
* returns immediately. If it is not \c NULL, it must |
* point to an initialized Blowfish context. |
*/ |
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ); |
/** |
* \brief Perform a Blowfish key schedule operation. |
* |
* \param ctx The Blowfish context to perform the key schedule on. |
* \param key The encryption key. This must be a readable buffer of |
* length \p keybits Bits. |
* \param keybits The length of \p key in Bits. This must be between |
* \c 32 and \c 448 and a multiple of \c 8. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief Perform a Blowfish-ECB block encryption/decryption operation. |
* |
* \param ctx The Blowfish context to use. This must be initialized |
* and bound to a key. |
* \param mode The mode of operation. Possible values are |
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or |
* #MBEDTLS_BLOWFISH_DECRYPT for decryption. |
* \param input The input block. This must be a readable buffer |
* of size \c 8 Bytes. |
* \param output The output block. This must be a writable buffer |
* of size \c 8 Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, |
int mode, |
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], |
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief Perform a Blowfish-CBC buffer encryption/decryption operation. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the function same function again on the following |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If on the other hand you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* \param ctx The Blowfish context to use. This must be initialized |
* and bound to a key. |
* \param mode The mode of operation. Possible values are |
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or |
* #MBEDTLS_BLOWFISH_DECRYPT for decryption. |
* \param length The length of the input data in Bytes. This must be |
* multiple of \c 8. |
* \param iv The initialization vector. This must be a read/write buffer |
* of length \c 8 Bytes. It is updated by this function. |
* \param input The input data. This must be a readable buffer of length |
* \p length Bytes. |
* \param output The output data. This must be a writable buffer of length |
* \p length Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/** |
* \brief Perform a Blowfish CFB buffer encryption/decryption operation. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the function same function again on the following |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If on the other hand you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* \param ctx The Blowfish context to use. This must be initialized |
* and bound to a key. |
* \param mode The mode of operation. Possible values are |
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or |
* #MBEDTLS_BLOWFISH_DECRYPT for decryption. |
* \param length The length of the input data in Bytes. |
* \param iv_off The offset in the initialiation vector. |
* The value pointed to must be smaller than \c 8 Bytes. |
* It is updated by this function to support the aforementioned |
* streaming usage. |
* \param iv The initialization vector. This must be a read/write buffer |
* of size \c 8 Bytes. It is updated after use. |
* \param input The input data. This must be a readable buffer of length |
* \p length Bytes. |
* \param output The output data. This must be a writable buffer of length |
* \p length Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ); |
#endif /*MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/** |
* \brief Perform a Blowfish-CTR buffer encryption/decryption operation. |
* |
* \warning You must never reuse a nonce value with the same key. Doing so |
* would void the encryption for the two messages encrypted with |
* the same nonce and key. |
* |
* There are two common strategies for managing nonces with CTR: |
* |
* 1. You can handle everything as a single message processed over |
* successive calls to this function. In that case, you want to |
* set \p nonce_counter and \p nc_off to 0 for the first call, and |
* then preserve the values of \p nonce_counter, \p nc_off and \p |
* stream_block across calls to this function as they will be |
* updated by this function. |
* |
* With this strategy, you must not encrypt more than 2**64 |
* blocks of data with the same key. |
* |
* 2. You can encrypt separate messages by dividing the \p |
* nonce_counter buffer in two areas: the first one used for a |
* per-message nonce, handled by yourself, and the second one |
* updated by this function internally. |
* |
* For example, you might reserve the first 4 bytes for the |
* per-message nonce, and the last 4 bytes for internal use. In that |
* case, before calling this function on a new message you need to |
* set the first 4 bytes of \p nonce_counter to your chosen nonce |
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p |
* stream_block to be ignored). That way, you can encrypt at most |
* 2**32 messages of up to 2**32 blocks each with the same key. |
* |
* The per-message nonce (or information sufficient to reconstruct |
* it) needs to be communicated with the ciphertext and must be unique. |
* The recommended way to ensure uniqueness is to use a message |
* counter. |
* |
* Note that for both stategies, sizes are measured in blocks and |
* that a Blowfish block is 8 bytes. |
* |
* \warning Upon return, \p stream_block contains sensitive data. Its |
* content must not be written to insecure storage and should be |
* securely discarded as soon as it's no longer needed. |
* |
* \param ctx The Blowfish context to use. This must be initialized |
* and bound to a key. |
* \param length The length of the input data in Bytes. |
* \param nc_off The offset in the current stream_block (for resuming |
* within current cipher stream). The offset pointer |
* should be \c 0 at the start of a stream and must be |
* smaller than \c 8. It is updated by this function. |
* \param nonce_counter The 64-bit nonce and counter. This must point to a |
* read/write buffer of length \c 8 Bytes. |
* \param stream_block The saved stream-block for resuming. This must point to |
* a read/write buffer of length \c 8 Bytes. |
* \param input The input data. This must be a readable buffer of |
* length \p length Bytes. |
* \param output The output data. This must be a writable buffer of |
* length \p length Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], |
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* blowfish.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/bn_mul.h |
---|
0,0 → 1,918 |
/** |
* \file bn_mul.h |
* |
* \brief Multi-precision integer library |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* 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 MBEDTLS_BN_MUL_H |
#define MBEDTLS_BN_MUL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "bignum.h" |
#if defined(MBEDTLS_HAVE_ASM) |
#ifndef asm |
#define asm __asm |
#endif |
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ |
#if defined(__GNUC__) && \ |
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) |
/* |
* Disable use of the i386 assembly code below if option -O0, to disable all |
* compiler optimisations, is passed, detected with __OPTIMIZE__ |
* This is done as the number of registers used in the assembly code doesn't |
* work with the -O0 option. |
*/ |
#if defined(__i386__) && defined(__OPTIMIZE__) |
#define MULADDC_INIT \ |
asm( \ |
"movl %%ebx, %0 \n\t" \ |
"movl %5, %%esi \n\t" \ |
"movl %6, %%edi \n\t" \ |
"movl %7, %%ecx \n\t" \ |
"movl %8, %%ebx \n\t" |
#define MULADDC_CORE \ |
"lodsl \n\t" \ |
"mull %%ebx \n\t" \ |
"addl %%ecx, %%eax \n\t" \ |
"adcl $0, %%edx \n\t" \ |
"addl (%%edi), %%eax \n\t" \ |
"adcl $0, %%edx \n\t" \ |
"movl %%edx, %%ecx \n\t" \ |
"stosl \n\t" |
#if defined(MBEDTLS_HAVE_SSE2) |
#define MULADDC_HUIT \ |
"movd %%ecx, %%mm1 \n\t" \ |
"movd %%ebx, %%mm0 \n\t" \ |
"movd (%%edi), %%mm3 \n\t" \ |
"paddq %%mm3, %%mm1 \n\t" \ |
"movd (%%esi), %%mm2 \n\t" \ |
"pmuludq %%mm0, %%mm2 \n\t" \ |
"movd 4(%%esi), %%mm4 \n\t" \ |
"pmuludq %%mm0, %%mm4 \n\t" \ |
"movd 8(%%esi), %%mm6 \n\t" \ |
"pmuludq %%mm0, %%mm6 \n\t" \ |
"movd 12(%%esi), %%mm7 \n\t" \ |
"pmuludq %%mm0, %%mm7 \n\t" \ |
"paddq %%mm2, %%mm1 \n\t" \ |
"movd 4(%%edi), %%mm3 \n\t" \ |
"paddq %%mm4, %%mm3 \n\t" \ |
"movd 8(%%edi), %%mm5 \n\t" \ |
"paddq %%mm6, %%mm5 \n\t" \ |
"movd 12(%%edi), %%mm4 \n\t" \ |
"paddq %%mm4, %%mm7 \n\t" \ |
"movd %%mm1, (%%edi) \n\t" \ |
"movd 16(%%esi), %%mm2 \n\t" \ |
"pmuludq %%mm0, %%mm2 \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"movd 20(%%esi), %%mm4 \n\t" \ |
"pmuludq %%mm0, %%mm4 \n\t" \ |
"paddq %%mm3, %%mm1 \n\t" \ |
"movd 24(%%esi), %%mm6 \n\t" \ |
"pmuludq %%mm0, %%mm6 \n\t" \ |
"movd %%mm1, 4(%%edi) \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"movd 28(%%esi), %%mm3 \n\t" \ |
"pmuludq %%mm0, %%mm3 \n\t" \ |
"paddq %%mm5, %%mm1 \n\t" \ |
"movd 16(%%edi), %%mm5 \n\t" \ |
"paddq %%mm5, %%mm2 \n\t" \ |
"movd %%mm1, 8(%%edi) \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"paddq %%mm7, %%mm1 \n\t" \ |
"movd 20(%%edi), %%mm5 \n\t" \ |
"paddq %%mm5, %%mm4 \n\t" \ |
"movd %%mm1, 12(%%edi) \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"paddq %%mm2, %%mm1 \n\t" \ |
"movd 24(%%edi), %%mm5 \n\t" \ |
"paddq %%mm5, %%mm6 \n\t" \ |
"movd %%mm1, 16(%%edi) \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"paddq %%mm4, %%mm1 \n\t" \ |
"movd 28(%%edi), %%mm5 \n\t" \ |
"paddq %%mm5, %%mm3 \n\t" \ |
"movd %%mm1, 20(%%edi) \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"paddq %%mm6, %%mm1 \n\t" \ |
"movd %%mm1, 24(%%edi) \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"paddq %%mm3, %%mm1 \n\t" \ |
"movd %%mm1, 28(%%edi) \n\t" \ |
"addl $32, %%edi \n\t" \ |
"addl $32, %%esi \n\t" \ |
"psrlq $32, %%mm1 \n\t" \ |
"movd %%mm1, %%ecx \n\t" |
#define MULADDC_STOP \ |
"emms \n\t" \ |
"movl %4, %%ebx \n\t" \ |
"movl %%ecx, %1 \n\t" \ |
"movl %%edi, %2 \n\t" \ |
"movl %%esi, %3 \n\t" \ |
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "eax", "ebx", "ecx", "edx", "esi", "edi" \ |
); |
#else |
#define MULADDC_STOP \ |
"movl %4, %%ebx \n\t" \ |
"movl %%ecx, %1 \n\t" \ |
"movl %%edi, %2 \n\t" \ |
"movl %%esi, %3 \n\t" \ |
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "eax", "ebx", "ecx", "edx", "esi", "edi" \ |
); |
#endif /* SSE2 */ |
#endif /* i386 */ |
#if defined(__amd64__) || defined (__x86_64__) |
#define MULADDC_INIT \ |
asm( \ |
"xorq %%r8, %%r8\n" |
#define MULADDC_CORE \ |
"movq (%%rsi), %%rax\n" \ |
"mulq %%rbx\n" \ |
"addq $8, %%rsi\n" \ |
"addq %%rcx, %%rax\n" \ |
"movq %%r8, %%rcx\n" \ |
"adcq $0, %%rdx\n" \ |
"nop \n" \ |
"addq %%rax, (%%rdi)\n" \ |
"adcq %%rdx, %%rcx\n" \ |
"addq $8, %%rdi\n" |
#define MULADDC_STOP \ |
: "+c" (c), "+D" (d), "+S" (s) \ |
: "b" (b) \ |
: "rax", "rdx", "r8" \ |
); |
#endif /* AMD64 */ |
#if defined(__mc68020__) || defined(__mcpu32__) |
#define MULADDC_INIT \ |
asm( \ |
"movl %3, %%a2 \n\t" \ |
"movl %4, %%a3 \n\t" \ |
"movl %5, %%d3 \n\t" \ |
"movl %6, %%d2 \n\t" \ |
"moveq #0, %%d0 \n\t" |
#define MULADDC_CORE \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d4:%%d1 \n\t" \ |
"addl %%d3, %%d1 \n\t" \ |
"addxl %%d0, %%d4 \n\t" \ |
"moveq #0, %%d3 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"addxl %%d4, %%d3 \n\t" |
#define MULADDC_STOP \ |
"movl %%d3, %0 \n\t" \ |
"movl %%a3, %1 \n\t" \ |
"movl %%a2, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ |
); |
#define MULADDC_HUIT \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d4:%%d1 \n\t" \ |
"addxl %%d3, %%d1 \n\t" \ |
"addxl %%d0, %%d4 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d3:%%d1 \n\t" \ |
"addxl %%d4, %%d1 \n\t" \ |
"addxl %%d0, %%d3 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d4:%%d1 \n\t" \ |
"addxl %%d3, %%d1 \n\t" \ |
"addxl %%d0, %%d4 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d3:%%d1 \n\t" \ |
"addxl %%d4, %%d1 \n\t" \ |
"addxl %%d0, %%d3 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d4:%%d1 \n\t" \ |
"addxl %%d3, %%d1 \n\t" \ |
"addxl %%d0, %%d4 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d3:%%d1 \n\t" \ |
"addxl %%d4, %%d1 \n\t" \ |
"addxl %%d0, %%d3 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d4:%%d1 \n\t" \ |
"addxl %%d3, %%d1 \n\t" \ |
"addxl %%d0, %%d4 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"movel %%a2@+, %%d1 \n\t" \ |
"mulul %%d2, %%d3:%%d1 \n\t" \ |
"addxl %%d4, %%d1 \n\t" \ |
"addxl %%d0, %%d3 \n\t" \ |
"addl %%d1, %%a3@+ \n\t" \ |
"addxl %%d0, %%d3 \n\t" |
#endif /* MC68000 */ |
#if defined(__powerpc64__) || defined(__ppc64__) |
#if defined(__MACH__) && defined(__APPLE__) |
#define MULADDC_INIT \ |
asm( \ |
"ld r3, %3 \n\t" \ |
"ld r4, %4 \n\t" \ |
"ld r5, %5 \n\t" \ |
"ld r6, %6 \n\t" \ |
"addi r3, r3, -8 \n\t" \ |
"addi r4, r4, -8 \n\t" \ |
"addic r5, r5, 0 \n\t" |
#define MULADDC_CORE \ |
"ldu r7, 8(r3) \n\t" \ |
"mulld r8, r7, r6 \n\t" \ |
"mulhdu r9, r7, r6 \n\t" \ |
"adde r8, r8, r5 \n\t" \ |
"ld r7, 8(r4) \n\t" \ |
"addze r5, r9 \n\t" \ |
"addc r8, r8, r7 \n\t" \ |
"stdu r8, 8(r4) \n\t" |
#define MULADDC_STOP \ |
"addze r5, r5 \n\t" \ |
"addi r4, r4, 8 \n\t" \ |
"addi r3, r3, 8 \n\t" \ |
"std r5, %0 \n\t" \ |
"std r4, %1 \n\t" \ |
"std r3, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ |
); |
#else /* __MACH__ && __APPLE__ */ |
#define MULADDC_INIT \ |
asm( \ |
"ld %%r3, %3 \n\t" \ |
"ld %%r4, %4 \n\t" \ |
"ld %%r5, %5 \n\t" \ |
"ld %%r6, %6 \n\t" \ |
"addi %%r3, %%r3, -8 \n\t" \ |
"addi %%r4, %%r4, -8 \n\t" \ |
"addic %%r5, %%r5, 0 \n\t" |
#define MULADDC_CORE \ |
"ldu %%r7, 8(%%r3) \n\t" \ |
"mulld %%r8, %%r7, %%r6 \n\t" \ |
"mulhdu %%r9, %%r7, %%r6 \n\t" \ |
"adde %%r8, %%r8, %%r5 \n\t" \ |
"ld %%r7, 8(%%r4) \n\t" \ |
"addze %%r5, %%r9 \n\t" \ |
"addc %%r8, %%r8, %%r7 \n\t" \ |
"stdu %%r8, 8(%%r4) \n\t" |
#define MULADDC_STOP \ |
"addze %%r5, %%r5 \n\t" \ |
"addi %%r4, %%r4, 8 \n\t" \ |
"addi %%r3, %%r3, 8 \n\t" \ |
"std %%r5, %0 \n\t" \ |
"std %%r4, %1 \n\t" \ |
"std %%r3, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ |
); |
#endif /* __MACH__ && __APPLE__ */ |
#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ |
#if defined(__MACH__) && defined(__APPLE__) |
#define MULADDC_INIT \ |
asm( \ |
"lwz r3, %3 \n\t" \ |
"lwz r4, %4 \n\t" \ |
"lwz r5, %5 \n\t" \ |
"lwz r6, %6 \n\t" \ |
"addi r3, r3, -4 \n\t" \ |
"addi r4, r4, -4 \n\t" \ |
"addic r5, r5, 0 \n\t" |
#define MULADDC_CORE \ |
"lwzu r7, 4(r3) \n\t" \ |
"mullw r8, r7, r6 \n\t" \ |
"mulhwu r9, r7, r6 \n\t" \ |
"adde r8, r8, r5 \n\t" \ |
"lwz r7, 4(r4) \n\t" \ |
"addze r5, r9 \n\t" \ |
"addc r8, r8, r7 \n\t" \ |
"stwu r8, 4(r4) \n\t" |
#define MULADDC_STOP \ |
"addze r5, r5 \n\t" \ |
"addi r4, r4, 4 \n\t" \ |
"addi r3, r3, 4 \n\t" \ |
"stw r5, %0 \n\t" \ |
"stw r4, %1 \n\t" \ |
"stw r3, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ |
); |
#else /* __MACH__ && __APPLE__ */ |
#define MULADDC_INIT \ |
asm( \ |
"lwz %%r3, %3 \n\t" \ |
"lwz %%r4, %4 \n\t" \ |
"lwz %%r5, %5 \n\t" \ |
"lwz %%r6, %6 \n\t" \ |
"addi %%r3, %%r3, -4 \n\t" \ |
"addi %%r4, %%r4, -4 \n\t" \ |
"addic %%r5, %%r5, 0 \n\t" |
#define MULADDC_CORE \ |
"lwzu %%r7, 4(%%r3) \n\t" \ |
"mullw %%r8, %%r7, %%r6 \n\t" \ |
"mulhwu %%r9, %%r7, %%r6 \n\t" \ |
"adde %%r8, %%r8, %%r5 \n\t" \ |
"lwz %%r7, 4(%%r4) \n\t" \ |
"addze %%r5, %%r9 \n\t" \ |
"addc %%r8, %%r8, %%r7 \n\t" \ |
"stwu %%r8, 4(%%r4) \n\t" |
#define MULADDC_STOP \ |
"addze %%r5, %%r5 \n\t" \ |
"addi %%r4, %%r4, 4 \n\t" \ |
"addi %%r3, %%r3, 4 \n\t" \ |
"stw %%r5, %0 \n\t" \ |
"stw %%r4, %1 \n\t" \ |
"stw %%r3, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ |
); |
#endif /* __MACH__ && __APPLE__ */ |
#endif /* PPC32 */ |
/* |
* The Sparc(64) assembly is reported to be broken. |
* Disable it for now, until we're able to fix it. |
*/ |
#if 0 && defined(__sparc__) |
#if defined(__sparc64__) |
#define MULADDC_INIT \ |
asm( \ |
"ldx %3, %%o0 \n\t" \ |
"ldx %4, %%o1 \n\t" \ |
"ld %5, %%o2 \n\t" \ |
"ld %6, %%o3 \n\t" |
#define MULADDC_CORE \ |
"ld [%%o0], %%o4 \n\t" \ |
"inc 4, %%o0 \n\t" \ |
"ld [%%o1], %%o5 \n\t" \ |
"umul %%o3, %%o4, %%o4 \n\t" \ |
"addcc %%o4, %%o2, %%o4 \n\t" \ |
"rd %%y, %%g1 \n\t" \ |
"addx %%g1, 0, %%g1 \n\t" \ |
"addcc %%o4, %%o5, %%o4 \n\t" \ |
"st %%o4, [%%o1] \n\t" \ |
"addx %%g1, 0, %%o2 \n\t" \ |
"inc 4, %%o1 \n\t" |
#define MULADDC_STOP \ |
"st %%o2, %0 \n\t" \ |
"stx %%o1, %1 \n\t" \ |
"stx %%o0, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "g1", "o0", "o1", "o2", "o3", "o4", \ |
"o5" \ |
); |
#else /* __sparc64__ */ |
#define MULADDC_INIT \ |
asm( \ |
"ld %3, %%o0 \n\t" \ |
"ld %4, %%o1 \n\t" \ |
"ld %5, %%o2 \n\t" \ |
"ld %6, %%o3 \n\t" |
#define MULADDC_CORE \ |
"ld [%%o0], %%o4 \n\t" \ |
"inc 4, %%o0 \n\t" \ |
"ld [%%o1], %%o5 \n\t" \ |
"umul %%o3, %%o4, %%o4 \n\t" \ |
"addcc %%o4, %%o2, %%o4 \n\t" \ |
"rd %%y, %%g1 \n\t" \ |
"addx %%g1, 0, %%g1 \n\t" \ |
"addcc %%o4, %%o5, %%o4 \n\t" \ |
"st %%o4, [%%o1] \n\t" \ |
"addx %%g1, 0, %%o2 \n\t" \ |
"inc 4, %%o1 \n\t" |
#define MULADDC_STOP \ |
"st %%o2, %0 \n\t" \ |
"st %%o1, %1 \n\t" \ |
"st %%o0, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "g1", "o0", "o1", "o2", "o3", "o4", \ |
"o5" \ |
); |
#endif /* __sparc64__ */ |
#endif /* __sparc__ */ |
#if defined(__microblaze__) || defined(microblaze) |
#define MULADDC_INIT \ |
asm( \ |
"lwi r3, %3 \n\t" \ |
"lwi r4, %4 \n\t" \ |
"lwi r5, %5 \n\t" \ |
"lwi r6, %6 \n\t" \ |
"andi r7, r6, 0xffff \n\t" \ |
"bsrli r6, r6, 16 \n\t" |
#define MULADDC_CORE \ |
"lhui r8, r3, 0 \n\t" \ |
"addi r3, r3, 2 \n\t" \ |
"lhui r9, r3, 0 \n\t" \ |
"addi r3, r3, 2 \n\t" \ |
"mul r10, r9, r6 \n\t" \ |
"mul r11, r8, r7 \n\t" \ |
"mul r12, r9, r7 \n\t" \ |
"mul r13, r8, r6 \n\t" \ |
"bsrli r8, r10, 16 \n\t" \ |
"bsrli r9, r11, 16 \n\t" \ |
"add r13, r13, r8 \n\t" \ |
"add r13, r13, r9 \n\t" \ |
"bslli r10, r10, 16 \n\t" \ |
"bslli r11, r11, 16 \n\t" \ |
"add r12, r12, r10 \n\t" \ |
"addc r13, r13, r0 \n\t" \ |
"add r12, r12, r11 \n\t" \ |
"addc r13, r13, r0 \n\t" \ |
"lwi r10, r4, 0 \n\t" \ |
"add r12, r12, r10 \n\t" \ |
"addc r13, r13, r0 \n\t" \ |
"add r12, r12, r5 \n\t" \ |
"addc r5, r13, r0 \n\t" \ |
"swi r12, r4, 0 \n\t" \ |
"addi r4, r4, 4 \n\t" |
#define MULADDC_STOP \ |
"swi r5, %0 \n\t" \ |
"swi r4, %1 \n\t" \ |
"swi r3, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r3", "r4", "r5", "r6", "r7", "r8", \ |
"r9", "r10", "r11", "r12", "r13" \ |
); |
#endif /* MicroBlaze */ |
#if defined(__tricore__) |
#define MULADDC_INIT \ |
asm( \ |
"ld.a %%a2, %3 \n\t" \ |
"ld.a %%a3, %4 \n\t" \ |
"ld.w %%d4, %5 \n\t" \ |
"ld.w %%d1, %6 \n\t" \ |
"xor %%d5, %%d5 \n\t" |
#define MULADDC_CORE \ |
"ld.w %%d0, [%%a2+] \n\t" \ |
"madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ |
"ld.w %%d0, [%%a3] \n\t" \ |
"addx %%d2, %%d2, %%d0 \n\t" \ |
"addc %%d3, %%d3, 0 \n\t" \ |
"mov %%d4, %%d3 \n\t" \ |
"st.w [%%a3+], %%d2 \n\t" |
#define MULADDC_STOP \ |
"st.w %0, %%d4 \n\t" \ |
"st.a %1, %%a3 \n\t" \ |
"st.a %2, %%a2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "d0", "d1", "e2", "d4", "a2", "a3" \ |
); |
#endif /* TriCore */ |
/* |
* Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about |
* our use of r7 below, unless -fomit-frame-pointer is passed. |
* |
* On the other hand, -fomit-frame-pointer is implied by any -Ox options with |
* x !=0, which we can detect using __OPTIMIZE__ (which is also defined by |
* clang and armcc5 under the same conditions). |
* |
* So, only use the optimized assembly below for optimized build, which avoids |
* the build error and is pretty reasonable anyway. |
*/ |
#if defined(__GNUC__) && !defined(__OPTIMIZE__) |
#define MULADDC_CANNOT_USE_R7 |
#endif |
#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7) |
#if defined(__thumb__) && !defined(__thumb2__) |
#define MULADDC_INIT \ |
asm( \ |
"ldr r0, %3 \n\t" \ |
"ldr r1, %4 \n\t" \ |
"ldr r2, %5 \n\t" \ |
"ldr r3, %6 \n\t" \ |
"lsr r7, r3, #16 \n\t" \ |
"mov r9, r7 \n\t" \ |
"lsl r7, r3, #16 \n\t" \ |
"lsr r7, r7, #16 \n\t" \ |
"mov r8, r7 \n\t" |
#define MULADDC_CORE \ |
"ldmia r0!, {r6} \n\t" \ |
"lsr r7, r6, #16 \n\t" \ |
"lsl r6, r6, #16 \n\t" \ |
"lsr r6, r6, #16 \n\t" \ |
"mov r4, r8 \n\t" \ |
"mul r4, r6 \n\t" \ |
"mov r3, r9 \n\t" \ |
"mul r6, r3 \n\t" \ |
"mov r5, r9 \n\t" \ |
"mul r5, r7 \n\t" \ |
"mov r3, r8 \n\t" \ |
"mul r7, r3 \n\t" \ |
"lsr r3, r6, #16 \n\t" \ |
"add r5, r5, r3 \n\t" \ |
"lsr r3, r7, #16 \n\t" \ |
"add r5, r5, r3 \n\t" \ |
"add r4, r4, r2 \n\t" \ |
"mov r2, #0 \n\t" \ |
"adc r5, r2 \n\t" \ |
"lsl r3, r6, #16 \n\t" \ |
"add r4, r4, r3 \n\t" \ |
"adc r5, r2 \n\t" \ |
"lsl r3, r7, #16 \n\t" \ |
"add r4, r4, r3 \n\t" \ |
"adc r5, r2 \n\t" \ |
"ldr r3, [r1] \n\t" \ |
"add r4, r4, r3 \n\t" \ |
"adc r2, r5 \n\t" \ |
"stmia r1!, {r4} \n\t" |
#define MULADDC_STOP \ |
"str r2, %0 \n\t" \ |
"str r1, %1 \n\t" \ |
"str r0, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r0", "r1", "r2", "r3", "r4", "r5", \ |
"r6", "r7", "r8", "r9", "cc" \ |
); |
#elif (__ARM_ARCH >= 6) && \ |
defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1) |
#define MULADDC_INIT \ |
asm( |
#define MULADDC_CORE \ |
"ldr r0, [%0], #4 \n\t" \ |
"ldr r1, [%1] \n\t" \ |
"umaal r1, %2, %3, r0 \n\t" \ |
"str r1, [%1], #4 \n\t" |
#define MULADDC_STOP \ |
: "=r" (s), "=r" (d), "=r" (c) \ |
: "r" (b), "0" (s), "1" (d), "2" (c) \ |
: "r0", "r1", "memory" \ |
); |
#else |
#define MULADDC_INIT \ |
asm( \ |
"ldr r0, %3 \n\t" \ |
"ldr r1, %4 \n\t" \ |
"ldr r2, %5 \n\t" \ |
"ldr r3, %6 \n\t" |
#define MULADDC_CORE \ |
"ldr r4, [r0], #4 \n\t" \ |
"mov r5, #0 \n\t" \ |
"ldr r6, [r1] \n\t" \ |
"umlal r2, r5, r3, r4 \n\t" \ |
"adds r7, r6, r2 \n\t" \ |
"adc r2, r5, #0 \n\t" \ |
"str r7, [r1], #4 \n\t" |
#define MULADDC_STOP \ |
"str r2, %0 \n\t" \ |
"str r1, %1 \n\t" \ |
"str r0, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "r0", "r1", "r2", "r3", "r4", "r5", \ |
"r6", "r7", "cc" \ |
); |
#endif /* Thumb */ |
#endif /* ARMv3 */ |
#if defined(__alpha__) |
#define MULADDC_INIT \ |
asm( \ |
"ldq $1, %3 \n\t" \ |
"ldq $2, %4 \n\t" \ |
"ldq $3, %5 \n\t" \ |
"ldq $4, %6 \n\t" |
#define MULADDC_CORE \ |
"ldq $6, 0($1) \n\t" \ |
"addq $1, 8, $1 \n\t" \ |
"mulq $6, $4, $7 \n\t" \ |
"umulh $6, $4, $6 \n\t" \ |
"addq $7, $3, $7 \n\t" \ |
"cmpult $7, $3, $3 \n\t" \ |
"ldq $5, 0($2) \n\t" \ |
"addq $7, $5, $7 \n\t" \ |
"cmpult $7, $5, $5 \n\t" \ |
"stq $7, 0($2) \n\t" \ |
"addq $2, 8, $2 \n\t" \ |
"addq $6, $3, $3 \n\t" \ |
"addq $5, $3, $3 \n\t" |
#define MULADDC_STOP \ |
"stq $3, %0 \n\t" \ |
"stq $2, %1 \n\t" \ |
"stq $1, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ |
); |
#endif /* Alpha */ |
#if defined(__mips__) && !defined(__mips64) |
#define MULADDC_INIT \ |
asm( \ |
"lw $10, %3 \n\t" \ |
"lw $11, %4 \n\t" \ |
"lw $12, %5 \n\t" \ |
"lw $13, %6 \n\t" |
#define MULADDC_CORE \ |
"lw $14, 0($10) \n\t" \ |
"multu $13, $14 \n\t" \ |
"addi $10, $10, 4 \n\t" \ |
"mflo $14 \n\t" \ |
"mfhi $9 \n\t" \ |
"addu $14, $12, $14 \n\t" \ |
"lw $15, 0($11) \n\t" \ |
"sltu $12, $14, $12 \n\t" \ |
"addu $15, $14, $15 \n\t" \ |
"sltu $14, $15, $14 \n\t" \ |
"addu $12, $12, $9 \n\t" \ |
"sw $15, 0($11) \n\t" \ |
"addu $12, $12, $14 \n\t" \ |
"addi $11, $11, 4 \n\t" |
#define MULADDC_STOP \ |
"sw $12, %0 \n\t" \ |
"sw $11, %1 \n\t" \ |
"sw $10, %2 \n\t" \ |
: "=m" (c), "=m" (d), "=m" (s) \ |
: "m" (s), "m" (d), "m" (c), "m" (b) \ |
: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \ |
); |
#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(MBEDTLS_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 /* MBEDTLS_HAVE_ASM */ |
#if !defined(MULADDC_CORE) |
#if defined(MBEDTLS_HAVE_UDBL) |
#define MULADDC_INIT \ |
{ \ |
mbedtls_t_udbl r; \ |
mbedtls_mpi_uint r0, r1; |
#define MULADDC_CORE \ |
r = *(s++) * (mbedtls_t_udbl) b; \ |
r0 = (mbedtls_mpi_uint) r; \ |
r1 = (mbedtls_mpi_uint)( r >> biL ); \ |
r0 += c; r1 += (r0 < c); \ |
r0 += *d; r1 += (r0 < *d); \ |
c = r1; *(d++) = r0; |
#define MULADDC_STOP \ |
} |
#else |
#define MULADDC_INIT \ |
{ \ |
mbedtls_mpi_uint s0, s1, b0, b1; \ |
mbedtls_mpi_uint 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 */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/camellia.h |
---|
0,0 → 1,328 |
/** |
* \file camellia.h |
* |
* \brief Camellia block cipher |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CAMELLIA_H |
#define MBEDTLS_CAMELLIA_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
#include "platform_util.h" |
#define MBEDTLS_CAMELLIA_ENCRYPT 1 |
#define MBEDTLS_CAMELLIA_DECRYPT 0 |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 ) |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */ |
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */ |
/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_CAMELLIA_ALT) |
// Regular implementation |
// |
/** |
* \brief CAMELLIA context structure |
*/ |
typedef struct mbedtls_camellia_context |
{ |
int nr; /*!< number of rounds */ |
uint32_t rk[68]; /*!< CAMELLIA round keys */ |
} |
mbedtls_camellia_context; |
#else /* MBEDTLS_CAMELLIA_ALT */ |
#include "camellia_alt.h" |
#endif /* MBEDTLS_CAMELLIA_ALT */ |
/** |
* \brief Initialize a CAMELLIA context. |
* |
* \param ctx The CAMELLIA context to be initialized. |
* This must not be \c NULL. |
*/ |
void mbedtls_camellia_init( mbedtls_camellia_context *ctx ); |
/** |
* \brief Clear a CAMELLIA context. |
* |
* \param ctx The CAMELLIA context to be cleared. This may be \c NULL, |
* in which case this function returns immediately. If it is not |
* \c NULL, it must be initialized. |
*/ |
void mbedtls_camellia_free( mbedtls_camellia_context *ctx ); |
/** |
* \brief Perform a CAMELLIA key schedule operation for encryption. |
* |
* \param ctx The CAMELLIA context to use. This must be initialized. |
* \param key The encryption key to use. This must be a readable buffer |
* of size \p keybits Bits. |
* \param keybits The length of \p key in Bits. This must be either \c 128, |
* \c 192 or \c 256. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief Perform a CAMELLIA key schedule operation for decryption. |
* |
* \param ctx The CAMELLIA context to use. This must be initialized. |
* \param key The decryption key. This must be a readable buffer |
* of size \p keybits Bits. |
* \param keybits The length of \p key in Bits. This must be either \c 128, |
* \c 192 or \c 256. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation. |
* |
* \param ctx The CAMELLIA context to use. This must be initialized |
* and bound to a key. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. |
* \param input The input block. This must be a readable buffer |
* of size \c 16 Bytes. |
* \param output The output block. This must be a writable buffer |
* of size \c 16 Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the function same function again on the following |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If on the other hand you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* \param ctx The CAMELLIA context to use. This must be initialized |
* and bound to a key. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. |
* \param length The length in Bytes of the input data \p input. |
* This must be a multiple of \c 16 Bytes. |
* \param iv The initialization vector. This must be a read/write buffer |
* of length \c 16 Bytes. It is updated to allow streaming |
* use as explained above. |
* \param input The buffer holding the input data. This must point to a |
* readable buffer of length \p length Bytes. |
* \param output The buffer holding the output data. This must point to a |
* writable buffer of length \p length Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/** |
* \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption |
* operation. |
* |
* \note Due to the nature of CFB mode, you should use the same |
* key for both encryption and decryption. In particular, calls |
* to this function should be preceded by a key-schedule via |
* mbedtls_camellia_setkey_enc() regardless of whether \p mode |
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the function same function again on the following |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If on the other hand you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* \param ctx The CAMELLIA context to use. This must be initialized |
* and bound to a key. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. |
* \param length The length of the input data \p input. Any value is allowed. |
* \param iv_off The current offset in the IV. This must be smaller |
* than \c 16 Bytes. It is updated after this call to allow |
* the aforementioned streaming usage. |
* \param iv The initialization vector. This must be a read/write buffer |
* of length \c 16 Bytes. It is updated after this call to |
* allow the aforementioned streaming usage. |
* \param input The buffer holding the input data. This must be a readable |
* buffer of size \p length Bytes. |
* \param output The buffer to hold the output data. This must be a writable |
* buffer of length \p length Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/** |
* \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation. |
* |
* *note Due to the nature of CTR mode, you should use the same |
* key for both encryption and decryption. In particular, calls |
* to this function should be preceded by a key-schedule via |
* mbedtls_camellia_setkey_enc() regardless of whether \p mode |
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. |
* |
* \warning You must never reuse a nonce value with the same key. Doing so |
* would void the encryption for the two messages encrypted with |
* the same nonce and key. |
* |
* There are two common strategies for managing nonces with CTR: |
* |
* 1. You can handle everything as a single message processed over |
* successive calls to this function. In that case, you want to |
* set \p nonce_counter and \p nc_off to 0 for the first call, and |
* then preserve the values of \p nonce_counter, \p nc_off and \p |
* stream_block across calls to this function as they will be |
* updated by this function. |
* |
* With this strategy, you must not encrypt more than 2**128 |
* blocks of data with the same key. |
* |
* 2. You can encrypt separate messages by dividing the \p |
* nonce_counter buffer in two areas: the first one used for a |
* per-message nonce, handled by yourself, and the second one |
* updated by this function internally. |
* |
* For example, you might reserve the first \c 12 Bytes for the |
* per-message nonce, and the last \c 4 Bytes for internal use. |
* In that case, before calling this function on a new message you |
* need to set the first \c 12 Bytes of \p nonce_counter to your |
* chosen nonce value, the last four to \c 0, and \p nc_off to \c 0 |
* (which will cause \p stream_block to be ignored). That way, you |
* can encrypt at most \c 2**96 messages of up to \c 2**32 blocks |
* each with the same key. |
* |
* The per-message nonce (or information sufficient to reconstruct |
* it) needs to be communicated with the ciphertext and must be |
* unique. The recommended way to ensure uniqueness is to use a |
* message counter. An alternative is to generate random nonces, |
* but this limits the number of messages that can be securely |
* encrypted: for example, with 96-bit random nonces, you should |
* not encrypt more than 2**32 messages with the same key. |
* |
* Note that for both stategies, sizes are measured in blocks and |
* that a CAMELLIA block is \c 16 Bytes. |
* |
* \warning Upon return, \p stream_block contains sensitive data. Its |
* content must not be written to insecure storage and should be |
* securely discarded as soon as it's no longer needed. |
* |
* \param ctx The CAMELLIA context to use. This must be initialized |
* and bound to a key. |
* \param length The length of the input data \p input in Bytes. |
* Any value is allowed. |
* \param nc_off The offset in the current \p stream_block (for resuming |
* within current cipher stream). The offset pointer to |
* should be \c 0 at the start of a stream. It is updated |
* at the end of this call. |
* \param nonce_counter The 128-bit nonce and counter. This must be a read/write |
* buffer of length \c 16 Bytes. |
* \param stream_block The saved stream-block for resuming. This must be a |
* read/write buffer of length \c 16 Bytes. |
* \param input The input data stream. This must be a readable buffer of |
* size \p length Bytes. |
* \param output The output data stream. This must be a writable buffer |
* of size \p length Bytes. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[16], |
unsigned char stream_block[16], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_camellia_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* camellia.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ccm.h |
---|
0,0 → 1,312 |
/** |
* \file ccm.h |
* |
* \brief This file provides an API for the CCM authenticated encryption |
* mode for block ciphers. |
* |
* CCM combines Counter mode encryption with CBC-MAC authentication |
* for 128-bit block ciphers. |
* |
* Input to CCM includes the following elements: |
* <ul><li>Payload - data that is both authenticated and encrypted.</li> |
* <li>Associated data (Adata) - data that is authenticated but not |
* encrypted, For example, a header.</li> |
* <li>Nonce - A unique value that is assigned to the payload and the |
* associated data.</li></ul> |
* |
* Definition of CCM: |
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf |
* RFC 3610 "Counter with CBC-MAC (CCM)" |
* |
* Related: |
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption" |
* |
* Definition of CCM*: |
* IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks |
* Integer representation is fixed most-significant-octet-first order and |
* the representation of octets is most-significant-bit-first order. This is |
* consistent with RFC 3610. |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CCM_H |
#define MBEDTLS_CCM_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "cipher.h" |
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */ |
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ |
/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_CCM_ALT) |
// Regular implementation |
// |
/** |
* \brief The CCM context-type definition. The CCM context is passed |
* to the APIs called. |
*/ |
typedef struct mbedtls_ccm_context |
{ |
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ |
} |
mbedtls_ccm_context; |
#else /* MBEDTLS_CCM_ALT */ |
#include "ccm_alt.h" |
#endif /* MBEDTLS_CCM_ALT */ |
/** |
* \brief This function initializes the specified CCM context, |
* to make references valid, and prepare the context |
* for mbedtls_ccm_setkey() or mbedtls_ccm_free(). |
* |
* \param ctx The CCM context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); |
/** |
* \brief This function initializes the CCM context set in the |
* \p ctx parameter and sets the encryption key. |
* |
* \param ctx The CCM context to initialize. This must be an initialized |
* context. |
* \param cipher The 128-bit block cipher to use. |
* \param key The encryption key. This must not be \c NULL. |
* \param keybits The key size in bits. This must be acceptable by the cipher. |
* |
* \return \c 0 on success. |
* \return A CCM or cipher-specific error code on failure. |
*/ |
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, |
mbedtls_cipher_id_t cipher, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief This function releases and clears the specified CCM context |
* and underlying cipher sub-context. |
* |
* \param ctx The CCM context to clear. If this is \c NULL, the function |
* has no effect. Otherwise, this must be initialized. |
*/ |
void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); |
/** |
* \brief This function encrypts a buffer using CCM. |
* |
* \note The tag is written to a separate buffer. To concatenate |
* the \p tag with the \p output, as done in <em>RFC-3610: |
* Counter with CBC-MAC (CCM)</em>, use |
* \p tag = \p output + \p length, and make sure that the |
* output buffer is at least \p length + \p tag_len wide. |
* |
* \param ctx The CCM context to use for encryption. This must be |
* initialized and bound to a key. |
* \param length The length of the input data in Bytes. |
* \param iv The initialization vector (nonce). This must be a readable |
* buffer of at least \p iv_len Bytes. |
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, |
* or 13. The length L of the message length field is |
* 15 - \p iv_len. |
* \param add The additional data field. If \p add_len is greater than |
* zero, \p add must be a readable buffer of at least that |
* length. |
* \param add_len The length of additional data in Bytes. |
* This must be less than `2^16 - 2^8`. |
* \param input The buffer holding the input data. If \p length is greater |
* than zero, \p input must be a readable buffer of at least |
* that length. |
* \param output The buffer holding the output data. If \p length is greater |
* than zero, \p output must be a writable buffer of at least |
* that length. |
* \param tag The buffer holding the authentication field. This must be a |
* readable buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the authentication field to generate in Bytes: |
* 4, 6, 8, 10, 12, 14 or 16. |
* |
* \return \c 0 on success. |
* \return A CCM or cipher-specific error code on failure. |
*/ |
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
unsigned char *tag, size_t tag_len ); |
/** |
* \brief This function encrypts a buffer using CCM*. |
* |
* \note The tag is written to a separate buffer. To concatenate |
* the \p tag with the \p output, as done in <em>RFC-3610: |
* Counter with CBC-MAC (CCM)</em>, use |
* \p tag = \p output + \p length, and make sure that the |
* output buffer is at least \p length + \p tag_len wide. |
* |
* \note When using this function in a variable tag length context, |
* the tag length has to be encoded into the \p iv passed to |
* this function. |
* |
* \param ctx The CCM context to use for encryption. This must be |
* initialized and bound to a key. |
* \param length The length of the input data in Bytes. |
* \param iv The initialization vector (nonce). This must be a readable |
* buffer of at least \p iv_len Bytes. |
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, |
* or 13. The length L of the message length field is |
* 15 - \p iv_len. |
* \param add The additional data field. This must be a readable buffer of |
* at least \p add_len Bytes. |
* \param add_len The length of additional data in Bytes. |
* This must be less than 2^16 - 2^8. |
* \param input The buffer holding the input data. If \p length is greater |
* than zero, \p input must be a readable buffer of at least |
* that length. |
* \param output The buffer holding the output data. If \p length is greater |
* than zero, \p output must be a writable buffer of at least |
* that length. |
* \param tag The buffer holding the authentication field. This must be a |
* readable buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the authentication field to generate in Bytes: |
* 0, 4, 6, 8, 10, 12, 14 or 16. |
* |
* \warning Passing \c 0 as \p tag_len means that the message is no |
* longer authenticated. |
* |
* \return \c 0 on success. |
* \return A CCM or cipher-specific error code on failure. |
*/ |
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
unsigned char *tag, size_t tag_len ); |
/** |
* \brief This function performs a CCM authenticated decryption of a |
* buffer. |
* |
* \param ctx The CCM context to use for decryption. This must be |
* initialized and bound to a key. |
* \param length The length of the input data in Bytes. |
* \param iv The initialization vector (nonce). This must be a readable |
* buffer of at least \p iv_len Bytes. |
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, |
* or 13. The length L of the message length field is |
* 15 - \p iv_len. |
* \param add The additional data field. This must be a readable buffer |
* of at least that \p add_len Bytes.. |
* \param add_len The length of additional data in Bytes. |
* This must be less than 2^16 - 2^8. |
* \param input The buffer holding the input data. If \p length is greater |
* than zero, \p input must be a readable buffer of at least |
* that length. |
* \param output The buffer holding the output data. If \p length is greater |
* than zero, \p output must be a writable buffer of at least |
* that length. |
* \param tag The buffer holding the authentication field. This must be a |
* readable buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the authentication field to generate in Bytes: |
* 4, 6, 8, 10, 12, 14 or 16. |
* |
* \return \c 0 on success. This indicates that the message is authentic. |
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. |
* \return A cipher-specific error code on calculation failure. |
*/ |
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
const unsigned char *tag, size_t tag_len ); |
/** |
* \brief This function performs a CCM* authenticated decryption of a |
* buffer. |
* |
* \note When using this function in a variable tag length context, |
* the tag length has to be decoded from \p iv and passed to |
* this function as \p tag_len. (\p tag needs to be adjusted |
* accordingly.) |
* |
* \param ctx The CCM context to use for decryption. This must be |
* initialized and bound to a key. |
* \param length The length of the input data in Bytes. |
* \param iv The initialization vector (nonce). This must be a readable |
* buffer of at least \p iv_len Bytes. |
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, |
* or 13. The length L of the message length field is |
* 15 - \p iv_len. |
* \param add The additional data field. This must be a readable buffer of |
* at least that \p add_len Bytes. |
* \param add_len The length of additional data in Bytes. |
* This must be less than 2^16 - 2^8. |
* \param input The buffer holding the input data. If \p length is greater |
* than zero, \p input must be a readable buffer of at least |
* that length. |
* \param output The buffer holding the output data. If \p length is greater |
* than zero, \p output must be a writable buffer of at least |
* that length. |
* \param tag The buffer holding the authentication field. This must be a |
* readable buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the authentication field in Bytes. |
* 0, 4, 6, 8, 10, 12, 14 or 16. |
* |
* \warning Passing \c 0 as \p tag_len means that the message is nos |
* longer authenticated. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. |
* \return A cipher-specific error code on calculation failure. |
*/ |
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
const unsigned char *tag, size_t tag_len ); |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
/** |
* \brief The CCM checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_ccm_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_CCM_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/certs.h |
---|
0,0 → 1,254 |
/** |
* \file certs.h |
* |
* \brief Sample certificates and DHM parameters for testing |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CERTS_H |
#define MBEDTLS_CERTS_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* List of all PEM-encoded CA certificates, terminated by NULL; |
* PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded |
* otherwise. */ |
extern const char * mbedtls_test_cas[]; |
extern const size_t mbedtls_test_cas_len[]; |
/* List of all DER-encoded CA certificates, terminated by NULL */ |
extern const unsigned char * mbedtls_test_cas_der[]; |
extern const size_t mbedtls_test_cas_der_len[]; |
#if defined(MBEDTLS_PEM_PARSE_C) |
/* Concatenation of all CA certificates in PEM format if available */ |
extern const char mbedtls_test_cas_pem[]; |
extern const size_t mbedtls_test_cas_pem_len; |
#endif /* MBEDTLS_PEM_PARSE_C */ |
/* |
* CA test certificates |
*/ |
extern const char mbedtls_test_ca_crt_ec_pem[]; |
extern const char mbedtls_test_ca_key_ec_pem[]; |
extern const char mbedtls_test_ca_pwd_ec_pem[]; |
extern const char mbedtls_test_ca_key_rsa_pem[]; |
extern const char mbedtls_test_ca_pwd_rsa_pem[]; |
extern const char mbedtls_test_ca_crt_rsa_sha1_pem[]; |
extern const char mbedtls_test_ca_crt_rsa_sha256_pem[]; |
extern const unsigned char mbedtls_test_ca_crt_ec_der[]; |
extern const unsigned char mbedtls_test_ca_key_ec_der[]; |
extern const unsigned char mbedtls_test_ca_key_rsa_der[]; |
extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[]; |
extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[]; |
extern const size_t mbedtls_test_ca_crt_ec_pem_len; |
extern const size_t mbedtls_test_ca_key_ec_pem_len; |
extern const size_t mbedtls_test_ca_pwd_ec_pem_len; |
extern const size_t mbedtls_test_ca_key_rsa_pem_len; |
extern const size_t mbedtls_test_ca_pwd_rsa_pem_len; |
extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len; |
extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len; |
extern const size_t mbedtls_test_ca_crt_ec_der_len; |
extern const size_t mbedtls_test_ca_key_ec_der_len; |
extern const size_t mbedtls_test_ca_pwd_ec_der_len; |
extern const size_t mbedtls_test_ca_key_rsa_der_len; |
extern const size_t mbedtls_test_ca_pwd_rsa_der_len; |
extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len; |
extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len; |
/* Config-dependent dispatch between PEM and DER encoding |
* (PEM if enabled, otherwise DER) */ |
extern const char mbedtls_test_ca_crt_ec[]; |
extern const char mbedtls_test_ca_key_ec[]; |
extern const char mbedtls_test_ca_pwd_ec[]; |
extern const char mbedtls_test_ca_key_rsa[]; |
extern const char mbedtls_test_ca_pwd_rsa[]; |
extern const char mbedtls_test_ca_crt_rsa_sha1[]; |
extern const char mbedtls_test_ca_crt_rsa_sha256[]; |
extern const size_t mbedtls_test_ca_crt_ec_len; |
extern const size_t mbedtls_test_ca_key_ec_len; |
extern const size_t mbedtls_test_ca_pwd_ec_len; |
extern const size_t mbedtls_test_ca_key_rsa_len; |
extern const size_t mbedtls_test_ca_pwd_rsa_len; |
extern const size_t mbedtls_test_ca_crt_rsa_sha1_len; |
extern const size_t mbedtls_test_ca_crt_rsa_sha256_len; |
/* Config-dependent dispatch between SHA-1 and SHA-256 |
* (SHA-256 if enabled, otherwise SHA-1) */ |
extern const char mbedtls_test_ca_crt_rsa[]; |
extern const size_t mbedtls_test_ca_crt_rsa_len; |
/* Config-dependent dispatch between EC and RSA |
* (RSA if enabled, otherwise EC) */ |
extern const char * mbedtls_test_ca_crt; |
extern const char * mbedtls_test_ca_key; |
extern const char * mbedtls_test_ca_pwd; |
extern const size_t mbedtls_test_ca_crt_len; |
extern const size_t mbedtls_test_ca_key_len; |
extern const size_t mbedtls_test_ca_pwd_len; |
/* |
* Server test certificates |
*/ |
extern const char mbedtls_test_srv_crt_ec_pem[]; |
extern const char mbedtls_test_srv_key_ec_pem[]; |
extern const char mbedtls_test_srv_pwd_ec_pem[]; |
extern const char mbedtls_test_srv_key_rsa_pem[]; |
extern const char mbedtls_test_srv_pwd_rsa_pem[]; |
extern const char mbedtls_test_srv_crt_rsa_sha1_pem[]; |
extern const char mbedtls_test_srv_crt_rsa_sha256_pem[]; |
extern const unsigned char mbedtls_test_srv_crt_ec_der[]; |
extern const unsigned char mbedtls_test_srv_key_ec_der[]; |
extern const unsigned char mbedtls_test_srv_key_rsa_der[]; |
extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[]; |
extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[]; |
extern const size_t mbedtls_test_srv_crt_ec_pem_len; |
extern const size_t mbedtls_test_srv_key_ec_pem_len; |
extern const size_t mbedtls_test_srv_pwd_ec_pem_len; |
extern const size_t mbedtls_test_srv_key_rsa_pem_len; |
extern const size_t mbedtls_test_srv_pwd_rsa_pem_len; |
extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len; |
extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len; |
extern const size_t mbedtls_test_srv_crt_ec_der_len; |
extern const size_t mbedtls_test_srv_key_ec_der_len; |
extern const size_t mbedtls_test_srv_pwd_ec_der_len; |
extern const size_t mbedtls_test_srv_key_rsa_der_len; |
extern const size_t mbedtls_test_srv_pwd_rsa_der_len; |
extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len; |
extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len; |
/* Config-dependent dispatch between PEM and DER encoding |
* (PEM if enabled, otherwise DER) */ |
extern const char mbedtls_test_srv_crt_ec[]; |
extern const char mbedtls_test_srv_key_ec[]; |
extern const char mbedtls_test_srv_pwd_ec[]; |
extern const char mbedtls_test_srv_key_rsa[]; |
extern const char mbedtls_test_srv_pwd_rsa[]; |
extern const char mbedtls_test_srv_crt_rsa_sha1[]; |
extern const char mbedtls_test_srv_crt_rsa_sha256[]; |
extern const size_t mbedtls_test_srv_crt_ec_len; |
extern const size_t mbedtls_test_srv_key_ec_len; |
extern const size_t mbedtls_test_srv_pwd_ec_len; |
extern const size_t mbedtls_test_srv_key_rsa_len; |
extern const size_t mbedtls_test_srv_pwd_rsa_len; |
extern const size_t mbedtls_test_srv_crt_rsa_sha1_len; |
extern const size_t mbedtls_test_srv_crt_rsa_sha256_len; |
/* Config-dependent dispatch between SHA-1 and SHA-256 |
* (SHA-256 if enabled, otherwise SHA-1) */ |
extern const char mbedtls_test_srv_crt_rsa[]; |
extern const size_t mbedtls_test_srv_crt_rsa_len; |
/* Config-dependent dispatch between EC and RSA |
* (RSA if enabled, otherwise EC) */ |
extern const char * mbedtls_test_srv_crt; |
extern const char * mbedtls_test_srv_key; |
extern const char * mbedtls_test_srv_pwd; |
extern const size_t mbedtls_test_srv_crt_len; |
extern const size_t mbedtls_test_srv_key_len; |
extern const size_t mbedtls_test_srv_pwd_len; |
/* |
* Client test certificates |
*/ |
extern const char mbedtls_test_cli_crt_ec_pem[]; |
extern const char mbedtls_test_cli_key_ec_pem[]; |
extern const char mbedtls_test_cli_pwd_ec_pem[]; |
extern const char mbedtls_test_cli_key_rsa_pem[]; |
extern const char mbedtls_test_cli_pwd_rsa_pem[]; |
extern const char mbedtls_test_cli_crt_rsa_pem[]; |
extern const unsigned char mbedtls_test_cli_crt_ec_der[]; |
extern const unsigned char mbedtls_test_cli_key_ec_der[]; |
extern const unsigned char mbedtls_test_cli_key_rsa_der[]; |
extern const unsigned char mbedtls_test_cli_crt_rsa_der[]; |
extern const size_t mbedtls_test_cli_crt_ec_pem_len; |
extern const size_t mbedtls_test_cli_key_ec_pem_len; |
extern const size_t mbedtls_test_cli_pwd_ec_pem_len; |
extern const size_t mbedtls_test_cli_key_rsa_pem_len; |
extern const size_t mbedtls_test_cli_pwd_rsa_pem_len; |
extern const size_t mbedtls_test_cli_crt_rsa_pem_len; |
extern const size_t mbedtls_test_cli_crt_ec_der_len; |
extern const size_t mbedtls_test_cli_key_ec_der_len; |
extern const size_t mbedtls_test_cli_key_rsa_der_len; |
extern const size_t mbedtls_test_cli_crt_rsa_der_len; |
/* Config-dependent dispatch between PEM and DER encoding |
* (PEM if enabled, otherwise DER) */ |
extern const char mbedtls_test_cli_crt_ec[]; |
extern const char mbedtls_test_cli_key_ec[]; |
extern const char mbedtls_test_cli_pwd_ec[]; |
extern const char mbedtls_test_cli_key_rsa[]; |
extern const char mbedtls_test_cli_pwd_rsa[]; |
extern const char mbedtls_test_cli_crt_rsa[]; |
extern const size_t mbedtls_test_cli_crt_ec_len; |
extern const size_t mbedtls_test_cli_key_ec_len; |
extern const size_t mbedtls_test_cli_pwd_ec_len; |
extern const size_t mbedtls_test_cli_key_rsa_len; |
extern const size_t mbedtls_test_cli_pwd_rsa_len; |
extern const size_t mbedtls_test_cli_crt_rsa_len; |
/* Config-dependent dispatch between EC and RSA |
* (RSA if enabled, otherwise EC) */ |
extern const char * mbedtls_test_cli_crt; |
extern const char * mbedtls_test_cli_key; |
extern const char * mbedtls_test_cli_pwd; |
extern const size_t mbedtls_test_cli_crt_len; |
extern const size_t mbedtls_test_cli_key_len; |
extern const size_t mbedtls_test_cli_pwd_len; |
#ifdef __cplusplus |
} |
#endif |
#endif /* certs.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/chacha20.h |
---|
0,0 → 1,228 |
/** |
* \file chacha20.h |
* |
* \brief This file contains ChaCha20 definitions and functions. |
* |
* ChaCha20 is a stream cipher that can encrypt and decrypt |
* information. ChaCha was created by Daniel Bernstein as a variant of |
* its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf |
* ChaCha20 is the variant with 20 rounds, that was also standardized |
* in RFC 7539. |
* |
* \author Daniel King <damaki.gh@gmail.com> |
*/ |
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CHACHA20_H |
#define MBEDTLS_CHACHA20_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stdint.h> |
#include <stddef.h> |
#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 /**< Invalid input parameter(s). */ |
/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be |
* used. */ |
#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */ |
/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED -0x0055 /**< Chacha20 hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_CHACHA20_ALT) |
typedef struct mbedtls_chacha20_context |
{ |
uint32_t state[16]; /*! The state (before round operations). */ |
uint8_t keystream8[64]; /*! Leftover keystream bytes. */ |
size_t keystream_bytes_used; /*! Number of keystream bytes already used. */ |
} |
mbedtls_chacha20_context; |
#else /* MBEDTLS_CHACHA20_ALT */ |
#include "chacha20_alt.h" |
#endif /* MBEDTLS_CHACHA20_ALT */ |
/** |
* \brief This function initializes the specified ChaCha20 context. |
* |
* It must be the first API called before using |
* the context. |
* |
* It is usually followed by calls to |
* \c mbedtls_chacha20_setkey() and |
* \c mbedtls_chacha20_starts(), then one or more calls to |
* to \c mbedtls_chacha20_update(), and finally to |
* \c mbedtls_chacha20_free(). |
* |
* \param ctx The ChaCha20 context to initialize. |
* This must not be \c NULL. |
*/ |
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ); |
/** |
* \brief This function releases and clears the specified |
* ChaCha20 context. |
* |
* \param ctx The ChaCha20 context to clear. This may be \c NULL, |
* in which case this function is a no-op. If it is not |
* \c NULL, it must point to an initialized context. |
* |
*/ |
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ); |
/** |
* \brief This function sets the encryption/decryption key. |
* |
* \note After using this function, you must also call |
* \c mbedtls_chacha20_starts() to set a nonce before you |
* start encrypting/decrypting data with |
* \c mbedtls_chacha_update(). |
* |
* \param ctx The ChaCha20 context to which the key should be bound. |
* It must be initialized. |
* \param key The encryption/decryption key. This must be \c 32 Bytes |
* in length. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL. |
*/ |
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, |
const unsigned char key[32] ); |
/** |
* \brief This function sets the nonce and initial counter value. |
* |
* \note A ChaCha20 context can be re-used with the same key by |
* calling this function to change the nonce. |
* |
* \warning You must never use the same nonce twice with the same key. |
* This would void any confidentiality guarantees for the |
* messages encrypted with the same nonce and key. |
* |
* \param ctx The ChaCha20 context to which the nonce should be bound. |
* It must be initialized and bound to a key. |
* \param nonce The nonce. This must be \c 12 Bytes in size. |
* \param counter The initial counter value. This is usually \c 0. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is |
* NULL. |
*/ |
int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, |
const unsigned char nonce[12], |
uint32_t counter ); |
/** |
* \brief This function encrypts or decrypts data. |
* |
* Since ChaCha20 is a stream cipher, the same operation is |
* used for encrypting and decrypting data. |
* |
* \note The \p input and \p output pointers must either be equal or |
* point to non-overlapping buffers. |
* |
* \note \c mbedtls_chacha20_setkey() and |
* \c mbedtls_chacha20_starts() must be called at least once |
* to setup the context before this function can be called. |
* |
* \note This function can be called multiple times in a row in |
* order to encrypt of decrypt data piecewise with the same |
* key and nonce. |
* |
* \param ctx The ChaCha20 context to use for encryption or decryption. |
* It must be initialized and bound to a key and nonce. |
* \param size The length of the input data in Bytes. |
* \param input The buffer holding the input data. |
* This pointer can be \c NULL if `size == 0`. |
* \param output The buffer holding the output data. |
* This must be able to hold \p size Bytes. |
* This pointer can be \c NULL if `size == 0`. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, |
size_t size, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function encrypts or decrypts data with ChaCha20 and |
* the given key and nonce. |
* |
* Since ChaCha20 is a stream cipher, the same operation is |
* used for encrypting and decrypting data. |
* |
* \warning You must never use the same (key, nonce) pair more than |
* once. This would void any confidentiality guarantees for |
* the messages encrypted with the same nonce and key. |
* |
* \note The \p input and \p output pointers must either be equal or |
* point to non-overlapping buffers. |
* |
* \param key The encryption/decryption key. |
* This must be \c 32 Bytes in length. |
* \param nonce The nonce. This must be \c 12 Bytes in size. |
* \param counter The initial counter value. This is usually \c 0. |
* \param size The length of the input data in Bytes. |
* \param input The buffer holding the input data. |
* This pointer can be \c NULL if `size == 0`. |
* \param output The buffer holding the output data. |
* This must be able to hold \p size Bytes. |
* This pointer can be \c NULL if `size == 0`. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_chacha20_crypt( const unsigned char key[32], |
const unsigned char nonce[12], |
uint32_t counter, |
size_t size, |
const unsigned char* input, |
unsigned char* output ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The ChaCha20 checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_chacha20_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_CHACHA20_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/chachapoly.h |
---|
0,0 → 1,360 |
/** |
* \file chachapoly.h |
* |
* \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and |
* functions. |
* |
* ChaCha20-Poly1305 is an algorithm for Authenticated Encryption |
* with Associated Data (AEAD) that can be used to encrypt and |
* authenticate data. It is based on ChaCha20 and Poly1305 by Daniel |
* Bernstein and was standardized in RFC 7539. |
* |
* \author Daniel King <damaki.gh@gmail.com> |
*/ |
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CHACHAPOLY_H |
#define MBEDTLS_CHACHAPOLY_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
/* for shared error codes */ |
#include "poly1305.h" |
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */ |
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
typedef enum |
{ |
MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */ |
MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */ |
} |
mbedtls_chachapoly_mode_t; |
#if !defined(MBEDTLS_CHACHAPOLY_ALT) |
#include "chacha20.h" |
typedef struct mbedtls_chachapoly_context |
{ |
mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */ |
mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */ |
uint64_t aad_len; /**< The length (bytes) of the Additional Authenticated Data. */ |
uint64_t ciphertext_len; /**< The length (bytes) of the ciphertext. */ |
int state; /**< The current state of the context. */ |
mbedtls_chachapoly_mode_t mode; /**< Cipher mode (encrypt or decrypt). */ |
} |
mbedtls_chachapoly_context; |
#else /* !MBEDTLS_CHACHAPOLY_ALT */ |
#include "chachapoly_alt.h" |
#endif /* !MBEDTLS_CHACHAPOLY_ALT */ |
/** |
* \brief This function initializes the specified ChaCha20-Poly1305 context. |
* |
* It must be the first API called before using |
* the context. It must be followed by a call to |
* \c mbedtls_chachapoly_setkey() before any operation can be |
* done, and to \c mbedtls_chachapoly_free() once all |
* operations with that context have been finished. |
* |
* In order to encrypt or decrypt full messages at once, for |
* each message you should make a single call to |
* \c mbedtls_chachapoly_crypt_and_tag() or |
* \c mbedtls_chachapoly_auth_decrypt(). |
* |
* In order to encrypt messages piecewise, for each |
* message you should make a call to |
* \c mbedtls_chachapoly_starts(), then 0 or more calls to |
* \c mbedtls_chachapoly_update_aad(), then 0 or more calls to |
* \c mbedtls_chachapoly_update(), then one call to |
* \c mbedtls_chachapoly_finish(). |
* |
* \warning Decryption with the piecewise API is discouraged! Always |
* use \c mbedtls_chachapoly_auth_decrypt() when possible! |
* |
* If however this is not possible because the data is too |
* large to fit in memory, you need to: |
* |
* - call \c mbedtls_chachapoly_starts() and (if needed) |
* \c mbedtls_chachapoly_update_aad() as above, |
* - call \c mbedtls_chachapoly_update() multiple times and |
* ensure its output (the plaintext) is NOT used in any other |
* way than placing it in temporary storage at this point, |
* - call \c mbedtls_chachapoly_finish() to compute the |
* authentication tag and compared it in constant time to the |
* tag received with the ciphertext. |
* |
* If the tags are not equal, you must immediately discard |
* all previous outputs of \c mbedtls_chachapoly_update(), |
* otherwise you can now safely use the plaintext. |
* |
* \param ctx The ChachaPoly context to initialize. Must not be \c NULL. |
*/ |
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ); |
/** |
* \brief This function releases and clears the specified |
* ChaCha20-Poly1305 context. |
* |
* \param ctx The ChachaPoly context to clear. This may be \c NULL, in which |
* case this function is a no-op. |
*/ |
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); |
/** |
* \brief This function sets the ChaCha20-Poly1305 |
* symmetric encryption key. |
* |
* \param ctx The ChaCha20-Poly1305 context to which the key should be |
* bound. This must be initialized. |
* \param key The \c 256 Bit (\c 32 Bytes) key. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, |
const unsigned char key[32] ); |
/** |
* \brief This function starts a ChaCha20-Poly1305 encryption or |
* decryption operation. |
* |
* \warning You must never use the same nonce twice with the same key. |
* This would void any confidentiality and authenticity |
* guarantees for the messages encrypted with the same nonce |
* and key. |
* |
* \note If the context is being used for AAD only (no data to |
* encrypt or decrypt) then \p mode can be set to any value. |
* |
* \warning Decryption with the piecewise API is discouraged, see the |
* warning on \c mbedtls_chachapoly_init(). |
* |
* \param ctx The ChaCha20-Poly1305 context. This must be initialized |
* and bound to a key. |
* \param nonce The nonce/IV to use for the message. |
* This must be a redable buffer of length \c 12 Bytes. |
* \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or |
* #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning). |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, |
const unsigned char nonce[12], |
mbedtls_chachapoly_mode_t mode ); |
/** |
* \brief This function feeds additional data to be authenticated |
* into an ongoing ChaCha20-Poly1305 operation. |
* |
* The Additional Authenticated Data (AAD), also called |
* Associated Data (AD) is only authenticated but not |
* encrypted nor included in the encrypted output. It is |
* usually transmitted separately from the ciphertext or |
* computed locally by each party. |
* |
* \note This function is called before data is encrypted/decrypted. |
* I.e. call this function to process the AAD before calling |
* \c mbedtls_chachapoly_update(). |
* |
* You may call this function multiple times to process |
* an arbitrary amount of AAD. It is permitted to call |
* this function 0 times, if no AAD is used. |
* |
* This function cannot be called any more if data has |
* been processed by \c mbedtls_chachapoly_update(), |
* or if the context has been finished. |
* |
* \warning Decryption with the piecewise API is discouraged, see the |
* warning on \c mbedtls_chachapoly_init(). |
* |
* \param ctx The ChaCha20-Poly1305 context. This must be initialized |
* and bound to a key. |
* \param aad_len The length in Bytes of the AAD. The length has no |
* restrictions. |
* \param aad Buffer containing the AAD. |
* This pointer can be \c NULL if `aad_len == 0`. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA |
* if \p ctx or \p aad are NULL. |
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE |
* if the operations has not been started or has been |
* finished, or if the AAD has been finished. |
*/ |
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, |
const unsigned char *aad, |
size_t aad_len ); |
/** |
* \brief Thus function feeds data to be encrypted or decrypted |
* into an on-going ChaCha20-Poly1305 |
* operation. |
* |
* The direction (encryption or decryption) depends on the |
* mode that was given when calling |
* \c mbedtls_chachapoly_starts(). |
* |
* You may call this function multiple times to process |
* an arbitrary amount of data. It is permitted to call |
* this function 0 times, if no data is to be encrypted |
* or decrypted. |
* |
* \warning Decryption with the piecewise API is discouraged, see the |
* warning on \c mbedtls_chachapoly_init(). |
* |
* \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. |
* \param len The length (in bytes) of the data to encrypt or decrypt. |
* \param input The buffer containing the data to encrypt or decrypt. |
* This pointer can be \c NULL if `len == 0`. |
* \param output The buffer to where the encrypted or decrypted data is |
* written. This must be able to hold \p len bytes. |
* This pointer can be \c NULL if `len == 0`. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE |
* if the operation has not been started or has been |
* finished. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, |
size_t len, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function finished the ChaCha20-Poly1305 operation and |
* generates the MAC (authentication tag). |
* |
* \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. |
* \param mac The buffer to where the 128-bit (16 bytes) MAC is written. |
* |
* \warning Decryption with the piecewise API is discouraged, see the |
* warning on \c mbedtls_chachapoly_init(). |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE |
* if the operation has not been started or has been |
* finished. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, |
unsigned char mac[16] ); |
/** |
* \brief This function performs a complete ChaCha20-Poly1305 |
* authenticated encryption with the previously-set key. |
* |
* \note Before using this function, you must set the key with |
* \c mbedtls_chachapoly_setkey(). |
* |
* \warning You must never use the same nonce twice with the same key. |
* This would void any confidentiality and authenticity |
* guarantees for the messages encrypted with the same nonce |
* and key. |
* |
* \param ctx The ChaCha20-Poly1305 context to use (holds the key). |
* This must be initialized. |
* \param length The length (in bytes) of the data to encrypt or decrypt. |
* \param nonce The 96-bit (12 bytes) nonce/IV to use. |
* \param aad The buffer containing the additional authenticated |
* data (AAD). This pointer can be \c NULL if `aad_len == 0`. |
* \param aad_len The length (in bytes) of the AAD data to process. |
* \param input The buffer containing the data to encrypt or decrypt. |
* This pointer can be \c NULL if `ilen == 0`. |
* \param output The buffer to where the encrypted or decrypted data |
* is written. This pointer can be \c NULL if `ilen == 0`. |
* \param tag The buffer to where the computed 128-bit (16 bytes) MAC |
* is written. This must not be \c NULL. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, |
size_t length, |
const unsigned char nonce[12], |
const unsigned char *aad, |
size_t aad_len, |
const unsigned char *input, |
unsigned char *output, |
unsigned char tag[16] ); |
/** |
* \brief This function performs a complete ChaCha20-Poly1305 |
* authenticated decryption with the previously-set key. |
* |
* \note Before using this function, you must set the key with |
* \c mbedtls_chachapoly_setkey(). |
* |
* \param ctx The ChaCha20-Poly1305 context to use (holds the key). |
* \param length The length (in Bytes) of the data to decrypt. |
* \param nonce The \c 96 Bit (\c 12 bytes) nonce/IV to use. |
* \param aad The buffer containing the additional authenticated data (AAD). |
* This pointer can be \c NULL if `aad_len == 0`. |
* \param aad_len The length (in bytes) of the AAD data to process. |
* \param tag The buffer holding the authentication tag. |
* This must be a readable buffer of length \c 16 Bytes. |
* \param input The buffer containing the data to decrypt. |
* This pointer can be \c NULL if `ilen == 0`. |
* \param output The buffer to where the decrypted data is written. |
* This pointer can be \c NULL if `ilen == 0`. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED |
* if the data was not authentic. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, |
size_t length, |
const unsigned char nonce[12], |
const unsigned char *aad, |
size_t aad_len, |
const unsigned char tag[16], |
const unsigned char *input, |
unsigned char *output ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The ChaCha20-Poly1305 checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_chachapoly_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_CHACHAPOLY_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/check_config.h |
---|
0,0 → 1,731 |
/** |
* \file check_config.h |
* |
* \brief Consistency checks for configuration options |
*/ |
/* |
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* It is recommended to include this file from your config.h |
* in order to catch dependency issues early. |
*/ |
#ifndef MBEDTLS_CHECK_CONFIG_H |
#define MBEDTLS_CHECK_CONFIG_H |
/* |
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our |
* target platforms, so not an issue, but let's just be extra sure. |
*/ |
#include <limits.h> |
#if CHAR_BIT != 8 |
#error "mbed TLS requires a platform with 8-bit chars" |
#endif |
#if defined(_WIN32) |
#if !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_C is required on Windows" |
#endif |
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as |
* it would confuse config.pl. */ |
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ |
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) |
#define MBEDTLS_PLATFORM_SNPRINTF_ALT |
#endif |
#endif /* _WIN32 */ |
#if defined(TARGET_LIKE_MBED) && \ |
( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) ) |
#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS" |
#endif |
#if defined(MBEDTLS_DEPRECATED_WARNING) && \ |
!defined(__GNUC__) && !defined(__clang__) |
#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" |
#endif |
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) |
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" |
#endif |
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) |
#error "MBEDTLS_AESNI_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) |
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) |
#error "MBEDTLS_DHM_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_CMAC_C) && \ |
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) |
#error "MBEDTLS_CMAC_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_NIST_KW_C) && \ |
( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) |
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) |
#error "MBEDTLS_ECDH_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECDSA_C) && \ |
( !defined(MBEDTLS_ECP_C) || \ |
!defined(MBEDTLS_ASN1_PARSE_C) || \ |
!defined(MBEDTLS_ASN1_WRITE_C) ) |
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECJPAKE_C) && \ |
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) |
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) && \ |
( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \ |
defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \ |
defined(MBEDTLS_ECDSA_SIGN_ALT) || \ |
defined(MBEDTLS_ECDSA_VERIFY_ALT) || \ |
defined(MBEDTLS_ECDSA_GENKEY_ALT) || \ |
defined(MBEDTLS_ECP_INTERNAL_ALT) || \ |
defined(MBEDTLS_ECP_ALT) ) |
#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation" |
#endif |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) |
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ |
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \ |
!defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) ) |
#error "MBEDTLS_ECP_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C) |
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites" |
#endif |
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ |
!defined(MBEDTLS_SHA256_C)) |
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ |
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) |
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" |
#endif |
#if defined(MBEDTLS_ENTROPY_C) && \ |
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ |
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) |
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" |
#endif |
#if defined(MBEDTLS_ENTROPY_C) && \ |
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) |
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ |
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) |
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ |
( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ |
defined(MBEDTLS_HAVEGE_C) ) |
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" |
#endif |
#if defined(MBEDTLS_GCM_C) && ( \ |
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) |
#error "MBEDTLS_GCM_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) |
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) |
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) |
#error "MBEDTLS_HKDF_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) |
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ |
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) |
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ |
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) |
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) |
#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ |
!defined(MBEDTLS_ECDH_C) |
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ |
( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ |
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) |
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ |
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ |
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) |
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ |
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ |
!defined(MBEDTLS_X509_CRT_PARSE_C) ) |
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ |
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ |
!defined(MBEDTLS_PKCS1_V15) ) |
#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ |
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ |
!defined(MBEDTLS_PKCS1_V15) ) |
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ |
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ |
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) |
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ |
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) |
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) |
#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequesites" |
#endif |
#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) |
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequesites" |
#endif |
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) |
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) |
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) |
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PK_C) && \ |
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) |
#error "MBEDTLS_PK_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) |
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) |
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) |
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ |
defined(MBEDTLS_PLATFORM_EXIT_ALT) ) |
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ |
( !defined(MBEDTLS_PLATFORM_C) ||\ |
!defined(MBEDTLS_HAVE_TIME) ) |
#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ |
( !defined(MBEDTLS_PLATFORM_C) ||\ |
!defined(MBEDTLS_HAVE_TIME) ) |
#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ |
( !defined(MBEDTLS_PLATFORM_C) ||\ |
!defined(MBEDTLS_HAVE_TIME) ) |
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ |
defined(MBEDTLS_PLATFORM_TIME_ALT) ) |
#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ |
defined(MBEDTLS_PLATFORM_TIME_ALT) ) |
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ |
defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) |
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ |
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) |
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ |
defined(MBEDTLS_PLATFORM_STD_FREE) |
#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) |
#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" |
#endif |
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ |
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) |
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ |
defined(MBEDTLS_PLATFORM_STD_CALLOC) |
#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) |
#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" |
#endif |
#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ |
defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) |
#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) |
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ |
defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) |
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ |
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) |
#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) |
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) |
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) |
#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ |
!defined(MBEDTLS_PLATFORM_EXIT_ALT) |
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ |
( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ |
!defined(MBEDTLS_HAVE_TIME) ) |
#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ |
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT) |
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ |
!defined(MBEDTLS_PLATFORM_PRINTF_ALT) |
#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ |
!defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) |
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ |
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) |
#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ |
!defined(MBEDTLS_ENTROPY_NV_SEED) |
#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ |
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT) |
#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ |
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT) |
#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ |
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) |
#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ |
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ |
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) |
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" |
#endif |
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ |
!defined(MBEDTLS_OID_C) ) |
#error "MBEDTLS_RSA_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ |
!defined(MBEDTLS_PKCS1_V15) ) |
#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" |
#endif |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ |
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) |
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ |
!defined(MBEDTLS_SHA1_C) ) |
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ |
!defined(MBEDTLS_SHA1_C) ) |
#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ |
!defined(MBEDTLS_SHA1_C) ) |
#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ |
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) |
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" |
#endif |
#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ |
!(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) |
#error "One or more versions of the TLS protocol are enabled " \ |
"but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) |
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ |
!defined(MBEDTLS_MD_C) ) |
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) |
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_2)) |
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) |
#error "Illegal protocol selection" |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) |
#error "Illegal protocol selection" |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_1))) |
#error "Illegal protocol selection" |
#endif |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) |
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ |
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) |
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ |
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) |
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ |
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) |
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites" |
#endif |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ |
!defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" |
#endif |
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) |
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ |
!defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) |
#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ |
!defined(MBEDTLS_X509_CRT_PARSE_C) |
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_THREADING_PTHREAD) |
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) |
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" |
#endif |
#define MBEDTLS_THREADING_IMPL |
#endif |
#if defined(MBEDTLS_THREADING_ALT) |
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) |
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" |
#endif |
#define MBEDTLS_THREADING_IMPL |
#endif |
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) |
#error "MBEDTLS_THREADING_C defined, single threading implementation required" |
#endif |
#undef MBEDTLS_THREADING_IMPL |
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) |
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ |
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ |
!defined(MBEDTLS_PK_PARSE_C) ) |
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ |
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ |
!defined(MBEDTLS_PK_WRITE_C) ) |
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C) |
#error "MBEDTLS_CERTS_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) |
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) |
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) |
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) |
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) |
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" |
#endif |
#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) |
#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" |
#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ |
#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \ |
defined(MBEDTLS_HAVE_ASM) |
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously" |
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */ |
/* |
* Avoid warning from -pedantic. This is a convenient place for this |
* workaround since this is included by every single file before the |
* #if defined(MBEDTLS_xxx_C) that results in empty translation units. |
*/ |
typedef int mbedtls_iso_c_forbids_empty_translation_units; |
#endif /* MBEDTLS_CHECK_CONFIG_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/cipher.h |
---|
0,0 → 1,874 |
/** |
* \file cipher.h |
* |
* \brief This file contains an abstraction interface for use with the cipher |
* primitives provided by the library. It provides a common interface to all of |
* the available cipher operations. |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CIPHER_H |
#define MBEDTLS_CIPHER_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include "platform_util.h" |
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) |
#define MBEDTLS_CIPHER_MODE_AEAD |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#define MBEDTLS_CIPHER_MODE_WITH_PADDING |
#endif |
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ |
defined(MBEDTLS_CHACHA20_C) |
#define MBEDTLS_CIPHER_MODE_STREAM |
#endif |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ |
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */ |
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ |
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ |
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ |
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ |
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */ |
/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */ |
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ |
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Supported cipher types. |
* |
* \warning RC4 and DES are considered weak ciphers and their use |
* constitutes a security risk. Arm recommends considering stronger |
* ciphers instead. |
*/ |
typedef enum { |
MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ |
MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ |
MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ |
MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */ |
MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */ |
MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ |
MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ |
MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ |
MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ |
MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ |
} mbedtls_cipher_id_t; |
/** |
* \brief Supported {cipher type, cipher mode} pairs. |
* |
* \warning RC4 and DES are considered weak ciphers and their use |
* constitutes a security risk. Arm recommends considering stronger |
* ciphers instead. |
*/ |
typedef enum { |
MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ |
MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ |
MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ |
MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ |
MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ |
MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ |
MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ |
MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ |
MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ |
MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ |
MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ |
MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ |
MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ |
MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ |
MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ |
MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ |
MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ |
MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ |
MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ |
MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ |
MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ |
MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ |
MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ |
MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ |
MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ |
MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ |
MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ |
MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ |
MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */ |
MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */ |
MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */ |
MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */ |
MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */ |
MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */ |
MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */ |
MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */ |
MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */ |
MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */ |
MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */ |
MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ |
MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ |
MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ |
MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ |
MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ |
MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ |
MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ |
MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ |
MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ |
MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ |
MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ |
MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ |
MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ |
MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ |
MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ |
MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ |
MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ |
MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ |
MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ |
MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ |
MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ |
MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ |
MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ |
MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ |
MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ |
MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ |
MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ |
MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ |
MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ |
MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ |
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ |
} mbedtls_cipher_type_t; |
/** Supported cipher modes. */ |
typedef enum { |
MBEDTLS_MODE_NONE = 0, /**< None. */ |
MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ |
MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ |
MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ |
MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ |
MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ |
MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ |
MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ |
MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ |
MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ |
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ |
} mbedtls_cipher_mode_t; |
/** Supported cipher padding types. */ |
typedef enum { |
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ |
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ |
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ |
MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ |
MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ |
} mbedtls_cipher_padding_t; |
/** Type of operation. */ |
typedef enum { |
MBEDTLS_OPERATION_NONE = -1, |
MBEDTLS_DECRYPT = 0, |
MBEDTLS_ENCRYPT, |
} mbedtls_operation_t; |
enum { |
/** Undefined key length. */ |
MBEDTLS_KEY_LENGTH_NONE = 0, |
/** Key length, in bits (including parity), for DES keys. */ |
MBEDTLS_KEY_LENGTH_DES = 64, |
/** Key length in bits, including parity, for DES in two-key EDE. */ |
MBEDTLS_KEY_LENGTH_DES_EDE = 128, |
/** Key length in bits, including parity, for DES in three-key EDE. */ |
MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, |
}; |
/** Maximum length of any IV, in Bytes. */ |
#define MBEDTLS_MAX_IV_LENGTH 16 |
/** Maximum block size of any cipher, in Bytes. */ |
#define MBEDTLS_MAX_BLOCK_LENGTH 16 |
/** |
* Base cipher information (opaque struct). |
*/ |
typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; |
/** |
* CMAC context (opaque struct). |
*/ |
typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; |
/** |
* Cipher information. Allows calling cipher functions |
* in a generic way. |
*/ |
typedef struct mbedtls_cipher_info_t |
{ |
/** Full cipher identifier. For example, |
* MBEDTLS_CIPHER_AES_256_CBC. |
*/ |
mbedtls_cipher_type_t type; |
/** The cipher mode. For example, MBEDTLS_MODE_CBC. */ |
mbedtls_cipher_mode_t mode; |
/** The cipher key length, in bits. This is the |
* default length for variable sized ciphers. |
* Includes parity bits for ciphers like DES. |
*/ |
unsigned int key_bitlen; |
/** Name of the cipher. */ |
const char * name; |
/** IV or nonce size, in Bytes. |
* For ciphers that accept variable IV sizes, |
* this is the recommended size. |
*/ |
unsigned int iv_size; |
/** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and |
* MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the |
* cipher supports variable IV or variable key sizes, respectively. |
*/ |
int flags; |
/** The block size, in Bytes. */ |
unsigned int block_size; |
/** Struct for base cipher information and functions. */ |
const mbedtls_cipher_base_t *base; |
} mbedtls_cipher_info_t; |
/** |
* Generic cipher context. |
*/ |
typedef struct mbedtls_cipher_context_t |
{ |
/** Information about the associated cipher. */ |
const mbedtls_cipher_info_t *cipher_info; |
/** Key length to use. */ |
int key_bitlen; |
/** Operation that the key of the context has been |
* initialized for. |
*/ |
mbedtls_operation_t operation; |
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) |
/** Padding functions to use, if relevant for |
* the specific cipher mode. |
*/ |
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); |
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); |
#endif |
/** Buffer for input that has not been processed yet. */ |
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; |
/** Number of Bytes that have not been processed yet. */ |
size_t unprocessed_len; |
/** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number |
* for XTS-mode. */ |
unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; |
/** IV size in Bytes, for ciphers with variable-length IVs. */ |
size_t iv_size; |
/** The cipher-specific context. */ |
void *cipher_ctx; |
#if defined(MBEDTLS_CMAC_C) |
/** CMAC-specific context. */ |
mbedtls_cmac_context_t *cmac_ctx; |
#endif |
} mbedtls_cipher_context_t; |
/** |
* \brief This function retrieves the list of ciphers supported by the generic |
* cipher module. |
* |
* \return A statically-allocated array of ciphers. The last entry |
* is zero. |
*/ |
const int *mbedtls_cipher_list( void ); |
/** |
* \brief This function retrieves the cipher-information |
* structure associated with the given cipher name. |
* |
* \param cipher_name Name of the cipher to search for. This must not be |
* \c NULL. |
* |
* \return The cipher information structure associated with the |
* given \p cipher_name. |
* \return \c NULL if the associated cipher information is not found. |
*/ |
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); |
/** |
* \brief This function retrieves the cipher-information |
* structure associated with the given cipher type. |
* |
* \param cipher_type Type of the cipher to search for. |
* |
* \return The cipher information structure associated with the |
* given \p cipher_type. |
* \return \c NULL if the associated cipher information is not found. |
*/ |
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); |
/** |
* \brief This function retrieves the cipher-information |
* structure associated with the given cipher ID, |
* key size and mode. |
* |
* \param cipher_id The ID of the cipher to search for. For example, |
* #MBEDTLS_CIPHER_ID_AES. |
* \param key_bitlen The length of the key in bits. |
* \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. |
* |
* \return The cipher information structure associated with the |
* given \p cipher_id. |
* \return \c NULL if the associated cipher information is not found. |
*/ |
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, |
int key_bitlen, |
const mbedtls_cipher_mode_t mode ); |
/** |
* \brief This function initializes a \p cipher_context as NONE. |
* |
* \param ctx The context to be initialized. This must not be \c NULL. |
*/ |
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); |
/** |
* \brief This function frees and clears the cipher-specific |
* context of \p ctx. Freeing \p ctx itself remains the |
* responsibility of the caller. |
* |
* \param ctx The context to be freed. If this is \c NULL, the |
* function has no effect, otherwise this must point to an |
* initialized context. |
*/ |
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); |
/** |
* \brief This function initializes and fills the cipher-context |
* structure with the appropriate values. It also clears |
* the structure. |
* |
* \param ctx The context to initialize. This must be initialized. |
* \param cipher_info The cipher to use. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the |
* cipher-specific context fails. |
* |
* \internal Currently, the function also clears the structure. |
* In future versions, the caller will be required to call |
* mbedtls_cipher_init() on the structure first. |
*/ |
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, |
const mbedtls_cipher_info_t *cipher_info ); |
/** |
* \brief This function returns the block size of the given cipher. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The block size of the underlying cipher. |
* \return \c 0 if \p ctx has not been initialized. |
*/ |
static inline unsigned int mbedtls_cipher_get_block_size( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); |
if( ctx->cipher_info == NULL ) |
return 0; |
return ctx->cipher_info->block_size; |
} |
/** |
* \brief This function returns the mode of operation for |
* the cipher. For example, MBEDTLS_MODE_CBC. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The mode of operation. |
* \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. |
*/ |
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE ); |
if( ctx->cipher_info == NULL ) |
return MBEDTLS_MODE_NONE; |
return ctx->cipher_info->mode; |
} |
/** |
* \brief This function returns the size of the IV or nonce |
* of the cipher, in Bytes. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The recommended IV size if no IV has been set. |
* \return \c 0 for ciphers not using an IV or a nonce. |
* \return The actual size if an IV has been set. |
*/ |
static inline int mbedtls_cipher_get_iv_size( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); |
if( ctx->cipher_info == NULL ) |
return 0; |
if( ctx->iv_size != 0 ) |
return (int) ctx->iv_size; |
return (int) ctx->cipher_info->iv_size; |
} |
/** |
* \brief This function returns the type of the given cipher. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The type of the cipher. |
* \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. |
*/ |
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( |
ctx != NULL, MBEDTLS_CIPHER_NONE ); |
if( ctx->cipher_info == NULL ) |
return MBEDTLS_CIPHER_NONE; |
return ctx->cipher_info->type; |
} |
/** |
* \brief This function returns the name of the given cipher |
* as a string. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The name of the cipher. |
* \return NULL if \p ctx has not been not initialized. |
*/ |
static inline const char *mbedtls_cipher_get_name( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); |
if( ctx->cipher_info == NULL ) |
return 0; |
return ctx->cipher_info->name; |
} |
/** |
* \brief This function returns the key length of the cipher. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The key length of the cipher in bits. |
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been |
* initialized. |
*/ |
static inline int mbedtls_cipher_get_key_bitlen( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( |
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE ); |
if( ctx->cipher_info == NULL ) |
return MBEDTLS_KEY_LENGTH_NONE; |
return (int) ctx->cipher_info->key_bitlen; |
} |
/** |
* \brief This function returns the operation of the given cipher. |
* |
* \param ctx The context of the cipher. This must be initialized. |
* |
* \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. |
* \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. |
*/ |
static inline mbedtls_operation_t mbedtls_cipher_get_operation( |
const mbedtls_cipher_context_t *ctx ) |
{ |
MBEDTLS_INTERNAL_VALIDATE_RET( |
ctx != NULL, MBEDTLS_OPERATION_NONE ); |
if( ctx->cipher_info == NULL ) |
return MBEDTLS_OPERATION_NONE; |
return ctx->operation; |
} |
/** |
* \brief This function sets the key to use with the given context. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* bound to a cipher information structure. |
* \param key The key to use. This must be a readable buffer of at |
* least \p key_bitlen Bits. |
* \param key_bitlen The key length to use, in Bits. |
* \param operation The operation that the key will be used for: |
* #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, |
const unsigned char *key, |
int key_bitlen, |
const mbedtls_operation_t operation ); |
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) |
/** |
* \brief This function sets the padding mode, for cipher modes |
* that use padding. |
* |
* The default passing mode is PKCS7 padding. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* bound to a cipher information structure. |
* \param mode The padding mode. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE |
* if the selected padding mode is not supported. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode |
* does not support padding. |
*/ |
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, |
mbedtls_cipher_padding_t mode ); |
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ |
/** |
* \brief This function sets the initialization vector (IV) |
* or nonce. |
* |
* \note Some ciphers do not use IVs nor nonce. For these |
* ciphers, this function has no effect. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* bound to a cipher information structure. |
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This |
* must be a readable buffer of at least \p iv_len Bytes. |
* \param iv_len The IV length for ciphers with variable-size IV. |
* This parameter is discarded by ciphers with fixed-size IV. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
*/ |
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, |
size_t iv_len ); |
/** |
* \brief This function resets the cipher state. |
* |
* \param ctx The generic cipher context. This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
*/ |
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); |
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) |
/** |
* \brief This function adds additional data for AEAD ciphers. |
* Currently supported with GCM and ChaCha20+Poly1305. |
* This must be called exactly once, after |
* mbedtls_cipher_reset(). |
* |
* \param ctx The generic cipher context. This must be initialized. |
* \param ad The additional data to use. This must be a readable |
* buffer of at least \p ad_len Bytes. |
* \param ad_len the Length of \p ad Bytes. |
* |
* \return \c 0 on success. |
* \return A specific error code on failure. |
*/ |
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, |
const unsigned char *ad, size_t ad_len ); |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ |
/** |
* \brief The generic cipher update function. It encrypts or |
* decrypts using the given cipher context. Writes as |
* many block-sized blocks of data as possible to output. |
* Any data that cannot be written immediately is either |
* added to the next block, or flushed when |
* mbedtls_cipher_finish() is called. |
* Exception: For MBEDTLS_MODE_ECB, expects a single block |
* in size. For example, 16 Bytes for AES. |
* |
* \note If the underlying cipher is used in GCM mode, all calls |
* to this function, except for the last one before |
* mbedtls_cipher_finish(), must have \p ilen as a |
* multiple of the block size of the cipher. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* bound to a key. |
* \param input The buffer holding the input data. This must be a |
* readable buffer of at least \p ilen Bytes. |
* \param ilen The length of the input data. |
* \param output The buffer for the output data. This must be able to |
* hold at least `ilen + block_size`. This must not be the |
* same buffer as \p input. |
* \param olen The length of the output data, to be updated with the |
* actual number of Bytes written. This must not be |
* \c NULL. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an |
* unsupported mode for a cipher. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, |
size_t ilen, unsigned char *output, size_t *olen ); |
/** |
* \brief The generic cipher finalization function. If data still |
* needs to be flushed from an incomplete block, the data |
* contained in it is padded to the size of |
* the last block, and written to the \p output buffer. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* bound to a key. |
* \param output The buffer to write data to. This needs to be a writable |
* buffer of at least \p block_size Bytes. |
* \param olen The length of the data written to the \p output buffer. |
* This may not be \c NULL. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption |
* expecting a full block but not receiving one. |
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding |
* while decrypting. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, |
unsigned char *output, size_t *olen ); |
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) |
/** |
* \brief This function writes a tag for AEAD ciphers. |
* Currently supported with GCM and ChaCha20+Poly1305. |
* This must be called after mbedtls_cipher_finish(). |
* |
* \param ctx The generic cipher context. This must be initialized, |
* bound to a key, and have just completed a cipher |
* operation through mbedtls_cipher_finish() the tag for |
* which should be written. |
* \param tag The buffer to write the tag to. This must be a writable |
* buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the tag to write. |
* |
* \return \c 0 on success. |
* \return A specific error code on failure. |
*/ |
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, |
unsigned char *tag, size_t tag_len ); |
/** |
* \brief This function checks the tag for AEAD ciphers. |
* Currently supported with GCM and ChaCha20+Poly1305. |
* This must be called after mbedtls_cipher_finish(). |
* |
* \param ctx The generic cipher context. This must be initialized. |
* \param tag The buffer holding the tag. This must be a readable |
* buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the tag to check. |
* |
* \return \c 0 on success. |
* \return A specific error code on failure. |
*/ |
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, |
const unsigned char *tag, size_t tag_len ); |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ |
/** |
* \brief The generic all-in-one encryption/decryption function, |
* for all ciphers except AEAD constructs. |
* |
* \param ctx The generic cipher context. This must be initialized. |
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. |
* This must be a readable buffer of at least \p iv_len |
* Bytes. |
* \param iv_len The IV length for ciphers with variable-size IV. |
* This parameter is discarded by ciphers with fixed-size |
* IV. |
* \param input The buffer holding the input data. This must be a |
* readable buffer of at least \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* \param output The buffer for the output data. This must be able to |
* hold at least `ilen + block_size`. This must not be the |
* same buffer as \p input. |
* \param olen The length of the output data, to be updated with the |
* actual number of Bytes written. This must not be |
* \c NULL. |
* |
* \note Some ciphers do not use IVs nor nonce. For these |
* ciphers, use \p iv = NULL and \p iv_len = 0. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption |
* expecting a full block but not receiving one. |
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding |
* while decrypting. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen ); |
#if defined(MBEDTLS_CIPHER_MODE_AEAD) |
/** |
* \brief The generic autenticated encryption (AEAD) function. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* bound to a key. |
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. |
* This must be a readable buffer of at least \p iv_len |
* Bytes. |
* \param iv_len The IV length for ciphers with variable-size IV. |
* This parameter is discarded by ciphers with fixed-size IV. |
* \param ad The additional data to authenticate. This must be a |
* readable buffer of at least \p ad_len Bytes. |
* \param ad_len The length of \p ad. |
* \param input The buffer holding the input data. This must be a |
* readable buffer of at least \p ilen Bytes. |
* \param ilen The length of the input data. |
* \param output The buffer for the output data. This must be able to |
* hold at least \p ilen Bytes. |
* \param olen The length of the output data, to be updated with the |
* actual number of Bytes written. This must not be |
* \c NULL. |
* \param tag The buffer for the authentication tag. This must be a |
* writable buffer of at least \p tag_len Bytes. |
* \param tag_len The desired length of the authentication tag. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *ad, size_t ad_len, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, |
unsigned char *tag, size_t tag_len ); |
/** |
* \brief The generic autenticated decryption (AEAD) function. |
* |
* \note If the data is not authentic, then the output buffer |
* is zeroed out to prevent the unauthentic plaintext being |
* used, making this interface safer. |
* |
* \param ctx The generic cipher context. This must be initialized and |
* and bound to a key. |
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. |
* This must be a readable buffer of at least \p iv_len |
* Bytes. |
* \param iv_len The IV length for ciphers with variable-size IV. |
* This parameter is discarded by ciphers with fixed-size IV. |
* \param ad The additional data to be authenticated. This must be a |
* readable buffer of at least \p ad_len Bytes. |
* \param ad_len The length of \p ad. |
* \param input The buffer holding the input data. This must be a |
* readable buffer of at least \p ilen Bytes. |
* \param ilen The length of the input data. |
* \param output The buffer for the output data. |
* This must be able to hold at least \p ilen Bytes. |
* \param olen The length of the output data, to be updated with the |
* actual number of Bytes written. This must not be |
* \c NULL. |
* \param tag The buffer holding the authentication tag. This must be |
* a readable buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the authentication tag. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on |
* parameter-verification failure. |
* \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *ad, size_t ad_len, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, |
const unsigned char *tag, size_t tag_len ); |
#endif /* MBEDTLS_CIPHER_MODE_AEAD */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_CIPHER_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/cipher_internal.h |
---|
0,0 → 1,127 |
/** |
* \file cipher_internal.h |
* |
* \brief Cipher wrappers. |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CIPHER_WRAP_H |
#define MBEDTLS_CIPHER_WRAP_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "cipher.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Base cipher information. The non-mode specific functions and values. |
*/ |
struct mbedtls_cipher_base_t |
{ |
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ |
mbedtls_cipher_id_t cipher; |
/** Encrypt using ECB */ |
int (*ecb_func)( void *ctx, mbedtls_operation_t mode, |
const unsigned char *input, unsigned char *output ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** Encrypt using CBC */ |
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, |
unsigned char *iv, const unsigned char *input, |
unsigned char *output ); |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/** Encrypt using CFB (Full length) */ |
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, |
unsigned char *iv, const unsigned char *input, |
unsigned char *output ); |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
/** Encrypt using OFB (Full length) */ |
int (*ofb_func)( void *ctx, size_t length, size_t *iv_off, |
unsigned char *iv, |
const unsigned char *input, |
unsigned char *output ); |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/** Encrypt using CTR */ |
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, |
unsigned char *nonce_counter, unsigned char *stream_block, |
const unsigned char *input, unsigned char *output ); |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/** Encrypt or decrypt using XTS. */ |
int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, |
const unsigned char data_unit[16], |
const unsigned char *input, unsigned char *output ); |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
/** Encrypt using STREAM */ |
int (*stream_func)( void *ctx, size_t length, |
const unsigned char *input, unsigned char *output ); |
#endif |
/** Set key for encryption purposes */ |
int (*setkey_enc_func)( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ); |
/** Set key for decryption purposes */ |
int (*setkey_dec_func)( void *ctx, const unsigned char *key, |
unsigned int key_bitlen); |
/** Allocate a new context */ |
void * (*ctx_alloc_func)( void ); |
/** Free the given context */ |
void (*ctx_free_func)( void *ctx ); |
}; |
typedef struct |
{ |
mbedtls_cipher_type_t type; |
const mbedtls_cipher_info_t *info; |
} mbedtls_cipher_definition_t; |
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; |
extern int mbedtls_cipher_supported[]; |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_CIPHER_WRAP_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/cmac.h |
---|
0,0 → 1,215 |
/** |
* \file cmac.h |
* |
* \brief This file contains CMAC definitions and functions. |
* |
* The Cipher-based Message Authentication Code (CMAC) Mode for |
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>. |
*/ |
/* |
* Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CMAC_H |
#define MBEDTLS_CMAC_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "cipher.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */ |
#define MBEDTLS_AES_BLOCK_SIZE 16 |
#define MBEDTLS_DES3_BLOCK_SIZE 8 |
#if defined(MBEDTLS_AES_C) |
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */ |
#else |
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */ |
#endif |
#if !defined(MBEDTLS_CMAC_ALT) |
/** |
* The CMAC context structure. |
*/ |
struct mbedtls_cmac_context_t |
{ |
/** The internal state of the CMAC algorithm. */ |
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
/** Unprocessed data - either data that was not block aligned and is still |
* pending processing, or the final block. */ |
unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
/** The length of data pending processing. */ |
size_t unprocessed_len; |
}; |
#else /* !MBEDTLS_CMAC_ALT */ |
#include "cmac_alt.h" |
#endif /* !MBEDTLS_CMAC_ALT */ |
/** |
* \brief This function sets the CMAC key, and prepares to authenticate |
* the input data. |
* Must be called with an initialized cipher context. |
* |
* \param ctx The cipher context used for the CMAC operation, initialized |
* as one of the following types: MBEDTLS_CIPHER_AES_128_ECB, |
* MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB, |
* or MBEDTLS_CIPHER_DES_EDE3_ECB. |
* \param key The CMAC key. |
* \param keybits The length of the CMAC key in bits. |
* Must be supported by the cipher. |
* |
* \return \c 0 on success. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, |
const unsigned char *key, size_t keybits ); |
/** |
* \brief This function feeds an input buffer into an ongoing CMAC |
* computation. |
* |
* It is called between mbedtls_cipher_cmac_starts() or |
* mbedtls_cipher_cmac_reset(), and mbedtls_cipher_cmac_finish(). |
* Can be called repeatedly. |
* |
* \param ctx The cipher context used for the CMAC operation. |
* \param input The buffer holding the input data. |
* \param ilen The length of the input data. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA |
* if parameter verification fails. |
*/ |
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, |
const unsigned char *input, size_t ilen ); |
/** |
* \brief This function finishes the CMAC operation, and writes |
* the result to the output buffer. |
* |
* It is called after mbedtls_cipher_cmac_update(). |
* It can be followed by mbedtls_cipher_cmac_reset() and |
* mbedtls_cipher_cmac_update(), or mbedtls_cipher_free(). |
* |
* \param ctx The cipher context used for the CMAC operation. |
* \param output The output buffer for the CMAC checksum result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA |
* if parameter verification fails. |
*/ |
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, |
unsigned char *output ); |
/** |
* \brief This function prepares the authentication of another |
* message with the same key as the previous CMAC |
* operation. |
* |
* It is called after mbedtls_cipher_cmac_finish() |
* and before mbedtls_cipher_cmac_update(). |
* |
* \param ctx The cipher context used for the CMAC operation. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA |
* if parameter verification fails. |
*/ |
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ); |
/** |
* \brief This function calculates the full generic CMAC |
* on the input buffer with the provided key. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The CMAC result is calculated as |
* output = generic CMAC(cmac key, input buffer). |
* |
* |
* \param cipher_info The cipher information. |
* \param key The CMAC key. |
* \param keylen The length of the CMAC key in bits. |
* \param input The buffer holding the input data. |
* \param ilen The length of the input data. |
* \param output The buffer for the generic CMAC result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA |
* if parameter verification fails. |
*/ |
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, |
const unsigned char *key, size_t keylen, |
const unsigned char *input, size_t ilen, |
unsigned char *output ); |
#if defined(MBEDTLS_AES_C) |
/** |
* \brief This function implements the AES-CMAC-PRF-128 pseudorandom |
* function, as defined in |
* <em>RFC-4615: The Advanced Encryption Standard-Cipher-based |
* Message Authentication Code-Pseudo-Random Function-128 |
* (AES-CMAC-PRF-128) Algorithm for the Internet Key |
* Exchange Protocol (IKE).</em> |
* |
* \param key The key to use. |
* \param key_len The key length in Bytes. |
* \param input The buffer holding the input data. |
* \param in_len The length of the input data in Bytes. |
* \param output The buffer holding the generated 16 Bytes of |
* pseudorandom output. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len, |
const unsigned char *input, size_t in_len, |
unsigned char output[16] ); |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) ) |
/** |
* \brief The CMAC checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_cmac_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_CMAC_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/compat-1.3.h |
---|
0,0 → 1,2533 |
/** |
* \file compat-1.3.h |
* |
* \brief Compatibility definitions for using mbed TLS with client code written |
* for the PolarSSL naming conventions. |
* |
* \deprecated Use the new names directly instead |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#warning "Including compat-1.3.h is deprecated" |
#endif |
#ifndef MBEDTLS_COMPAT13_H |
#define MBEDTLS_COMPAT13_H |
/* |
* config.h options |
*/ |
#if defined MBEDTLS_AESNI_C |
#define POLARSSL_AESNI_C MBEDTLS_AESNI_C |
#endif |
#if defined MBEDTLS_AES_ALT |
#define POLARSSL_AES_ALT MBEDTLS_AES_ALT |
#endif |
#if defined MBEDTLS_AES_C |
#define POLARSSL_AES_C MBEDTLS_AES_C |
#endif |
#if defined MBEDTLS_AES_ROM_TABLES |
#define POLARSSL_AES_ROM_TABLES MBEDTLS_AES_ROM_TABLES |
#endif |
#if defined MBEDTLS_ARC4_ALT |
#define POLARSSL_ARC4_ALT MBEDTLS_ARC4_ALT |
#endif |
#if defined MBEDTLS_ARC4_C |
#define POLARSSL_ARC4_C MBEDTLS_ARC4_C |
#endif |
#if defined MBEDTLS_ASN1_PARSE_C |
#define POLARSSL_ASN1_PARSE_C MBEDTLS_ASN1_PARSE_C |
#endif |
#if defined MBEDTLS_ASN1_WRITE_C |
#define POLARSSL_ASN1_WRITE_C MBEDTLS_ASN1_WRITE_C |
#endif |
#if defined MBEDTLS_BASE64_C |
#define POLARSSL_BASE64_C MBEDTLS_BASE64_C |
#endif |
#if defined MBEDTLS_BIGNUM_C |
#define POLARSSL_BIGNUM_C MBEDTLS_BIGNUM_C |
#endif |
#if defined MBEDTLS_BLOWFISH_ALT |
#define POLARSSL_BLOWFISH_ALT MBEDTLS_BLOWFISH_ALT |
#endif |
#if defined MBEDTLS_BLOWFISH_C |
#define POLARSSL_BLOWFISH_C MBEDTLS_BLOWFISH_C |
#endif |
#if defined MBEDTLS_CAMELLIA_ALT |
#define POLARSSL_CAMELLIA_ALT MBEDTLS_CAMELLIA_ALT |
#endif |
#if defined MBEDTLS_CAMELLIA_C |
#define POLARSSL_CAMELLIA_C MBEDTLS_CAMELLIA_C |
#endif |
#if defined MBEDTLS_CAMELLIA_SMALL_MEMORY |
#define POLARSSL_CAMELLIA_SMALL_MEMORY MBEDTLS_CAMELLIA_SMALL_MEMORY |
#endif |
#if defined MBEDTLS_CCM_C |
#define POLARSSL_CCM_C MBEDTLS_CCM_C |
#endif |
#if defined MBEDTLS_CERTS_C |
#define POLARSSL_CERTS_C MBEDTLS_CERTS_C |
#endif |
#if defined MBEDTLS_CIPHER_C |
#define POLARSSL_CIPHER_C MBEDTLS_CIPHER_C |
#endif |
#if defined MBEDTLS_CIPHER_MODE_CBC |
#define POLARSSL_CIPHER_MODE_CBC MBEDTLS_CIPHER_MODE_CBC |
#endif |
#if defined MBEDTLS_CIPHER_MODE_CFB |
#define POLARSSL_CIPHER_MODE_CFB MBEDTLS_CIPHER_MODE_CFB |
#endif |
#if defined MBEDTLS_CIPHER_MODE_CTR |
#define POLARSSL_CIPHER_MODE_CTR MBEDTLS_CIPHER_MODE_CTR |
#endif |
#if defined MBEDTLS_CIPHER_NULL_CIPHER |
#define POLARSSL_CIPHER_NULL_CIPHER MBEDTLS_CIPHER_NULL_CIPHER |
#endif |
#if defined MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS |
#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS |
#endif |
#if defined MBEDTLS_CIPHER_PADDING_PKCS7 |
#define POLARSSL_CIPHER_PADDING_PKCS7 MBEDTLS_CIPHER_PADDING_PKCS7 |
#endif |
#if defined MBEDTLS_CIPHER_PADDING_ZEROS |
#define POLARSSL_CIPHER_PADDING_ZEROS MBEDTLS_CIPHER_PADDING_ZEROS |
#endif |
#if defined MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN |
#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN |
#endif |
#if defined MBEDTLS_CTR_DRBG_C |
#define POLARSSL_CTR_DRBG_C MBEDTLS_CTR_DRBG_C |
#endif |
#if defined MBEDTLS_DEBUG_C |
#define POLARSSL_DEBUG_C MBEDTLS_DEBUG_C |
#endif |
#if defined MBEDTLS_DEPRECATED_REMOVED |
#define POLARSSL_DEPRECATED_REMOVED MBEDTLS_DEPRECATED_REMOVED |
#endif |
#if defined MBEDTLS_DEPRECATED_WARNING |
#define POLARSSL_DEPRECATED_WARNING MBEDTLS_DEPRECATED_WARNING |
#endif |
#if defined MBEDTLS_DES_ALT |
#define POLARSSL_DES_ALT MBEDTLS_DES_ALT |
#endif |
#if defined MBEDTLS_DES_C |
#define POLARSSL_DES_C MBEDTLS_DES_C |
#endif |
#if defined MBEDTLS_DHM_C |
#define POLARSSL_DHM_C MBEDTLS_DHM_C |
#endif |
#if defined MBEDTLS_ECDH_C |
#define POLARSSL_ECDH_C MBEDTLS_ECDH_C |
#endif |
#if defined MBEDTLS_ECDSA_C |
#define POLARSSL_ECDSA_C MBEDTLS_ECDSA_C |
#endif |
#if defined MBEDTLS_ECDSA_DETERMINISTIC |
#define POLARSSL_ECDSA_DETERMINISTIC MBEDTLS_ECDSA_DETERMINISTIC |
#endif |
#if defined MBEDTLS_ECP_C |
#define POLARSSL_ECP_C MBEDTLS_ECP_C |
#endif |
#if defined MBEDTLS_ECP_DP_BP256R1_ENABLED |
#define POLARSSL_ECP_DP_BP256R1_ENABLED MBEDTLS_ECP_DP_BP256R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_BP384R1_ENABLED |
#define POLARSSL_ECP_DP_BP384R1_ENABLED MBEDTLS_ECP_DP_BP384R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_BP512R1_ENABLED |
#define POLARSSL_ECP_DP_BP512R1_ENABLED MBEDTLS_ECP_DP_BP512R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_CURVE25519_ENABLED |
#define POLARSSL_ECP_DP_M255_ENABLED MBEDTLS_ECP_DP_CURVE25519_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP192K1_ENABLED |
#define POLARSSL_ECP_DP_SECP192K1_ENABLED MBEDTLS_ECP_DP_SECP192K1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP192R1_ENABLED |
#define POLARSSL_ECP_DP_SECP192R1_ENABLED MBEDTLS_ECP_DP_SECP192R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP224K1_ENABLED |
#define POLARSSL_ECP_DP_SECP224K1_ENABLED MBEDTLS_ECP_DP_SECP224K1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP224R1_ENABLED |
#define POLARSSL_ECP_DP_SECP224R1_ENABLED MBEDTLS_ECP_DP_SECP224R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP256K1_ENABLED |
#define POLARSSL_ECP_DP_SECP256K1_ENABLED MBEDTLS_ECP_DP_SECP256K1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP256R1_ENABLED |
#define POLARSSL_ECP_DP_SECP256R1_ENABLED MBEDTLS_ECP_DP_SECP256R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP384R1_ENABLED |
#define POLARSSL_ECP_DP_SECP384R1_ENABLED MBEDTLS_ECP_DP_SECP384R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_DP_SECP521R1_ENABLED |
#define POLARSSL_ECP_DP_SECP521R1_ENABLED MBEDTLS_ECP_DP_SECP521R1_ENABLED |
#endif |
#if defined MBEDTLS_ECP_FIXED_POINT_OPTIM |
#define POLARSSL_ECP_FIXED_POINT_OPTIM MBEDTLS_ECP_FIXED_POINT_OPTIM |
#endif |
#if defined MBEDTLS_ECP_MAX_BITS |
#define POLARSSL_ECP_MAX_BITS MBEDTLS_ECP_MAX_BITS |
#endif |
#if defined MBEDTLS_ECP_NIST_OPTIM |
#define POLARSSL_ECP_NIST_OPTIM MBEDTLS_ECP_NIST_OPTIM |
#endif |
#if defined MBEDTLS_ECP_WINDOW_SIZE |
#define POLARSSL_ECP_WINDOW_SIZE MBEDTLS_ECP_WINDOW_SIZE |
#endif |
#if defined MBEDTLS_ENABLE_WEAK_CIPHERSUITES |
#define POLARSSL_ENABLE_WEAK_CIPHERSUITES MBEDTLS_ENABLE_WEAK_CIPHERSUITES |
#endif |
#if defined MBEDTLS_ENTROPY_C |
#define POLARSSL_ENTROPY_C MBEDTLS_ENTROPY_C |
#endif |
#if defined MBEDTLS_ENTROPY_FORCE_SHA256 |
#define POLARSSL_ENTROPY_FORCE_SHA256 MBEDTLS_ENTROPY_FORCE_SHA256 |
#endif |
#if defined MBEDTLS_ERROR_C |
#define POLARSSL_ERROR_C MBEDTLS_ERROR_C |
#endif |
#if defined MBEDTLS_ERROR_STRERROR_DUMMY |
#define POLARSSL_ERROR_STRERROR_DUMMY MBEDTLS_ERROR_STRERROR_DUMMY |
#endif |
#if defined MBEDTLS_FS_IO |
#define POLARSSL_FS_IO MBEDTLS_FS_IO |
#endif |
#if defined MBEDTLS_GCM_C |
#define POLARSSL_GCM_C MBEDTLS_GCM_C |
#endif |
#if defined MBEDTLS_GENPRIME |
#define POLARSSL_GENPRIME MBEDTLS_GENPRIME |
#endif |
#if defined MBEDTLS_HAVEGE_C |
#define POLARSSL_HAVEGE_C MBEDTLS_HAVEGE_C |
#endif |
#if defined MBEDTLS_HAVE_ASM |
#define POLARSSL_HAVE_ASM MBEDTLS_HAVE_ASM |
#endif |
#if defined MBEDTLS_HAVE_SSE2 |
#define POLARSSL_HAVE_SSE2 MBEDTLS_HAVE_SSE2 |
#endif |
#if defined MBEDTLS_HAVE_TIME |
#define POLARSSL_HAVE_TIME MBEDTLS_HAVE_TIME |
#endif |
#if defined MBEDTLS_HMAC_DRBG_C |
#define POLARSSL_HMAC_DRBG_C MBEDTLS_HMAC_DRBG_C |
#endif |
#if defined MBEDTLS_HMAC_DRBG_MAX_INPUT |
#define POLARSSL_HMAC_DRBG_MAX_INPUT MBEDTLS_HMAC_DRBG_MAX_INPUT |
#endif |
#if defined MBEDTLS_HMAC_DRBG_MAX_REQUEST |
#define POLARSSL_HMAC_DRBG_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST |
#endif |
#if defined MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT |
#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT |
#endif |
#if defined MBEDTLS_HMAC_DRBG_RESEED_INTERVAL |
#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL MBEDTLS_HMAC_DRBG_RESEED_INTERVAL |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED |
#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED |
#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED |
#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED |
#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED |
#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED |
#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED |
#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_PSK_ENABLED |
#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_PSK_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_RSA_ENABLED |
#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_ENABLED |
#endif |
#if defined MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED |
#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED |
#endif |
#if defined MBEDTLS_MD2_ALT |
#define POLARSSL_MD2_ALT MBEDTLS_MD2_ALT |
#endif |
#if defined MBEDTLS_MD2_C |
#define POLARSSL_MD2_C MBEDTLS_MD2_C |
#endif |
#if defined MBEDTLS_MD2_PROCESS_ALT |
#define POLARSSL_MD2_PROCESS_ALT MBEDTLS_MD2_PROCESS_ALT |
#endif |
#if defined MBEDTLS_MD4_ALT |
#define POLARSSL_MD4_ALT MBEDTLS_MD4_ALT |
#endif |
#if defined MBEDTLS_MD4_C |
#define POLARSSL_MD4_C MBEDTLS_MD4_C |
#endif |
#if defined MBEDTLS_MD4_PROCESS_ALT |
#define POLARSSL_MD4_PROCESS_ALT MBEDTLS_MD4_PROCESS_ALT |
#endif |
#if defined MBEDTLS_MD5_ALT |
#define POLARSSL_MD5_ALT MBEDTLS_MD5_ALT |
#endif |
#if defined MBEDTLS_MD5_C |
#define POLARSSL_MD5_C MBEDTLS_MD5_C |
#endif |
#if defined MBEDTLS_MD5_PROCESS_ALT |
#define POLARSSL_MD5_PROCESS_ALT MBEDTLS_MD5_PROCESS_ALT |
#endif |
#if defined MBEDTLS_MD_C |
#define POLARSSL_MD_C MBEDTLS_MD_C |
#endif |
#if defined MBEDTLS_MEMORY_ALIGN_MULTIPLE |
#define POLARSSL_MEMORY_ALIGN_MULTIPLE MBEDTLS_MEMORY_ALIGN_MULTIPLE |
#endif |
#if defined MBEDTLS_MEMORY_BACKTRACE |
#define POLARSSL_MEMORY_BACKTRACE MBEDTLS_MEMORY_BACKTRACE |
#endif |
#if defined MBEDTLS_MEMORY_BUFFER_ALLOC_C |
#define POLARSSL_MEMORY_BUFFER_ALLOC_C MBEDTLS_MEMORY_BUFFER_ALLOC_C |
#endif |
#if defined MBEDTLS_MEMORY_DEBUG |
#define POLARSSL_MEMORY_DEBUG MBEDTLS_MEMORY_DEBUG |
#endif |
#if defined MBEDTLS_MPI_MAX_SIZE |
#define POLARSSL_MPI_MAX_SIZE MBEDTLS_MPI_MAX_SIZE |
#endif |
#if defined MBEDTLS_MPI_WINDOW_SIZE |
#define POLARSSL_MPI_WINDOW_SIZE MBEDTLS_MPI_WINDOW_SIZE |
#endif |
#if defined MBEDTLS_NET_C |
#define POLARSSL_NET_C MBEDTLS_NET_C |
#endif |
#if defined MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES |
#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES |
#endif |
#if defined MBEDTLS_NO_PLATFORM_ENTROPY |
#define POLARSSL_NO_PLATFORM_ENTROPY MBEDTLS_NO_PLATFORM_ENTROPY |
#endif |
#if defined MBEDTLS_OID_C |
#define POLARSSL_OID_C MBEDTLS_OID_C |
#endif |
#if defined MBEDTLS_PADLOCK_C |
#define POLARSSL_PADLOCK_C MBEDTLS_PADLOCK_C |
#endif |
#if defined MBEDTLS_PEM_PARSE_C |
#define POLARSSL_PEM_PARSE_C MBEDTLS_PEM_PARSE_C |
#endif |
#if defined MBEDTLS_PEM_WRITE_C |
#define POLARSSL_PEM_WRITE_C MBEDTLS_PEM_WRITE_C |
#endif |
#if defined MBEDTLS_PKCS11_C |
#define POLARSSL_PKCS11_C MBEDTLS_PKCS11_C |
#endif |
#if defined MBEDTLS_PKCS12_C |
#define POLARSSL_PKCS12_C MBEDTLS_PKCS12_C |
#endif |
#if defined MBEDTLS_PKCS1_V15 |
#define POLARSSL_PKCS1_V15 MBEDTLS_PKCS1_V15 |
#endif |
#if defined MBEDTLS_PKCS1_V21 |
#define POLARSSL_PKCS1_V21 MBEDTLS_PKCS1_V21 |
#endif |
#if defined MBEDTLS_PKCS5_C |
#define POLARSSL_PKCS5_C MBEDTLS_PKCS5_C |
#endif |
#if defined MBEDTLS_PK_C |
#define POLARSSL_PK_C MBEDTLS_PK_C |
#endif |
#if defined MBEDTLS_PK_PARSE_C |
#define POLARSSL_PK_PARSE_C MBEDTLS_PK_PARSE_C |
#endif |
#if defined MBEDTLS_PK_PARSE_EC_EXTENDED |
#define POLARSSL_PK_PARSE_EC_EXTENDED MBEDTLS_PK_PARSE_EC_EXTENDED |
#endif |
#if defined MBEDTLS_PK_RSA_ALT_SUPPORT |
#define POLARSSL_PK_RSA_ALT_SUPPORT MBEDTLS_PK_RSA_ALT_SUPPORT |
#endif |
#if defined MBEDTLS_PK_WRITE_C |
#define POLARSSL_PK_WRITE_C MBEDTLS_PK_WRITE_C |
#endif |
#if defined MBEDTLS_PLATFORM_C |
#define POLARSSL_PLATFORM_C MBEDTLS_PLATFORM_C |
#endif |
#if defined MBEDTLS_PLATFORM_EXIT_ALT |
#define POLARSSL_PLATFORM_EXIT_ALT MBEDTLS_PLATFORM_EXIT_ALT |
#endif |
#if defined MBEDTLS_PLATFORM_EXIT_MACRO |
#define POLARSSL_PLATFORM_EXIT_MACRO MBEDTLS_PLATFORM_EXIT_MACRO |
#endif |
#if defined MBEDTLS_PLATFORM_FPRINTF_ALT |
#define POLARSSL_PLATFORM_FPRINTF_ALT MBEDTLS_PLATFORM_FPRINTF_ALT |
#endif |
#if defined MBEDTLS_PLATFORM_FPRINTF_MACRO |
#define POLARSSL_PLATFORM_FPRINTF_MACRO MBEDTLS_PLATFORM_FPRINTF_MACRO |
#endif |
#if defined MBEDTLS_PLATFORM_FREE_MACRO |
#define POLARSSL_PLATFORM_FREE_MACRO MBEDTLS_PLATFORM_FREE_MACRO |
#endif |
#if defined MBEDTLS_PLATFORM_MEMORY |
#define POLARSSL_PLATFORM_MEMORY MBEDTLS_PLATFORM_MEMORY |
#endif |
#if defined MBEDTLS_PLATFORM_NO_STD_FUNCTIONS |
#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS MBEDTLS_PLATFORM_NO_STD_FUNCTIONS |
#endif |
#if defined MBEDTLS_PLATFORM_PRINTF_ALT |
#define POLARSSL_PLATFORM_PRINTF_ALT MBEDTLS_PLATFORM_PRINTF_ALT |
#endif |
#if defined MBEDTLS_PLATFORM_PRINTF_MACRO |
#define POLARSSL_PLATFORM_PRINTF_MACRO MBEDTLS_PLATFORM_PRINTF_MACRO |
#endif |
#if defined MBEDTLS_PLATFORM_SNPRINTF_ALT |
#define POLARSSL_PLATFORM_SNPRINTF_ALT MBEDTLS_PLATFORM_SNPRINTF_ALT |
#endif |
#if defined MBEDTLS_PLATFORM_SNPRINTF_MACRO |
#define POLARSSL_PLATFORM_SNPRINTF_MACRO MBEDTLS_PLATFORM_SNPRINTF_MACRO |
#endif |
#if defined MBEDTLS_PLATFORM_STD_EXIT |
#define POLARSSL_PLATFORM_STD_EXIT MBEDTLS_PLATFORM_STD_EXIT |
#endif |
#if defined MBEDTLS_PLATFORM_STD_FPRINTF |
#define POLARSSL_PLATFORM_STD_FPRINTF MBEDTLS_PLATFORM_STD_FPRINTF |
#endif |
#if defined MBEDTLS_PLATFORM_STD_FREE |
#define POLARSSL_PLATFORM_STD_FREE MBEDTLS_PLATFORM_STD_FREE |
#endif |
#if defined MBEDTLS_PLATFORM_STD_MEM_HDR |
#define POLARSSL_PLATFORM_STD_MEM_HDR MBEDTLS_PLATFORM_STD_MEM_HDR |
#endif |
#if defined MBEDTLS_PLATFORM_STD_PRINTF |
#define POLARSSL_PLATFORM_STD_PRINTF MBEDTLS_PLATFORM_STD_PRINTF |
#endif |
#if defined MBEDTLS_PLATFORM_STD_SNPRINTF |
#define POLARSSL_PLATFORM_STD_SNPRINTF MBEDTLS_PLATFORM_STD_SNPRINTF |
#endif |
#if defined MBEDTLS_PSK_MAX_LEN |
#define POLARSSL_PSK_MAX_LEN MBEDTLS_PSK_MAX_LEN |
#endif |
#if defined MBEDTLS_REMOVE_ARC4_CIPHERSUITES |
#define POLARSSL_REMOVE_ARC4_CIPHERSUITES MBEDTLS_REMOVE_ARC4_CIPHERSUITES |
#endif |
#if defined MBEDTLS_RIPEMD160_ALT |
#define POLARSSL_RIPEMD160_ALT MBEDTLS_RIPEMD160_ALT |
#endif |
#if defined MBEDTLS_RIPEMD160_C |
#define POLARSSL_RIPEMD160_C MBEDTLS_RIPEMD160_C |
#endif |
#if defined MBEDTLS_RIPEMD160_PROCESS_ALT |
#define POLARSSL_RIPEMD160_PROCESS_ALT MBEDTLS_RIPEMD160_PROCESS_ALT |
#endif |
#if defined MBEDTLS_RSA_C |
#define POLARSSL_RSA_C MBEDTLS_RSA_C |
#endif |
#if defined MBEDTLS_RSA_NO_CRT |
#define POLARSSL_RSA_NO_CRT MBEDTLS_RSA_NO_CRT |
#endif |
#if defined MBEDTLS_SELF_TEST |
#define POLARSSL_SELF_TEST MBEDTLS_SELF_TEST |
#endif |
#if defined MBEDTLS_SHA1_ALT |
#define POLARSSL_SHA1_ALT MBEDTLS_SHA1_ALT |
#endif |
#if defined MBEDTLS_SHA1_C |
#define POLARSSL_SHA1_C MBEDTLS_SHA1_C |
#endif |
#if defined MBEDTLS_SHA1_PROCESS_ALT |
#define POLARSSL_SHA1_PROCESS_ALT MBEDTLS_SHA1_PROCESS_ALT |
#endif |
#if defined MBEDTLS_SHA256_ALT |
#define POLARSSL_SHA256_ALT MBEDTLS_SHA256_ALT |
#endif |
#if defined MBEDTLS_SHA256_C |
#define POLARSSL_SHA256_C MBEDTLS_SHA256_C |
#endif |
#if defined MBEDTLS_SHA256_PROCESS_ALT |
#define POLARSSL_SHA256_PROCESS_ALT MBEDTLS_SHA256_PROCESS_ALT |
#endif |
#if defined MBEDTLS_SHA512_ALT |
#define POLARSSL_SHA512_ALT MBEDTLS_SHA512_ALT |
#endif |
#if defined MBEDTLS_SHA512_C |
#define POLARSSL_SHA512_C MBEDTLS_SHA512_C |
#endif |
#if defined MBEDTLS_SHA512_PROCESS_ALT |
#define POLARSSL_SHA512_PROCESS_ALT MBEDTLS_SHA512_PROCESS_ALT |
#endif |
#if defined MBEDTLS_SSL_ALL_ALERT_MESSAGES |
#define POLARSSL_SSL_ALL_ALERT_MESSAGES MBEDTLS_SSL_ALL_ALERT_MESSAGES |
#endif |
#if defined MBEDTLS_SSL_ALPN |
#define POLARSSL_SSL_ALPN MBEDTLS_SSL_ALPN |
#endif |
#if defined MBEDTLS_SSL_CACHE_C |
#define POLARSSL_SSL_CACHE_C MBEDTLS_SSL_CACHE_C |
#endif |
#if defined MBEDTLS_SSL_CBC_RECORD_SPLITTING |
#define POLARSSL_SSL_CBC_RECORD_SPLITTING MBEDTLS_SSL_CBC_RECORD_SPLITTING |
#endif |
#if defined MBEDTLS_SSL_CLI_C |
#define POLARSSL_SSL_CLI_C MBEDTLS_SSL_CLI_C |
#endif |
#if defined MBEDTLS_SSL_COOKIE_C |
#define POLARSSL_SSL_COOKIE_C MBEDTLS_SSL_COOKIE_C |
#endif |
#if defined MBEDTLS_SSL_COOKIE_TIMEOUT |
#define POLARSSL_SSL_COOKIE_TIMEOUT MBEDTLS_SSL_COOKIE_TIMEOUT |
#endif |
#if defined MBEDTLS_SSL_DEBUG_ALL |
#define POLARSSL_SSL_DEBUG_ALL MBEDTLS_SSL_DEBUG_ALL |
#endif |
#if defined MBEDTLS_SSL_DTLS_ANTI_REPLAY |
#define POLARSSL_SSL_DTLS_ANTI_REPLAY MBEDTLS_SSL_DTLS_ANTI_REPLAY |
#endif |
#if defined MBEDTLS_SSL_DTLS_BADMAC_LIMIT |
#define POLARSSL_SSL_DTLS_BADMAC_LIMIT MBEDTLS_SSL_DTLS_BADMAC_LIMIT |
#endif |
#if defined MBEDTLS_SSL_DTLS_HELLO_VERIFY |
#define POLARSSL_SSL_DTLS_HELLO_VERIFY MBEDTLS_SSL_DTLS_HELLO_VERIFY |
#endif |
#if defined MBEDTLS_SSL_ENCRYPT_THEN_MAC |
#define POLARSSL_SSL_ENCRYPT_THEN_MAC MBEDTLS_SSL_ENCRYPT_THEN_MAC |
#endif |
#if defined MBEDTLS_SSL_EXTENDED_MASTER_SECRET |
#define POLARSSL_SSL_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MASTER_SECRET |
#endif |
#if defined MBEDTLS_SSL_FALLBACK_SCSV |
#define POLARSSL_SSL_FALLBACK_SCSV MBEDTLS_SSL_FALLBACK_SCSV |
#endif |
#if defined MBEDTLS_SSL_HW_RECORD_ACCEL |
#define POLARSSL_SSL_HW_RECORD_ACCEL MBEDTLS_SSL_HW_RECORD_ACCEL |
#endif |
#if defined MBEDTLS_SSL_MAX_FRAGMENT_LENGTH |
#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH MBEDTLS_SSL_MAX_FRAGMENT_LENGTH |
#endif |
#if defined MBEDTLS_SSL_PROTO_DTLS |
#define POLARSSL_SSL_PROTO_DTLS MBEDTLS_SSL_PROTO_DTLS |
#endif |
#if defined MBEDTLS_SSL_PROTO_SSL3 |
#define POLARSSL_SSL_PROTO_SSL3 MBEDTLS_SSL_PROTO_SSL3 |
#endif |
#if defined MBEDTLS_SSL_PROTO_TLS1 |
#define POLARSSL_SSL_PROTO_TLS1 MBEDTLS_SSL_PROTO_TLS1 |
#endif |
#if defined MBEDTLS_SSL_PROTO_TLS1_1 |
#define POLARSSL_SSL_PROTO_TLS1_1 MBEDTLS_SSL_PROTO_TLS1_1 |
#endif |
#if defined MBEDTLS_SSL_PROTO_TLS1_2 |
#define POLARSSL_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_2 |
#endif |
#if defined MBEDTLS_SSL_RENEGOTIATION |
#define POLARSSL_SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION |
#endif |
#if defined MBEDTLS_SSL_SERVER_NAME_INDICATION |
#define POLARSSL_SSL_SERVER_NAME_INDICATION MBEDTLS_SSL_SERVER_NAME_INDICATION |
#endif |
#if defined MBEDTLS_SSL_SESSION_TICKETS |
#define POLARSSL_SSL_SESSION_TICKETS MBEDTLS_SSL_SESSION_TICKETS |
#endif |
#if defined MBEDTLS_SSL_SRV_C |
#define POLARSSL_SSL_SRV_C MBEDTLS_SSL_SRV_C |
#endif |
#if defined MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE |
#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE |
#endif |
#if defined MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO |
#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO |
#endif |
#if defined MBEDTLS_SSL_TLS_C |
#define POLARSSL_SSL_TLS_C MBEDTLS_SSL_TLS_C |
#endif |
#if defined MBEDTLS_SSL_TRUNCATED_HMAC |
#define POLARSSL_SSL_TRUNCATED_HMAC MBEDTLS_SSL_TRUNCATED_HMAC |
#endif |
#if defined MBEDTLS_THREADING_ALT |
#define POLARSSL_THREADING_ALT MBEDTLS_THREADING_ALT |
#endif |
#if defined MBEDTLS_THREADING_C |
#define POLARSSL_THREADING_C MBEDTLS_THREADING_C |
#endif |
#if defined MBEDTLS_THREADING_PTHREAD |
#define POLARSSL_THREADING_PTHREAD MBEDTLS_THREADING_PTHREAD |
#endif |
#if defined MBEDTLS_TIMING_ALT |
#define POLARSSL_TIMING_ALT MBEDTLS_TIMING_ALT |
#endif |
#if defined MBEDTLS_TIMING_C |
#define POLARSSL_TIMING_C MBEDTLS_TIMING_C |
#endif |
#if defined MBEDTLS_VERSION_C |
#define POLARSSL_VERSION_C MBEDTLS_VERSION_C |
#endif |
#if defined MBEDTLS_VERSION_FEATURES |
#define POLARSSL_VERSION_FEATURES MBEDTLS_VERSION_FEATURES |
#endif |
#if defined MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 |
#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 |
#endif |
#if defined MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION |
#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION |
#endif |
#if defined MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE |
#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE |
#endif |
#if defined MBEDTLS_X509_CHECK_KEY_USAGE |
#define POLARSSL_X509_CHECK_KEY_USAGE MBEDTLS_X509_CHECK_KEY_USAGE |
#endif |
#if defined MBEDTLS_X509_CREATE_C |
#define POLARSSL_X509_CREATE_C MBEDTLS_X509_CREATE_C |
#endif |
#if defined MBEDTLS_X509_CRL_PARSE_C |
#define POLARSSL_X509_CRL_PARSE_C MBEDTLS_X509_CRL_PARSE_C |
#endif |
#if defined MBEDTLS_X509_CRT_PARSE_C |
#define POLARSSL_X509_CRT_PARSE_C MBEDTLS_X509_CRT_PARSE_C |
#endif |
#if defined MBEDTLS_X509_CRT_WRITE_C |
#define POLARSSL_X509_CRT_WRITE_C MBEDTLS_X509_CRT_WRITE_C |
#endif |
#if defined MBEDTLS_X509_CSR_PARSE_C |
#define POLARSSL_X509_CSR_PARSE_C MBEDTLS_X509_CSR_PARSE_C |
#endif |
#if defined MBEDTLS_X509_CSR_WRITE_C |
#define POLARSSL_X509_CSR_WRITE_C MBEDTLS_X509_CSR_WRITE_C |
#endif |
#if defined MBEDTLS_X509_MAX_INTERMEDIATE_CA |
#define POLARSSL_X509_MAX_INTERMEDIATE_CA MBEDTLS_X509_MAX_INTERMEDIATE_CA |
#endif |
#if defined MBEDTLS_X509_RSASSA_PSS_SUPPORT |
#define POLARSSL_X509_RSASSA_PSS_SUPPORT MBEDTLS_X509_RSASSA_PSS_SUPPORT |
#endif |
#if defined MBEDTLS_X509_USE_C |
#define POLARSSL_X509_USE_C MBEDTLS_X509_USE_C |
#endif |
#if defined MBEDTLS_XTEA_ALT |
#define POLARSSL_XTEA_ALT MBEDTLS_XTEA_ALT |
#endif |
#if defined MBEDTLS_XTEA_C |
#define POLARSSL_XTEA_C MBEDTLS_XTEA_C |
#endif |
#if defined MBEDTLS_ZLIB_SUPPORT |
#define POLARSSL_ZLIB_SUPPORT MBEDTLS_ZLIB_SUPPORT |
#endif |
/* |
* Misc names (macros, types, functions, enum constants...) |
*/ |
#define AES_DECRYPT MBEDTLS_AES_DECRYPT |
#define AES_ENCRYPT MBEDTLS_AES_ENCRYPT |
#define ASN1_BIT_STRING MBEDTLS_ASN1_BIT_STRING |
#define ASN1_BMP_STRING MBEDTLS_ASN1_BMP_STRING |
#define ASN1_BOOLEAN MBEDTLS_ASN1_BOOLEAN |
#define ASN1_CHK_ADD MBEDTLS_ASN1_CHK_ADD |
#define ASN1_CONSTRUCTED MBEDTLS_ASN1_CONSTRUCTED |
#define ASN1_CONTEXT_SPECIFIC MBEDTLS_ASN1_CONTEXT_SPECIFIC |
#define ASN1_GENERALIZED_TIME MBEDTLS_ASN1_GENERALIZED_TIME |
#define ASN1_IA5_STRING MBEDTLS_ASN1_IA5_STRING |
#define ASN1_INTEGER MBEDTLS_ASN1_INTEGER |
#define ASN1_NULL MBEDTLS_ASN1_NULL |
#define ASN1_OCTET_STRING MBEDTLS_ASN1_OCTET_STRING |
#define ASN1_OID MBEDTLS_ASN1_OID |
#define ASN1_PRIMITIVE MBEDTLS_ASN1_PRIMITIVE |
#define ASN1_PRINTABLE_STRING MBEDTLS_ASN1_PRINTABLE_STRING |
#define ASN1_SEQUENCE MBEDTLS_ASN1_SEQUENCE |
#define ASN1_SET MBEDTLS_ASN1_SET |
#define ASN1_T61_STRING MBEDTLS_ASN1_T61_STRING |
#define ASN1_UNIVERSAL_STRING MBEDTLS_ASN1_UNIVERSAL_STRING |
#define ASN1_UTC_TIME MBEDTLS_ASN1_UTC_TIME |
#define ASN1_UTF8_STRING MBEDTLS_ASN1_UTF8_STRING |
#define BADCERT_CN_MISMATCH MBEDTLS_X509_BADCERT_CN_MISMATCH |
#define BADCERT_EXPIRED MBEDTLS_X509_BADCERT_EXPIRED |
#define BADCERT_FUTURE MBEDTLS_X509_BADCERT_FUTURE |
#define BADCERT_MISSING MBEDTLS_X509_BADCERT_MISSING |
#define BADCERT_NOT_TRUSTED MBEDTLS_X509_BADCERT_NOT_TRUSTED |
#define BADCERT_OTHER MBEDTLS_X509_BADCERT_OTHER |
#define BADCERT_REVOKED MBEDTLS_X509_BADCERT_REVOKED |
#define BADCERT_SKIP_VERIFY MBEDTLS_X509_BADCERT_SKIP_VERIFY |
#define BADCRL_EXPIRED MBEDTLS_X509_BADCRL_EXPIRED |
#define BADCRL_FUTURE MBEDTLS_X509_BADCRL_FUTURE |
#define BADCRL_NOT_TRUSTED MBEDTLS_X509_BADCRL_NOT_TRUSTED |
#define BLOWFISH_BLOCKSIZE MBEDTLS_BLOWFISH_BLOCKSIZE |
#define BLOWFISH_DECRYPT MBEDTLS_BLOWFISH_DECRYPT |
#define BLOWFISH_ENCRYPT MBEDTLS_BLOWFISH_ENCRYPT |
#define BLOWFISH_MAX_KEY MBEDTLS_BLOWFISH_MAX_KEY_BITS |
#define BLOWFISH_MIN_KEY MBEDTLS_BLOWFISH_MIN_KEY_BITS |
#define BLOWFISH_ROUNDS MBEDTLS_BLOWFISH_ROUNDS |
#define CAMELLIA_DECRYPT MBEDTLS_CAMELLIA_DECRYPT |
#define CAMELLIA_ENCRYPT MBEDTLS_CAMELLIA_ENCRYPT |
#define COLLECT_SIZE MBEDTLS_HAVEGE_COLLECT_SIZE |
#define CTR_DRBG_BLOCKSIZE MBEDTLS_CTR_DRBG_BLOCKSIZE |
#define CTR_DRBG_ENTROPY_LEN MBEDTLS_CTR_DRBG_ENTROPY_LEN |
#define CTR_DRBG_KEYBITS MBEDTLS_CTR_DRBG_KEYBITS |
#define CTR_DRBG_KEYSIZE MBEDTLS_CTR_DRBG_KEYSIZE |
#define CTR_DRBG_MAX_INPUT MBEDTLS_CTR_DRBG_MAX_INPUT |
#define CTR_DRBG_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST |
#define CTR_DRBG_MAX_SEED_INPUT MBEDTLS_CTR_DRBG_MAX_SEED_INPUT |
#define CTR_DRBG_PR_OFF MBEDTLS_CTR_DRBG_PR_OFF |
#define CTR_DRBG_PR_ON MBEDTLS_CTR_DRBG_PR_ON |
#define CTR_DRBG_RESEED_INTERVAL MBEDTLS_CTR_DRBG_RESEED_INTERVAL |
#define CTR_DRBG_SEEDLEN MBEDTLS_CTR_DRBG_SEEDLEN |
#define DEPRECATED MBEDTLS_DEPRECATED |
#define DES_DECRYPT MBEDTLS_DES_DECRYPT |
#define DES_ENCRYPT MBEDTLS_DES_ENCRYPT |
#define DES_KEY_SIZE MBEDTLS_DES_KEY_SIZE |
#define ENTROPY_BLOCK_SIZE MBEDTLS_ENTROPY_BLOCK_SIZE |
#define ENTROPY_MAX_GATHER MBEDTLS_ENTROPY_MAX_GATHER |
#define ENTROPY_MAX_SEED_SIZE MBEDTLS_ENTROPY_MAX_SEED_SIZE |
#define ENTROPY_MAX_SOURCES MBEDTLS_ENTROPY_MAX_SOURCES |
#define ENTROPY_MIN_HARDCLOCK MBEDTLS_ENTROPY_MIN_HARDCLOCK |
#define ENTROPY_MIN_HAVEGE MBEDTLS_ENTROPY_MIN_HAVEGE |
#define ENTROPY_MIN_PLATFORM MBEDTLS_ENTROPY_MIN_PLATFORM |
#define ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_SOURCE_MANUAL |
#define EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER |
#define EXT_BASIC_CONSTRAINTS MBEDTLS_X509_EXT_BASIC_CONSTRAINTS |
#define EXT_CERTIFICATE_POLICIES MBEDTLS_X509_EXT_CERTIFICATE_POLICIES |
#define EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS |
#define EXT_EXTENDED_KEY_USAGE MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE |
#define EXT_FRESHEST_CRL MBEDTLS_X509_EXT_FRESHEST_CRL |
#define EXT_INIHIBIT_ANYPOLICY MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY |
#define EXT_ISSUER_ALT_NAME MBEDTLS_X509_EXT_ISSUER_ALT_NAME |
#define EXT_KEY_USAGE MBEDTLS_X509_EXT_KEY_USAGE |
#define EXT_NAME_CONSTRAINTS MBEDTLS_X509_EXT_NAME_CONSTRAINTS |
#define EXT_NS_CERT_TYPE MBEDTLS_X509_EXT_NS_CERT_TYPE |
#define EXT_POLICY_CONSTRAINTS MBEDTLS_X509_EXT_POLICY_CONSTRAINTS |
#define EXT_POLICY_MAPPINGS MBEDTLS_X509_EXT_POLICY_MAPPINGS |
#define EXT_SUBJECT_ALT_NAME MBEDTLS_X509_EXT_SUBJECT_ALT_NAME |
#define EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS |
#define EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER |
#define GCM_DECRYPT MBEDTLS_GCM_DECRYPT |
#define GCM_ENCRYPT MBEDTLS_GCM_ENCRYPT |
#define KU_CRL_SIGN MBEDTLS_X509_KU_CRL_SIGN |
#define KU_DATA_ENCIPHERMENT MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
#define KU_DIGITAL_SIGNATURE MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
#define KU_KEY_AGREEMENT MBEDTLS_X509_KU_KEY_AGREEMENT |
#define KU_KEY_CERT_SIGN MBEDTLS_X509_KU_KEY_CERT_SIGN |
#define KU_KEY_ENCIPHERMENT MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
#define KU_NON_REPUDIATION MBEDTLS_X509_KU_NON_REPUDIATION |
#define LN_2_DIV_LN_10_SCALE100 MBEDTLS_LN_2_DIV_LN_10_SCALE100 |
#define MEMORY_VERIFY_ALLOC MBEDTLS_MEMORY_VERIFY_ALLOC |
#define MEMORY_VERIFY_ALWAYS MBEDTLS_MEMORY_VERIFY_ALWAYS |
#define MEMORY_VERIFY_FREE MBEDTLS_MEMORY_VERIFY_FREE |
#define MEMORY_VERIFY_NONE MBEDTLS_MEMORY_VERIFY_NONE |
#define MPI_CHK MBEDTLS_MPI_CHK |
#define NET_PROTO_TCP MBEDTLS_NET_PROTO_TCP |
#define NET_PROTO_UDP MBEDTLS_NET_PROTO_UDP |
#define NS_CERT_TYPE_EMAIL MBEDTLS_X509_NS_CERT_TYPE_EMAIL |
#define NS_CERT_TYPE_EMAIL_CA MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA |
#define NS_CERT_TYPE_OBJECT_SIGNING MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING |
#define NS_CERT_TYPE_OBJECT_SIGNING_CA MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA |
#define NS_CERT_TYPE_RESERVED MBEDTLS_X509_NS_CERT_TYPE_RESERVED |
#define NS_CERT_TYPE_SSL_CA MBEDTLS_X509_NS_CERT_TYPE_SSL_CA |
#define NS_CERT_TYPE_SSL_CLIENT MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT |
#define NS_CERT_TYPE_SSL_SERVER MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER |
#define OID_ANSI_X9_62 MBEDTLS_OID_ANSI_X9_62 |
#define OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE |
#define OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD |
#define OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62_SIG |
#define OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 |
#define OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE |
#define OID_AT MBEDTLS_OID_AT |
#define OID_AT_CN MBEDTLS_OID_AT_CN |
#define OID_AT_COUNTRY MBEDTLS_OID_AT_COUNTRY |
#define OID_AT_DN_QUALIFIER MBEDTLS_OID_AT_DN_QUALIFIER |
#define OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT_GENERATION_QUALIFIER |
#define OID_AT_GIVEN_NAME MBEDTLS_OID_AT_GIVEN_NAME |
#define OID_AT_INITIALS MBEDTLS_OID_AT_INITIALS |
#define OID_AT_LOCALITY MBEDTLS_OID_AT_LOCALITY |
#define OID_AT_ORGANIZATION MBEDTLS_OID_AT_ORGANIZATION |
#define OID_AT_ORG_UNIT MBEDTLS_OID_AT_ORG_UNIT |
#define OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT_POSTAL_ADDRESS |
#define OID_AT_POSTAL_CODE MBEDTLS_OID_AT_POSTAL_CODE |
#define OID_AT_PSEUDONYM MBEDTLS_OID_AT_PSEUDONYM |
#define OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT_SERIAL_NUMBER |
#define OID_AT_STATE MBEDTLS_OID_AT_STATE |
#define OID_AT_SUR_NAME MBEDTLS_OID_AT_SUR_NAME |
#define OID_AT_TITLE MBEDTLS_OID_AT_TITLE |
#define OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT_UNIQUE_IDENTIFIER |
#define OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER |
#define OID_BASIC_CONSTRAINTS MBEDTLS_OID_BASIC_CONSTRAINTS |
#define OID_CERTICOM MBEDTLS_OID_CERTICOM |
#define OID_CERTIFICATE_POLICIES MBEDTLS_OID_CERTIFICATE_POLICIES |
#define OID_CLIENT_AUTH MBEDTLS_OID_CLIENT_AUTH |
#define OID_CMP MBEDTLS_OID_CMP |
#define OID_CODE_SIGNING MBEDTLS_OID_CODE_SIGNING |
#define OID_COUNTRY_US MBEDTLS_OID_COUNTRY_US |
#define OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_CRL_DISTRIBUTION_POINTS |
#define OID_CRL_NUMBER MBEDTLS_OID_CRL_NUMBER |
#define OID_DES_CBC MBEDTLS_OID_DES_CBC |
#define OID_DES_EDE3_CBC MBEDTLS_OID_DES_EDE3_CBC |
#define OID_DIGEST_ALG_MD2 MBEDTLS_OID_DIGEST_ALG_MD2 |
#define OID_DIGEST_ALG_MD4 MBEDTLS_OID_DIGEST_ALG_MD4 |
#define OID_DIGEST_ALG_MD5 MBEDTLS_OID_DIGEST_ALG_MD5 |
#define OID_DIGEST_ALG_SHA1 MBEDTLS_OID_DIGEST_ALG_SHA1 |
#define OID_DIGEST_ALG_SHA224 MBEDTLS_OID_DIGEST_ALG_SHA224 |
#define OID_DIGEST_ALG_SHA256 MBEDTLS_OID_DIGEST_ALG_SHA256 |
#define OID_DIGEST_ALG_SHA384 MBEDTLS_OID_DIGEST_ALG_SHA384 |
#define OID_DIGEST_ALG_SHA512 MBEDTLS_OID_DIGEST_ALG_SHA512 |
#define OID_DOMAIN_COMPONENT MBEDTLS_OID_DOMAIN_COMPONENT |
#define OID_ECDSA_SHA1 MBEDTLS_OID_ECDSA_SHA1 |
#define OID_ECDSA_SHA224 MBEDTLS_OID_ECDSA_SHA224 |
#define OID_ECDSA_SHA256 MBEDTLS_OID_ECDSA_SHA256 |
#define OID_ECDSA_SHA384 MBEDTLS_OID_ECDSA_SHA384 |
#define OID_ECDSA_SHA512 MBEDTLS_OID_ECDSA_SHA512 |
#define OID_EC_ALG_ECDH MBEDTLS_OID_EC_ALG_ECDH |
#define OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_EC_ALG_UNRESTRICTED |
#define OID_EC_BRAINPOOL_V1 MBEDTLS_OID_EC_BRAINPOOL_V1 |
#define OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_GRP_BP256R1 |
#define OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_GRP_BP384R1 |
#define OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_GRP_BP512R1 |
#define OID_EC_GRP_SECP192K1 MBEDTLS_OID_EC_GRP_SECP192K1 |
#define OID_EC_GRP_SECP192R1 MBEDTLS_OID_EC_GRP_SECP192R1 |
#define OID_EC_GRP_SECP224K1 MBEDTLS_OID_EC_GRP_SECP224K1 |
#define OID_EC_GRP_SECP224R1 MBEDTLS_OID_EC_GRP_SECP224R1 |
#define OID_EC_GRP_SECP256K1 MBEDTLS_OID_EC_GRP_SECP256K1 |
#define OID_EC_GRP_SECP256R1 MBEDTLS_OID_EC_GRP_SECP256R1 |
#define OID_EC_GRP_SECP384R1 MBEDTLS_OID_EC_GRP_SECP384R1 |
#define OID_EC_GRP_SECP521R1 MBEDTLS_OID_EC_GRP_SECP521R1 |
#define OID_EMAIL_PROTECTION MBEDTLS_OID_EMAIL_PROTECTION |
#define OID_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE |
#define OID_FRESHEST_CRL MBEDTLS_OID_FRESHEST_CRL |
#define OID_GOV MBEDTLS_OID_GOV |
#define OID_HMAC_SHA1 MBEDTLS_OID_HMAC_SHA1 |
#define OID_ID_CE MBEDTLS_OID_ID_CE |
#define OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_INIHIBIT_ANYPOLICY |
#define OID_ISO_CCITT_DS MBEDTLS_OID_ISO_CCITT_DS |
#define OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ISO_IDENTIFIED_ORG |
#define OID_ISO_ITU_COUNTRY MBEDTLS_OID_ISO_ITU_COUNTRY |
#define OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_US_ORG |
#define OID_ISO_MEMBER_BODIES MBEDTLS_OID_ISO_MEMBER_BODIES |
#define OID_ISSUER_ALT_NAME MBEDTLS_OID_ISSUER_ALT_NAME |
#define OID_KEY_USAGE MBEDTLS_OID_KEY_USAGE |
#define OID_KP MBEDTLS_OID_KP |
#define OID_MGF1 MBEDTLS_OID_MGF1 |
#define OID_NAME_CONSTRAINTS MBEDTLS_OID_NAME_CONSTRAINTS |
#define OID_NETSCAPE MBEDTLS_OID_NETSCAPE |
#define OID_NS_BASE_URL MBEDTLS_OID_NS_BASE_URL |
#define OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CA_POLICY_URL |
#define OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CA_REVOCATION_URL |
#define OID_NS_CERT MBEDTLS_OID_NS_CERT |
#define OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_CERT_SEQUENCE |
#define OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT_TYPE |
#define OID_NS_COMMENT MBEDTLS_OID_NS_COMMENT |
#define OID_NS_DATA_TYPE MBEDTLS_OID_NS_DATA_TYPE |
#define OID_NS_RENEWAL_URL MBEDTLS_OID_NS_RENEWAL_URL |
#define OID_NS_REVOCATION_URL MBEDTLS_OID_NS_REVOCATION_URL |
#define OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_SSL_SERVER_NAME |
#define OID_OCSP_SIGNING MBEDTLS_OID_OCSP_SIGNING |
#define OID_OIW_SECSIG MBEDTLS_OID_OIW_SECSIG |
#define OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG_ALG |
#define OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_SHA1 |
#define OID_ORGANIZATION MBEDTLS_OID_ORGANIZATION |
#define OID_ORG_ANSI_X9_62 MBEDTLS_OID_ORG_ANSI_X9_62 |
#define OID_ORG_CERTICOM MBEDTLS_OID_ORG_CERTICOM |
#define OID_ORG_DOD MBEDTLS_OID_ORG_DOD |
#define OID_ORG_GOV MBEDTLS_OID_ORG_GOV |
#define OID_ORG_NETSCAPE MBEDTLS_OID_ORG_NETSCAPE |
#define OID_ORG_OIW MBEDTLS_OID_ORG_OIW |
#define OID_ORG_RSA_DATA_SECURITY MBEDTLS_OID_ORG_RSA_DATA_SECURITY |
#define OID_ORG_TELETRUST MBEDTLS_OID_ORG_TELETRUST |
#define OID_PKCS MBEDTLS_OID_PKCS |
#define OID_PKCS1 MBEDTLS_OID_PKCS1 |
#define OID_PKCS12 MBEDTLS_OID_PKCS12 |
#define OID_PKCS12_PBE MBEDTLS_OID_PKCS12_PBE |
#define OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC |
#define OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC |
#define OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC |
#define OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC |
#define OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128 |
#define OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40 |
#define OID_PKCS1_MD2 MBEDTLS_OID_PKCS1_MD2 |
#define OID_PKCS1_MD4 MBEDTLS_OID_PKCS1_MD4 |
#define OID_PKCS1_MD5 MBEDTLS_OID_PKCS1_MD5 |
#define OID_PKCS1_RSA MBEDTLS_OID_PKCS1_RSA |
#define OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1_SHA1 |
#define OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1_SHA224 |
#define OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1_SHA256 |
#define OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1_SHA384 |
#define OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1_SHA512 |
#define OID_PKCS5 MBEDTLS_OID_PKCS5 |
#define OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5_PBES2 |
#define OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC |
#define OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC |
#define OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC |
#define OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC |
#define OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC |
#define OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC |
#define OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5_PBKDF2 |
#define OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5_PBMAC1 |
#define OID_PKCS9 MBEDTLS_OID_PKCS9 |
#define OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9_CSR_EXT_REQ |
#define OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9_EMAIL |
#define OID_PKIX MBEDTLS_OID_PKIX |
#define OID_POLICY_CONSTRAINTS MBEDTLS_OID_POLICY_CONSTRAINTS |
#define OID_POLICY_MAPPINGS MBEDTLS_OID_POLICY_MAPPINGS |
#define OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD |
#define OID_RSASSA_PSS MBEDTLS_OID_RSASSA_PSS |
#define OID_RSA_COMPANY MBEDTLS_OID_RSA_COMPANY |
#define OID_RSA_SHA_OBS MBEDTLS_OID_RSA_SHA_OBS |
#define OID_SERVER_AUTH MBEDTLS_OID_SERVER_AUTH |
#define OID_SIZE MBEDTLS_OID_SIZE |
#define OID_SUBJECT_ALT_NAME MBEDTLS_OID_SUBJECT_ALT_NAME |
#define OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS |
#define OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER |
#define OID_TELETRUST MBEDTLS_OID_TELETRUST |
#define OID_TIME_STAMPING MBEDTLS_OID_TIME_STAMPING |
#define PADLOCK_ACE MBEDTLS_PADLOCK_ACE |
#define PADLOCK_ALIGN16 MBEDTLS_PADLOCK_ALIGN16 |
#define PADLOCK_PHE MBEDTLS_PADLOCK_PHE |
#define PADLOCK_PMM MBEDTLS_PADLOCK_PMM |
#define PADLOCK_RNG MBEDTLS_PADLOCK_RNG |
#define PKCS12_DERIVE_IV MBEDTLS_PKCS12_DERIVE_IV |
#define PKCS12_DERIVE_KEY MBEDTLS_PKCS12_DERIVE_KEY |
#define PKCS12_DERIVE_MAC_KEY MBEDTLS_PKCS12_DERIVE_MAC_KEY |
#define PKCS12_PBE_DECRYPT MBEDTLS_PKCS12_PBE_DECRYPT |
#define PKCS12_PBE_ENCRYPT MBEDTLS_PKCS12_PBE_ENCRYPT |
#define PKCS5_DECRYPT MBEDTLS_PKCS5_DECRYPT |
#define PKCS5_ENCRYPT MBEDTLS_PKCS5_ENCRYPT |
#define POLARSSL_AESNI_AES MBEDTLS_AESNI_AES |
#define POLARSSL_AESNI_CLMUL MBEDTLS_AESNI_CLMUL |
#define POLARSSL_AESNI_H MBEDTLS_AESNI_H |
#define POLARSSL_AES_H MBEDTLS_AES_H |
#define POLARSSL_ARC4_H MBEDTLS_ARC4_H |
#define POLARSSL_ASN1_H MBEDTLS_ASN1_H |
#define POLARSSL_ASN1_WRITE_H MBEDTLS_ASN1_WRITE_H |
#define POLARSSL_BASE64_H MBEDTLS_BASE64_H |
#define POLARSSL_BIGNUM_H MBEDTLS_BIGNUM_H |
#define POLARSSL_BLOWFISH_H MBEDTLS_BLOWFISH_H |
#define POLARSSL_BN_MUL_H MBEDTLS_BN_MUL_H |
#define POLARSSL_CAMELLIA_H MBEDTLS_CAMELLIA_H |
#define POLARSSL_CCM_H MBEDTLS_CCM_H |
#define POLARSSL_CERTS_H MBEDTLS_CERTS_H |
#define POLARSSL_CHECK_CONFIG_H MBEDTLS_CHECK_CONFIG_H |
#define POLARSSL_CIPHERSUITE_NODTLS MBEDTLS_CIPHERSUITE_NODTLS |
#define POLARSSL_CIPHERSUITE_SHORT_TAG MBEDTLS_CIPHERSUITE_SHORT_TAG |
#define POLARSSL_CIPHERSUITE_WEAK MBEDTLS_CIPHERSUITE_WEAK |
#define POLARSSL_CIPHER_AES_128_CBC MBEDTLS_CIPHER_AES_128_CBC |
#define POLARSSL_CIPHER_AES_128_CCM MBEDTLS_CIPHER_AES_128_CCM |
#define POLARSSL_CIPHER_AES_128_CFB128 MBEDTLS_CIPHER_AES_128_CFB128 |
#define POLARSSL_CIPHER_AES_128_CTR MBEDTLS_CIPHER_AES_128_CTR |
#define POLARSSL_CIPHER_AES_128_ECB MBEDTLS_CIPHER_AES_128_ECB |
#define POLARSSL_CIPHER_AES_128_GCM MBEDTLS_CIPHER_AES_128_GCM |
#define POLARSSL_CIPHER_AES_192_CBC MBEDTLS_CIPHER_AES_192_CBC |
#define POLARSSL_CIPHER_AES_192_CCM MBEDTLS_CIPHER_AES_192_CCM |
#define POLARSSL_CIPHER_AES_192_CFB128 MBEDTLS_CIPHER_AES_192_CFB128 |
#define POLARSSL_CIPHER_AES_192_CTR MBEDTLS_CIPHER_AES_192_CTR |
#define POLARSSL_CIPHER_AES_192_ECB MBEDTLS_CIPHER_AES_192_ECB |
#define POLARSSL_CIPHER_AES_192_GCM MBEDTLS_CIPHER_AES_192_GCM |
#define POLARSSL_CIPHER_AES_256_CBC MBEDTLS_CIPHER_AES_256_CBC |
#define POLARSSL_CIPHER_AES_256_CCM MBEDTLS_CIPHER_AES_256_CCM |
#define POLARSSL_CIPHER_AES_256_CFB128 MBEDTLS_CIPHER_AES_256_CFB128 |
#define POLARSSL_CIPHER_AES_256_CTR MBEDTLS_CIPHER_AES_256_CTR |
#define POLARSSL_CIPHER_AES_256_ECB MBEDTLS_CIPHER_AES_256_ECB |
#define POLARSSL_CIPHER_AES_256_GCM MBEDTLS_CIPHER_AES_256_GCM |
#define POLARSSL_CIPHER_ARC4_128 MBEDTLS_CIPHER_ARC4_128 |
#define POLARSSL_CIPHER_BLOWFISH_CBC MBEDTLS_CIPHER_BLOWFISH_CBC |
#define POLARSSL_CIPHER_BLOWFISH_CFB64 MBEDTLS_CIPHER_BLOWFISH_CFB64 |
#define POLARSSL_CIPHER_BLOWFISH_CTR MBEDTLS_CIPHER_BLOWFISH_CTR |
#define POLARSSL_CIPHER_BLOWFISH_ECB MBEDTLS_CIPHER_BLOWFISH_ECB |
#define POLARSSL_CIPHER_CAMELLIA_128_CBC MBEDTLS_CIPHER_CAMELLIA_128_CBC |
#define POLARSSL_CIPHER_CAMELLIA_128_CCM MBEDTLS_CIPHER_CAMELLIA_128_CCM |
#define POLARSSL_CIPHER_CAMELLIA_128_CFB128 MBEDTLS_CIPHER_CAMELLIA_128_CFB128 |
#define POLARSSL_CIPHER_CAMELLIA_128_CTR MBEDTLS_CIPHER_CAMELLIA_128_CTR |
#define POLARSSL_CIPHER_CAMELLIA_128_ECB MBEDTLS_CIPHER_CAMELLIA_128_ECB |
#define POLARSSL_CIPHER_CAMELLIA_128_GCM MBEDTLS_CIPHER_CAMELLIA_128_GCM |
#define POLARSSL_CIPHER_CAMELLIA_192_CBC MBEDTLS_CIPHER_CAMELLIA_192_CBC |
#define POLARSSL_CIPHER_CAMELLIA_192_CCM MBEDTLS_CIPHER_CAMELLIA_192_CCM |
#define POLARSSL_CIPHER_CAMELLIA_192_CFB128 MBEDTLS_CIPHER_CAMELLIA_192_CFB128 |
#define POLARSSL_CIPHER_CAMELLIA_192_CTR MBEDTLS_CIPHER_CAMELLIA_192_CTR |
#define POLARSSL_CIPHER_CAMELLIA_192_ECB MBEDTLS_CIPHER_CAMELLIA_192_ECB |
#define POLARSSL_CIPHER_CAMELLIA_192_GCM MBEDTLS_CIPHER_CAMELLIA_192_GCM |
#define POLARSSL_CIPHER_CAMELLIA_256_CBC MBEDTLS_CIPHER_CAMELLIA_256_CBC |
#define POLARSSL_CIPHER_CAMELLIA_256_CCM MBEDTLS_CIPHER_CAMELLIA_256_CCM |
#define POLARSSL_CIPHER_CAMELLIA_256_CFB128 MBEDTLS_CIPHER_CAMELLIA_256_CFB128 |
#define POLARSSL_CIPHER_CAMELLIA_256_CTR MBEDTLS_CIPHER_CAMELLIA_256_CTR |
#define POLARSSL_CIPHER_CAMELLIA_256_ECB MBEDTLS_CIPHER_CAMELLIA_256_ECB |
#define POLARSSL_CIPHER_CAMELLIA_256_GCM MBEDTLS_CIPHER_CAMELLIA_256_GCM |
#define POLARSSL_CIPHER_DES_CBC MBEDTLS_CIPHER_DES_CBC |
#define POLARSSL_CIPHER_DES_ECB MBEDTLS_CIPHER_DES_ECB |
#define POLARSSL_CIPHER_DES_EDE3_CBC MBEDTLS_CIPHER_DES_EDE3_CBC |
#define POLARSSL_CIPHER_DES_EDE3_ECB MBEDTLS_CIPHER_DES_EDE3_ECB |
#define POLARSSL_CIPHER_DES_EDE_CBC MBEDTLS_CIPHER_DES_EDE_CBC |
#define POLARSSL_CIPHER_DES_EDE_ECB MBEDTLS_CIPHER_DES_EDE_ECB |
#define POLARSSL_CIPHER_H MBEDTLS_CIPHER_H |
#define POLARSSL_CIPHER_ID_3DES MBEDTLS_CIPHER_ID_3DES |
#define POLARSSL_CIPHER_ID_AES MBEDTLS_CIPHER_ID_AES |
#define POLARSSL_CIPHER_ID_ARC4 MBEDTLS_CIPHER_ID_ARC4 |
#define POLARSSL_CIPHER_ID_BLOWFISH MBEDTLS_CIPHER_ID_BLOWFISH |
#define POLARSSL_CIPHER_ID_CAMELLIA MBEDTLS_CIPHER_ID_CAMELLIA |
#define POLARSSL_CIPHER_ID_DES MBEDTLS_CIPHER_ID_DES |
#define POLARSSL_CIPHER_ID_NONE MBEDTLS_CIPHER_ID_NONE |
#define POLARSSL_CIPHER_ID_NULL MBEDTLS_CIPHER_ID_NULL |
#define POLARSSL_CIPHER_MODE_AEAD MBEDTLS_CIPHER_MODE_AEAD |
#define POLARSSL_CIPHER_MODE_STREAM MBEDTLS_CIPHER_MODE_STREAM |
#define POLARSSL_CIPHER_MODE_WITH_PADDING MBEDTLS_CIPHER_MODE_WITH_PADDING |
#define POLARSSL_CIPHER_NONE MBEDTLS_CIPHER_NONE |
#define POLARSSL_CIPHER_NULL MBEDTLS_CIPHER_NULL |
#define POLARSSL_CIPHER_VARIABLE_IV_LEN MBEDTLS_CIPHER_VARIABLE_IV_LEN |
#define POLARSSL_CIPHER_VARIABLE_KEY_LEN MBEDTLS_CIPHER_VARIABLE_KEY_LEN |
#define POLARSSL_CIPHER_WRAP_H MBEDTLS_CIPHER_WRAP_H |
#define POLARSSL_CONFIG_H MBEDTLS_CONFIG_H |
#define POLARSSL_CTR_DRBG_H MBEDTLS_CTR_DRBG_H |
#define POLARSSL_DEBUG_H MBEDTLS_DEBUG_H |
#define POLARSSL_DECRYPT MBEDTLS_DECRYPT |
#define POLARSSL_DES_H MBEDTLS_DES_H |
#define POLARSSL_DHM_H MBEDTLS_DHM_H |
#define POLARSSL_DHM_RFC3526_MODP_2048_G MBEDTLS_DHM_RFC3526_MODP_2048_G |
#define POLARSSL_DHM_RFC3526_MODP_2048_P MBEDTLS_DHM_RFC3526_MODP_2048_P |
#define POLARSSL_DHM_RFC3526_MODP_3072_G MBEDTLS_DHM_RFC3526_MODP_3072_G |
#define POLARSSL_DHM_RFC3526_MODP_3072_P MBEDTLS_DHM_RFC3526_MODP_3072_P |
#define POLARSSL_DHM_RFC5114_MODP_2048_G MBEDTLS_DHM_RFC5114_MODP_2048_G |
#define POLARSSL_DHM_RFC5114_MODP_2048_P MBEDTLS_DHM_RFC5114_MODP_2048_P |
#define POLARSSL_ECDH_H MBEDTLS_ECDH_H |
#define POLARSSL_ECDH_OURS MBEDTLS_ECDH_OURS |
#define POLARSSL_ECDH_THEIRS MBEDTLS_ECDH_THEIRS |
#define POLARSSL_ECDSA_H MBEDTLS_ECDSA_H |
#define POLARSSL_ECP_DP_BP256R1 MBEDTLS_ECP_DP_BP256R1 |
#define POLARSSL_ECP_DP_BP384R1 MBEDTLS_ECP_DP_BP384R1 |
#define POLARSSL_ECP_DP_BP512R1 MBEDTLS_ECP_DP_BP512R1 |
#define POLARSSL_ECP_DP_M255 MBEDTLS_ECP_DP_CURVE25519 |
#define POLARSSL_ECP_DP_MAX MBEDTLS_ECP_DP_MAX |
#define POLARSSL_ECP_DP_NONE MBEDTLS_ECP_DP_NONE |
#define POLARSSL_ECP_DP_SECP192K1 MBEDTLS_ECP_DP_SECP192K1 |
#define POLARSSL_ECP_DP_SECP192R1 MBEDTLS_ECP_DP_SECP192R1 |
#define POLARSSL_ECP_DP_SECP224K1 MBEDTLS_ECP_DP_SECP224K1 |
#define POLARSSL_ECP_DP_SECP224R1 MBEDTLS_ECP_DP_SECP224R1 |
#define POLARSSL_ECP_DP_SECP256K1 MBEDTLS_ECP_DP_SECP256K1 |
#define POLARSSL_ECP_DP_SECP256R1 MBEDTLS_ECP_DP_SECP256R1 |
#define POLARSSL_ECP_DP_SECP384R1 MBEDTLS_ECP_DP_SECP384R1 |
#define POLARSSL_ECP_DP_SECP521R1 MBEDTLS_ECP_DP_SECP521R1 |
#define POLARSSL_ECP_H MBEDTLS_ECP_H |
#define POLARSSL_ECP_MAX_BYTES MBEDTLS_ECP_MAX_BYTES |
#define POLARSSL_ECP_MAX_PT_LEN MBEDTLS_ECP_MAX_PT_LEN |
#define POLARSSL_ECP_PF_COMPRESSED MBEDTLS_ECP_PF_COMPRESSED |
#define POLARSSL_ECP_PF_UNCOMPRESSED MBEDTLS_ECP_PF_UNCOMPRESSED |
#define POLARSSL_ECP_TLS_NAMED_CURVE MBEDTLS_ECP_TLS_NAMED_CURVE |
#define POLARSSL_ENCRYPT MBEDTLS_ENCRYPT |
#define POLARSSL_ENTROPY_H MBEDTLS_ENTROPY_H |
#define POLARSSL_ENTROPY_POLL_H MBEDTLS_ENTROPY_POLL_H |
#define POLARSSL_ENTROPY_SHA256_ACCUMULATOR MBEDTLS_ENTROPY_SHA256_ACCUMULATOR |
#define POLARSSL_ENTROPY_SHA512_ACCUMULATOR MBEDTLS_ENTROPY_SHA512_ACCUMULATOR |
#define POLARSSL_ERROR_H MBEDTLS_ERROR_H |
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH |
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH MBEDTLS_ERR_AES_INVALID_KEY_LENGTH |
#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL MBEDTLS_ERR_ASN1_BUF_TOO_SMALL |
#define POLARSSL_ERR_ASN1_INVALID_DATA MBEDTLS_ERR_ASN1_INVALID_DATA |
#define POLARSSL_ERR_ASN1_INVALID_LENGTH MBEDTLS_ERR_ASN1_INVALID_LENGTH |
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH MBEDTLS_ERR_ASN1_LENGTH_MISMATCH |
#define POLARSSL_ERR_ASN1_MALLOC_FAILED MBEDTLS_ERR_ASN1_ALLOC_FAILED |
#define POLARSSL_ERR_ASN1_OUT_OF_DATA MBEDTLS_ERR_ASN1_OUT_OF_DATA |
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG MBEDTLS_ERR_ASN1_UNEXPECTED_TAG |
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL |
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER MBEDTLS_ERR_BASE64_INVALID_CHARACTER |
#define POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH |
#define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH |
#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH |
#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH |
#define POLARSSL_ERR_CCM_AUTH_FAILED MBEDTLS_ERR_CCM_AUTH_FAILED |
#define POLARSSL_ERR_CCM_BAD_INPUT MBEDTLS_ERR_CCM_BAD_INPUT |
#define POLARSSL_ERR_CIPHER_ALLOC_FAILED MBEDTLS_ERR_CIPHER_ALLOC_FAILED |
#define POLARSSL_ERR_CIPHER_AUTH_FAILED MBEDTLS_ERR_CIPHER_AUTH_FAILED |
#define POLARSSL_ERR_CIPHER_BAD_INPUT_DATA MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA |
#define POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED |
#define POLARSSL_ERR_CIPHER_INVALID_PADDING MBEDTLS_ERR_CIPHER_INVALID_PADDING |
#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED |
#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR |
#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG |
#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG |
#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH |
#define POLARSSL_ERR_DHM_BAD_INPUT_DATA MBEDTLS_ERR_DHM_BAD_INPUT_DATA |
#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED MBEDTLS_ERR_DHM_CALC_SECRET_FAILED |
#define POLARSSL_ERR_DHM_FILE_IO_ERROR MBEDTLS_ERR_DHM_FILE_IO_ERROR |
#define POLARSSL_ERR_DHM_INVALID_FORMAT MBEDTLS_ERR_DHM_INVALID_FORMAT |
#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED |
#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED |
#define POLARSSL_ERR_DHM_MALLOC_FAILED MBEDTLS_ERR_DHM_ALLOC_FAILED |
#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED MBEDTLS_ERR_DHM_READ_PARAMS_FAILED |
#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED |
#define POLARSSL_ERR_ECP_BAD_INPUT_DATA MBEDTLS_ERR_ECP_BAD_INPUT_DATA |
#define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL |
#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_ECP_INVALID_KEY MBEDTLS_ERR_ECP_INVALID_KEY |
#define POLARSSL_ERR_ECP_MALLOC_FAILED MBEDTLS_ERR_ECP_ALLOC_FAILED |
#define POLARSSL_ERR_ECP_RANDOM_FAILED MBEDTLS_ERR_ECP_RANDOM_FAILED |
#define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH |
#define POLARSSL_ERR_ECP_VERIFY_FAILED MBEDTLS_ERR_ECP_VERIFY_FAILED |
#define POLARSSL_ERR_ENTROPY_FILE_IO_ERROR MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR |
#define POLARSSL_ERR_ENTROPY_MAX_SOURCES MBEDTLS_ERR_ENTROPY_MAX_SOURCES |
#define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED |
#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_ENTROPY_SOURCE_FAILED |
#define POLARSSL_ERR_GCM_AUTH_FAILED MBEDTLS_ERR_GCM_AUTH_FAILED |
#define POLARSSL_ERR_GCM_BAD_INPUT MBEDTLS_ERR_GCM_BAD_INPUT |
#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR |
#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG |
#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG |
#define POLARSSL_ERR_MD_ALLOC_FAILED MBEDTLS_ERR_MD_ALLOC_FAILED |
#define POLARSSL_ERR_MD_BAD_INPUT_DATA MBEDTLS_ERR_MD_BAD_INPUT_DATA |
#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_MD_FILE_IO_ERROR MBEDTLS_ERR_MD_FILE_IO_ERROR |
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA MBEDTLS_ERR_MPI_BAD_INPUT_DATA |
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL |
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO MBEDTLS_ERR_MPI_DIVISION_BY_ZERO |
#define POLARSSL_ERR_MPI_FILE_IO_ERROR MBEDTLS_ERR_MPI_FILE_IO_ERROR |
#define POLARSSL_ERR_MPI_INVALID_CHARACTER MBEDTLS_ERR_MPI_INVALID_CHARACTER |
#define POLARSSL_ERR_MPI_MALLOC_FAILED MBEDTLS_ERR_MPI_ALLOC_FAILED |
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE MBEDTLS_ERR_MPI_NEGATIVE_VALUE |
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE MBEDTLS_ERR_MPI_NOT_ACCEPTABLE |
#define POLARSSL_ERR_NET_ACCEPT_FAILED MBEDTLS_ERR_NET_ACCEPT_FAILED |
#define POLARSSL_ERR_NET_BIND_FAILED MBEDTLS_ERR_NET_BIND_FAILED |
#define POLARSSL_ERR_NET_CONNECT_FAILED MBEDTLS_ERR_NET_CONNECT_FAILED |
#define POLARSSL_ERR_NET_CONN_RESET MBEDTLS_ERR_NET_CONN_RESET |
#define POLARSSL_ERR_NET_LISTEN_FAILED MBEDTLS_ERR_NET_LISTEN_FAILED |
#define POLARSSL_ERR_NET_RECV_FAILED MBEDTLS_ERR_NET_RECV_FAILED |
#define POLARSSL_ERR_NET_SEND_FAILED MBEDTLS_ERR_NET_SEND_FAILED |
#define POLARSSL_ERR_NET_SOCKET_FAILED MBEDTLS_ERR_NET_SOCKET_FAILED |
#define POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_SSL_TIMEOUT |
#define POLARSSL_ERR_NET_UNKNOWN_HOST MBEDTLS_ERR_NET_UNKNOWN_HOST |
#define POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_SSL_WANT_READ |
#define POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE |
#define POLARSSL_ERR_OID_BUF_TOO_SMALL MBEDTLS_ERR_OID_BUF_TOO_SMALL |
#define POLARSSL_ERR_OID_NOT_FOUND MBEDTLS_ERR_OID_NOT_FOUND |
#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED |
#define POLARSSL_ERR_PEM_BAD_INPUT_DATA MBEDTLS_ERR_PEM_BAD_INPUT_DATA |
#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_PEM_INVALID_DATA MBEDTLS_ERR_PEM_INVALID_DATA |
#define POLARSSL_ERR_PEM_INVALID_ENC_IV MBEDTLS_ERR_PEM_INVALID_ENC_IV |
#define POLARSSL_ERR_PEM_MALLOC_FAILED MBEDTLS_ERR_PEM_ALLOC_FAILED |
#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT |
#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH MBEDTLS_ERR_PEM_PASSWORD_MISMATCH |
#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED MBEDTLS_ERR_PEM_PASSWORD_REQUIRED |
#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG |
#define POLARSSL_ERR_PKCS12_BAD_INPUT_DATA MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA |
#define POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH |
#define POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT |
#define POLARSSL_ERR_PKCS5_BAD_INPUT_DATA MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA |
#define POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_PKCS5_INVALID_FORMAT MBEDTLS_ERR_PKCS5_INVALID_FORMAT |
#define POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH |
#define POLARSSL_ERR_PK_BAD_INPUT_DATA MBEDTLS_ERR_PK_BAD_INPUT_DATA |
#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_PK_FILE_IO_ERROR MBEDTLS_ERR_PK_FILE_IO_ERROR |
#define POLARSSL_ERR_PK_INVALID_ALG MBEDTLS_ERR_PK_INVALID_ALG |
#define POLARSSL_ERR_PK_INVALID_PUBKEY MBEDTLS_ERR_PK_INVALID_PUBKEY |
#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT MBEDTLS_ERR_PK_KEY_INVALID_FORMAT |
#define POLARSSL_ERR_PK_KEY_INVALID_VERSION MBEDTLS_ERR_PK_KEY_INVALID_VERSION |
#define POLARSSL_ERR_PK_MALLOC_FAILED MBEDTLS_ERR_PK_ALLOC_FAILED |
#define POLARSSL_ERR_PK_PASSWORD_MISMATCH MBEDTLS_ERR_PK_PASSWORD_MISMATCH |
#define POLARSSL_ERR_PK_PASSWORD_REQUIRED MBEDTLS_ERR_PK_PASSWORD_REQUIRED |
#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH MBEDTLS_ERR_PK_SIG_LEN_MISMATCH |
#define POLARSSL_ERR_PK_TYPE_MISMATCH MBEDTLS_ERR_PK_TYPE_MISMATCH |
#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE |
#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG MBEDTLS_ERR_PK_UNKNOWN_PK_ALG |
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA MBEDTLS_ERR_RSA_BAD_INPUT_DATA |
#define POLARSSL_ERR_RSA_INVALID_PADDING MBEDTLS_ERR_RSA_INVALID_PADDING |
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED MBEDTLS_ERR_RSA_KEY_CHECK_FAILED |
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED MBEDTLS_ERR_RSA_KEY_GEN_FAILED |
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE |
#define POLARSSL_ERR_RSA_PRIVATE_FAILED MBEDTLS_ERR_RSA_PRIVATE_FAILED |
#define POLARSSL_ERR_RSA_PUBLIC_FAILED MBEDTLS_ERR_RSA_PUBLIC_FAILED |
#define POLARSSL_ERR_RSA_RNG_FAILED MBEDTLS_ERR_RSA_RNG_FAILED |
#define POLARSSL_ERR_RSA_VERIFY_FAILED MBEDTLS_ERR_RSA_VERIFY_FAILED |
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE |
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST |
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY |
#define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC |
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO |
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE |
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS |
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP |
#define POLARSSL_ERR_SSL_BAD_HS_FINISHED MBEDTLS_ERR_SSL_BAD_HS_FINISHED |
#define POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET |
#define POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION |
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO |
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE |
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE |
#define POLARSSL_ERR_SSL_BAD_INPUT_DATA MBEDTLS_ERR_SSL_BAD_INPUT_DATA |
#define POLARSSL_ERR_SSL_BUFFER_TOO_SMALL MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL |
#define POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED |
#define POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED |
#define POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE |
#define POLARSSL_ERR_SSL_COMPRESSION_FAILED MBEDTLS_ERR_SSL_COMPRESSION_FAILED |
#define POLARSSL_ERR_SSL_CONN_EOF MBEDTLS_ERR_SSL_CONN_EOF |
#define POLARSSL_ERR_SSL_COUNTER_WRAPPING MBEDTLS_ERR_SSL_COUNTER_WRAPPING |
#define POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE |
#define POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED |
#define POLARSSL_ERR_SSL_HW_ACCEL_FAILED MBEDTLS_ERR_SSL_HW_ACCEL_FAILED |
#define POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH |
#define POLARSSL_ERR_SSL_INTERNAL_ERROR MBEDTLS_ERR_SSL_INTERNAL_ERROR |
#define POLARSSL_ERR_SSL_INVALID_MAC MBEDTLS_ERR_SSL_INVALID_MAC |
#define POLARSSL_ERR_SSL_INVALID_RECORD MBEDTLS_ERR_SSL_INVALID_RECORD |
#define POLARSSL_ERR_SSL_MALLOC_FAILED MBEDTLS_ERR_SSL_ALLOC_FAILED |
#define POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN |
#define POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE |
#define POLARSSL_ERR_SSL_NO_RNG MBEDTLS_ERR_SSL_NO_RNG |
#define POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE |
#define POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY |
#define POLARSSL_ERR_SSL_PEER_VERIFY_FAILED MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED |
#define POLARSSL_ERR_SSL_PK_TYPE_MISMATCH MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH |
#define POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED |
#define POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED |
#define POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE |
#define POLARSSL_ERR_SSL_UNKNOWN_CIPHER MBEDTLS_ERR_SSL_UNKNOWN_CIPHER |
#define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY |
#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO |
#define POLARSSL_ERR_THREADING_BAD_INPUT_DATA MBEDTLS_ERR_THREADING_BAD_INPUT_DATA |
#define POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_THREADING_MUTEX_ERROR MBEDTLS_ERR_THREADING_MUTEX_ERROR |
#define POLARSSL_ERR_X509_BAD_INPUT_DATA MBEDTLS_ERR_X509_BAD_INPUT_DATA |
#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT |
#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED MBEDTLS_ERR_X509_CERT_VERIFY_FAILED |
#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE |
#define POLARSSL_ERR_X509_FILE_IO_ERROR MBEDTLS_ERR_X509_FILE_IO_ERROR |
#define POLARSSL_ERR_X509_INVALID_ALG MBEDTLS_ERR_X509_INVALID_ALG |
#define POLARSSL_ERR_X509_INVALID_DATE MBEDTLS_ERR_X509_INVALID_DATE |
#define POLARSSL_ERR_X509_INVALID_EXTENSIONS MBEDTLS_ERR_X509_INVALID_EXTENSIONS |
#define POLARSSL_ERR_X509_INVALID_FORMAT MBEDTLS_ERR_X509_INVALID_FORMAT |
#define POLARSSL_ERR_X509_INVALID_NAME MBEDTLS_ERR_X509_INVALID_NAME |
#define POLARSSL_ERR_X509_INVALID_SERIAL MBEDTLS_ERR_X509_INVALID_SERIAL |
#define POLARSSL_ERR_X509_INVALID_SIGNATURE MBEDTLS_ERR_X509_INVALID_SIGNATURE |
#define POLARSSL_ERR_X509_INVALID_VERSION MBEDTLS_ERR_X509_INVALID_VERSION |
#define POLARSSL_ERR_X509_MALLOC_FAILED MBEDTLS_ERR_X509_ALLOC_FAILED |
#define POLARSSL_ERR_X509_SIG_MISMATCH MBEDTLS_ERR_X509_SIG_MISMATCH |
#define POLARSSL_ERR_X509_UNKNOWN_OID MBEDTLS_ERR_X509_UNKNOWN_OID |
#define POLARSSL_ERR_X509_UNKNOWN_SIG_ALG MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG |
#define POLARSSL_ERR_X509_UNKNOWN_VERSION MBEDTLS_ERR_X509_UNKNOWN_VERSION |
#define POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH |
#define POLARSSL_GCM_H MBEDTLS_GCM_H |
#define POLARSSL_HAVEGE_H MBEDTLS_HAVEGE_H |
#define POLARSSL_HAVE_INT32 MBEDTLS_HAVE_INT32 |
#define POLARSSL_HAVE_INT64 MBEDTLS_HAVE_INT64 |
#define POLARSSL_HAVE_UDBL MBEDTLS_HAVE_UDBL |
#define POLARSSL_HAVE_X86 MBEDTLS_HAVE_X86 |
#define POLARSSL_HAVE_X86_64 MBEDTLS_HAVE_X86_64 |
#define POLARSSL_HMAC_DRBG_H MBEDTLS_HMAC_DRBG_H |
#define POLARSSL_HMAC_DRBG_PR_OFF MBEDTLS_HMAC_DRBG_PR_OFF |
#define POLARSSL_HMAC_DRBG_PR_ON MBEDTLS_HMAC_DRBG_PR_ON |
#define POLARSSL_KEY_EXCHANGE_DHE_PSK MBEDTLS_KEY_EXCHANGE_DHE_PSK |
#define POLARSSL_KEY_EXCHANGE_DHE_RSA MBEDTLS_KEY_EXCHANGE_DHE_RSA |
#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA |
#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK MBEDTLS_KEY_EXCHANGE_ECDHE_PSK |
#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA MBEDTLS_KEY_EXCHANGE_ECDHE_RSA |
#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA |
#define POLARSSL_KEY_EXCHANGE_ECDH_RSA MBEDTLS_KEY_EXCHANGE_ECDH_RSA |
#define POLARSSL_KEY_EXCHANGE_NONE MBEDTLS_KEY_EXCHANGE_NONE |
#define POLARSSL_KEY_EXCHANGE_PSK MBEDTLS_KEY_EXCHANGE_PSK |
#define POLARSSL_KEY_EXCHANGE_RSA MBEDTLS_KEY_EXCHANGE_RSA |
#define POLARSSL_KEY_EXCHANGE_RSA_PSK MBEDTLS_KEY_EXCHANGE_RSA_PSK |
#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED |
#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED |
#define POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED |
#define POLARSSL_KEY_LENGTH_DES MBEDTLS_KEY_LENGTH_DES |
#define POLARSSL_KEY_LENGTH_DES_EDE MBEDTLS_KEY_LENGTH_DES_EDE |
#define POLARSSL_KEY_LENGTH_DES_EDE3 MBEDTLS_KEY_LENGTH_DES_EDE3 |
#define POLARSSL_KEY_LENGTH_NONE MBEDTLS_KEY_LENGTH_NONE |
#define POLARSSL_MAX_BLOCK_LENGTH MBEDTLS_MAX_BLOCK_LENGTH |
#define POLARSSL_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH |
#define POLARSSL_MD2_H MBEDTLS_MD2_H |
#define POLARSSL_MD4_H MBEDTLS_MD4_H |
#define POLARSSL_MD5_H MBEDTLS_MD5_H |
#define POLARSSL_MD_H MBEDTLS_MD_H |
#define POLARSSL_MD_MAX_SIZE MBEDTLS_MD_MAX_SIZE |
#define POLARSSL_MD_MD2 MBEDTLS_MD_MD2 |
#define POLARSSL_MD_MD4 MBEDTLS_MD_MD4 |
#define POLARSSL_MD_MD5 MBEDTLS_MD_MD5 |
#define POLARSSL_MD_NONE MBEDTLS_MD_NONE |
#define POLARSSL_MD_RIPEMD160 MBEDTLS_MD_RIPEMD160 |
#define POLARSSL_MD_SHA1 MBEDTLS_MD_SHA1 |
#define POLARSSL_MD_SHA224 MBEDTLS_MD_SHA224 |
#define POLARSSL_MD_SHA256 MBEDTLS_MD_SHA256 |
#define POLARSSL_MD_SHA384 MBEDTLS_MD_SHA384 |
#define POLARSSL_MD_SHA512 MBEDTLS_MD_SHA512 |
#define POLARSSL_MD_WRAP_H MBEDTLS_MD_WRAP_H |
#define POLARSSL_MEMORY_BUFFER_ALLOC_H MBEDTLS_MEMORY_BUFFER_ALLOC_H |
#define POLARSSL_MODE_CBC MBEDTLS_MODE_CBC |
#define POLARSSL_MODE_CCM MBEDTLS_MODE_CCM |
#define POLARSSL_MODE_CFB MBEDTLS_MODE_CFB |
#define POLARSSL_MODE_CTR MBEDTLS_MODE_CTR |
#define POLARSSL_MODE_ECB MBEDTLS_MODE_ECB |
#define POLARSSL_MODE_GCM MBEDTLS_MODE_GCM |
#define POLARSSL_MODE_NONE MBEDTLS_MODE_NONE |
#define POLARSSL_MODE_OFB MBEDTLS_MODE_OFB |
#define POLARSSL_MODE_STREAM MBEDTLS_MODE_STREAM |
#define POLARSSL_MPI_MAX_BITS MBEDTLS_MPI_MAX_BITS |
#define POLARSSL_MPI_MAX_BITS_SCALE100 MBEDTLS_MPI_MAX_BITS_SCALE100 |
#define POLARSSL_MPI_MAX_LIMBS MBEDTLS_MPI_MAX_LIMBS |
#define POLARSSL_MPI_RW_BUFFER_SIZE MBEDTLS_MPI_RW_BUFFER_SIZE |
#define POLARSSL_NET_H MBEDTLS_NET_SOCKETS_H |
#define POLARSSL_NET_LISTEN_BACKLOG MBEDTLS_NET_LISTEN_BACKLOG |
#define POLARSSL_OID_H MBEDTLS_OID_H |
#define POLARSSL_OPERATION_NONE MBEDTLS_OPERATION_NONE |
#define POLARSSL_PADDING_NONE MBEDTLS_PADDING_NONE |
#define POLARSSL_PADDING_ONE_AND_ZEROS MBEDTLS_PADDING_ONE_AND_ZEROS |
#define POLARSSL_PADDING_PKCS7 MBEDTLS_PADDING_PKCS7 |
#define POLARSSL_PADDING_ZEROS MBEDTLS_PADDING_ZEROS |
#define POLARSSL_PADDING_ZEROS_AND_LEN MBEDTLS_PADDING_ZEROS_AND_LEN |
#define POLARSSL_PADLOCK_H MBEDTLS_PADLOCK_H |
#define POLARSSL_PEM_H MBEDTLS_PEM_H |
#define POLARSSL_PKCS11_H MBEDTLS_PKCS11_H |
#define POLARSSL_PKCS12_H MBEDTLS_PKCS12_H |
#define POLARSSL_PKCS5_H MBEDTLS_PKCS5_H |
#define POLARSSL_PK_DEBUG_ECP MBEDTLS_PK_DEBUG_ECP |
#define POLARSSL_PK_DEBUG_MAX_ITEMS MBEDTLS_PK_DEBUG_MAX_ITEMS |
#define POLARSSL_PK_DEBUG_MPI MBEDTLS_PK_DEBUG_MPI |
#define POLARSSL_PK_DEBUG_NONE MBEDTLS_PK_DEBUG_NONE |
#define POLARSSL_PK_ECDSA MBEDTLS_PK_ECDSA |
#define POLARSSL_PK_ECKEY MBEDTLS_PK_ECKEY |
#define POLARSSL_PK_ECKEY_DH MBEDTLS_PK_ECKEY_DH |
#define POLARSSL_PK_H MBEDTLS_PK_H |
#define POLARSSL_PK_NONE MBEDTLS_PK_NONE |
#define POLARSSL_PK_RSA MBEDTLS_PK_RSA |
#define POLARSSL_PK_RSASSA_PSS MBEDTLS_PK_RSASSA_PSS |
#define POLARSSL_PK_RSA_ALT MBEDTLS_PK_RSA_ALT |
#define POLARSSL_PK_WRAP_H MBEDTLS_PK_WRAP_H |
#define POLARSSL_PLATFORM_H MBEDTLS_PLATFORM_H |
#define POLARSSL_PREMASTER_SIZE MBEDTLS_PREMASTER_SIZE |
#define POLARSSL_RIPEMD160_H MBEDTLS_RIPEMD160_H |
#define POLARSSL_RSA_H MBEDTLS_RSA_H |
#define POLARSSL_SHA1_H MBEDTLS_SHA1_H |
#define POLARSSL_SHA256_H MBEDTLS_SHA256_H |
#define POLARSSL_SHA512_H MBEDTLS_SHA512_H |
#define POLARSSL_SSL_CACHE_H MBEDTLS_SSL_CACHE_H |
#define POLARSSL_SSL_CIPHERSUITES_H MBEDTLS_SSL_CIPHERSUITES_H |
#define POLARSSL_SSL_COOKIE_H MBEDTLS_SSL_COOKIE_H |
#define POLARSSL_SSL_H MBEDTLS_SSL_H |
#define POLARSSL_THREADING_H MBEDTLS_THREADING_H |
#define POLARSSL_THREADING_IMPL MBEDTLS_THREADING_IMPL |
#define POLARSSL_TIMING_H MBEDTLS_TIMING_H |
#define POLARSSL_VERSION_H MBEDTLS_VERSION_H |
#define POLARSSL_VERSION_MAJOR MBEDTLS_VERSION_MAJOR |
#define POLARSSL_VERSION_MINOR MBEDTLS_VERSION_MINOR |
#define POLARSSL_VERSION_NUMBER MBEDTLS_VERSION_NUMBER |
#define POLARSSL_VERSION_PATCH MBEDTLS_VERSION_PATCH |
#define POLARSSL_VERSION_STRING MBEDTLS_VERSION_STRING |
#define POLARSSL_VERSION_STRING_FULL MBEDTLS_VERSION_STRING_FULL |
#define POLARSSL_X509_CRL_H MBEDTLS_X509_CRL_H |
#define POLARSSL_X509_CRT_H MBEDTLS_X509_CRT_H |
#define POLARSSL_X509_CSR_H MBEDTLS_X509_CSR_H |
#define POLARSSL_X509_H MBEDTLS_X509_H |
#define POLARSSL_XTEA_H MBEDTLS_XTEA_H |
#define RSA_CRYPT MBEDTLS_RSA_CRYPT |
#define RSA_PKCS_V15 MBEDTLS_RSA_PKCS_V15 |
#define RSA_PKCS_V21 MBEDTLS_RSA_PKCS_V21 |
#define RSA_PRIVATE MBEDTLS_RSA_PRIVATE |
#define RSA_PUBLIC MBEDTLS_RSA_PUBLIC |
#define RSA_SALT_LEN_ANY MBEDTLS_RSA_SALT_LEN_ANY |
#define RSA_SIGN MBEDTLS_RSA_SIGN |
#define SSL_ALERT_LEVEL_FATAL MBEDTLS_SSL_ALERT_LEVEL_FATAL |
#define SSL_ALERT_LEVEL_WARNING MBEDTLS_SSL_ALERT_LEVEL_WARNING |
#define SSL_ALERT_MSG_ACCESS_DENIED MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED |
#define SSL_ALERT_MSG_BAD_CERT MBEDTLS_SSL_ALERT_MSG_BAD_CERT |
#define SSL_ALERT_MSG_BAD_RECORD_MAC MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC |
#define SSL_ALERT_MSG_CERT_EXPIRED MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED |
#define SSL_ALERT_MSG_CERT_REVOKED MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED |
#define SSL_ALERT_MSG_CERT_UNKNOWN MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN |
#define SSL_ALERT_MSG_CLOSE_NOTIFY MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY |
#define SSL_ALERT_MSG_DECODE_ERROR MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR |
#define SSL_ALERT_MSG_DECOMPRESSION_FAILURE MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE |
#define SSL_ALERT_MSG_DECRYPTION_FAILED MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED |
#define SSL_ALERT_MSG_DECRYPT_ERROR MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR |
#define SSL_ALERT_MSG_EXPORT_RESTRICTION MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION |
#define SSL_ALERT_MSG_HANDSHAKE_FAILURE MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE |
#define SSL_ALERT_MSG_ILLEGAL_PARAMETER MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER |
#define SSL_ALERT_MSG_INAPROPRIATE_FALLBACK MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK |
#define SSL_ALERT_MSG_INSUFFICIENT_SECURITY MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY |
#define SSL_ALERT_MSG_INTERNAL_ERROR MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR |
#define SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL |
#define SSL_ALERT_MSG_NO_CERT MBEDTLS_SSL_ALERT_MSG_NO_CERT |
#define SSL_ALERT_MSG_NO_RENEGOTIATION MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION |
#define SSL_ALERT_MSG_PROTOCOL_VERSION MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION |
#define SSL_ALERT_MSG_RECORD_OVERFLOW MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW |
#define SSL_ALERT_MSG_UNEXPECTED_MESSAGE MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE |
#define SSL_ALERT_MSG_UNKNOWN_CA MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA |
#define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY |
#define SSL_ALERT_MSG_UNRECOGNIZED_NAME MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME |
#define SSL_ALERT_MSG_UNSUPPORTED_CERT MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT |
#define SSL_ALERT_MSG_UNSUPPORTED_EXT MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT |
#define SSL_ALERT_MSG_USER_CANCELED MBEDTLS_SSL_ALERT_MSG_USER_CANCELED |
#define SSL_ANTI_REPLAY_DISABLED MBEDTLS_SSL_ANTI_REPLAY_DISABLED |
#define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED |
#define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED |
#define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED |
#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \ |
? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) |
#define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES |
#define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT |
#define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED |
#define SSL_CBC_RECORD_SPLITTING_ENABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED |
#define SSL_CERTIFICATE_REQUEST MBEDTLS_SSL_CERTIFICATE_REQUEST |
#define SSL_CERTIFICATE_VERIFY MBEDTLS_SSL_CERTIFICATE_VERIFY |
#define SSL_CERT_TYPE_ECDSA_SIGN MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN |
#define SSL_CERT_TYPE_RSA_SIGN MBEDTLS_SSL_CERT_TYPE_RSA_SIGN |
#define SSL_CHANNEL_INBOUND MBEDTLS_SSL_CHANNEL_INBOUND |
#define SSL_CHANNEL_OUTBOUND MBEDTLS_SSL_CHANNEL_OUTBOUND |
#define SSL_CIPHERSUITES MBEDTLS_SSL_CIPHERSUITES |
#define SSL_CLIENT_CERTIFICATE MBEDTLS_SSL_CLIENT_CERTIFICATE |
#define SSL_CLIENT_CHANGE_CIPHER_SPEC MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC |
#define SSL_CLIENT_FINISHED MBEDTLS_SSL_CLIENT_FINISHED |
#define SSL_CLIENT_HELLO MBEDTLS_SSL_CLIENT_HELLO |
#define SSL_CLIENT_KEY_EXCHANGE MBEDTLS_SSL_CLIENT_KEY_EXCHANGE |
#define SSL_COMPRESSION_ADD MBEDTLS_SSL_COMPRESSION_ADD |
#define SSL_COMPRESS_DEFLATE MBEDTLS_SSL_COMPRESS_DEFLATE |
#define SSL_COMPRESS_NULL MBEDTLS_SSL_COMPRESS_NULL |
#define SSL_DEBUG_BUF MBEDTLS_SSL_DEBUG_BUF |
#define SSL_DEBUG_CRT MBEDTLS_SSL_DEBUG_CRT |
#define SSL_DEBUG_ECP MBEDTLS_SSL_DEBUG_ECP |
#define SSL_DEBUG_MPI MBEDTLS_SSL_DEBUG_MPI |
#define SSL_DEBUG_MSG MBEDTLS_SSL_DEBUG_MSG |
#define SSL_DEBUG_RET MBEDTLS_SSL_DEBUG_RET |
#define SSL_DEFAULT_TICKET_LIFETIME MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME |
#define SSL_DTLS_TIMEOUT_DFL_MAX MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX |
#define SSL_DTLS_TIMEOUT_DFL_MIN MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN |
#define SSL_EMPTY_RENEGOTIATION_INFO MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO |
#define SSL_ETM_DISABLED MBEDTLS_SSL_ETM_DISABLED |
#define SSL_ETM_ENABLED MBEDTLS_SSL_ETM_ENABLED |
#define SSL_EXTENDED_MS_DISABLED MBEDTLS_SSL_EXTENDED_MS_DISABLED |
#define SSL_EXTENDED_MS_ENABLED MBEDTLS_SSL_EXTENDED_MS_ENABLED |
#define SSL_FALLBACK_SCSV MBEDTLS_SSL_FALLBACK_SCSV |
#define SSL_FLUSH_BUFFERS MBEDTLS_SSL_FLUSH_BUFFERS |
#define SSL_HANDSHAKE_OVER MBEDTLS_SSL_HANDSHAKE_OVER |
#define SSL_HANDSHAKE_WRAPUP MBEDTLS_SSL_HANDSHAKE_WRAPUP |
#define SSL_HASH_MD5 MBEDTLS_SSL_HASH_MD5 |
#define SSL_HASH_NONE MBEDTLS_SSL_HASH_NONE |
#define SSL_HASH_SHA1 MBEDTLS_SSL_HASH_SHA1 |
#define SSL_HASH_SHA224 MBEDTLS_SSL_HASH_SHA224 |
#define SSL_HASH_SHA256 MBEDTLS_SSL_HASH_SHA256 |
#define SSL_HASH_SHA384 MBEDTLS_SSL_HASH_SHA384 |
#define SSL_HASH_SHA512 MBEDTLS_SSL_HASH_SHA512 |
#define SSL_HELLO_REQUEST MBEDTLS_SSL_HELLO_REQUEST |
#define SSL_HS_CERTIFICATE MBEDTLS_SSL_HS_CERTIFICATE |
#define SSL_HS_CERTIFICATE_REQUEST MBEDTLS_SSL_HS_CERTIFICATE_REQUEST |
#define SSL_HS_CERTIFICATE_VERIFY MBEDTLS_SSL_HS_CERTIFICATE_VERIFY |
#define SSL_HS_CLIENT_HELLO MBEDTLS_SSL_HS_CLIENT_HELLO |
#define SSL_HS_CLIENT_KEY_EXCHANGE MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE |
#define SSL_HS_FINISHED MBEDTLS_SSL_HS_FINISHED |
#define SSL_HS_HELLO_REQUEST MBEDTLS_SSL_HS_HELLO_REQUEST |
#define SSL_HS_HELLO_VERIFY_REQUEST MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST |
#define SSL_HS_NEW_SESSION_TICKET MBEDTLS_SSL_HS_NEW_SESSION_TICKET |
#define SSL_HS_SERVER_HELLO MBEDTLS_SSL_HS_SERVER_HELLO |
#define SSL_HS_SERVER_HELLO_DONE MBEDTLS_SSL_HS_SERVER_HELLO_DONE |
#define SSL_HS_SERVER_KEY_EXCHANGE MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE |
#define SSL_INITIAL_HANDSHAKE MBEDTLS_SSL_INITIAL_HANDSHAKE |
#define SSL_IS_CLIENT MBEDTLS_SSL_IS_CLIENT |
#define SSL_IS_FALLBACK MBEDTLS_SSL_IS_FALLBACK |
#define SSL_IS_NOT_FALLBACK MBEDTLS_SSL_IS_NOT_FALLBACK |
#define SSL_IS_SERVER MBEDTLS_SSL_IS_SERVER |
#define SSL_LEGACY_ALLOW_RENEGOTIATION MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION |
#define SSL_LEGACY_BREAK_HANDSHAKE MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE |
#define SSL_LEGACY_NO_RENEGOTIATION MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION |
#define SSL_LEGACY_RENEGOTIATION MBEDTLS_SSL_LEGACY_RENEGOTIATION |
#define SSL_MAC_ADD MBEDTLS_SSL_MAC_ADD |
#define SSL_MAJOR_VERSION_3 MBEDTLS_SSL_MAJOR_VERSION_3 |
#define SSL_MAX_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN |
#define SSL_MAX_FRAG_LEN_1024 MBEDTLS_SSL_MAX_FRAG_LEN_1024 |
#define SSL_MAX_FRAG_LEN_2048 MBEDTLS_SSL_MAX_FRAG_LEN_2048 |
#define SSL_MAX_FRAG_LEN_4096 MBEDTLS_SSL_MAX_FRAG_LEN_4096 |
#define SSL_MAX_FRAG_LEN_512 MBEDTLS_SSL_MAX_FRAG_LEN_512 |
#define SSL_MAX_FRAG_LEN_INVALID MBEDTLS_SSL_MAX_FRAG_LEN_INVALID |
#define SSL_MAX_FRAG_LEN_NONE MBEDTLS_SSL_MAX_FRAG_LEN_NONE |
#define SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAX_MAJOR_VERSION |
#define SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MAX_MINOR_VERSION |
#define SSL_MINOR_VERSION_0 MBEDTLS_SSL_MINOR_VERSION_0 |
#define SSL_MINOR_VERSION_1 MBEDTLS_SSL_MINOR_VERSION_1 |
#define SSL_MINOR_VERSION_2 MBEDTLS_SSL_MINOR_VERSION_2 |
#define SSL_MINOR_VERSION_3 MBEDTLS_SSL_MINOR_VERSION_3 |
#define SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MIN_MAJOR_VERSION |
#define SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MIN_MINOR_VERSION |
#define SSL_MSG_ALERT MBEDTLS_SSL_MSG_ALERT |
#define SSL_MSG_APPLICATION_DATA MBEDTLS_SSL_MSG_APPLICATION_DATA |
#define SSL_MSG_CHANGE_CIPHER_SPEC MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC |
#define SSL_MSG_HANDSHAKE MBEDTLS_SSL_MSG_HANDSHAKE |
#define SSL_PADDING_ADD MBEDTLS_SSL_PADDING_ADD |
#define SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION |
#define SSL_RENEGOTIATION_DISABLED MBEDTLS_SSL_RENEGOTIATION_DISABLED |
#define SSL_RENEGOTIATION_DONE MBEDTLS_SSL_RENEGOTIATION_DONE |
#define SSL_RENEGOTIATION_ENABLED MBEDTLS_SSL_RENEGOTIATION_ENABLED |
#define SSL_RENEGOTIATION_NOT_ENFORCED MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED |
#define SSL_RENEGOTIATION_PENDING MBEDTLS_SSL_RENEGOTIATION_PENDING |
#define SSL_RENEGO_MAX_RECORDS_DEFAULT MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT |
#define SSL_RETRANS_FINISHED MBEDTLS_SSL_RETRANS_FINISHED |
#define SSL_RETRANS_PREPARING MBEDTLS_SSL_RETRANS_PREPARING |
#define SSL_RETRANS_SENDING MBEDTLS_SSL_RETRANS_SENDING |
#define SSL_RETRANS_WAITING MBEDTLS_SSL_RETRANS_WAITING |
#define SSL_SECURE_RENEGOTIATION MBEDTLS_SSL_SECURE_RENEGOTIATION |
#define SSL_SERVER_CERTIFICATE MBEDTLS_SSL_SERVER_CERTIFICATE |
#define SSL_SERVER_CHANGE_CIPHER_SPEC MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC |
#define SSL_SERVER_FINISHED MBEDTLS_SSL_SERVER_FINISHED |
#define SSL_SERVER_HELLO MBEDTLS_SSL_SERVER_HELLO |
#define SSL_SERVER_HELLO_DONE MBEDTLS_SSL_SERVER_HELLO_DONE |
#define SSL_SERVER_HELLO_VERIFY_REQUEST_SENT MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT |
#define SSL_SERVER_KEY_EXCHANGE MBEDTLS_SSL_SERVER_KEY_EXCHANGE |
#define SSL_SERVER_NEW_SESSION_TICKET MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET |
#define SSL_SESSION_TICKETS_DISABLED MBEDTLS_SSL_SESSION_TICKETS_DISABLED |
#define SSL_SESSION_TICKETS_ENABLED MBEDTLS_SSL_SESSION_TICKETS_ENABLED |
#define SSL_SIG_ANON MBEDTLS_SSL_SIG_ANON |
#define SSL_SIG_ECDSA MBEDTLS_SSL_SIG_ECDSA |
#define SSL_SIG_RSA MBEDTLS_SSL_SIG_RSA |
#define SSL_TRANSPORT_DATAGRAM MBEDTLS_SSL_TRANSPORT_DATAGRAM |
#define SSL_TRANSPORT_STREAM MBEDTLS_SSL_TRANSPORT_STREAM |
#define SSL_TRUNCATED_HMAC_LEN MBEDTLS_SSL_TRUNCATED_HMAC_LEN |
#define SSL_TRUNC_HMAC_DISABLED MBEDTLS_SSL_TRUNC_HMAC_DISABLED |
#define SSL_TRUNC_HMAC_ENABLED MBEDTLS_SSL_TRUNC_HMAC_ENABLED |
#define SSL_VERIFY_DATA_MAX_LEN MBEDTLS_SSL_VERIFY_DATA_MAX_LEN |
#define SSL_VERIFY_NONE MBEDTLS_SSL_VERIFY_NONE |
#define SSL_VERIFY_OPTIONAL MBEDTLS_SSL_VERIFY_OPTIONAL |
#define SSL_VERIFY_REQUIRED MBEDTLS_SSL_VERIFY_REQUIRED |
#define TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA |
#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA |
#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 |
#define TLS_DHE_PSK_WITH_AES_128_CCM MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM |
#define TLS_DHE_PSK_WITH_AES_128_CCM_8 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 |
#define TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 |
#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA |
#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 |
#define TLS_DHE_PSK_WITH_AES_256_CCM MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM |
#define TLS_DHE_PSK_WITH_AES_256_CCM_8 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 |
#define TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 |
#define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_DHE_PSK_WITH_NULL_SHA MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA |
#define TLS_DHE_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 |
#define TLS_DHE_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 |
#define TLS_DHE_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA |
#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA |
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA |
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 |
#define TLS_DHE_RSA_WITH_AES_128_CCM MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM |
#define TLS_DHE_RSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 |
#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 |
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA |
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 |
#define TLS_DHE_RSA_WITH_AES_256_CCM MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM |
#define TLS_DHE_RSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 |
#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 |
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA |
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA |
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 |
#define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_DHE_RSA_WITH_DES_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA |
#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA |
#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA |
#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 |
#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM |
#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 |
#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA |
#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 |
#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM |
#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 |
#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 |
#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_ECDHE_ECDSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA |
#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA |
#define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA |
#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA |
#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 |
#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA |
#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 |
#define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_ECDHE_PSK_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA |
#define TLS_ECDHE_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 |
#define TLS_ECDHE_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 |
#define TLS_ECDHE_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA |
#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA |
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA |
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 |
#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 |
#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA |
#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 |
#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 |
#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_ECDHE_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA |
#define TLS_ECDHE_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA |
#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA |
#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA |
#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 |
#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 |
#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA |
#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 |
#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 |
#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_ECDH_ECDSA_WITH_NULL_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA |
#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA |
#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA |
#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA |
#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 |
#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 |
#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA |
#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 |
#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 |
#define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_ECDH_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA |
#define TLS_ECDH_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA |
#define TLS_EXT_ALPN MBEDTLS_TLS_EXT_ALPN |
#define TLS_EXT_ENCRYPT_THEN_MAC MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC |
#define TLS_EXT_EXTENDED_MASTER_SECRET MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET |
#define TLS_EXT_MAX_FRAGMENT_LENGTH MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH |
#define TLS_EXT_RENEGOTIATION_INFO MBEDTLS_TLS_EXT_RENEGOTIATION_INFO |
#define TLS_EXT_SERVERNAME MBEDTLS_TLS_EXT_SERVERNAME |
#define TLS_EXT_SERVERNAME_HOSTNAME MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME |
#define TLS_EXT_SESSION_TICKET MBEDTLS_TLS_EXT_SESSION_TICKET |
#define TLS_EXT_SIG_ALG MBEDTLS_TLS_EXT_SIG_ALG |
#define TLS_EXT_SUPPORTED_ELLIPTIC_CURVES MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES |
#define TLS_EXT_SUPPORTED_POINT_FORMATS MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS |
#define TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT |
#define TLS_EXT_TRUNCATED_HMAC MBEDTLS_TLS_EXT_TRUNCATED_HMAC |
#define TLS_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA |
#define TLS_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA |
#define TLS_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 |
#define TLS_PSK_WITH_AES_128_CCM MBEDTLS_TLS_PSK_WITH_AES_128_CCM |
#define TLS_PSK_WITH_AES_128_CCM_8 MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 |
#define TLS_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 |
#define TLS_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA |
#define TLS_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 |
#define TLS_PSK_WITH_AES_256_CCM MBEDTLS_TLS_PSK_WITH_AES_256_CCM |
#define TLS_PSK_WITH_AES_256_CCM_8 MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 |
#define TLS_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 |
#define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_PSK_WITH_NULL_SHA MBEDTLS_TLS_PSK_WITH_NULL_SHA |
#define TLS_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_PSK_WITH_NULL_SHA256 |
#define TLS_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_PSK_WITH_NULL_SHA384 |
#define TLS_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_PSK_WITH_RC4_128_SHA |
#define TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA |
#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA |
#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 |
#define TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 |
#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA |
#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 |
#define TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 |
#define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
#define TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_RSA_PSK_WITH_NULL_SHA MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA |
#define TLS_RSA_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 |
#define TLS_RSA_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 |
#define TLS_RSA_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA |
#define TLS_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA |
#define TLS_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA |
#define TLS_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 |
#define TLS_RSA_WITH_AES_128_CCM MBEDTLS_TLS_RSA_WITH_AES_128_CCM |
#define TLS_RSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 |
#define TLS_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 |
#define TLS_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA |
#define TLS_RSA_WITH_AES_256_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 |
#define TLS_RSA_WITH_AES_256_CCM MBEDTLS_TLS_RSA_WITH_AES_256_CCM |
#define TLS_RSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 |
#define TLS_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 |
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA |
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
#define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA |
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 |
#define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
#define TLS_RSA_WITH_DES_CBC_SHA MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA |
#define TLS_RSA_WITH_NULL_MD5 MBEDTLS_TLS_RSA_WITH_NULL_MD5 |
#define TLS_RSA_WITH_NULL_SHA MBEDTLS_TLS_RSA_WITH_NULL_SHA |
#define TLS_RSA_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_WITH_NULL_SHA256 |
#define TLS_RSA_WITH_RC4_128_MD5 MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 |
#define TLS_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_WITH_RC4_128_SHA |
#define X509_CRT_VERSION_1 MBEDTLS_X509_CRT_VERSION_1 |
#define X509_CRT_VERSION_2 MBEDTLS_X509_CRT_VERSION_2 |
#define X509_CRT_VERSION_3 MBEDTLS_X509_CRT_VERSION_3 |
#define X509_FORMAT_DER MBEDTLS_X509_FORMAT_DER |
#define X509_FORMAT_PEM MBEDTLS_X509_FORMAT_PEM |
#define X509_MAX_DN_NAME_SIZE MBEDTLS_X509_MAX_DN_NAME_SIZE |
#define X509_RFC5280_MAX_SERIAL_LEN MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN |
#define X509_RFC5280_UTC_TIME_LEN MBEDTLS_X509_RFC5280_UTC_TIME_LEN |
#define XTEA_DECRYPT MBEDTLS_XTEA_DECRYPT |
#define XTEA_ENCRYPT MBEDTLS_XTEA_ENCRYPT |
#define _asn1_bitstring mbedtls_asn1_bitstring |
#define _asn1_buf mbedtls_asn1_buf |
#define _asn1_named_data mbedtls_asn1_named_data |
#define _asn1_sequence mbedtls_asn1_sequence |
#define _ssl_cache_context mbedtls_ssl_cache_context |
#define _ssl_cache_entry mbedtls_ssl_cache_entry |
#define _ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t |
#define _ssl_context mbedtls_ssl_context |
#define _ssl_flight_item mbedtls_ssl_flight_item |
#define _ssl_handshake_params mbedtls_ssl_handshake_params |
#define _ssl_key_cert mbedtls_ssl_key_cert |
#define _ssl_premaster_secret mbedtls_ssl_premaster_secret |
#define _ssl_session mbedtls_ssl_session |
#define _ssl_transform mbedtls_ssl_transform |
#define _x509_crl mbedtls_x509_crl |
#define _x509_crl_entry mbedtls_x509_crl_entry |
#define _x509_crt mbedtls_x509_crt |
#define _x509_csr mbedtls_x509_csr |
#define _x509_time mbedtls_x509_time |
#define _x509write_cert mbedtls_x509write_cert |
#define _x509write_csr mbedtls_x509write_csr |
#define aes_context mbedtls_aes_context |
#define aes_crypt_cbc mbedtls_aes_crypt_cbc |
#define aes_crypt_cfb128 mbedtls_aes_crypt_cfb128 |
#define aes_crypt_cfb8 mbedtls_aes_crypt_cfb8 |
#define aes_crypt_ctr mbedtls_aes_crypt_ctr |
#define aes_crypt_ecb mbedtls_aes_crypt_ecb |
#define aes_free mbedtls_aes_free |
#define aes_init mbedtls_aes_init |
#define aes_self_test mbedtls_aes_self_test |
#define aes_setkey_dec mbedtls_aes_setkey_dec |
#define aes_setkey_enc mbedtls_aes_setkey_enc |
#define aesni_crypt_ecb mbedtls_aesni_crypt_ecb |
#define aesni_gcm_mult mbedtls_aesni_gcm_mult |
#define aesni_inverse_key mbedtls_aesni_inverse_key |
#define aesni_setkey_enc mbedtls_aesni_setkey_enc |
#define aesni_supports mbedtls_aesni_has_support |
#define alarmed mbedtls_timing_alarmed |
#define arc4_context mbedtls_arc4_context |
#define arc4_crypt mbedtls_arc4_crypt |
#define arc4_free mbedtls_arc4_free |
#define arc4_init mbedtls_arc4_init |
#define arc4_self_test mbedtls_arc4_self_test |
#define arc4_setup mbedtls_arc4_setup |
#define asn1_bitstring mbedtls_asn1_bitstring |
#define asn1_buf mbedtls_asn1_buf |
#define asn1_find_named_data mbedtls_asn1_find_named_data |
#define asn1_free_named_data mbedtls_asn1_free_named_data |
#define asn1_free_named_data_list mbedtls_asn1_free_named_data_list |
#define asn1_get_alg mbedtls_asn1_get_alg |
#define asn1_get_alg_null mbedtls_asn1_get_alg_null |
#define asn1_get_bitstring mbedtls_asn1_get_bitstring |
#define asn1_get_bitstring_null mbedtls_asn1_get_bitstring_null |
#define asn1_get_bool mbedtls_asn1_get_bool |
#define asn1_get_int mbedtls_asn1_get_int |
#define asn1_get_len mbedtls_asn1_get_len |
#define asn1_get_mpi mbedtls_asn1_get_mpi |
#define asn1_get_sequence_of mbedtls_asn1_get_sequence_of |
#define asn1_get_tag mbedtls_asn1_get_tag |
#define asn1_named_data mbedtls_asn1_named_data |
#define asn1_sequence mbedtls_asn1_sequence |
#define asn1_store_named_data mbedtls_asn1_store_named_data |
#define asn1_write_algorithm_identifier mbedtls_asn1_write_algorithm_identifier |
#define asn1_write_bitstring mbedtls_asn1_write_bitstring |
#define asn1_write_bool mbedtls_asn1_write_bool |
#define asn1_write_ia5_string mbedtls_asn1_write_ia5_string |
#define asn1_write_int mbedtls_asn1_write_int |
#define asn1_write_len mbedtls_asn1_write_len |
#define asn1_write_mpi mbedtls_asn1_write_mpi |
#define asn1_write_null mbedtls_asn1_write_null |
#define asn1_write_octet_string mbedtls_asn1_write_octet_string |
#define asn1_write_oid mbedtls_asn1_write_oid |
#define asn1_write_printable_string mbedtls_asn1_write_printable_string |
#define asn1_write_raw_buffer mbedtls_asn1_write_raw_buffer |
#define asn1_write_tag mbedtls_asn1_write_tag |
#define base64_decode mbedtls_base64_decode |
#define base64_encode mbedtls_base64_encode |
#define base64_self_test mbedtls_base64_self_test |
#define blowfish_context mbedtls_blowfish_context |
#define blowfish_crypt_cbc mbedtls_blowfish_crypt_cbc |
#define blowfish_crypt_cfb64 mbedtls_blowfish_crypt_cfb64 |
#define blowfish_crypt_ctr mbedtls_blowfish_crypt_ctr |
#define blowfish_crypt_ecb mbedtls_blowfish_crypt_ecb |
#define blowfish_free mbedtls_blowfish_free |
#define blowfish_init mbedtls_blowfish_init |
#define blowfish_setkey mbedtls_blowfish_setkey |
#define camellia_context mbedtls_camellia_context |
#define camellia_crypt_cbc mbedtls_camellia_crypt_cbc |
#define camellia_crypt_cfb128 mbedtls_camellia_crypt_cfb128 |
#define camellia_crypt_ctr mbedtls_camellia_crypt_ctr |
#define camellia_crypt_ecb mbedtls_camellia_crypt_ecb |
#define camellia_free mbedtls_camellia_free |
#define camellia_init mbedtls_camellia_init |
#define camellia_self_test mbedtls_camellia_self_test |
#define camellia_setkey_dec mbedtls_camellia_setkey_dec |
#define camellia_setkey_enc mbedtls_camellia_setkey_enc |
#define ccm_auth_decrypt mbedtls_ccm_auth_decrypt |
#define ccm_context mbedtls_ccm_context |
#define ccm_encrypt_and_tag mbedtls_ccm_encrypt_and_tag |
#define ccm_free mbedtls_ccm_free |
#define ccm_init mbedtls_ccm_init |
#define ccm_self_test mbedtls_ccm_self_test |
#define cipher_auth_decrypt mbedtls_cipher_auth_decrypt |
#define cipher_auth_encrypt mbedtls_cipher_auth_encrypt |
#define cipher_base_t mbedtls_cipher_base_t |
#define cipher_check_tag mbedtls_cipher_check_tag |
#define cipher_context_t mbedtls_cipher_context_t |
#define cipher_crypt mbedtls_cipher_crypt |
#define cipher_definition_t mbedtls_cipher_definition_t |
#define cipher_definitions mbedtls_cipher_definitions |
#define cipher_finish mbedtls_cipher_finish |
#define cipher_free mbedtls_cipher_free |
#define cipher_get_block_size mbedtls_cipher_get_block_size |
#define cipher_get_cipher_mode mbedtls_cipher_get_cipher_mode |
#define cipher_get_iv_size mbedtls_cipher_get_iv_size |
#define cipher_get_key_size mbedtls_cipher_get_key_bitlen |
#define cipher_get_name mbedtls_cipher_get_name |
#define cipher_get_operation mbedtls_cipher_get_operation |
#define cipher_get_type mbedtls_cipher_get_type |
#define cipher_id_t mbedtls_cipher_id_t |
#define cipher_info_from_string mbedtls_cipher_info_from_string |
#define cipher_info_from_type mbedtls_cipher_info_from_type |
#define cipher_info_from_values mbedtls_cipher_info_from_values |
#define cipher_info_t mbedtls_cipher_info_t |
#define cipher_init mbedtls_cipher_init |
#define cipher_init_ctx mbedtls_cipher_setup |
#define cipher_list mbedtls_cipher_list |
#define cipher_mode_t mbedtls_cipher_mode_t |
#define cipher_padding_t mbedtls_cipher_padding_t |
#define cipher_reset mbedtls_cipher_reset |
#define cipher_set_iv mbedtls_cipher_set_iv |
#define cipher_set_padding_mode mbedtls_cipher_set_padding_mode |
#define cipher_setkey mbedtls_cipher_setkey |
#define cipher_type_t mbedtls_cipher_type_t |
#define cipher_update mbedtls_cipher_update |
#define cipher_update_ad mbedtls_cipher_update_ad |
#define cipher_write_tag mbedtls_cipher_write_tag |
#define ctr_drbg_context mbedtls_ctr_drbg_context |
#define ctr_drbg_free mbedtls_ctr_drbg_free |
#define ctr_drbg_init mbedtls_ctr_drbg_init |
#define ctr_drbg_random mbedtls_ctr_drbg_random |
#define ctr_drbg_random_with_add mbedtls_ctr_drbg_random_with_add |
#define ctr_drbg_reseed mbedtls_ctr_drbg_reseed |
#define ctr_drbg_self_test mbedtls_ctr_drbg_self_test |
#define ctr_drbg_set_entropy_len mbedtls_ctr_drbg_set_entropy_len |
#define ctr_drbg_set_prediction_resistance mbedtls_ctr_drbg_set_prediction_resistance |
#define ctr_drbg_set_reseed_interval mbedtls_ctr_drbg_set_reseed_interval |
#define ctr_drbg_update mbedtls_ctr_drbg_update |
#define ctr_drbg_update_seed_file mbedtls_ctr_drbg_update_seed_file |
#define ctr_drbg_write_seed_file mbedtls_ctr_drbg_write_seed_file |
#define debug_print_buf mbedtls_debug_print_buf |
#define debug_print_crt mbedtls_debug_print_crt |
#define debug_print_ecp mbedtls_debug_print_ecp |
#define debug_print_mpi mbedtls_debug_print_mpi |
#define debug_print_msg mbedtls_debug_print_msg |
#define debug_print_ret mbedtls_debug_print_ret |
#define debug_set_threshold mbedtls_debug_set_threshold |
#define des3_context mbedtls_des3_context |
#define des3_crypt_cbc mbedtls_des3_crypt_cbc |
#define des3_crypt_ecb mbedtls_des3_crypt_ecb |
#define des3_free mbedtls_des3_free |
#define des3_init mbedtls_des3_init |
#define des3_set2key_dec mbedtls_des3_set2key_dec |
#define des3_set2key_enc mbedtls_des3_set2key_enc |
#define des3_set3key_dec mbedtls_des3_set3key_dec |
#define des3_set3key_enc mbedtls_des3_set3key_enc |
#define des_context mbedtls_des_context |
#define des_crypt_cbc mbedtls_des_crypt_cbc |
#define des_crypt_ecb mbedtls_des_crypt_ecb |
#define des_free mbedtls_des_free |
#define des_init mbedtls_des_init |
#define des_key_check_key_parity mbedtls_des_key_check_key_parity |
#define des_key_check_weak mbedtls_des_key_check_weak |
#define des_key_set_parity mbedtls_des_key_set_parity |
#define des_self_test mbedtls_des_self_test |
#define des_setkey_dec mbedtls_des_setkey_dec |
#define des_setkey_enc mbedtls_des_setkey_enc |
#define dhm_calc_secret mbedtls_dhm_calc_secret |
#define dhm_context mbedtls_dhm_context |
#define dhm_free mbedtls_dhm_free |
#define dhm_init mbedtls_dhm_init |
#define dhm_make_params mbedtls_dhm_make_params |
#define dhm_make_public mbedtls_dhm_make_public |
#define dhm_parse_dhm mbedtls_dhm_parse_dhm |
#define dhm_parse_dhmfile mbedtls_dhm_parse_dhmfile |
#define dhm_read_params mbedtls_dhm_read_params |
#define dhm_read_public mbedtls_dhm_read_public |
#define dhm_self_test mbedtls_dhm_self_test |
#define ecdh_calc_secret mbedtls_ecdh_calc_secret |
#define ecdh_compute_shared mbedtls_ecdh_compute_shared |
#define ecdh_context mbedtls_ecdh_context |
#define ecdh_free mbedtls_ecdh_free |
#define ecdh_gen_public mbedtls_ecdh_gen_public |
#define ecdh_get_params mbedtls_ecdh_get_params |
#define ecdh_init mbedtls_ecdh_init |
#define ecdh_make_params mbedtls_ecdh_make_params |
#define ecdh_make_public mbedtls_ecdh_make_public |
#define ecdh_read_params mbedtls_ecdh_read_params |
#define ecdh_read_public mbedtls_ecdh_read_public |
#define ecdh_side mbedtls_ecdh_side |
#define ecdsa_context mbedtls_ecdsa_context |
#define ecdsa_free mbedtls_ecdsa_free |
#define ecdsa_from_keypair mbedtls_ecdsa_from_keypair |
#define ecdsa_genkey mbedtls_ecdsa_genkey |
#define ecdsa_info mbedtls_ecdsa_info |
#define ecdsa_init mbedtls_ecdsa_init |
#define ecdsa_read_signature mbedtls_ecdsa_read_signature |
#define ecdsa_sign mbedtls_ecdsa_sign |
#define ecdsa_sign_det mbedtls_ecdsa_sign_det |
#define ecdsa_verify mbedtls_ecdsa_verify |
#define ecdsa_write_signature mbedtls_ecdsa_write_signature |
#define ecdsa_write_signature_det mbedtls_ecdsa_write_signature_det |
#define eckey_info mbedtls_eckey_info |
#define eckeydh_info mbedtls_eckeydh_info |
#define ecp_check_privkey mbedtls_ecp_check_privkey |
#define ecp_check_pub_priv mbedtls_ecp_check_pub_priv |
#define ecp_check_pubkey mbedtls_ecp_check_pubkey |
#define ecp_copy mbedtls_ecp_copy |
#define ecp_curve_info mbedtls_ecp_curve_info |
#define ecp_curve_info_from_grp_id mbedtls_ecp_curve_info_from_grp_id |
#define ecp_curve_info_from_name mbedtls_ecp_curve_info_from_name |
#define ecp_curve_info_from_tls_id mbedtls_ecp_curve_info_from_tls_id |
#define ecp_curve_list mbedtls_ecp_curve_list |
#define ecp_gen_key mbedtls_ecp_gen_key |
#define ecp_gen_keypair mbedtls_ecp_gen_keypair |
#define ecp_group mbedtls_ecp_group |
#define ecp_group_copy mbedtls_ecp_group_copy |
#define ecp_group_free mbedtls_ecp_group_free |
#define ecp_group_id mbedtls_ecp_group_id |
#define ecp_group_init mbedtls_ecp_group_init |
#define ecp_grp_id_list mbedtls_ecp_grp_id_list |
#define ecp_is_zero mbedtls_ecp_is_zero |
#define ecp_keypair mbedtls_ecp_keypair |
#define ecp_keypair_free mbedtls_ecp_keypair_free |
#define ecp_keypair_init mbedtls_ecp_keypair_init |
#define ecp_mul mbedtls_ecp_mul |
#define ecp_point mbedtls_ecp_point |
#define ecp_point_free mbedtls_ecp_point_free |
#define ecp_point_init mbedtls_ecp_point_init |
#define ecp_point_read_binary mbedtls_ecp_point_read_binary |
#define ecp_point_read_string mbedtls_ecp_point_read_string |
#define ecp_point_write_binary mbedtls_ecp_point_write_binary |
#define ecp_self_test mbedtls_ecp_self_test |
#define ecp_set_zero mbedtls_ecp_set_zero |
#define ecp_tls_read_group mbedtls_ecp_tls_read_group |
#define ecp_tls_read_point mbedtls_ecp_tls_read_point |
#define ecp_tls_write_group mbedtls_ecp_tls_write_group |
#define ecp_tls_write_point mbedtls_ecp_tls_write_point |
#define ecp_use_known_dp mbedtls_ecp_group_load |
#define entropy_add_source mbedtls_entropy_add_source |
#define entropy_context mbedtls_entropy_context |
#define entropy_free mbedtls_entropy_free |
#define entropy_func mbedtls_entropy_func |
#define entropy_gather mbedtls_entropy_gather |
#define entropy_init mbedtls_entropy_init |
#define entropy_self_test mbedtls_entropy_self_test |
#define entropy_update_manual mbedtls_entropy_update_manual |
#define entropy_update_seed_file mbedtls_entropy_update_seed_file |
#define entropy_write_seed_file mbedtls_entropy_write_seed_file |
#define error_strerror mbedtls_strerror |
#define f_source_ptr mbedtls_entropy_f_source_ptr |
#define gcm_auth_decrypt mbedtls_gcm_auth_decrypt |
#define gcm_context mbedtls_gcm_context |
#define gcm_crypt_and_tag mbedtls_gcm_crypt_and_tag |
#define gcm_finish mbedtls_gcm_finish |
#define gcm_free mbedtls_gcm_free |
#define gcm_init mbedtls_gcm_init |
#define gcm_self_test mbedtls_gcm_self_test |
#define gcm_starts mbedtls_gcm_starts |
#define gcm_update mbedtls_gcm_update |
#define get_timer mbedtls_timing_get_timer |
#define hardclock mbedtls_timing_hardclock |
#define hardclock_poll mbedtls_hardclock_poll |
#define havege_free mbedtls_havege_free |
#define havege_init mbedtls_havege_init |
#define havege_poll mbedtls_havege_poll |
#define havege_random mbedtls_havege_random |
#define havege_state mbedtls_havege_state |
#define hmac_drbg_context mbedtls_hmac_drbg_context |
#define hmac_drbg_free mbedtls_hmac_drbg_free |
#define hmac_drbg_init mbedtls_hmac_drbg_init |
#define hmac_drbg_random mbedtls_hmac_drbg_random |
#define hmac_drbg_random_with_add mbedtls_hmac_drbg_random_with_add |
#define hmac_drbg_reseed mbedtls_hmac_drbg_reseed |
#define hmac_drbg_self_test mbedtls_hmac_drbg_self_test |
#define hmac_drbg_set_entropy_len mbedtls_hmac_drbg_set_entropy_len |
#define hmac_drbg_set_prediction_resistance mbedtls_hmac_drbg_set_prediction_resistance |
#define hmac_drbg_set_reseed_interval mbedtls_hmac_drbg_set_reseed_interval |
#define hmac_drbg_update mbedtls_hmac_drbg_update |
#define hmac_drbg_update_seed_file mbedtls_hmac_drbg_update_seed_file |
#define hmac_drbg_write_seed_file mbedtls_hmac_drbg_write_seed_file |
#define hr_time mbedtls_timing_hr_time |
#define key_exchange_type_t mbedtls_key_exchange_type_t |
#define md mbedtls_md |
#define md2 mbedtls_md2 |
#define md2_context mbedtls_md2_context |
#define md2_finish mbedtls_md2_finish |
#define md2_free mbedtls_md2_free |
#define md2_info mbedtls_md2_info |
#define md2_init mbedtls_md2_init |
#define md2_process mbedtls_md2_process |
#define md2_self_test mbedtls_md2_self_test |
#define md2_starts mbedtls_md2_starts |
#define md2_update mbedtls_md2_update |
#define md4 mbedtls_md4 |
#define md4_context mbedtls_md4_context |
#define md4_finish mbedtls_md4_finish |
#define md4_free mbedtls_md4_free |
#define md4_info mbedtls_md4_info |
#define md4_init mbedtls_md4_init |
#define md4_process mbedtls_md4_process |
#define md4_self_test mbedtls_md4_self_test |
#define md4_starts mbedtls_md4_starts |
#define md4_update mbedtls_md4_update |
#define md5 mbedtls_md5 |
#define md5_context mbedtls_md5_context |
#define md5_finish mbedtls_md5_finish |
#define md5_free mbedtls_md5_free |
#define md5_info mbedtls_md5_info |
#define md5_init mbedtls_md5_init |
#define md5_process mbedtls_md5_process |
#define md5_self_test mbedtls_md5_self_test |
#define md5_starts mbedtls_md5_starts |
#define md5_update mbedtls_md5_update |
#define md_context_t mbedtls_md_context_t |
#define md_file mbedtls_md_file |
#define md_finish mbedtls_md_finish |
#define md_free mbedtls_md_free |
#define md_get_name mbedtls_md_get_name |
#define md_get_size mbedtls_md_get_size |
#define md_get_type mbedtls_md_get_type |
#define md_hmac mbedtls_md_hmac |
#define md_hmac_finish mbedtls_md_hmac_finish |
#define md_hmac_reset mbedtls_md_hmac_reset |
#define md_hmac_starts mbedtls_md_hmac_starts |
#define md_hmac_update mbedtls_md_hmac_update |
#define md_info_from_string mbedtls_md_info_from_string |
#define md_info_from_type mbedtls_md_info_from_type |
#define md_info_t mbedtls_md_info_t |
#define md_init mbedtls_md_init |
#define md_init_ctx mbedtls_md_init_ctx |
#define md_list mbedtls_md_list |
#define md_process mbedtls_md_process |
#define md_starts mbedtls_md_starts |
#define md_type_t mbedtls_md_type_t |
#define md_update mbedtls_md_update |
#define memory_buffer_alloc_cur_get mbedtls_memory_buffer_alloc_cur_get |
#define memory_buffer_alloc_free mbedtls_memory_buffer_alloc_free |
#define memory_buffer_alloc_init mbedtls_memory_buffer_alloc_init |
#define memory_buffer_alloc_max_get mbedtls_memory_buffer_alloc_max_get |
#define memory_buffer_alloc_max_reset mbedtls_memory_buffer_alloc_max_reset |
#define memory_buffer_alloc_self_test mbedtls_memory_buffer_alloc_self_test |
#define memory_buffer_alloc_status mbedtls_memory_buffer_alloc_status |
#define memory_buffer_alloc_verify mbedtls_memory_buffer_alloc_verify |
#define memory_buffer_set_verify mbedtls_memory_buffer_set_verify |
#define mpi mbedtls_mpi |
#define mpi_add_abs mbedtls_mpi_add_abs |
#define mpi_add_int mbedtls_mpi_add_int |
#define mpi_add_mpi mbedtls_mpi_add_mpi |
#define mpi_cmp_abs mbedtls_mpi_cmp_abs |
#define mpi_cmp_int mbedtls_mpi_cmp_int |
#define mpi_cmp_mpi mbedtls_mpi_cmp_mpi |
#define mpi_copy mbedtls_mpi_copy |
#define mpi_div_int mbedtls_mpi_div_int |
#define mpi_div_mpi mbedtls_mpi_div_mpi |
#define mpi_exp_mod mbedtls_mpi_exp_mod |
#define mpi_fill_random mbedtls_mpi_fill_random |
#define mpi_free mbedtls_mpi_free |
#define mpi_gcd mbedtls_mpi_gcd |
#define mpi_gen_prime mbedtls_mpi_gen_prime |
#define mpi_get_bit mbedtls_mpi_get_bit |
#define mpi_grow mbedtls_mpi_grow |
#define mpi_init mbedtls_mpi_init |
#define mpi_inv_mod mbedtls_mpi_inv_mod |
#define mpi_is_prime mbedtls_mpi_is_prime |
#define mpi_lsb mbedtls_mpi_lsb |
#define mpi_lset mbedtls_mpi_lset |
#define mpi_mod_int mbedtls_mpi_mod_int |
#define mpi_mod_mpi mbedtls_mpi_mod_mpi |
#define mpi_msb mbedtls_mpi_bitlen |
#define mpi_mul_int mbedtls_mpi_mul_int |
#define mpi_mul_mpi mbedtls_mpi_mul_mpi |
#define mpi_read_binary mbedtls_mpi_read_binary |
#define mpi_read_file mbedtls_mpi_read_file |
#define mpi_read_string mbedtls_mpi_read_string |
#define mpi_safe_cond_assign mbedtls_mpi_safe_cond_assign |
#define mpi_safe_cond_swap mbedtls_mpi_safe_cond_swap |
#define mpi_self_test mbedtls_mpi_self_test |
#define mpi_set_bit mbedtls_mpi_set_bit |
#define mpi_shift_l mbedtls_mpi_shift_l |
#define mpi_shift_r mbedtls_mpi_shift_r |
#define mpi_shrink mbedtls_mpi_shrink |
#define mpi_size mbedtls_mpi_size |
#define mpi_sub_abs mbedtls_mpi_sub_abs |
#define mpi_sub_int mbedtls_mpi_sub_int |
#define mpi_sub_mpi mbedtls_mpi_sub_mpi |
#define mpi_swap mbedtls_mpi_swap |
#define mpi_write_binary mbedtls_mpi_write_binary |
#define mpi_write_file mbedtls_mpi_write_file |
#define mpi_write_string mbedtls_mpi_write_string |
#define net_accept mbedtls_net_accept |
#define net_bind mbedtls_net_bind |
#define net_close mbedtls_net_free |
#define net_connect mbedtls_net_connect |
#define net_recv mbedtls_net_recv |
#define net_recv_timeout mbedtls_net_recv_timeout |
#define net_send mbedtls_net_send |
#define net_set_block mbedtls_net_set_block |
#define net_set_nonblock mbedtls_net_set_nonblock |
#define net_usleep mbedtls_net_usleep |
#define oid_descriptor_t mbedtls_oid_descriptor_t |
#define oid_get_attr_short_name mbedtls_oid_get_attr_short_name |
#define oid_get_cipher_alg mbedtls_oid_get_cipher_alg |
#define oid_get_ec_grp mbedtls_oid_get_ec_grp |
#define oid_get_extended_key_usage mbedtls_oid_get_extended_key_usage |
#define oid_get_md_alg mbedtls_oid_get_md_alg |
#define oid_get_numeric_string mbedtls_oid_get_numeric_string |
#define oid_get_oid_by_ec_grp mbedtls_oid_get_oid_by_ec_grp |
#define oid_get_oid_by_md mbedtls_oid_get_oid_by_md |
#define oid_get_oid_by_pk_alg mbedtls_oid_get_oid_by_pk_alg |
#define oid_get_oid_by_sig_alg mbedtls_oid_get_oid_by_sig_alg |
#define oid_get_pk_alg mbedtls_oid_get_pk_alg |
#define oid_get_pkcs12_pbe_alg mbedtls_oid_get_pkcs12_pbe_alg |
#define oid_get_sig_alg mbedtls_oid_get_sig_alg |
#define oid_get_sig_alg_desc mbedtls_oid_get_sig_alg_desc |
#define oid_get_x509_ext_type mbedtls_oid_get_x509_ext_type |
#define operation_t mbedtls_operation_t |
#define padlock_supports mbedtls_padlock_has_support |
#define padlock_xcryptcbc mbedtls_padlock_xcryptcbc |
#define padlock_xcryptecb mbedtls_padlock_xcryptecb |
#define pem_context mbedtls_pem_context |
#define pem_free mbedtls_pem_free |
#define pem_init mbedtls_pem_init |
#define pem_read_buffer mbedtls_pem_read_buffer |
#define pem_write_buffer mbedtls_pem_write_buffer |
#define pk_can_do mbedtls_pk_can_do |
#define pk_check_pair mbedtls_pk_check_pair |
#define pk_context mbedtls_pk_context |
#define pk_debug mbedtls_pk_debug |
#define pk_debug_item mbedtls_pk_debug_item |
#define pk_debug_type mbedtls_pk_debug_type |
#define pk_decrypt mbedtls_pk_decrypt |
#define pk_ec mbedtls_pk_ec |
#define pk_encrypt mbedtls_pk_encrypt |
#define pk_free mbedtls_pk_free |
#define pk_get_len mbedtls_pk_get_len |
#define pk_get_name mbedtls_pk_get_name |
#define pk_get_size mbedtls_pk_get_bitlen |
#define pk_get_type mbedtls_pk_get_type |
#define pk_info_from_type mbedtls_pk_info_from_type |
#define pk_info_t mbedtls_pk_info_t |
#define pk_init mbedtls_pk_init |
#define pk_init_ctx mbedtls_pk_setup |
#define pk_init_ctx_rsa_alt mbedtls_pk_setup_rsa_alt |
#define pk_load_file mbedtls_pk_load_file |
#define pk_parse_key mbedtls_pk_parse_key |
#define pk_parse_keyfile mbedtls_pk_parse_keyfile |
#define pk_parse_public_key mbedtls_pk_parse_public_key |
#define pk_parse_public_keyfile mbedtls_pk_parse_public_keyfile |
#define pk_parse_subpubkey mbedtls_pk_parse_subpubkey |
#define pk_rsa mbedtls_pk_rsa |
#define pk_rsa_alt_decrypt_func mbedtls_pk_rsa_alt_decrypt_func |
#define pk_rsa_alt_key_len_func mbedtls_pk_rsa_alt_key_len_func |
#define pk_rsa_alt_sign_func mbedtls_pk_rsa_alt_sign_func |
#define pk_rsassa_pss_options mbedtls_pk_rsassa_pss_options |
#define pk_sign mbedtls_pk_sign |
#define pk_type_t mbedtls_pk_type_t |
#define pk_verify mbedtls_pk_verify |
#define pk_verify_ext mbedtls_pk_verify_ext |
#define pk_write_key_der mbedtls_pk_write_key_der |
#define pk_write_key_pem mbedtls_pk_write_key_pem |
#define pk_write_pubkey mbedtls_pk_write_pubkey |
#define pk_write_pubkey_der mbedtls_pk_write_pubkey_der |
#define pk_write_pubkey_pem mbedtls_pk_write_pubkey_pem |
#define pkcs11_context mbedtls_pkcs11_context |
#define pkcs11_decrypt mbedtls_pkcs11_decrypt |
#define pkcs11_priv_key_free mbedtls_pkcs11_priv_key_free |
#define pkcs11_priv_key_init mbedtls_pkcs11_priv_key_bind |
#define pkcs11_sign mbedtls_pkcs11_sign |
#define pkcs11_x509_cert_init mbedtls_pkcs11_x509_cert_bind |
#define pkcs12_derivation mbedtls_pkcs12_derivation |
#define pkcs12_pbe mbedtls_pkcs12_pbe |
#define pkcs12_pbe_sha1_rc4_128 mbedtls_pkcs12_pbe_sha1_rc4_128 |
#define pkcs5_pbes2 mbedtls_pkcs5_pbes2 |
#define pkcs5_pbkdf2_hmac mbedtls_pkcs5_pbkdf2_hmac |
#define pkcs5_self_test mbedtls_pkcs5_self_test |
#define platform_entropy_poll mbedtls_platform_entropy_poll |
#define platform_set_exit mbedtls_platform_set_exit |
#define platform_set_fprintf mbedtls_platform_set_fprintf |
#define platform_set_printf mbedtls_platform_set_printf |
#define platform_set_snprintf mbedtls_platform_set_snprintf |
#define polarssl_exit mbedtls_exit |
#define polarssl_fprintf mbedtls_fprintf |
#define polarssl_free mbedtls_free |
#define polarssl_mutex_free mbedtls_mutex_free |
#define polarssl_mutex_init mbedtls_mutex_init |
#define polarssl_mutex_lock mbedtls_mutex_lock |
#define polarssl_mutex_unlock mbedtls_mutex_unlock |
#define polarssl_printf mbedtls_printf |
#define polarssl_snprintf mbedtls_snprintf |
#define polarssl_strerror mbedtls_strerror |
#define ripemd160 mbedtls_ripemd160 |
#define ripemd160_context mbedtls_ripemd160_context |
#define ripemd160_finish mbedtls_ripemd160_finish |
#define ripemd160_free mbedtls_ripemd160_free |
#define ripemd160_info mbedtls_ripemd160_info |
#define ripemd160_init mbedtls_ripemd160_init |
#define ripemd160_process mbedtls_ripemd160_process |
#define ripemd160_self_test mbedtls_ripemd160_self_test |
#define ripemd160_starts mbedtls_ripemd160_starts |
#define ripemd160_update mbedtls_ripemd160_update |
#define rsa_alt_context mbedtls_rsa_alt_context |
#define rsa_alt_info mbedtls_rsa_alt_info |
#define rsa_check_privkey mbedtls_rsa_check_privkey |
#define rsa_check_pub_priv mbedtls_rsa_check_pub_priv |
#define rsa_check_pubkey mbedtls_rsa_check_pubkey |
#define rsa_context mbedtls_rsa_context |
#define rsa_copy mbedtls_rsa_copy |
#define rsa_free mbedtls_rsa_free |
#define rsa_gen_key mbedtls_rsa_gen_key |
#define rsa_info mbedtls_rsa_info |
#define rsa_init mbedtls_rsa_init |
#define rsa_pkcs1_decrypt mbedtls_rsa_pkcs1_decrypt |
#define rsa_pkcs1_encrypt mbedtls_rsa_pkcs1_encrypt |
#define rsa_pkcs1_sign mbedtls_rsa_pkcs1_sign |
#define rsa_pkcs1_verify mbedtls_rsa_pkcs1_verify |
#define rsa_private mbedtls_rsa_private |
#define rsa_public mbedtls_rsa_public |
#define rsa_rsaes_oaep_decrypt mbedtls_rsa_rsaes_oaep_decrypt |
#define rsa_rsaes_oaep_encrypt mbedtls_rsa_rsaes_oaep_encrypt |
#define rsa_rsaes_pkcs1_v15_decrypt mbedtls_rsa_rsaes_pkcs1_v15_decrypt |
#define rsa_rsaes_pkcs1_v15_encrypt mbedtls_rsa_rsaes_pkcs1_v15_encrypt |
#define rsa_rsassa_pkcs1_v15_sign mbedtls_rsa_rsassa_pkcs1_v15_sign |
#define rsa_rsassa_pkcs1_v15_verify mbedtls_rsa_rsassa_pkcs1_v15_verify |
#define rsa_rsassa_pss_sign mbedtls_rsa_rsassa_pss_sign |
#define rsa_rsassa_pss_verify mbedtls_rsa_rsassa_pss_verify |
#define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext |
#define rsa_self_test mbedtls_rsa_self_test |
#define rsa_set_padding mbedtls_rsa_set_padding |
#define safer_memcmp mbedtls_ssl_safer_memcmp |
#define set_alarm mbedtls_set_alarm |
#define sha1 mbedtls_sha1 |
#define sha1_context mbedtls_sha1_context |
#define sha1_finish mbedtls_sha1_finish |
#define sha1_free mbedtls_sha1_free |
#define sha1_info mbedtls_sha1_info |
#define sha1_init mbedtls_sha1_init |
#define sha1_process mbedtls_sha1_process |
#define sha1_self_test mbedtls_sha1_self_test |
#define sha1_starts mbedtls_sha1_starts |
#define sha1_update mbedtls_sha1_update |
#define sha224_info mbedtls_sha224_info |
#define sha256 mbedtls_sha256 |
#define sha256_context mbedtls_sha256_context |
#define sha256_finish mbedtls_sha256_finish |
#define sha256_free mbedtls_sha256_free |
#define sha256_info mbedtls_sha256_info |
#define sha256_init mbedtls_sha256_init |
#define sha256_process mbedtls_sha256_process |
#define sha256_self_test mbedtls_sha256_self_test |
#define sha256_starts mbedtls_sha256_starts |
#define sha256_update mbedtls_sha256_update |
#define sha384_info mbedtls_sha384_info |
#define sha512 mbedtls_sha512 |
#define sha512_context mbedtls_sha512_context |
#define sha512_finish mbedtls_sha512_finish |
#define sha512_free mbedtls_sha512_free |
#define sha512_info mbedtls_sha512_info |
#define sha512_init mbedtls_sha512_init |
#define sha512_process mbedtls_sha512_process |
#define sha512_self_test mbedtls_sha512_self_test |
#define sha512_starts mbedtls_sha512_starts |
#define sha512_update mbedtls_sha512_update |
#define source_state mbedtls_entropy_source_state |
#define ssl_cache_context mbedtls_ssl_cache_context |
#define ssl_cache_entry mbedtls_ssl_cache_entry |
#define ssl_cache_free mbedtls_ssl_cache_free |
#define ssl_cache_get mbedtls_ssl_cache_get |
#define ssl_cache_init mbedtls_ssl_cache_init |
#define ssl_cache_set mbedtls_ssl_cache_set |
#define ssl_cache_set_max_entries mbedtls_ssl_cache_set_max_entries |
#define ssl_cache_set_timeout mbedtls_ssl_cache_set_timeout |
#define ssl_check_cert_usage mbedtls_ssl_check_cert_usage |
#define ssl_ciphersuite_from_id mbedtls_ssl_ciphersuite_from_id |
#define ssl_ciphersuite_from_string mbedtls_ssl_ciphersuite_from_string |
#define ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t |
#define ssl_ciphersuite_uses_ec mbedtls_ssl_ciphersuite_uses_ec |
#define ssl_ciphersuite_uses_psk mbedtls_ssl_ciphersuite_uses_psk |
#define ssl_close_notify mbedtls_ssl_close_notify |
#define ssl_context mbedtls_ssl_context |
#define ssl_cookie_check mbedtls_ssl_cookie_check |
#define ssl_cookie_check_t mbedtls_ssl_cookie_check_t |
#define ssl_cookie_ctx mbedtls_ssl_cookie_ctx |
#define ssl_cookie_free mbedtls_ssl_cookie_free |
#define ssl_cookie_init mbedtls_ssl_cookie_init |
#define ssl_cookie_set_timeout mbedtls_ssl_cookie_set_timeout |
#define ssl_cookie_setup mbedtls_ssl_cookie_setup |
#define ssl_cookie_write mbedtls_ssl_cookie_write |
#define ssl_cookie_write_t mbedtls_ssl_cookie_write_t |
#define ssl_derive_keys mbedtls_ssl_derive_keys |
#define ssl_dtls_replay_check mbedtls_ssl_dtls_replay_check |
#define ssl_dtls_replay_update mbedtls_ssl_dtls_replay_update |
#define ssl_fetch_input mbedtls_ssl_fetch_input |
#define ssl_flight_item mbedtls_ssl_flight_item |
#define ssl_flush_output mbedtls_ssl_flush_output |
#define ssl_free mbedtls_ssl_free |
#define ssl_get_alpn_protocol mbedtls_ssl_get_alpn_protocol |
#define ssl_get_bytes_avail mbedtls_ssl_get_bytes_avail |
#define ssl_get_ciphersuite mbedtls_ssl_get_ciphersuite |
#define ssl_get_ciphersuite_id mbedtls_ssl_get_ciphersuite_id |
#define ssl_get_ciphersuite_name mbedtls_ssl_get_ciphersuite_name |
#define ssl_get_ciphersuite_sig_pk_alg mbedtls_ssl_get_ciphersuite_sig_pk_alg |
#define ssl_get_peer_cert mbedtls_ssl_get_peer_cert |
#define ssl_get_record_expansion mbedtls_ssl_get_record_expansion |
#define ssl_get_session mbedtls_ssl_get_session |
#define ssl_get_verify_result mbedtls_ssl_get_verify_result |
#define ssl_get_version mbedtls_ssl_get_version |
#define ssl_handshake mbedtls_ssl_handshake |
#define ssl_handshake_client_step mbedtls_ssl_handshake_client_step |
#define ssl_handshake_free mbedtls_ssl_handshake_free |
#define ssl_handshake_params mbedtls_ssl_handshake_params |
#define ssl_handshake_server_step mbedtls_ssl_handshake_server_step |
#define ssl_handshake_step mbedtls_ssl_handshake_step |
#define ssl_handshake_wrapup mbedtls_ssl_handshake_wrapup |
#define ssl_hdr_len mbedtls_ssl_hdr_len |
#define ssl_hs_hdr_len mbedtls_ssl_hs_hdr_len |
#define ssl_hw_record_activate mbedtls_ssl_hw_record_activate |
#define ssl_hw_record_finish mbedtls_ssl_hw_record_finish |
#define ssl_hw_record_init mbedtls_ssl_hw_record_init |
#define ssl_hw_record_read mbedtls_ssl_hw_record_read |
#define ssl_hw_record_reset mbedtls_ssl_hw_record_reset |
#define ssl_hw_record_write mbedtls_ssl_hw_record_write |
#define ssl_init mbedtls_ssl_init |
#define ssl_key_cert mbedtls_ssl_key_cert |
#define ssl_legacy_renegotiation mbedtls_ssl_conf_legacy_renegotiation |
#define ssl_list_ciphersuites mbedtls_ssl_list_ciphersuites |
#define ssl_md_alg_from_hash mbedtls_ssl_md_alg_from_hash |
#define ssl_optimize_checksum mbedtls_ssl_optimize_checksum |
#define ssl_own_cert mbedtls_ssl_own_cert |
#define ssl_own_key mbedtls_ssl_own_key |
#define ssl_parse_certificate mbedtls_ssl_parse_certificate |
#define ssl_parse_change_cipher_spec mbedtls_ssl_parse_change_cipher_spec |
#define ssl_parse_finished mbedtls_ssl_parse_finished |
#define ssl_pk_alg_from_sig mbedtls_ssl_pk_alg_from_sig |
#define ssl_pkcs11_decrypt mbedtls_ssl_pkcs11_decrypt |
#define ssl_pkcs11_key_len mbedtls_ssl_pkcs11_key_len |
#define ssl_pkcs11_sign mbedtls_ssl_pkcs11_sign |
#define ssl_psk_derive_premaster mbedtls_ssl_psk_derive_premaster |
#define ssl_read mbedtls_ssl_read |
#define ssl_read_record mbedtls_ssl_read_record |
#define ssl_read_version mbedtls_ssl_read_version |
#define ssl_recv_flight_completed mbedtls_ssl_recv_flight_completed |
#define ssl_renegotiate mbedtls_ssl_renegotiate |
#define ssl_resend mbedtls_ssl_resend |
#define ssl_reset_checksum mbedtls_ssl_reset_checksum |
#define ssl_send_alert_message mbedtls_ssl_send_alert_message |
#define ssl_send_fatal_handshake_failure mbedtls_ssl_send_fatal_handshake_failure |
#define ssl_send_flight_completed mbedtls_ssl_send_flight_completed |
#define ssl_session mbedtls_ssl_session |
#define ssl_session_free mbedtls_ssl_session_free |
#define ssl_session_init mbedtls_ssl_session_init |
#define ssl_session_reset mbedtls_ssl_session_reset |
#define ssl_set_alpn_protocols mbedtls_ssl_conf_alpn_protocols |
#define ssl_set_arc4_support mbedtls_ssl_conf_arc4_support |
#define ssl_set_authmode mbedtls_ssl_conf_authmode |
#define ssl_set_bio mbedtls_ssl_set_bio |
#define ssl_set_ca_chain mbedtls_ssl_conf_ca_chain |
#define ssl_set_cbc_record_splitting mbedtls_ssl_conf_cbc_record_splitting |
#define ssl_set_ciphersuites mbedtls_ssl_conf_ciphersuites |
#define ssl_set_ciphersuites_for_version mbedtls_ssl_conf_ciphersuites_for_version |
#define ssl_set_client_transport_id mbedtls_ssl_set_client_transport_id |
#define ssl_set_curves mbedtls_ssl_conf_curves |
#define ssl_set_dbg mbedtls_ssl_conf_dbg |
#define ssl_set_dh_param mbedtls_ssl_conf_dh_param |
#define ssl_set_dh_param_ctx mbedtls_ssl_conf_dh_param_ctx |
#define ssl_set_dtls_anti_replay mbedtls_ssl_conf_dtls_anti_replay |
#define ssl_set_dtls_badmac_limit mbedtls_ssl_conf_dtls_badmac_limit |
#define ssl_set_dtls_cookies mbedtls_ssl_conf_dtls_cookies |
#define ssl_set_encrypt_then_mac mbedtls_ssl_conf_encrypt_then_mac |
#define ssl_set_endpoint mbedtls_ssl_conf_endpoint |
#define ssl_set_extended_master_secret mbedtls_ssl_conf_extended_master_secret |
#define ssl_set_fallback mbedtls_ssl_conf_fallback |
#define ssl_set_handshake_timeout mbedtls_ssl_conf_handshake_timeout |
#define ssl_set_hostname mbedtls_ssl_set_hostname |
#define ssl_set_max_frag_len mbedtls_ssl_conf_max_frag_len |
#define ssl_set_max_version mbedtls_ssl_conf_max_version |
#define ssl_set_min_version mbedtls_ssl_conf_min_version |
#define ssl_set_own_cert mbedtls_ssl_conf_own_cert |
#define ssl_set_psk mbedtls_ssl_conf_psk |
#define ssl_set_psk_cb mbedtls_ssl_conf_psk_cb |
#define ssl_set_renegotiation mbedtls_ssl_conf_renegotiation |
#define ssl_set_renegotiation_enforced mbedtls_ssl_conf_renegotiation_enforced |
#define ssl_set_renegotiation_period mbedtls_ssl_conf_renegotiation_period |
#define ssl_set_rng mbedtls_ssl_conf_rng |
#define ssl_set_session mbedtls_ssl_set_session |
#define ssl_set_session_cache mbedtls_ssl_conf_session_cache |
#define ssl_set_session_tickets mbedtls_ssl_conf_session_tickets |
#define ssl_set_sni mbedtls_ssl_conf_sni |
#define ssl_set_transport mbedtls_ssl_conf_transport |
#define ssl_set_truncated_hmac mbedtls_ssl_conf_truncated_hmac |
#define ssl_set_verify mbedtls_ssl_conf_verify |
#define ssl_sig_from_pk mbedtls_ssl_sig_from_pk |
#define ssl_states mbedtls_ssl_states |
#define ssl_transform mbedtls_ssl_transform |
#define ssl_transform_free mbedtls_ssl_transform_free |
#define ssl_write mbedtls_ssl_write |
#define ssl_write_certificate mbedtls_ssl_write_certificate |
#define ssl_write_change_cipher_spec mbedtls_ssl_write_change_cipher_spec |
#define ssl_write_finished mbedtls_ssl_write_finished |
#define ssl_write_record mbedtls_ssl_write_record |
#define ssl_write_version mbedtls_ssl_write_version |
#define supported_ciphers mbedtls_cipher_supported |
#define t_sint mbedtls_mpi_sint |
#define t_udbl mbedtls_t_udbl |
#define t_uint mbedtls_mpi_uint |
#define test_ca_crt mbedtls_test_ca_crt |
#define test_ca_crt_ec mbedtls_test_ca_crt_ec |
#define test_ca_crt_rsa mbedtls_test_ca_crt_rsa |
#define test_ca_key mbedtls_test_ca_key |
#define test_ca_key_ec mbedtls_test_ca_key_ec |
#define test_ca_key_rsa mbedtls_test_ca_key_rsa |
#define test_ca_list mbedtls_test_cas_pem |
#define test_ca_pwd mbedtls_test_ca_pwd |
#define test_ca_pwd_ec mbedtls_test_ca_pwd_ec |
#define test_ca_pwd_rsa mbedtls_test_ca_pwd_rsa |
#define test_cli_crt mbedtls_test_cli_crt |
#define test_cli_crt_ec mbedtls_test_cli_crt_ec |
#define test_cli_crt_rsa mbedtls_test_cli_crt_rsa |
#define test_cli_key mbedtls_test_cli_key |
#define test_cli_key_ec mbedtls_test_cli_key_ec |
#define test_cli_key_rsa mbedtls_test_cli_key_rsa |
#define test_srv_crt mbedtls_test_srv_crt |
#define test_srv_crt_ec mbedtls_test_srv_crt_ec |
#define test_srv_crt_rsa mbedtls_test_srv_crt_rsa |
#define test_srv_key mbedtls_test_srv_key |
#define test_srv_key_ec mbedtls_test_srv_key_ec |
#define test_srv_key_rsa mbedtls_test_srv_key_rsa |
#define threading_mutex_t mbedtls_threading_mutex_t |
#define threading_set_alt mbedtls_threading_set_alt |
#define timing_self_test mbedtls_timing_self_test |
#define version_check_feature mbedtls_version_check_feature |
#define version_get_number mbedtls_version_get_number |
#define version_get_string mbedtls_version_get_string |
#define version_get_string_full mbedtls_version_get_string_full |
#define x509_bitstring mbedtls_x509_bitstring |
#define x509_buf mbedtls_x509_buf |
#define x509_crl mbedtls_x509_crl |
#define x509_crl_entry mbedtls_x509_crl_entry |
#define x509_crl_free mbedtls_x509_crl_free |
#define x509_crl_info mbedtls_x509_crl_info |
#define x509_crl_init mbedtls_x509_crl_init |
#define x509_crl_parse mbedtls_x509_crl_parse |
#define x509_crl_parse_der mbedtls_x509_crl_parse_der |
#define x509_crl_parse_file mbedtls_x509_crl_parse_file |
#define x509_crt mbedtls_x509_crt |
#define x509_crt_check_extended_key_usage mbedtls_x509_crt_check_extended_key_usage |
#define x509_crt_check_key_usage mbedtls_x509_crt_check_key_usage |
#define x509_crt_free mbedtls_x509_crt_free |
#define x509_crt_info mbedtls_x509_crt_info |
#define x509_crt_init mbedtls_x509_crt_init |
#define x509_crt_parse mbedtls_x509_crt_parse |
#define x509_crt_parse_der mbedtls_x509_crt_parse_der |
#define x509_crt_parse_file mbedtls_x509_crt_parse_file |
#define x509_crt_parse_path mbedtls_x509_crt_parse_path |
#define x509_crt_revoked mbedtls_x509_crt_is_revoked |
#define x509_crt_verify mbedtls_x509_crt_verify |
#define x509_csr mbedtls_x509_csr |
#define x509_csr_free mbedtls_x509_csr_free |
#define x509_csr_info mbedtls_x509_csr_info |
#define x509_csr_init mbedtls_x509_csr_init |
#define x509_csr_parse mbedtls_x509_csr_parse |
#define x509_csr_parse_der mbedtls_x509_csr_parse_der |
#define x509_csr_parse_file mbedtls_x509_csr_parse_file |
#define x509_dn_gets mbedtls_x509_dn_gets |
#define x509_get_alg mbedtls_x509_get_alg |
#define x509_get_alg_null mbedtls_x509_get_alg_null |
#define x509_get_ext mbedtls_x509_get_ext |
#define x509_get_name mbedtls_x509_get_name |
#define x509_get_rsassa_pss_params mbedtls_x509_get_rsassa_pss_params |
#define x509_get_serial mbedtls_x509_get_serial |
#define x509_get_sig mbedtls_x509_get_sig |
#define x509_get_sig_alg mbedtls_x509_get_sig_alg |
#define x509_get_time mbedtls_x509_get_time |
#define x509_key_size_helper mbedtls_x509_key_size_helper |
#define x509_name mbedtls_x509_name |
#define x509_self_test mbedtls_x509_self_test |
#define x509_sequence mbedtls_x509_sequence |
#define x509_serial_gets mbedtls_x509_serial_gets |
#define x509_set_extension mbedtls_x509_set_extension |
#define x509_sig_alg_gets mbedtls_x509_sig_alg_gets |
#define x509_string_to_names mbedtls_x509_string_to_names |
#define x509_time mbedtls_x509_time |
#define x509_time_expired mbedtls_x509_time_is_past |
#define x509_time_future mbedtls_x509_time_is_future |
#define x509_write_extensions mbedtls_x509_write_extensions |
#define x509_write_names mbedtls_x509_write_names |
#define x509_write_sig mbedtls_x509_write_sig |
#define x509write_cert mbedtls_x509write_cert |
#define x509write_crt_der mbedtls_x509write_crt_der |
#define x509write_crt_free mbedtls_x509write_crt_free |
#define x509write_crt_init mbedtls_x509write_crt_init |
#define x509write_crt_pem mbedtls_x509write_crt_pem |
#define x509write_crt_set_authority_key_identifier mbedtls_x509write_crt_set_authority_key_identifier |
#define x509write_crt_set_basic_constraints mbedtls_x509write_crt_set_basic_constraints |
#define x509write_crt_set_extension mbedtls_x509write_crt_set_extension |
#define x509write_crt_set_issuer_key mbedtls_x509write_crt_set_issuer_key |
#define x509write_crt_set_issuer_name mbedtls_x509write_crt_set_issuer_name |
#define x509write_crt_set_key_usage mbedtls_x509write_crt_set_key_usage |
#define x509write_crt_set_md_alg mbedtls_x509write_crt_set_md_alg |
#define x509write_crt_set_ns_cert_type mbedtls_x509write_crt_set_ns_cert_type |
#define x509write_crt_set_serial mbedtls_x509write_crt_set_serial |
#define x509write_crt_set_subject_key mbedtls_x509write_crt_set_subject_key |
#define x509write_crt_set_subject_key_identifier mbedtls_x509write_crt_set_subject_key_identifier |
#define x509write_crt_set_subject_name mbedtls_x509write_crt_set_subject_name |
#define x509write_crt_set_validity mbedtls_x509write_crt_set_validity |
#define x509write_crt_set_version mbedtls_x509write_crt_set_version |
#define x509write_csr mbedtls_x509write_csr |
#define x509write_csr_der mbedtls_x509write_csr_der |
#define x509write_csr_free mbedtls_x509write_csr_free |
#define x509write_csr_init mbedtls_x509write_csr_init |
#define x509write_csr_pem mbedtls_x509write_csr_pem |
#define x509write_csr_set_extension mbedtls_x509write_csr_set_extension |
#define x509write_csr_set_key mbedtls_x509write_csr_set_key |
#define x509write_csr_set_key_usage mbedtls_x509write_csr_set_key_usage |
#define x509write_csr_set_md_alg mbedtls_x509write_csr_set_md_alg |
#define x509write_csr_set_ns_cert_type mbedtls_x509write_csr_set_ns_cert_type |
#define x509write_csr_set_subject_name mbedtls_x509write_csr_set_subject_name |
#define xtea_context mbedtls_xtea_context |
#define xtea_crypt_cbc mbedtls_xtea_crypt_cbc |
#define xtea_crypt_ecb mbedtls_xtea_crypt_ecb |
#define xtea_free mbedtls_xtea_free |
#define xtea_init mbedtls_xtea_init |
#define xtea_self_test mbedtls_xtea_self_test |
#define xtea_setup mbedtls_xtea_setup |
#endif /* compat-1.3.h */ |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/config.h |
---|
0,0 → 1,3350 |
/** |
* \file config.h |
* |
* \brief Configuration options (set of defines) |
* |
* This set of compile-time options may be used to enable |
* or disable features selectively, and reduce the global |
* memory footprint. |
*/ |
/* |
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CONFIG_H |
#define MBEDTLS_CONFIG_H |
#undef _WIN32 |
#undef _WIN32_WCE |
#undef _WIN32_WINNT |
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) |
#define _CRT_SECURE_NO_DEPRECATE 1 |
#endif |
/** |
* \name SECTION: System support |
* |
* This section sets system specific settings. |
* \{ |
*/ |
/** |
* \def MBEDTLS_HAVE_ASM |
* |
* The compiler has support for asm(). |
* |
* Requires support for asm() in compiler. |
* |
* Used in: |
* library/aria.c |
* library/timing.c |
* include/mbedtls/bn_mul.h |
* |
* Required by: |
* MBEDTLS_AESNI_C |
* MBEDTLS_PADLOCK_C |
* |
* Comment to disable the use of assembly code. |
*/ |
#define MBEDTLS_HAVE_ASM |
/** |
* \def MBEDTLS_NO_UDBL_DIVISION |
* |
* The platform lacks support for double-width integer division (64-bit |
* division on a 32-bit platform, 128-bit division on a 64-bit platform). |
* |
* Used in: |
* include/mbedtls/bignum.h |
* library/bignum.c |
* |
* The bignum code uses double-width division to speed up some operations. |
* Double-width division is often implemented in software that needs to |
* be linked with the program. The presence of a double-width integer |
* type is usually detected automatically through preprocessor macros, |
* but the automatic detection cannot know whether the code needs to |
* and can be linked with an implementation of division for that type. |
* By default division is assumed to be usable if the type is present. |
* Uncomment this option to prevent the use of double-width division. |
* |
* Note that division for the native integer type is always required. |
* Furthermore, a 64-bit type is always required even on a 32-bit |
* platform, but it need not support multiplication or division. In some |
* cases it is also desirable to disable some double-width operations. For |
* example, if double-width division is implemented in software, disabling |
* it can reduce code size in some embedded targets. |
*/ |
//#define MBEDTLS_NO_UDBL_DIVISION |
/** |
* \def MBEDTLS_NO_64BIT_MULTIPLICATION |
* |
* The platform lacks support for 32x32 -> 64-bit multiplication. |
* |
* Used in: |
* library/poly1305.c |
* |
* Some parts of the library may use multiplication of two unsigned 32-bit |
* operands with a 64-bit result in order to speed up computations. On some |
* platforms, this is not available in hardware and has to be implemented in |
* software, usually in a library provided by the toolchain. |
* |
* Sometimes it is not desirable to have to link to that library. This option |
* removes the dependency of that library on platforms that lack a hardware |
* 64-bit multiplier by embedding a software implementation in Mbed TLS. |
* |
* Note that depending on the compiler, this may decrease performance compared |
* to using the library function provided by the toolchain. |
*/ |
//#define MBEDTLS_NO_64BIT_MULTIPLICATION |
/** |
* \def MBEDTLS_HAVE_SSE2 |
* |
* CPU supports SSE2 instruction set. |
* |
* Uncomment if the CPU supports SSE2 (IA-32 specific). |
*/ |
//#define MBEDTLS_HAVE_SSE2 |
/** |
* \def MBEDTLS_HAVE_TIME |
* |
* System has time.h and time(). |
* The time does not need to be correct, only time differences are used, |
* by contrast with MBEDTLS_HAVE_TIME_DATE |
* |
* Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, |
* MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and |
* MBEDTLS_PLATFORM_STD_TIME. |
* |
* Comment if your system does not support time functions |
*/ |
#define MBEDTLS_HAVE_TIME |
/** |
* \def MBEDTLS_HAVE_TIME_DATE |
* |
* System has time.h, time(), and an implementation for |
* mbedtls_platform_gmtime_r() (see below). |
* The time needs to be correct (not necessarily very accurate, but at least |
* the date should be correct). This is used to verify the validity period of |
* X.509 certificates. |
* |
* Comment if your system does not have a correct clock. |
* |
* \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that |
* behaves similarly to the gmtime_r() function from the C standard. Refer to |
* the documentation for mbedtls_platform_gmtime_r() for more information. |
* |
* \note It is possible to configure an implementation for |
* mbedtls_platform_gmtime_r() at compile-time by using the macro |
* MBEDTLS_PLATFORM_GMTIME_R_ALT. |
*/ |
#define MBEDTLS_HAVE_TIME_DATE |
/** |
* \def MBEDTLS_PLATFORM_MEMORY |
* |
* Enable the memory allocation layer. |
* |
* By default mbed TLS uses the system-provided calloc() and free(). |
* This allows different allocators (self-implemented or provided) to be |
* provided to the platform abstraction layer. |
* |
* Enabling MBEDTLS_PLATFORM_MEMORY without the |
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide |
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and |
* free() function pointer at runtime. |
* |
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying |
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the |
* alternate function at compile time. |
* |
* Requires: MBEDTLS_PLATFORM_C |
* |
* Enable this layer to allow use of alternative memory allocators. |
*/ |
//#define MBEDTLS_PLATFORM_MEMORY |
/** |
* \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS |
* |
* Do not assign standard functions in the platform layer (e.g. calloc() to |
* MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) |
* |
* This makes sure there are no linking errors on platforms that do not support |
* these functions. You will HAVE to provide alternatives, either at runtime |
* via the platform_set_xxx() functions or at compile time by setting |
* the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a |
* MBEDTLS_PLATFORM_XXX_MACRO. |
* |
* Requires: MBEDTLS_PLATFORM_C |
* |
* Uncomment to prevent default assignment of standard functions in the |
* platform layer. |
*/ |
//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS |
/** |
* \def MBEDTLS_PLATFORM_EXIT_ALT |
* |
* MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the |
* function in the platform abstraction layer. |
* |
* Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will |
* provide a function "mbedtls_platform_set_printf()" that allows you to set an |
* alternative printf function pointer. |
* |
* All these define require MBEDTLS_PLATFORM_C to be defined! |
* |
* \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; |
* it will be enabled automatically by check_config.h |
* |
* \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as |
* MBEDTLS_PLATFORM_XXX_MACRO! |
* |
* Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME |
* |
* Uncomment a macro to enable alternate implementation of specific base |
* platform function |
*/ |
//#define MBEDTLS_PLATFORM_EXIT_ALT |
//#define MBEDTLS_PLATFORM_TIME_ALT |
//#define MBEDTLS_PLATFORM_FPRINTF_ALT |
//#define MBEDTLS_PLATFORM_PRINTF_ALT |
//#define MBEDTLS_PLATFORM_SNPRINTF_ALT |
//#define MBEDTLS_PLATFORM_NV_SEED_ALT |
//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT |
/** |
* \def MBEDTLS_DEPRECATED_WARNING |
* |
* Mark deprecated functions so that they generate a warning if used. |
* Functions deprecated in one version will usually be removed in the next |
* version. You can enable this to help you prepare the transition to a new |
* major version by making sure your code is not using these functions. |
* |
* This only works with GCC and Clang. With other compilers, you may want to |
* use MBEDTLS_DEPRECATED_REMOVED |
* |
* Uncomment to get warnings on using deprecated functions. |
*/ |
//#define MBEDTLS_DEPRECATED_WARNING |
/** |
* \def MBEDTLS_DEPRECATED_REMOVED |
* |
* Remove deprecated functions so that they generate an error if used. |
* Functions deprecated in one version will usually be removed in the next |
* version. You can enable this to help you prepare the transition to a new |
* major version by making sure your code is not using these functions. |
* |
* Uncomment to get errors on using deprecated functions. |
*/ |
//#define MBEDTLS_DEPRECATED_REMOVED |
/** |
* \def MBEDTLS_CHECK_PARAMS |
* |
* This configuration option controls whether the library validates more of |
* the parameters passed to it. |
* |
* When this flag is not defined, the library only attempts to validate an |
* input parameter if: (1) they may come from the outside world (such as the |
* network, the filesystem, etc.) or (2) not validating them could result in |
* internal memory errors such as overflowing a buffer controlled by the |
* library. On the other hand, it doesn't attempt to validate parameters whose |
* values are fully controlled by the application (such as pointers). |
* |
* When this flag is defined, the library additionally attempts to validate |
* parameters that are fully controlled by the application, and should always |
* be valid if the application code is fully correct and trusted. |
* |
* For example, when a function accepts as input a pointer to a buffer that may |
* contain untrusted data, and its documentation mentions that this pointer |
* must not be NULL: |
* - The pointer is checked to be non-NULL only if this option is enabled. |
* - The content of the buffer is always validated. |
* |
* When this flag is defined, if a library function receives a parameter that |
* is invalid: |
* 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). |
* 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function |
* will immediately return. If the function returns an Mbed TLS error code, |
* the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. |
* |
* When defining this flag, you also need to arrange a definition for |
* MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: |
* - By default, the library defines MBEDTLS_PARAM_FAILED() to call a |
* function mbedtls_param_failed(), but the library does not define this |
* function. If you do not make any other arrangements, you must provide |
* the function mbedtls_param_failed() in your application. |
* See `platform_util.h` for its prototype. |
* - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the |
* library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. |
* You can still supply an alternative definition of |
* MBEDTLS_PARAM_FAILED(), which may call `assert`. |
* - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` |
* or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, |
* the library will call the macro that you defined and will not supply |
* its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, |
* you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source |
* files include `<assert.h>`. |
* |
* Uncomment to enable validation of application-controlled parameters. |
*/ |
//#define MBEDTLS_CHECK_PARAMS |
/** |
* \def MBEDTLS_CHECK_PARAMS_ASSERT |
* |
* Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to |
* `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. |
* |
* If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to |
* calling a function mbedtls_param_failed(). See the documentation of |
* #MBEDTLS_CHECK_PARAMS for details. |
* |
* Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. |
*/ |
//#define MBEDTLS_CHECK_PARAMS_ASSERT |
/* \} name SECTION: System support */ |
/** |
* \name SECTION: mbed TLS feature support |
* |
* This section sets support for features that are or are not needed |
* within the modules that are enabled. |
* \{ |
*/ |
/** |
* \def MBEDTLS_TIMING_ALT |
* |
* Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), |
* mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() |
* |
* Only works if you have MBEDTLS_TIMING_C enabled. |
* |
* You will need to provide a header "timing_alt.h" and an implementation at |
* compile time. |
*/ |
//#define MBEDTLS_TIMING_ALT |
/** |
* \def MBEDTLS_AES_ALT |
* |
* MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your |
* alternate core implementation of a symmetric crypto, an arithmetic or hash |
* module (e.g. platform specific assembly optimized implementations). Keep |
* in mind that the function prototypes should remain the same. |
* |
* This replaces the whole module. If you only want to replace one of the |
* functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. |
* |
* Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer |
* provide the "struct mbedtls_aes_context" definition and omit the base |
* function declarations and implementations. "aes_alt.h" will be included from |
* "aes.h" to include the new function definitions. |
* |
* Uncomment a macro to enable alternate implementation of the corresponding |
* module. |
* |
* \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their |
* use constitutes a security risk. If possible, we recommend |
* avoiding dependencies on them, and considering stronger message |
* digests and ciphers instead. |
* |
*/ |
//#define MBEDTLS_AES_ALT |
//#define MBEDTLS_ARC4_ALT |
//#define MBEDTLS_ARIA_ALT |
//#define MBEDTLS_BLOWFISH_ALT |
//#define MBEDTLS_CAMELLIA_ALT |
//#define MBEDTLS_CCM_ALT |
//#define MBEDTLS_CHACHA20_ALT |
//#define MBEDTLS_CHACHAPOLY_ALT |
//#define MBEDTLS_CMAC_ALT |
//#define MBEDTLS_DES_ALT |
//#define MBEDTLS_DHM_ALT |
//#define MBEDTLS_ECJPAKE_ALT |
//#define MBEDTLS_GCM_ALT |
//#define MBEDTLS_NIST_KW_ALT |
//#define MBEDTLS_MD2_ALT |
//#define MBEDTLS_MD4_ALT |
//#define MBEDTLS_MD5_ALT |
//#define MBEDTLS_POLY1305_ALT |
//#define MBEDTLS_RIPEMD160_ALT |
//#define MBEDTLS_RSA_ALT |
//#define MBEDTLS_SHA1_ALT |
//#define MBEDTLS_SHA256_ALT |
//#define MBEDTLS_SHA512_ALT |
//#define MBEDTLS_XTEA_ALT |
/* |
* When replacing the elliptic curve module, pleace consider, that it is |
* implemented with two .c files: |
* - ecp.c |
* - ecp_curves.c |
* You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT |
* macros as described above. The only difference is that you have to make sure |
* that you provide functionality for both .c files. |
*/ |
//#define MBEDTLS_ECP_ALT |
/** |
* \def MBEDTLS_MD2_PROCESS_ALT |
* |
* MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you |
* alternate core implementation of symmetric crypto or hash function. Keep in |
* mind that function prototypes should remain the same. |
* |
* This replaces only one function. The header file from mbed TLS is still |
* used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. |
* |
* Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will |
* no longer provide the mbedtls_sha1_process() function, but it will still provide |
* the other function (using your mbedtls_sha1_process() function) and the definition |
* of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible |
* with this definition. |
* |
* \note Because of a signature change, the core AES encryption and decryption routines are |
* currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, |
* respectively. When setting up alternative implementations, these functions should |
* be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt |
* must stay untouched. |
* |
* \note If you use the AES_xxx_ALT macros, then is is recommended to also set |
* MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES |
* tables. |
* |
* Uncomment a macro to enable alternate implementation of the corresponding |
* function. |
* |
* \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use |
* constitutes a security risk. If possible, we recommend avoiding |
* dependencies on them, and considering stronger message digests |
* and ciphers instead. |
* |
* \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are |
* enabled, then the deterministic ECDH signature functions pass the |
* the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore |
* alternative implementations should use the RNG only for generating |
* the ephemeral key and nothing else. If this is not possible, then |
* MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative |
* implementation should be provided for mbedtls_ecdsa_sign_det_ext() |
* (and for mbedtls_ecdsa_sign_det() too if backward compatibility is |
* desirable). |
* |
*/ |
//#define MBEDTLS_MD2_PROCESS_ALT |
//#define MBEDTLS_MD4_PROCESS_ALT |
//#define MBEDTLS_MD5_PROCESS_ALT |
//#define MBEDTLS_RIPEMD160_PROCESS_ALT |
//#define MBEDTLS_SHA1_PROCESS_ALT |
//#define MBEDTLS_SHA256_PROCESS_ALT |
//#define MBEDTLS_SHA512_PROCESS_ALT |
//#define MBEDTLS_DES_SETKEY_ALT |
//#define MBEDTLS_DES_CRYPT_ECB_ALT |
//#define MBEDTLS_DES3_CRYPT_ECB_ALT |
//#define MBEDTLS_AES_SETKEY_ENC_ALT |
//#define MBEDTLS_AES_SETKEY_DEC_ALT |
//#define MBEDTLS_AES_ENCRYPT_ALT |
//#define MBEDTLS_AES_DECRYPT_ALT |
//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT |
//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT |
//#define MBEDTLS_ECDSA_VERIFY_ALT |
//#define MBEDTLS_ECDSA_SIGN_ALT |
//#define MBEDTLS_ECDSA_GENKEY_ALT |
/** |
* \def MBEDTLS_ECP_INTERNAL_ALT |
* |
* Expose a part of the internal interface of the Elliptic Curve Point module. |
* |
* MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your |
* alternative core implementation of elliptic curve arithmetic. Keep in mind |
* that function prototypes should remain the same. |
* |
* This partially replaces one function. The header file from mbed TLS is still |
* used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation |
* is still present and it is used for group structures not supported by the |
* alternative. |
* |
* Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT |
* and implementing the following functions: |
* unsigned char mbedtls_internal_ecp_grp_capable( |
* const mbedtls_ecp_group *grp ) |
* int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) |
* void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) |
* The mbedtls_internal_ecp_grp_capable function should return 1 if the |
* replacement functions implement arithmetic for the given group and 0 |
* otherwise. |
* The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are |
* called before and after each point operation and provide an opportunity to |
* implement optimized set up and tear down instructions. |
* |
* Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and |
* MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac |
* function, but will use your mbedtls_internal_ecp_double_jac if the group is |
* supported (your mbedtls_internal_ecp_grp_capable function returns 1 when |
* receives it as an argument). If the group is not supported then the original |
* implementation is used. The other functions and the definition of |
* mbedtls_ecp_group and mbedtls_ecp_point will not change, so your |
* implementation of mbedtls_internal_ecp_double_jac and |
* mbedtls_internal_ecp_grp_capable must be compatible with this definition. |
* |
* Uncomment a macro to enable alternate implementation of the corresponding |
* function. |
*/ |
/* Required for all the functions in this section */ |
//#define MBEDTLS_ECP_INTERNAL_ALT |
/* Support for Weierstrass curves with Jacobi representation */ |
//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT |
//#define MBEDTLS_ECP_ADD_MIXED_ALT |
//#define MBEDTLS_ECP_DOUBLE_JAC_ALT |
//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT |
//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT |
/* Support for curves with Montgomery arithmetic */ |
//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT |
//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT |
//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT |
/** |
* \def MBEDTLS_TEST_NULL_ENTROPY |
* |
* Enables testing and use of mbed TLS without any configured entropy sources. |
* This permits use of the library on platforms before an entropy source has |
* been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the |
* MBEDTLS_ENTROPY_NV_SEED switches). |
* |
* WARNING! This switch MUST be disabled in production builds, and is suitable |
* only for development. |
* Enabling the switch negates any security provided by the library. |
* |
* Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES |
* |
*/ |
//#define MBEDTLS_TEST_NULL_ENTROPY |
/** |
* \def MBEDTLS_ENTROPY_HARDWARE_ALT |
* |
* Uncomment this macro to let mbed TLS use your own implementation of a |
* hardware entropy collector. |
* |
* Your function must be called \c mbedtls_hardware_poll(), have the same |
* prototype as declared in entropy_poll.h, and accept NULL as first argument. |
* |
* Uncomment to use your own hardware entropy collector. |
*/ |
//#define MBEDTLS_ENTROPY_HARDWARE_ALT |
/** |
* \def MBEDTLS_AES_ROM_TABLES |
* |
* Use precomputed AES tables stored in ROM. |
* |
* Uncomment this macro to use precomputed AES tables stored in ROM. |
* Comment this macro to generate AES tables in RAM at runtime. |
* |
* Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb |
* (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the |
* initialization time before the first AES operation can be performed. |
* It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c |
* MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded |
* performance if ROM access is slower than RAM access. |
* |
* This option is independent of \c MBEDTLS_AES_FEWER_TABLES. |
* |
*/ |
//#define MBEDTLS_AES_ROM_TABLES |
/** |
* \def MBEDTLS_AES_FEWER_TABLES |
* |
* Use less ROM/RAM for AES tables. |
* |
* Uncommenting this macro omits 75% of the AES tables from |
* ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) |
* by computing their values on the fly during operations |
* (the tables are entry-wise rotations of one another). |
* |
* Tradeoff: Uncommenting this reduces the RAM / ROM footprint |
* by ~6kb but at the cost of more arithmetic operations during |
* runtime. Specifically, one has to compare 4 accesses within |
* different tables to 4 accesses with additional arithmetic |
* operations within the same table. The performance gain/loss |
* depends on the system and memory details. |
* |
* This option is independent of \c MBEDTLS_AES_ROM_TABLES. |
* |
*/ |
//#define MBEDTLS_AES_FEWER_TABLES |
/** |
* \def MBEDTLS_CAMELLIA_SMALL_MEMORY |
* |
* Use less ROM for the Camellia implementation (saves about 768 bytes). |
* |
* Uncomment this macro to use less memory for Camellia. |
*/ |
//#define MBEDTLS_CAMELLIA_SMALL_MEMORY |
/** |
* \def MBEDTLS_CIPHER_MODE_CBC |
* |
* Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. |
*/ |
#define MBEDTLS_CIPHER_MODE_CBC |
/** |
* \def MBEDTLS_CIPHER_MODE_CFB |
* |
* Enable Cipher Feedback mode (CFB) for symmetric ciphers. |
*/ |
#define MBEDTLS_CIPHER_MODE_CFB |
/** |
* \def MBEDTLS_CIPHER_MODE_CTR |
* |
* Enable Counter Block Cipher mode (CTR) for symmetric ciphers. |
*/ |
#define MBEDTLS_CIPHER_MODE_CTR |
/** |
* \def MBEDTLS_CIPHER_MODE_OFB |
* |
* Enable Output Feedback mode (OFB) for symmetric ciphers. |
*/ |
#define MBEDTLS_CIPHER_MODE_OFB |
/** |
* \def MBEDTLS_CIPHER_MODE_XTS |
* |
* Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. |
*/ |
#define MBEDTLS_CIPHER_MODE_XTS |
/** |
* \def MBEDTLS_CIPHER_NULL_CIPHER |
* |
* Enable NULL cipher. |
* Warning: Only do so when you know what you are doing. This allows for |
* encryption or channels without any security! |
* |
* Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable |
* the following ciphersuites: |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA |
* MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA |
* MBEDTLS_TLS_RSA_WITH_NULL_SHA256 |
* MBEDTLS_TLS_RSA_WITH_NULL_SHA |
* MBEDTLS_TLS_RSA_WITH_NULL_MD5 |
* MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA |
* MBEDTLS_TLS_PSK_WITH_NULL_SHA384 |
* MBEDTLS_TLS_PSK_WITH_NULL_SHA256 |
* MBEDTLS_TLS_PSK_WITH_NULL_SHA |
* |
* Uncomment this macro to enable the NULL cipher and ciphersuites |
*/ |
//#define MBEDTLS_CIPHER_NULL_CIPHER |
/** |
* \def MBEDTLS_CIPHER_PADDING_PKCS7 |
* |
* MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for |
* specific padding modes in the cipher layer with cipher modes that support |
* padding (e.g. CBC) |
* |
* If you disable all padding modes, only full blocks can be used with CBC. |
* |
* Enable padding modes in the cipher layer. |
*/ |
#define MBEDTLS_CIPHER_PADDING_PKCS7 |
#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS |
#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN |
#define MBEDTLS_CIPHER_PADDING_ZEROS |
/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY |
* |
* Uncomment this macro to use a 128-bit key in the CTR_DRBG module. |
* By default, CTR_DRBG uses a 256-bit key. |
*/ |
//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY |
/** |
* \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES |
* |
* Enable weak ciphersuites in SSL / TLS. |
* Warning: Only do so when you know what you are doing. This allows for |
* channels with virtually no security at all! |
* |
* This enables the following ciphersuites: |
* MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA |
* |
* Uncomment this macro to enable weak ciphersuites |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers instead. |
*/ |
//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES |
/** |
* \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES |
* |
* Remove RC4 ciphersuites by default in SSL / TLS. |
* This flag removes the ciphersuites based on RC4 from the default list as |
* returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to |
* enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them |
* explicitly. |
* |
* Uncomment this macro to remove RC4 ciphersuites by default. |
*/ |
#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES |
/** |
* \def MBEDTLS_REMOVE_3DES_CIPHERSUITES |
* |
* Remove 3DES ciphersuites by default in SSL / TLS. |
* This flag removes the ciphersuites based on 3DES from the default list as |
* returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible |
* to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including |
* them explicitly. |
* |
* A man-in-the-browser attacker can recover authentication tokens sent through |
* a TLS connection using a 3DES based cipher suite (see "On the Practical |
* (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan |
* Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls |
* in your threat model or you are unsure, then you should keep this option |
* enabled to remove 3DES based cipher suites. |
* |
* Comment this macro to keep 3DES in the default ciphersuite list. |
*/ |
#define MBEDTLS_REMOVE_3DES_CIPHERSUITES |
/** |
* \def MBEDTLS_ECP_DP_SECP192R1_ENABLED |
* |
* MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve |
* module. By default all supported curves are enabled. |
* |
* Comment macros to disable the curve and functions for it |
*/ |
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED |
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED |
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED |
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED |
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED |
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED |
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED |
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED |
#define MBEDTLS_ECP_DP_BP256R1_ENABLED |
#define MBEDTLS_ECP_DP_BP384R1_ENABLED |
#define MBEDTLS_ECP_DP_BP512R1_ENABLED |
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED |
#define MBEDTLS_ECP_DP_CURVE448_ENABLED |
/** |
* \def MBEDTLS_ECP_NIST_OPTIM |
* |
* Enable specific 'modulo p' routines for each NIST prime. |
* Depending on the prime and architecture, makes operations 4 to 8 times |
* faster on the corresponding curve. |
* |
* Comment this macro to disable NIST curves optimisation. |
*/ |
#define MBEDTLS_ECP_NIST_OPTIM |
/** |
* \def MBEDTLS_ECP_RESTARTABLE |
* |
* Enable "non-blocking" ECC operations that can return early and be resumed. |
* |
* This allows various functions to pause by returning |
* #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in |
* order to further progress and eventually complete their operation. This is |
* controlled through mbedtls_ecp_set_max_ops() which limits the maximum |
* number of ECC operations a function may perform before pausing; see |
* mbedtls_ecp_set_max_ops() for more information. |
* |
* This is useful in non-threaded environments if you want to avoid blocking |
* for too long on ECC (and, hence, X.509 or SSL/TLS) operations. |
* |
* Uncomment this macro to enable restartable ECC computations. |
* |
* \note This option only works with the default software implementation of |
* elliptic curve functionality. It is incompatible with |
* MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. |
*/ |
//#define MBEDTLS_ECP_RESTARTABLE |
/** |
* \def MBEDTLS_ECDSA_DETERMINISTIC |
* |
* Enable deterministic ECDSA (RFC 6979). |
* Standard ECDSA is "fragile" in the sense that lack of entropy when signing |
* may result in a compromise of the long-term signing key. This is avoided by |
* the deterministic variant. |
* |
* Requires: MBEDTLS_HMAC_DRBG_C |
* |
* Comment this macro to disable deterministic ECDSA. |
*/ |
#define MBEDTLS_ECDSA_DETERMINISTIC |
/** |
* \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED |
* |
* Enable the PSK based ciphersuite modes in SSL / TLS. |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_PSK_WITH_RC4_128_SHA |
*/ |
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED |
* |
* Enable the DHE-PSK based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_DHM_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA |
* |
* \warning Using DHE constitutes a security risk as it |
* is not possible to validate custom DH parameters. |
* If possible, it is recommended users should consider |
* preferring other methods of key exchange. |
* See dhm.h for more details. |
* |
*/ |
#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED |
* |
* Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_ECDH_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA |
*/ |
#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED |
* |
* Enable the RSA-PSK based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, |
* MBEDTLS_X509_CRT_PARSE_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA |
*/ |
#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED |
* |
* Enable the RSA-only based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, |
* MBEDTLS_X509_CRT_PARSE_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 |
*/ |
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED |
* |
* Enable the DHE-RSA based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, |
* MBEDTLS_X509_CRT_PARSE_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA |
* |
* \warning Using DHE constitutes a security risk as it |
* is not possible to validate custom DH parameters. |
* If possible, it is recommended users should consider |
* preferring other methods of key exchange. |
* See dhm.h for more details. |
* |
*/ |
#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED |
* |
* Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, |
* MBEDTLS_X509_CRT_PARSE_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA |
*/ |
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED |
* |
* Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA |
*/ |
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED |
* |
* Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 |
*/ |
#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED |
* |
* Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. |
* |
* Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
*/ |
#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED |
/** |
* \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED |
* |
* Enable the ECJPAKE based ciphersuite modes in SSL / TLS. |
* |
* \warning This is currently experimental. EC J-PAKE support is based on the |
* Thread v1.0.0 specification; incompatible changes to the specification |
* might still happen. For this reason, this is disabled by default. |
* |
* Requires: MBEDTLS_ECJPAKE_C |
* MBEDTLS_SHA256_C |
* MBEDTLS_ECP_DP_SECP256R1_ENABLED |
* |
* This enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 |
*/ |
//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED |
/** |
* \def MBEDTLS_PK_PARSE_EC_EXTENDED |
* |
* Enhance support for reading EC keys using variants of SEC1 not allowed by |
* RFC 5915 and RFC 5480. |
* |
* Currently this means parsing the SpecifiedECDomain choice of EC |
* parameters (only known groups are supported, not arbitrary domains, to |
* avoid validation issues). |
* |
* Disable if you only need to support RFC 5915 + 5480 key formats. |
*/ |
#define MBEDTLS_PK_PARSE_EC_EXTENDED |
/** |
* \def MBEDTLS_ERROR_STRERROR_DUMMY |
* |
* Enable a dummy error function to make use of mbedtls_strerror() in |
* third party libraries easier when MBEDTLS_ERROR_C is disabled |
* (no effect when MBEDTLS_ERROR_C is enabled). |
* |
* You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're |
* not using mbedtls_strerror() or error_strerror() in your application. |
* |
* Disable if you run into name conflicts and want to really remove the |
* mbedtls_strerror() |
*/ |
#define MBEDTLS_ERROR_STRERROR_DUMMY |
/** |
* \def MBEDTLS_GENPRIME |
* |
* Enable the prime-number generation code. |
* |
* Requires: MBEDTLS_BIGNUM_C |
*/ |
#define MBEDTLS_GENPRIME |
/** |
* \def MBEDTLS_FS_IO |
* |
* Enable functions that use the filesystem. |
*/ |
//#define MBEDTLS_FS_IO |
/** |
* \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES |
* |
* Do not add default entropy sources. These are the platform specific, |
* mbedtls_timing_hardclock and HAVEGE based poll functions. |
* |
* This is useful to have more control over the added entropy sources in an |
* application. |
* |
* Uncomment this macro to prevent loading of default entropy functions. |
*/ |
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES |
/** |
* \def MBEDTLS_NO_PLATFORM_ENTROPY |
* |
* Do not use built-in platform entropy functions. |
* This is useful if your platform does not support |
* standards like the /dev/urandom or Windows CryptoAPI. |
* |
* Uncomment this macro to disable the built-in platform entropy functions. |
*/ |
#define MBEDTLS_NO_PLATFORM_ENTROPY |
/** |
* \def MBEDTLS_ENTROPY_FORCE_SHA256 |
* |
* Force the entropy accumulator to use a SHA-256 accumulator instead of the |
* default SHA-512 based one (if both are available). |
* |
* Requires: MBEDTLS_SHA256_C |
* |
* On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option |
* if you have performance concerns. |
* |
* This option is only useful if both MBEDTLS_SHA256_C and |
* MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. |
*/ |
//#define MBEDTLS_ENTROPY_FORCE_SHA256 |
/** |
* \def MBEDTLS_ENTROPY_NV_SEED |
* |
* Enable the non-volatile (NV) seed file-based entropy source. |
* (Also enables the NV seed read/write functions in the platform layer) |
* |
* This is crucial (if not required) on systems that do not have a |
* cryptographic entropy source (in hardware or kernel) available. |
* |
* Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C |
* |
* \note The read/write functions that are used by the entropy source are |
* determined in the platform layer, and can be modified at runtime and/or |
* compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. |
* |
* \note If you use the default implementation functions that read a seedfile |
* with regular fopen(), please make sure you make a seedfile with the |
* proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at |
* least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from |
* and written to or you will get an entropy source error! The default |
* implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE |
* bytes from the file. |
* |
* \note The entropy collector will write to the seed file before entropy is |
* given to an external source, to update it. |
*/ |
//#define MBEDTLS_ENTROPY_NV_SEED |
/** |
* \def MBEDTLS_MEMORY_DEBUG |
* |
* Enable debugging of buffer allocator memory issues. Automatically prints |
* (to stderr) all (fatal) messages on memory allocation issues. Enables |
* function for 'debug output' of allocated memory. |
* |
* Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C |
* |
* Uncomment this macro to let the buffer allocator print out error messages. |
*/ |
//#define MBEDTLS_MEMORY_DEBUG |
/** |
* \def MBEDTLS_MEMORY_BACKTRACE |
* |
* Include backtrace information with each allocated block. |
* |
* Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C |
* GLIBC-compatible backtrace() an backtrace_symbols() support |
* |
* Uncomment this macro to include backtrace information |
*/ |
//#define MBEDTLS_MEMORY_BACKTRACE |
/** |
* \def MBEDTLS_PK_RSA_ALT_SUPPORT |
* |
* Support external private RSA keys (eg from a HSM) in the PK layer. |
* |
* Comment this macro to disable support for external private RSA keys. |
*/ |
#define MBEDTLS_PK_RSA_ALT_SUPPORT |
/** |
* \def MBEDTLS_PKCS1_V15 |
* |
* Enable support for PKCS#1 v1.5 encoding. |
* |
* Requires: MBEDTLS_RSA_C |
* |
* This enables support for PKCS#1 v1.5 operations. |
*/ |
#define MBEDTLS_PKCS1_V15 |
/** |
* \def MBEDTLS_PKCS1_V21 |
* |
* Enable support for PKCS#1 v2.1 encoding. |
* |
* Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C |
* |
* This enables support for RSAES-OAEP and RSASSA-PSS operations. |
*/ |
#define MBEDTLS_PKCS1_V21 |
/** |
* \def MBEDTLS_RSA_NO_CRT |
* |
* Do not use the Chinese Remainder Theorem |
* for the RSA private operation. |
* |
* Uncomment this macro to disable the use of CRT in RSA. |
* |
*/ |
//#define MBEDTLS_RSA_NO_CRT |
/** |
* \def MBEDTLS_SELF_TEST |
* |
* Enable the checkup functions (*_self_test). |
*/ |
#define MBEDTLS_SELF_TEST |
/** |
* \def MBEDTLS_SHA256_SMALLER |
* |
* Enable an implementation of SHA-256 that has lower ROM footprint but also |
* lower performance. |
* |
* The default implementation is meant to be a reasonnable compromise between |
* performance and size. This version optimizes more aggressively for size at |
* the expense of performance. Eg on Cortex-M4 it reduces the size of |
* mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about |
* 30%. |
* |
* Uncomment to enable the smaller implementation of SHA256. |
*/ |
//#define MBEDTLS_SHA256_SMALLER |
/** |
* \def MBEDTLS_SSL_ALL_ALERT_MESSAGES |
* |
* Enable sending of alert messages in case of encountered errors as per RFC. |
* If you choose not to send the alert messages, mbed TLS can still communicate |
* with other servers, only debugging of failures is harder. |
* |
* The advantage of not sending alert messages, is that no information is given |
* about reasons for failures thus preventing adversaries of gaining intel. |
* |
* Enable sending of all alert messages |
*/ |
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES |
/** |
* \def MBEDTLS_SSL_ASYNC_PRIVATE |
* |
* Enable asynchronous external private key operations in SSL. This allows |
* you to configure an SSL connection to call an external cryptographic |
* module to perform private key operations instead of performing the |
* operation inside the library. |
* |
*/ |
//#define MBEDTLS_SSL_ASYNC_PRIVATE |
/** |
* \def MBEDTLS_SSL_DEBUG_ALL |
* |
* Enable the debug messages in SSL module for all issues. |
* Debug messages have been disabled in some places to prevent timing |
* attacks due to (unbalanced) debugging function calls. |
* |
* If you need all error reporting you should enable this during debugging, |
* but remove this for production servers that should log as well. |
* |
* Uncomment this macro to report all debug messages on errors introducing |
* a timing side-channel. |
* |
*/ |
//#define MBEDTLS_SSL_DEBUG_ALL |
/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC |
* |
* Enable support for Encrypt-then-MAC, RFC 7366. |
* |
* This allows peers that both support it to use a more robust protection for |
* ciphersuites using CBC, providing deep resistance against timing attacks |
* on the padding or underlying cipher. |
* |
* This only affects CBC ciphersuites, and is useless if none is defined. |
* |
* Requires: MBEDTLS_SSL_PROTO_TLS1 or |
* MBEDTLS_SSL_PROTO_TLS1_1 or |
* MBEDTLS_SSL_PROTO_TLS1_2 |
* |
* Comment this macro to disable support for Encrypt-then-MAC |
*/ |
#define MBEDTLS_SSL_ENCRYPT_THEN_MAC |
/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET |
* |
* Enable support for Extended Master Secret, aka Session Hash |
* (draft-ietf-tls-session-hash-02). |
* |
* This was introduced as "the proper fix" to the Triple Handshake familiy of |
* attacks, but it is recommended to always use it (even if you disable |
* renegotiation), since it actually fixes a more fundamental issue in the |
* original SSL/TLS design, and has implications beyond Triple Handshake. |
* |
* Requires: MBEDTLS_SSL_PROTO_TLS1 or |
* MBEDTLS_SSL_PROTO_TLS1_1 or |
* MBEDTLS_SSL_PROTO_TLS1_2 |
* |
* Comment this macro to disable support for Extended Master Secret. |
*/ |
#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET |
/** |
* \def MBEDTLS_SSL_FALLBACK_SCSV |
* |
* Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). |
* |
* For servers, it is recommended to always enable this, unless you support |
* only one version of TLS, or know for sure that none of your clients |
* implements a fallback strategy. |
* |
* For clients, you only need this if you're using a fallback strategy, which |
* is not recommended in the first place, unless you absolutely need it to |
* interoperate with buggy (version-intolerant) servers. |
* |
* Comment this macro to disable support for FALLBACK_SCSV |
*/ |
#define MBEDTLS_SSL_FALLBACK_SCSV |
/** |
* \def MBEDTLS_SSL_HW_RECORD_ACCEL |
* |
* Enable hooking functions in SSL module for hardware acceleration of |
* individual records. |
* |
* Uncomment this macro to enable hooking functions. |
*/ |
//#define MBEDTLS_SSL_HW_RECORD_ACCEL |
/** |
* \def MBEDTLS_SSL_CBC_RECORD_SPLITTING |
* |
* Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. |
* |
* This is a countermeasure to the BEAST attack, which also minimizes the risk |
* of interoperability issues compared to sending 0-length records. |
* |
* Comment this macro to disable 1/n-1 record splitting. |
*/ |
#define MBEDTLS_SSL_CBC_RECORD_SPLITTING |
/** |
* \def MBEDTLS_SSL_RENEGOTIATION |
* |
* Enable support for TLS renegotiation. |
* |
* The two main uses of renegotiation are (1) refresh keys on long-lived |
* connections and (2) client authentication after the initial handshake. |
* If you don't need renegotiation, it's probably better to disable it, since |
* it has been associated with security issues in the past and is easy to |
* misuse/misunderstand. |
* |
* Comment this to disable support for renegotiation. |
* |
* \note Even if this option is disabled, both client and server are aware |
* of the Renegotiation Indication Extension (RFC 5746) used to |
* prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). |
* (See \c mbedtls_ssl_conf_legacy_renegotiation for the |
* configuration of this extension). |
* |
*/ |
#define MBEDTLS_SSL_RENEGOTIATION |
/** |
* \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO |
* |
* Enable support for receiving and parsing SSLv2 Client Hello messages for the |
* SSL Server module (MBEDTLS_SSL_SRV_C). |
* |
* Uncomment this macro to enable support for SSLv2 Client Hello messages. |
*/ |
//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO |
/** |
* \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE |
* |
* Pick the ciphersuite according to the client's preferences rather than ours |
* in the SSL Server module (MBEDTLS_SSL_SRV_C). |
* |
* Uncomment this macro to respect client's ciphersuite order |
*/ |
//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE |
/** |
* \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH |
* |
* Enable support for RFC 6066 max_fragment_length extension in SSL. |
* |
* Comment this macro to disable support for the max_fragment_length extension |
*/ |
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH |
/** |
* \def MBEDTLS_SSL_PROTO_SSL3 |
* |
* Enable support for SSL 3.0. |
* |
* Requires: MBEDTLS_MD5_C |
* MBEDTLS_SHA1_C |
* |
* Comment this macro to disable support for SSL 3.0 |
*/ |
//#define MBEDTLS_SSL_PROTO_SSL3 |
/** |
* \def MBEDTLS_SSL_PROTO_TLS1 |
* |
* Enable support for TLS 1.0. |
* |
* Requires: MBEDTLS_MD5_C |
* MBEDTLS_SHA1_C |
* |
* Comment this macro to disable support for TLS 1.0 |
*/ |
#define MBEDTLS_SSL_PROTO_TLS1 |
/** |
* \def MBEDTLS_SSL_PROTO_TLS1_1 |
* |
* Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). |
* |
* Requires: MBEDTLS_MD5_C |
* MBEDTLS_SHA1_C |
* |
* Comment this macro to disable support for TLS 1.1 / DTLS 1.0 |
*/ |
#define MBEDTLS_SSL_PROTO_TLS1_1 |
/** |
* \def MBEDTLS_SSL_PROTO_TLS1_2 |
* |
* Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). |
* |
* Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C |
* (Depends on ciphersuites) |
* |
* Comment this macro to disable support for TLS 1.2 / DTLS 1.2 |
*/ |
#define MBEDTLS_SSL_PROTO_TLS1_2 |
/** |
* \def MBEDTLS_SSL_PROTO_DTLS |
* |
* Enable support for DTLS (all available versions). |
* |
* Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, |
* and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. |
* |
* Requires: MBEDTLS_SSL_PROTO_TLS1_1 |
* or MBEDTLS_SSL_PROTO_TLS1_2 |
* |
* Comment this macro to disable support for DTLS |
*/ |
#define MBEDTLS_SSL_PROTO_DTLS |
/** |
* \def MBEDTLS_SSL_ALPN |
* |
* Enable support for RFC 7301 Application Layer Protocol Negotiation. |
* |
* Comment this macro to disable support for ALPN. |
*/ |
#define MBEDTLS_SSL_ALPN |
/** |
* \def MBEDTLS_SSL_DTLS_ANTI_REPLAY |
* |
* Enable support for the anti-replay mechanism in DTLS. |
* |
* Requires: MBEDTLS_SSL_TLS_C |
* MBEDTLS_SSL_PROTO_DTLS |
* |
* \warning Disabling this is often a security risk! |
* See mbedtls_ssl_conf_dtls_anti_replay() for details. |
* |
* Comment this to disable anti-replay in DTLS. |
*/ |
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY |
/** |
* \def MBEDTLS_SSL_DTLS_HELLO_VERIFY |
* |
* Enable support for HelloVerifyRequest on DTLS servers. |
* |
* This feature is highly recommended to prevent DTLS servers being used as |
* amplifiers in DoS attacks against other hosts. It should always be enabled |
* unless you know for sure amplification cannot be a problem in the |
* environment in which your server operates. |
* |
* \warning Disabling this can ba a security risk! (see above) |
* |
* Requires: MBEDTLS_SSL_PROTO_DTLS |
* |
* Comment this to disable support for HelloVerifyRequest. |
*/ |
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY |
/** |
* \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE |
* |
* Enable server-side support for clients that reconnect from the same port. |
* |
* Some clients unexpectedly close the connection and try to reconnect using the |
* same source port. This needs special support from the server to handle the |
* new connection securely, as described in section 4.2.8 of RFC 6347. This |
* flag enables that support. |
* |
* Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY |
* |
* Comment this to disable support for clients reusing the source port. |
*/ |
#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE |
/** |
* \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT |
* |
* Enable support for a limit of records with bad MAC. |
* |
* See mbedtls_ssl_conf_dtls_badmac_limit(). |
* |
* Requires: MBEDTLS_SSL_PROTO_DTLS |
*/ |
#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT |
/** |
* \def MBEDTLS_SSL_SESSION_TICKETS |
* |
* Enable support for RFC 5077 session tickets in SSL. |
* Client-side, provides full support for session tickets (maintenance of a |
* session store remains the responsibility of the application, though). |
* Server-side, you also need to provide callbacks for writing and parsing |
* tickets, including authenticated encryption and key management. Example |
* callbacks are provided by MBEDTLS_SSL_TICKET_C. |
* |
* Comment this macro to disable support for SSL session tickets |
*/ |
#define MBEDTLS_SSL_SESSION_TICKETS |
/** |
* \def MBEDTLS_SSL_EXPORT_KEYS |
* |
* Enable support for exporting key block and master secret. |
* This is required for certain users of TLS, e.g. EAP-TLS. |
* |
* Comment this macro to disable support for key export |
*/ |
#define MBEDTLS_SSL_EXPORT_KEYS |
/** |
* \def MBEDTLS_SSL_SERVER_NAME_INDICATION |
* |
* Enable support for RFC 6066 server name indication (SNI) in SSL. |
* |
* Requires: MBEDTLS_X509_CRT_PARSE_C |
* |
* Comment this macro to disable support for server name indication in SSL |
*/ |
#define MBEDTLS_SSL_SERVER_NAME_INDICATION |
/** |
* \def MBEDTLS_SSL_TRUNCATED_HMAC |
* |
* Enable support for RFC 6066 truncated HMAC in SSL. |
* |
* Comment this macro to disable support for truncated HMAC in SSL |
*/ |
#define MBEDTLS_SSL_TRUNCATED_HMAC |
/** |
* \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT |
* |
* Fallback to old (pre-2.7), non-conforming implementation of the truncated |
* HMAC extension which also truncates the HMAC key. Note that this option is |
* only meant for a transitory upgrade period and is likely to be removed in |
* a future version of the library. |
* |
* \warning The old implementation is non-compliant and has a security weakness |
* (2^80 brute force attack on the HMAC key used for a single, |
* uninterrupted connection). This should only be enabled temporarily |
* when (1) the use of truncated HMAC is essential in order to save |
* bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use |
* the fixed implementation yet (pre-2.7). |
* |
* \deprecated This option is deprecated and will likely be removed in a |
* future version of Mbed TLS. |
* |
* Uncomment to fallback to old, non-compliant truncated HMAC implementation. |
* |
* Requires: MBEDTLS_SSL_TRUNCATED_HMAC |
*/ |
//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT |
/** |
* \def MBEDTLS_THREADING_ALT |
* |
* Provide your own alternate threading implementation. |
* |
* Requires: MBEDTLS_THREADING_C |
* |
* Uncomment this to allow your own alternate threading implementation. |
*/ |
//#define MBEDTLS_THREADING_ALT |
/** |
* \def MBEDTLS_THREADING_PTHREAD |
* |
* Enable the pthread wrapper layer for the threading layer. |
* |
* Requires: MBEDTLS_THREADING_C |
* |
* Uncomment this to enable pthread mutexes. |
*/ |
//#define MBEDTLS_THREADING_PTHREAD |
/** |
* \def MBEDTLS_VERSION_FEATURES |
* |
* Allow run-time checking of compile-time enabled features. Thus allowing users |
* to check at run-time if the library is for instance compiled with threading |
* support via mbedtls_version_check_feature(). |
* |
* Requires: MBEDTLS_VERSION_C |
* |
* Comment this to disable run-time checking and save ROM space |
*/ |
#define MBEDTLS_VERSION_FEATURES |
/** |
* \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 |
* |
* If set, the X509 parser will not break-off when parsing an X509 certificate |
* and encountering an extension in a v1 or v2 certificate. |
* |
* Uncomment to prevent an error. |
*/ |
//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 |
/** |
* \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION |
* |
* If set, the X509 parser will not break-off when parsing an X509 certificate |
* and encountering an unknown critical extension. |
* |
* \warning Depending on your PKI use, enabling this can be a security risk! |
* |
* Uncomment to prevent an error. |
*/ |
//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION |
/** |
* \def MBEDTLS_X509_CHECK_KEY_USAGE |
* |
* Enable verification of the keyUsage extension (CA and leaf certificates). |
* |
* Disabling this avoids problems with mis-issued and/or misused |
* (intermediate) CA and leaf certificates. |
* |
* \warning Depending on your PKI use, disabling this can be a security risk! |
* |
* Comment to skip keyUsage checking for both CA and leaf certificates. |
*/ |
#define MBEDTLS_X509_CHECK_KEY_USAGE |
/** |
* \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE |
* |
* Enable verification of the extendedKeyUsage extension (leaf certificates). |
* |
* Disabling this avoids problems with mis-issued and/or misused certificates. |
* |
* \warning Depending on your PKI use, disabling this can be a security risk! |
* |
* Comment to skip extendedKeyUsage checking for certificates. |
*/ |
#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE |
/** |
* \def MBEDTLS_X509_RSASSA_PSS_SUPPORT |
* |
* Enable parsing and verification of X.509 certificates, CRLs and CSRS |
* signed with RSASSA-PSS (aka PKCS#1 v2.1). |
* |
* Comment this macro to disallow using RSASSA-PSS in certificates. |
*/ |
#define MBEDTLS_X509_RSASSA_PSS_SUPPORT |
/** |
* \def MBEDTLS_ZLIB_SUPPORT |
* |
* If set, the SSL/TLS module uses ZLIB to support compression and |
* decompression of packet data. |
* |
* \warning TLS-level compression MAY REDUCE SECURITY! See for example the |
* CRIME attack. Before enabling this option, you should examine with care if |
* CRIME or similar exploits may be applicable to your use case. |
* |
* \note Currently compression can't be used with DTLS. |
* |
* \deprecated This feature is deprecated and will be removed |
* in the next major revision of the library. |
* |
* Used in: library/ssl_tls.c |
* library/ssl_cli.c |
* library/ssl_srv.c |
* |
* This feature requires zlib library and headers to be present. |
* |
* Uncomment to enable use of ZLIB |
*/ |
//#define MBEDTLS_ZLIB_SUPPORT |
/* \} name SECTION: mbed TLS feature support */ |
/** |
* \name SECTION: mbed TLS modules |
* |
* This section enables or disables entire modules in mbed TLS |
* \{ |
*/ |
/** |
* \def MBEDTLS_AESNI_C |
* |
* Enable AES-NI support on x86-64. |
* |
* Module: library/aesni.c |
* Caller: library/aes.c |
* |
* Requires: MBEDTLS_HAVE_ASM |
* |
* This modules adds support for the AES-NI instructions on x86-64 |
*/ |
#define MBEDTLS_AESNI_C |
/** |
* \def MBEDTLS_AES_C |
* |
* Enable the AES block cipher. |
* |
* Module: library/aes.c |
* Caller: library/cipher.c |
* library/pem.c |
* library/ctr_drbg.c |
* |
* This module enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA |
* MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 |
* MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 |
* MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA |
* MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 |
* MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 |
* MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA |
* |
* PEM_PARSE uses AES for decrypting encrypted keys. |
*/ |
#define MBEDTLS_AES_C |
/** |
* \def MBEDTLS_ARC4_C |
* |
* Enable the ARCFOUR stream cipher. |
* |
* Module: library/arc4.c |
* Caller: library/cipher.c |
* |
* This module enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA |
* MBEDTLS_TLS_RSA_WITH_RC4_128_SHA |
* MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 |
* MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA |
* MBEDTLS_TLS_PSK_WITH_RC4_128_SHA |
* |
* \warning ARC4 is considered a weak cipher and its use constitutes a |
* security risk. If possible, we recommend avoidng dependencies on |
* it, and considering stronger ciphers instead. |
* |
*/ |
#define MBEDTLS_ARC4_C |
/** |
* \def MBEDTLS_ASN1_PARSE_C |
* |
* Enable the generic ASN1 parser. |
* |
* Module: library/asn1.c |
* Caller: library/x509.c |
* library/dhm.c |
* library/pkcs12.c |
* library/pkcs5.c |
* library/pkparse.c |
*/ |
#define MBEDTLS_ASN1_PARSE_C |
/** |
* \def MBEDTLS_ASN1_WRITE_C |
* |
* Enable the generic ASN1 writer. |
* |
* Module: library/asn1write.c |
* Caller: library/ecdsa.c |
* library/pkwrite.c |
* library/x509_create.c |
* library/x509write_crt.c |
* library/x509write_csr.c |
*/ |
#define MBEDTLS_ASN1_WRITE_C |
/** |
* \def MBEDTLS_BASE64_C |
* |
* Enable the Base64 module. |
* |
* Module: library/base64.c |
* Caller: library/pem.c |
* |
* This module is required for PEM support (required by X.509). |
*/ |
#define MBEDTLS_BASE64_C |
/** |
* \def MBEDTLS_BIGNUM_C |
* |
* Enable the multi-precision integer library. |
* |
* Module: library/bignum.c |
* Caller: library/dhm.c |
* library/ecp.c |
* library/ecdsa.c |
* library/rsa.c |
* library/rsa_internal.c |
* library/ssl_tls.c |
* |
* This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. |
*/ |
#define MBEDTLS_BIGNUM_C |
/** |
* \def MBEDTLS_BLOWFISH_C |
* |
* Enable the Blowfish block cipher. |
* |
* Module: library/blowfish.c |
*/ |
#define MBEDTLS_BLOWFISH_C |
/** |
* \def MBEDTLS_CAMELLIA_C |
* |
* Enable the Camellia block cipher. |
* |
* Module: library/camellia.c |
* Caller: library/cipher.c |
* |
* This module enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 |
* MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 |
*/ |
#define MBEDTLS_CAMELLIA_C |
/** |
* \def MBEDTLS_ARIA_C |
* |
* Enable the ARIA block cipher. |
* |
* Module: library/aria.c |
* Caller: library/cipher.c |
* |
* This module enables the following ciphersuites (if other requisites are |
* enabled as well): |
* |
* MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 |
* MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 |
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 |
* MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 |
*/ |
//#define MBEDTLS_ARIA_C |
/** |
* \def MBEDTLS_CCM_C |
* |
* Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. |
* |
* Module: library/ccm.c |
* |
* Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C |
* |
* This module enables the AES-CCM ciphersuites, if other requisites are |
* enabled as well. |
*/ |
#define MBEDTLS_CCM_C |
/** |
* \def MBEDTLS_CERTS_C |
* |
* Enable the test certificates. |
* |
* Module: library/certs.c |
* Caller: |
* |
* This module is used for testing (ssl_client/server). |
*/ |
#define MBEDTLS_CERTS_C |
/** |
* \def MBEDTLS_CHACHA20_C |
* |
* Enable the ChaCha20 stream cipher. |
* |
* Module: library/chacha20.c |
*/ |
#define MBEDTLS_CHACHA20_C |
/** |
* \def MBEDTLS_CHACHAPOLY_C |
* |
* Enable the ChaCha20-Poly1305 AEAD algorithm. |
* |
* Module: library/chachapoly.c |
* |
* This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C |
*/ |
#define MBEDTLS_CHACHAPOLY_C |
/** |
* \def MBEDTLS_CIPHER_C |
* |
* Enable the generic cipher layer. |
* |
* Module: library/cipher.c |
* Caller: library/ssl_tls.c |
* |
* Uncomment to enable generic cipher wrappers. |
*/ |
#define MBEDTLS_CIPHER_C |
/** |
* \def MBEDTLS_CMAC_C |
* |
* Enable the CMAC (Cipher-based Message Authentication Code) mode for block |
* ciphers. |
* |
* Module: library/cmac.c |
* |
* Requires: MBEDTLS_AES_C or MBEDTLS_DES_C |
* |
*/ |
//#define MBEDTLS_CMAC_C |
/** |
* \def MBEDTLS_CTR_DRBG_C |
* |
* Enable the CTR_DRBG AES-based random generator. |
* The CTR_DRBG generator uses AES-256 by default. |
* To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. |
* |
* \note To achieve a 256-bit security strength with CTR_DRBG, |
* you must use AES-256 *and* use sufficient entropy. |
* See ctr_drbg.h for more details. |
* |
* Module: library/ctr_drbg.c |
* Caller: |
* |
* Requires: MBEDTLS_AES_C |
* |
* This module provides the CTR_DRBG AES random number generator. |
*/ |
#define MBEDTLS_CTR_DRBG_C |
/** |
* \def MBEDTLS_DEBUG_C |
* |
* Enable the debug functions. |
* |
* Module: library/debug.c |
* Caller: library/ssl_cli.c |
* library/ssl_srv.c |
* library/ssl_tls.c |
* |
* This module provides debugging functions. |
*/ |
#define MBEDTLS_DEBUG_C |
/** |
* \def MBEDTLS_DES_C |
* |
* Enable the DES block cipher. |
* |
* Module: library/des.c |
* Caller: library/pem.c |
* library/cipher.c |
* |
* This module enables the following ciphersuites (if other requisites are |
* enabled as well): |
* MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA |
* MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA |
* |
* PEM_PARSE uses DES/3DES for decrypting encrypted keys. |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers instead. |
*/ |
#define MBEDTLS_DES_C |
/** |
* \def MBEDTLS_DHM_C |
* |
* Enable the Diffie-Hellman-Merkle module. |
* |
* Module: library/dhm.c |
* Caller: library/ssl_cli.c |
* library/ssl_srv.c |
* |
* This module is used by the following key exchanges: |
* DHE-RSA, DHE-PSK |
* |
* \warning Using DHE constitutes a security risk as it |
* is not possible to validate custom DH parameters. |
* If possible, it is recommended users should consider |
* preferring other methods of key exchange. |
* See dhm.h for more details. |
* |
*/ |
#define MBEDTLS_DHM_C |
/** |
* \def MBEDTLS_ECDH_C |
* |
* Enable the elliptic curve Diffie-Hellman library. |
* |
* Module: library/ecdh.c |
* Caller: library/ssl_cli.c |
* library/ssl_srv.c |
* |
* This module is used by the following key exchanges: |
* ECDHE-ECDSA, ECDHE-RSA, DHE-PSK |
* |
* Requires: MBEDTLS_ECP_C |
*/ |
#define MBEDTLS_ECDH_C |
/** |
* \def MBEDTLS_ECDSA_C |
* |
* Enable the elliptic curve DSA library. |
* |
* Module: library/ecdsa.c |
* Caller: |
* |
* This module is used by the following key exchanges: |
* ECDHE-ECDSA |
* |
* Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C |
*/ |
#define MBEDTLS_ECDSA_C |
/** |
* \def MBEDTLS_ECJPAKE_C |
* |
* Enable the elliptic curve J-PAKE library. |
* |
* \warning This is currently experimental. EC J-PAKE support is based on the |
* Thread v1.0.0 specification; incompatible changes to the specification |
* might still happen. For this reason, this is disabled by default. |
* |
* Module: library/ecjpake.c |
* Caller: |
* |
* This module is used by the following key exchanges: |
* ECJPAKE |
* |
* Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C |
*/ |
//#define MBEDTLS_ECJPAKE_C |
/** |
* \def MBEDTLS_ECP_C |
* |
* Enable the elliptic curve over GF(p) library. |
* |
* Module: library/ecp.c |
* Caller: library/ecdh.c |
* library/ecdsa.c |
* library/ecjpake.c |
* |
* Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED |
*/ |
#define MBEDTLS_ECP_C |
/** |
* \def MBEDTLS_ENTROPY_C |
* |
* Enable the platform-specific entropy code. |
* |
* Module: library/entropy.c |
* Caller: |
* |
* Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C |
* |
* This module provides a generic entropy pool |
*/ |
#define MBEDTLS_ENTROPY_C |
/** |
* \def MBEDTLS_ERROR_C |
* |
* Enable error code to error string conversion. |
* |
* Module: library/error.c |
* Caller: |
* |
* This module enables mbedtls_strerror(). |
*/ |
#define MBEDTLS_ERROR_C |
/** |
* \def MBEDTLS_GCM_C |
* |
* Enable the Galois/Counter Mode (GCM) for AES. |
* |
* Module: library/gcm.c |
* |
* Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C |
* |
* This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other |
* requisites are enabled as well. |
*/ |
#define MBEDTLS_GCM_C |
/** |
* \def MBEDTLS_HAVEGE_C |
* |
* Enable the HAVEGE random generator. |
* |
* Warning: the HAVEGE random generator is not suitable for virtualized |
* environments |
* |
* Warning: the HAVEGE random generator is dependent on timing and specific |
* processor traits. It is therefore not advised to use HAVEGE as |
* your applications primary random generator or primary entropy pool |
* input. As a secondary input to your entropy pool, it IS able add |
* the (limited) extra entropy it provides. |
* |
* Module: library/havege.c |
* Caller: |
* |
* Requires: MBEDTLS_TIMING_C |
* |
* Uncomment to enable the HAVEGE random generator. |
*/ |
//#define MBEDTLS_HAVEGE_C |
/** |
* \def MBEDTLS_HKDF_C |
* |
* Enable the HKDF algorithm (RFC 5869). |
* |
* Module: library/hkdf.c |
* Caller: |
* |
* Requires: MBEDTLS_MD_C |
* |
* This module adds support for the Hashed Message Authentication Code |
* (HMAC)-based key derivation function (HKDF). |
*/ |
#define MBEDTLS_HKDF_C |
/** |
* \def MBEDTLS_HMAC_DRBG_C |
* |
* Enable the HMAC_DRBG random generator. |
* |
* Module: library/hmac_drbg.c |
* Caller: |
* |
* Requires: MBEDTLS_MD_C |
* |
* Uncomment to enable the HMAC_DRBG random number geerator. |
*/ |
#define MBEDTLS_HMAC_DRBG_C |
/** |
* \def MBEDTLS_NIST_KW_C |
* |
* Enable the Key Wrapping mode for 128-bit block ciphers, |
* as defined in NIST SP 800-38F. Only KW and KWP modes |
* are supported. At the moment, only AES is approved by NIST. |
* |
* Module: library/nist_kw.c |
* |
* Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C |
*/ |
//#define MBEDTLS_NIST_KW_C |
/** |
* \def MBEDTLS_MD_C |
* |
* Enable the generic message digest layer. |
* |
* Module: library/md.c |
* Caller: |
* |
* Uncomment to enable generic message digest wrappers. |
*/ |
#define MBEDTLS_MD_C |
/** |
* \def MBEDTLS_MD2_C |
* |
* Enable the MD2 hash algorithm. |
* |
* Module: library/md2.c |
* Caller: |
* |
* Uncomment to enable support for (rare) MD2-signed X.509 certs. |
* |
* \warning MD2 is considered a weak message digest and its use constitutes a |
* security risk. If possible, we recommend avoiding dependencies on |
* it, and considering stronger message digests instead. |
* |
*/ |
//#define MBEDTLS_MD2_C |
/** |
* \def MBEDTLS_MD4_C |
* |
* Enable the MD4 hash algorithm. |
* |
* Module: library/md4.c |
* Caller: |
* |
* Uncomment to enable support for (rare) MD4-signed X.509 certs. |
* |
* \warning MD4 is considered a weak message digest and its use constitutes a |
* security risk. If possible, we recommend avoiding dependencies on |
* it, and considering stronger message digests instead. |
* |
*/ |
//#define MBEDTLS_MD4_C |
/** |
* \def MBEDTLS_MD5_C |
* |
* Enable the MD5 hash algorithm. |
* |
* Module: library/md5.c |
* Caller: library/md.c |
* library/pem.c |
* library/ssl_tls.c |
* |
* This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 |
* depending on the handshake parameters. Further, it is used for checking |
* MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded |
* encrypted keys. |
* |
* \warning MD5 is considered a weak message digest and its use constitutes a |
* security risk. If possible, we recommend avoiding dependencies on |
* it, and considering stronger message digests instead. |
* |
*/ |
#define MBEDTLS_MD5_C |
/** |
* \def MBEDTLS_MEMORY_BUFFER_ALLOC_C |
* |
* Enable the buffer allocator implementation that makes use of a (stack) |
* based buffer to 'allocate' dynamic memory. (replaces calloc() and free() |
* calls) |
* |
* Module: library/memory_buffer_alloc.c |
* |
* Requires: MBEDTLS_PLATFORM_C |
* MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) |
* |
* Enable this module to enable the buffer memory allocator. |
*/ |
//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C |
/** |
* \def MBEDTLS_NET_C |
* |
* Enable the TCP and UDP over IPv6/IPv4 networking routines. |
* |
* \note This module only works on POSIX/Unix (including Linux, BSD and OS X) |
* and Windows. For other platforms, you'll want to disable it, and write your |
* own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). |
* |
* \note See also our Knowledge Base article about porting to a new |
* environment: |
* https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS |
* |
* Module: library/net_sockets.c |
* |
* This module provides networking routines. |
*/ |
#define MBEDTLS_NET_C |
/** |
* \def MBEDTLS_OID_C |
* |
* Enable the OID database. |
* |
* Module: library/oid.c |
* Caller: library/asn1write.c |
* library/pkcs5.c |
* library/pkparse.c |
* library/pkwrite.c |
* library/rsa.c |
* library/x509.c |
* library/x509_create.c |
* library/x509_crl.c |
* library/x509_crt.c |
* library/x509_csr.c |
* library/x509write_crt.c |
* library/x509write_csr.c |
* |
* This modules translates between OIDs and internal values. |
*/ |
#define MBEDTLS_OID_C |
/** |
* \def MBEDTLS_PADLOCK_C |
* |
* Enable VIA Padlock support on x86. |
* |
* Module: library/padlock.c |
* Caller: library/aes.c |
* |
* Requires: MBEDTLS_HAVE_ASM |
* |
* This modules adds support for the VIA PadLock on x86. |
*/ |
#define MBEDTLS_PADLOCK_C |
/** |
* \def MBEDTLS_PEM_PARSE_C |
* |
* Enable PEM decoding / parsing. |
* |
* Module: library/pem.c |
* Caller: library/dhm.c |
* library/pkparse.c |
* library/x509_crl.c |
* library/x509_crt.c |
* library/x509_csr.c |
* |
* Requires: MBEDTLS_BASE64_C |
* |
* This modules adds support for decoding / parsing PEM files. |
*/ |
#define MBEDTLS_PEM_PARSE_C |
/** |
* \def MBEDTLS_PEM_WRITE_C |
* |
* Enable PEM encoding / writing. |
* |
* Module: library/pem.c |
* Caller: library/pkwrite.c |
* library/x509write_crt.c |
* library/x509write_csr.c |
* |
* Requires: MBEDTLS_BASE64_C |
* |
* This modules adds support for encoding / writing PEM files. |
*/ |
#define MBEDTLS_PEM_WRITE_C |
/** |
* \def MBEDTLS_PK_C |
* |
* Enable the generic public (asymetric) key layer. |
* |
* Module: library/pk.c |
* Caller: library/ssl_tls.c |
* library/ssl_cli.c |
* library/ssl_srv.c |
* |
* Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C |
* |
* Uncomment to enable generic public key wrappers. |
*/ |
#define MBEDTLS_PK_C |
/** |
* \def MBEDTLS_PK_PARSE_C |
* |
* Enable the generic public (asymetric) key parser. |
* |
* Module: library/pkparse.c |
* Caller: library/x509_crt.c |
* library/x509_csr.c |
* |
* Requires: MBEDTLS_PK_C |
* |
* Uncomment to enable generic public key parse functions. |
*/ |
#define MBEDTLS_PK_PARSE_C |
/** |
* \def MBEDTLS_PK_WRITE_C |
* |
* Enable the generic public (asymetric) key writer. |
* |
* Module: library/pkwrite.c |
* Caller: library/x509write.c |
* |
* Requires: MBEDTLS_PK_C |
* |
* Uncomment to enable generic public key write functions. |
*/ |
#define MBEDTLS_PK_WRITE_C |
/** |
* \def MBEDTLS_PKCS5_C |
* |
* Enable PKCS#5 functions. |
* |
* Module: library/pkcs5.c |
* |
* Requires: MBEDTLS_MD_C |
* |
* This module adds support for the PKCS#5 functions. |
*/ |
#define MBEDTLS_PKCS5_C |
/** |
* \def MBEDTLS_PKCS11_C |
* |
* Enable wrapper for PKCS#11 smartcard support. |
* |
* Module: library/pkcs11.c |
* Caller: library/pk.c |
* |
* Requires: MBEDTLS_PK_C |
* |
* This module enables SSL/TLS PKCS #11 smartcard support. |
* Requires the presence of the PKCS#11 helper library (libpkcs11-helper) |
*/ |
//#define MBEDTLS_PKCS11_C |
/** |
* \def MBEDTLS_PKCS12_C |
* |
* Enable PKCS#12 PBE functions. |
* Adds algorithms for parsing PKCS#8 encrypted private keys |
* |
* Module: library/pkcs12.c |
* Caller: library/pkparse.c |
* |
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C |
* Can use: MBEDTLS_ARC4_C |
* |
* This module enables PKCS#12 functions. |
*/ |
#define MBEDTLS_PKCS12_C |
/** |
* \def MBEDTLS_PLATFORM_C |
* |
* Enable the platform abstraction layer that allows you to re-assign |
* functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). |
* |
* Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT |
* or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned |
* above to be specified at runtime or compile time respectively. |
* |
* \note This abstraction layer must be enabled on Windows (including MSYS2) |
* as other module rely on it for a fixed snprintf implementation. |
* |
* Module: library/platform.c |
* Caller: Most other .c files |
* |
* This module enables abstraction of common (libc) functions. |
*/ |
#define MBEDTLS_PLATFORM_C |
/** |
* \def MBEDTLS_POLY1305_C |
* |
* Enable the Poly1305 MAC algorithm. |
* |
* Module: library/poly1305.c |
* Caller: library/chachapoly.c |
*/ |
#define MBEDTLS_POLY1305_C |
/** |
* \def MBEDTLS_RIPEMD160_C |
* |
* Enable the RIPEMD-160 hash algorithm. |
* |
* Module: library/ripemd160.c |
* Caller: library/md.c |
* |
*/ |
#define MBEDTLS_RIPEMD160_C |
/** |
* \def MBEDTLS_RSA_C |
* |
* Enable the RSA public-key cryptosystem. |
* |
* Module: library/rsa.c |
* library/rsa_internal.c |
* Caller: library/ssl_cli.c |
* library/ssl_srv.c |
* library/ssl_tls.c |
* library/x509.c |
* |
* This module is used by the following key exchanges: |
* RSA, DHE-RSA, ECDHE-RSA, RSA-PSK |
* |
* Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C |
*/ |
#define MBEDTLS_RSA_C |
/** |
* \def MBEDTLS_SHA1_C |
* |
* Enable the SHA1 cryptographic hash algorithm. |
* |
* Module: library/sha1.c |
* Caller: library/md.c |
* library/ssl_cli.c |
* library/ssl_srv.c |
* library/ssl_tls.c |
* library/x509write_crt.c |
* |
* This module is required for SSL/TLS up to version 1.1, for TLS 1.2 |
* depending on the handshake parameters, and for SHA1-signed certificates. |
* |
* \warning SHA-1 is considered a weak message digest and its use constitutes |
* a security risk. If possible, we recommend avoiding dependencies |
* on it, and considering stronger message digests instead. |
* |
*/ |
#define MBEDTLS_SHA1_C |
/** |
* \def MBEDTLS_SHA256_C |
* |
* Enable the SHA-224 and SHA-256 cryptographic hash algorithms. |
* |
* Module: library/sha256.c |
* Caller: library/entropy.c |
* library/md.c |
* library/ssl_cli.c |
* library/ssl_srv.c |
* library/ssl_tls.c |
* |
* This module adds support for SHA-224 and SHA-256. |
* This module is required for the SSL/TLS 1.2 PRF function. |
*/ |
#define MBEDTLS_SHA256_C |
/** |
* \def MBEDTLS_SHA512_C |
* |
* Enable the SHA-384 and SHA-512 cryptographic hash algorithms. |
* |
* Module: library/sha512.c |
* Caller: library/entropy.c |
* library/md.c |
* library/ssl_cli.c |
* library/ssl_srv.c |
* |
* This module adds support for SHA-384 and SHA-512. |
*/ |
#define MBEDTLS_SHA512_C |
/** |
* \def MBEDTLS_SSL_CACHE_C |
* |
* Enable simple SSL cache implementation. |
* |
* Module: library/ssl_cache.c |
* Caller: |
* |
* Requires: MBEDTLS_SSL_CACHE_C |
*/ |
#define MBEDTLS_SSL_CACHE_C |
/** |
* \def MBEDTLS_SSL_COOKIE_C |
* |
* Enable basic implementation of DTLS cookies for hello verification. |
* |
* Module: library/ssl_cookie.c |
* Caller: |
*/ |
#define MBEDTLS_SSL_COOKIE_C |
/** |
* \def MBEDTLS_SSL_TICKET_C |
* |
* Enable an implementation of TLS server-side callbacks for session tickets. |
* |
* Module: library/ssl_ticket.c |
* Caller: |
* |
* Requires: MBEDTLS_CIPHER_C |
*/ |
#define MBEDTLS_SSL_TICKET_C |
/** |
* \def MBEDTLS_SSL_CLI_C |
* |
* Enable the SSL/TLS client code. |
* |
* Module: library/ssl_cli.c |
* Caller: |
* |
* Requires: MBEDTLS_SSL_TLS_C |
* |
* This module is required for SSL/TLS client support. |
*/ |
#define MBEDTLS_SSL_CLI_C |
/** |
* \def MBEDTLS_SSL_SRV_C |
* |
* Enable the SSL/TLS server code. |
* |
* Module: library/ssl_srv.c |
* Caller: |
* |
* Requires: MBEDTLS_SSL_TLS_C |
* |
* This module is required for SSL/TLS server support. |
*/ |
#define MBEDTLS_SSL_SRV_C |
/** |
* \def MBEDTLS_SSL_TLS_C |
* |
* Enable the generic SSL/TLS code. |
* |
* Module: library/ssl_tls.c |
* Caller: library/ssl_cli.c |
* library/ssl_srv.c |
* |
* Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C |
* and at least one of the MBEDTLS_SSL_PROTO_XXX defines |
* |
* This module is required for SSL/TLS. |
*/ |
#define MBEDTLS_SSL_TLS_C |
/** |
* \def MBEDTLS_THREADING_C |
* |
* Enable the threading abstraction layer. |
* By default mbed TLS assumes it is used in a non-threaded environment or that |
* contexts are not shared between threads. If you do intend to use contexts |
* between threads, you will need to enable this layer to prevent race |
* conditions. See also our Knowledge Base article about threading: |
* https://tls.mbed.org/kb/development/thread-safety-and-multi-threading |
* |
* Module: library/threading.c |
* |
* This allows different threading implementations (self-implemented or |
* provided). |
* |
* You will have to enable either MBEDTLS_THREADING_ALT or |
* MBEDTLS_THREADING_PTHREAD. |
* |
* Enable this layer to allow use of mutexes within mbed TLS |
*/ |
//#define MBEDTLS_THREADING_C |
/** |
* \def MBEDTLS_TIMING_C |
* |
* Enable the semi-portable timing interface. |
* |
* \note The provided implementation only works on POSIX/Unix (including Linux, |
* BSD and OS X) and Windows. On other platforms, you can either disable that |
* module and provide your own implementations of the callbacks needed by |
* \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide |
* your own implementation of the whole module by setting |
* \c MBEDTLS_TIMING_ALT in the current file. |
* |
* \note See also our Knowledge Base article about porting to a new |
* environment: |
* https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS |
* |
* Module: library/timing.c |
* Caller: library/havege.c |
* |
* This module is used by the HAVEGE random number generator. |
*/ |
//#define MBEDTLS_TIMING_C |
/** |
* \def MBEDTLS_VERSION_C |
* |
* Enable run-time version information. |
* |
* Module: library/version.c |
* |
* This module provides run-time version information. |
*/ |
#define MBEDTLS_VERSION_C |
/** |
* \def MBEDTLS_X509_USE_C |
* |
* Enable X.509 core for using certificates. |
* |
* Module: library/x509.c |
* Caller: library/x509_crl.c |
* library/x509_crt.c |
* library/x509_csr.c |
* |
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, |
* MBEDTLS_PK_PARSE_C |
* |
* This module is required for the X.509 parsing modules. |
*/ |
#define MBEDTLS_X509_USE_C |
/** |
* \def MBEDTLS_X509_CRT_PARSE_C |
* |
* Enable X.509 certificate parsing. |
* |
* Module: library/x509_crt.c |
* Caller: library/ssl_cli.c |
* library/ssl_srv.c |
* library/ssl_tls.c |
* |
* Requires: MBEDTLS_X509_USE_C |
* |
* This module is required for X.509 certificate parsing. |
*/ |
#define MBEDTLS_X509_CRT_PARSE_C |
/** |
* \def MBEDTLS_X509_CRL_PARSE_C |
* |
* Enable X.509 CRL parsing. |
* |
* Module: library/x509_crl.c |
* Caller: library/x509_crt.c |
* |
* Requires: MBEDTLS_X509_USE_C |
* |
* This module is required for X.509 CRL parsing. |
*/ |
#define MBEDTLS_X509_CRL_PARSE_C |
/** |
* \def MBEDTLS_X509_CSR_PARSE_C |
* |
* Enable X.509 Certificate Signing Request (CSR) parsing. |
* |
* Module: library/x509_csr.c |
* Caller: library/x509_crt_write.c |
* |
* Requires: MBEDTLS_X509_USE_C |
* |
* This module is used for reading X.509 certificate request. |
*/ |
#define MBEDTLS_X509_CSR_PARSE_C |
/** |
* \def MBEDTLS_X509_CREATE_C |
* |
* Enable X.509 core for creating certificates. |
* |
* Module: library/x509_create.c |
* |
* Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C |
* |
* This module is the basis for creating X.509 certificates and CSRs. |
*/ |
#define MBEDTLS_X509_CREATE_C |
/** |
* \def MBEDTLS_X509_CRT_WRITE_C |
* |
* Enable creating X.509 certificates. |
* |
* Module: library/x509_crt_write.c |
* |
* Requires: MBEDTLS_X509_CREATE_C |
* |
* This module is required for X.509 certificate creation. |
*/ |
#define MBEDTLS_X509_CRT_WRITE_C |
/** |
* \def MBEDTLS_X509_CSR_WRITE_C |
* |
* Enable creating X.509 Certificate Signing Requests (CSR). |
* |
* Module: library/x509_csr_write.c |
* |
* Requires: MBEDTLS_X509_CREATE_C |
* |
* This module is required for X.509 certificate request writing. |
*/ |
#define MBEDTLS_X509_CSR_WRITE_C |
/** |
* \def MBEDTLS_XTEA_C |
* |
* Enable the XTEA block cipher. |
* |
* Module: library/xtea.c |
* Caller: |
*/ |
#define MBEDTLS_XTEA_C |
/* \} name SECTION: mbed TLS modules */ |
/** |
* \name SECTION: Module configuration options |
* |
* This section allows for the setting of module specific sizes and |
* configuration options. The default values are already present in the |
* relevant header files and should suffice for the regular use cases. |
* |
* Our advice is to enable options and change their values here |
* only if you have a good reason and know the consequences. |
* |
* Please check the respective header file for documentation on these |
* parameters (to prevent duplicate documentation). |
* \{ |
*/ |
/* MPI / BIGNUM options */ |
//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ |
//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ |
/* CTR_DRBG options */ |
//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ |
//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ |
//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ |
//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ |
//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ |
/* HMAC_DRBG options */ |
//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ |
//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ |
//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ |
//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ |
/* ECP options */ |
//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ |
//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ |
//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ |
/* Entropy options */ |
//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ |
//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ |
//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ |
/* Memory buffer allocator options */ |
//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ |
/* Platform options */ |
//#define MBEDTLS_PLATFORM_STD_MEM_HDR <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ |
//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ |
//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ |
/* Note: your snprintf must correctly zero-terminate the buffer! */ |
//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ |
/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ |
/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ |
//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ |
//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ |
//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ |
/* Note: your snprintf must correctly zero-terminate the buffer! */ |
//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ |
//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ |
/** |
* \brief This macro is invoked by the library when an invalid parameter |
* is detected that is only checked with #MBEDTLS_CHECK_PARAMS |
* (see the documentation of that option for context). |
* |
* When you leave this undefined here, the library provides |
* a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT |
* is defined, the default definition is `assert(cond)`, |
* otherwise the default definition calls a function |
* mbedtls_param_failed(). This function is declared in |
* `platform_util.h` for the benefit of the library, but |
* you need to define in your application. |
* |
* When you define this here, this replaces the default |
* definition in platform_util.h (which no longer declares the |
* function mbedtls_param_failed()) and it is your responsibility |
* to make sure this macro expands to something suitable (in |
* particular, that all the necessary declarations are visible |
* from within the library - you can ensure that by providing |
* them in this file next to the macro definition). |
* If you define this macro to call `assert`, also define |
* #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files |
* include `<assert.h>`. |
* |
* Note that you may define this macro to expand to nothing, in |
* which case you don't have to worry about declarations or |
* definitions. However, you will then be notified about invalid |
* parameters only in non-void functions, and void function will |
* just silently return early on invalid parameters, which |
* partially negates the benefits of enabling |
* #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged. |
* |
* \param cond The expression that should evaluate to true, but doesn't. |
*/ |
//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) |
/* SSL Cache options */ |
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ |
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ |
/* SSL options */ |
/** \def MBEDTLS_SSL_MAX_CONTENT_LEN |
* |
* Maximum length (in bytes) of incoming and outgoing plaintext fragments. |
* |
* This determines the size of both the incoming and outgoing TLS I/O buffers |
* in such a way that both are capable of holding the specified amount of |
* plaintext data, regardless of the protection mechanism used. |
* |
* To configure incoming and outgoing I/O buffers separately, use |
* #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN, |
* which overwrite the value set by this option. |
* |
* \note When using a value less than the default of 16KB on the client, it is |
* recommended to use the Maximum Fragment Length (MFL) extension to |
* inform the server about this limitation. On the server, there |
* is no supported, standardized way of informing the client about |
* restriction on the maximum size of incoming messages, and unless |
* the limitation has been communicated by other means, it is recommended |
* to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN |
* while keeping the default value of 16KB for the incoming buffer. |
* |
* Uncomment to set the maximum plaintext size of both |
* incoming and outgoing I/O buffers. |
*/ |
//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 |
/** \def MBEDTLS_SSL_IN_CONTENT_LEN |
* |
* Maximum length (in bytes) of incoming plaintext fragments. |
* |
* This determines the size of the incoming TLS I/O buffer in such a way |
* that it is capable of holding the specified amount of plaintext data, |
* regardless of the protection mechanism used. |
* |
* If this option is undefined, it inherits its value from |
* #MBEDTLS_SSL_MAX_CONTENT_LEN. |
* |
* \note When using a value less than the default of 16KB on the client, it is |
* recommended to use the Maximum Fragment Length (MFL) extension to |
* inform the server about this limitation. On the server, there |
* is no supported, standardized way of informing the client about |
* restriction on the maximum size of incoming messages, and unless |
* the limitation has been communicated by other means, it is recommended |
* to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN |
* while keeping the default value of 16KB for the incoming buffer. |
* |
* Uncomment to set the maximum plaintext size of the incoming I/O buffer |
* independently of the outgoing I/O buffer. |
*/ |
//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 |
/** \def MBEDTLS_SSL_OUT_CONTENT_LEN |
* |
* Maximum length (in bytes) of outgoing plaintext fragments. |
* |
* This determines the size of the outgoing TLS I/O buffer in such a way |
* that it is capable of holding the specified amount of plaintext data, |
* regardless of the protection mechanism used. |
* |
* If this option undefined, it inherits its value from |
* #MBEDTLS_SSL_MAX_CONTENT_LEN. |
* |
* It is possible to save RAM by setting a smaller outward buffer, while keeping |
* the default inward 16384 byte buffer to conform to the TLS specification. |
* |
* The minimum required outward buffer size is determined by the handshake |
* protocol's usage. Handshaking will fail if the outward buffer is too small. |
* The specific size requirement depends on the configured ciphers and any |
* certificate data which is sent during the handshake. |
* |
* Uncomment to set the maximum plaintext size of the outgoing I/O buffer |
* independently of the incoming I/O buffer. |
*/ |
//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 |
/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING |
* |
* Maximum number of heap-allocated bytes for the purpose of |
* DTLS handshake message reassembly and future message buffering. |
* |
* This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN |
* to account for a reassembled handshake message of maximum size, |
* together with its reassembly bitmap. |
* |
* A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) |
* should be sufficient for all practical situations as it allows |
* to reassembly a large handshake message (such as a certificate) |
* while buffering multiple smaller handshake messages. |
* |
*/ |
//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 |
//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ |
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ |
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ |
/** |
* Complete list of ciphersuites to use, in order of preference. |
* |
* \warning No dependency checking is done on that field! This option can only |
* be used to restrict the set of available ciphersuites. It is your |
* responsibility to make sure the needed modules are active. |
* |
* Use this to save a few hundred bytes of ROM (default ordering of all |
* available ciphersuites) and a few to a few hundred bytes of RAM. |
* |
* The value below is only an example, not the default. |
*/ |
//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
/* X509 options */ |
//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ |
//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ |
/** |
* Allow SHA-1 in the default TLS configuration for certificate signing. |
* Without this build-time option, SHA-1 support must be activated explicitly |
* through mbedtls_ssl_conf_cert_profile. Turning on this option is not |
* recommended because of it is possible to generate SHA-1 collisions, however |
* this may be safe for legacy infrastructure where additional controls apply. |
* |
* \warning SHA-1 is considered a weak message digest and its use constitutes |
* a security risk. If possible, we recommend avoiding dependencies |
* on it, and considering stronger message digests instead. |
* |
*/ |
// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES |
/** |
* Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake |
* signature and ciphersuite selection. Without this build-time option, SHA-1 |
* support must be activated explicitly through mbedtls_ssl_conf_sig_hashes. |
* The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by |
* default. At the time of writing, there is no practical attack on the use |
* of SHA-1 in handshake signatures, hence this option is turned on by default |
* to preserve compatibility with existing peers, but the general |
* warning applies nonetheless: |
* |
* \warning SHA-1 is considered a weak message digest and its use constitutes |
* a security risk. If possible, we recommend avoiding dependencies |
* on it, and considering stronger message digests instead. |
* |
*/ |
#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE |
/** |
* Uncomment the macro to let mbed TLS use your alternate implementation of |
* mbedtls_platform_zeroize(). This replaces the default implementation in |
* platform_util.c. |
* |
* mbedtls_platform_zeroize() is a widely used function across the library to |
* zero a block of memory. The implementation is expected to be secure in the |
* sense that it has been written to prevent the compiler from removing calls |
* to mbedtls_platform_zeroize() as part of redundant code elimination |
* optimizations. However, it is difficult to guarantee that calls to |
* mbedtls_platform_zeroize() will not be optimized by the compiler as older |
* versions of the C language standards do not provide a secure implementation |
* of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to |
* configure their own implementation of mbedtls_platform_zeroize(), for |
* example by using directives specific to their compiler, features from newer |
* C standards (e.g using memset_s() in C11) or calling a secure memset() from |
* their system (e.g explicit_bzero() in BSD). |
*/ |
//#define MBEDTLS_PLATFORM_ZEROIZE_ALT |
/** |
* Uncomment the macro to let Mbed TLS use your alternate implementation of |
* mbedtls_platform_gmtime_r(). This replaces the default implementation in |
* platform_util.c. |
* |
* gmtime() is not a thread-safe function as defined in the C standard. The |
* library will try to use safer implementations of this function, such as |
* gmtime_r() when available. However, if Mbed TLS cannot identify the target |
* system, the implementation of mbedtls_platform_gmtime_r() will default to |
* using the standard gmtime(). In this case, calls from the library to |
* gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex |
* if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the |
* library are also guarded with this mutex to avoid race conditions. However, |
* if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will |
* unconditionally use the implementation for mbedtls_platform_gmtime_r() |
* supplied at compile time. |
*/ |
//#define MBEDTLS_PLATFORM_GMTIME_R_ALT |
/* \} name SECTION: Customisation configuration options */ |
/* Target and application specific configurations |
* |
* Allow user to override any previous default. |
* |
*/ |
#if defined(MBEDTLS_USER_CONFIG_FILE) |
#include MBEDTLS_USER_CONFIG_FILE |
#endif |
#include "check_config.h" |
#endif /* MBEDTLS_CONFIG_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ctr_drbg.h |
---|
0,0 → 1,514 |
/** |
* \file ctr_drbg.h |
* |
* \brief This file contains definitions and functions for the |
* CTR_DRBG pseudorandom generator. |
* |
* CTR_DRBG is a standardized way of building a PRNG from a block-cipher |
* in counter mode operation, as defined in <em>NIST SP 800-90A: |
* Recommendation for Random Number Generation Using Deterministic Random |
* Bit Generators</em>. |
* |
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 |
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time) |
* as the underlying block cipher, with a derivation function. |
* The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy. |
* See the documentation of mbedtls_ctr_drbg_seed() for more details. |
* |
* Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2, |
* here are the security strengths achieved in typical configuration: |
* - 256 bits under the default configuration of the library, with AES-256 |
* and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. |
* - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set |
* to 32 or more, and the DRBG is initialized with an explicit |
* nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). |
* - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is |
* between 24 and 47 and the DRBG is not initialized with an explicit |
* nonce (see mbedtls_ctr_drbg_seed()). |
* - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled) |
* and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is |
* always the case unless it is explicitly set to a different value |
* in config.h). |
* |
* Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to: |
* - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol |
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time. |
* This is the default configuration of the library. |
* - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time. |
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. |
*/ |
/* |
* Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_CTR_DRBG_H |
#define MBEDTLS_CTR_DRBG_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "aes.h" |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ |
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< The requested random buffer length is too big. */ |
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */ |
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */ |
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ |
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) |
#define MBEDTLS_CTR_DRBG_KEYSIZE 16 |
/**< The key size in bytes used by the cipher. |
* |
* Compile-time choice: 16 bytes (128 bits) |
* because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. |
*/ |
#else |
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 |
/**< The key size in bytes used by the cipher. |
* |
* Compile-time choice: 32 bytes (256 bits) |
* because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. |
*/ |
#endif |
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */ |
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */ |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them using the compiler command |
* line. |
* \{ |
*/ |
/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN |
* |
* \brief The amount of entropy used per seed by default, in bytes. |
*/ |
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) |
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) |
/** This is 48 bytes because the entropy module uses SHA-512 |
* (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). |
*/ |
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 |
#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ |
/** This is 32 bytes because the entropy module uses SHA-256 |
* (the SHA512 module is disabled or |
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). |
*/ |
#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) |
/** \warning To achieve a 256-bit security strength, you must pass a nonce |
* to mbedtls_ctr_drbg_seed(). |
*/ |
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ |
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 |
#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ |
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ |
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) |
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 |
/**< The interval before reseed is performed by default. */ |
#endif |
#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT) |
#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 |
/**< The maximum number of additional input Bytes. */ |
#endif |
#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST) |
#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 |
/**< The maximum number of requested Bytes per call. */ |
#endif |
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) |
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 |
/**< The maximum size of seed or reseed buffer in bytes. */ |
#endif |
/* \} name SECTION: Module settings */ |
#define MBEDTLS_CTR_DRBG_PR_OFF 0 |
/**< Prediction resistance is disabled. */ |
#define MBEDTLS_CTR_DRBG_PR_ON 1 |
/**< Prediction resistance is enabled. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief The CTR_DRBG context structure. |
*/ |
typedef struct mbedtls_ctr_drbg_context |
{ |
unsigned char counter[16]; /*!< The counter (V). */ |
int reseed_counter; /*!< The reseed counter. */ |
int prediction_resistance; /*!< This determines whether prediction |
resistance is enabled, that is |
whether to systematically reseed before |
each random generation. */ |
size_t entropy_len; /*!< The amount of entropy grabbed on each |
seed or reseed operation. */ |
int reseed_interval; /*!< The reseed interval. */ |
mbedtls_aes_context aes_ctx; /*!< The AES context. */ |
/* |
* Callbacks (Entropy) |
*/ |
int (*f_entropy)(void *, unsigned char *, size_t); |
/*!< The entropy callback function. */ |
void *p_entropy; /*!< The context for the entropy function. */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; |
#endif |
} |
mbedtls_ctr_drbg_context; |
/** |
* \brief This function initializes the CTR_DRBG context, |
* and prepares it for mbedtls_ctr_drbg_seed() |
* or mbedtls_ctr_drbg_free(). |
* |
* \param ctx The CTR_DRBG context to initialize. |
*/ |
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); |
/** |
* \brief This function seeds and sets up the CTR_DRBG |
* entropy source for future reseeds. |
* |
* A typical choice for the \p f_entropy and \p p_entropy parameters is |
* to use the entropy module: |
* - \p f_entropy is mbedtls_entropy_func(); |
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized |
* with mbedtls_entropy_init() (which registers the platform's default |
* entropy sources). |
* |
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default. |
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len(). |
* |
* You can provide a personalization string in addition to the |
* entropy source, to make this instantiation as unique as possible. |
* |
* \note The _seed_material_ value passed to the derivation |
* function in the CTR_DRBG Instantiate Process |
* described in NIST SP 800-90A §10.2.1.3.2 |
* is the concatenation of the string obtained from |
* calling \p f_entropy and the \p custom string. |
* The origin of the nonce depends on the value of |
* the entropy length relative to the security strength. |
* - If the entropy length is at least 1.5 times the |
* security strength then the nonce is taken from the |
* string obtained with \p f_entropy. |
* - If the entropy length is less than the security |
* strength, then the nonce is taken from \p custom. |
* In this case, for compliance with SP 800-90A, |
* you must pass a unique value of \p custom at |
* each invocation. See SP 800-90A §8.6.7 for more |
* details. |
*/ |
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 |
/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than |
* #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the |
* maximum security strength permitted by CTR_DRBG, |
* you must pass a value of \p custom that is a nonce: |
* this value must never be repeated in subsequent |
* runs of the same application or on a different |
* device. |
*/ |
#endif |
/** |
* \param ctx The CTR_DRBG context to seed. |
* It must have been initialized with |
* mbedtls_ctr_drbg_init(). |
* After a successful call to mbedtls_ctr_drbg_seed(), |
* you may not call mbedtls_ctr_drbg_seed() again on |
* the same context unless you call |
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init() |
* again first. |
* \param f_entropy The entropy callback, taking as arguments the |
* \p p_entropy context, the buffer to fill, and the |
* length of the buffer. |
* \p f_entropy is always called with a buffer size |
* equal to the entropy length. |
* \param p_entropy The entropy context to pass to \p f_entropy. |
* \param custom The personalization string. |
* This can be \c NULL, in which case the personalization |
* string is empty regardless of the value of \p len. |
* \param len The length of the personalization string. |
* This must be at most |
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT |
* - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. |
*/ |
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, |
int (*f_entropy)(void *, unsigned char *, size_t), |
void *p_entropy, |
const unsigned char *custom, |
size_t len ); |
/** |
* \brief This function clears CTR_CRBG context data. |
* |
* \param ctx The CTR_DRBG context to clear. |
*/ |
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); |
/** |
* \brief This function turns prediction resistance on or off. |
* The default value is off. |
* |
* \note If enabled, entropy is gathered at the beginning of |
* every call to mbedtls_ctr_drbg_random_with_add() |
* or mbedtls_ctr_drbg_random(). |
* Only use this if your entropy source has sufficient |
* throughput. |
* |
* \param ctx The CTR_DRBG context. |
* \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF. |
*/ |
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, |
int resistance ); |
/** |
* \brief This function sets the amount of entropy grabbed on each |
* seed or reseed. |
* |
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. |
* |
* \note The security strength of CTR_DRBG is bounded by the |
* entropy length. Thus: |
* - When using AES-256 |
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, |
* which is the default), |
* \p len must be at least 32 (in bytes) |
* to achieve a 256-bit strength. |
* - When using AES-128 |
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) |
* \p len must be at least 16 (in bytes) |
* to achieve a 128-bit strength. |
* |
* \param ctx The CTR_DRBG context. |
* \param len The amount of entropy to grab, in bytes. |
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. |
*/ |
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, |
size_t len ); |
/** |
* \brief This function sets the reseed interval. |
* |
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random() |
* or mbedtls_ctr_drbg_random_with_add() after which the entropy function |
* is called again. |
* |
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. |
* |
* \param ctx The CTR_DRBG context. |
* \param interval The reseed interval. |
*/ |
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, |
int interval ); |
/** |
* \brief This function reseeds the CTR_DRBG context, that is |
* extracts data from the entropy source. |
* |
* \param ctx The CTR_DRBG context. |
* \param additional Additional data to add to the state. Can be \c NULL. |
* \param len The length of the additional data. |
* This must be less than |
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len |
* where \c entropy_len is the entropy length |
* configured for the context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. |
*/ |
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, |
const unsigned char *additional, size_t len ); |
/** |
* \brief This function updates the state of the CTR_DRBG context. |
* |
* \param ctx The CTR_DRBG context. |
* \param additional The data to update the state with. This must not be |
* \c NULL unless \p add_len is \c 0. |
* \param add_len Length of \p additional in bytes. This must be at |
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if |
* \p add_len is more than |
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. |
* \return An error from the underlying AES cipher on failure. |
*/ |
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, |
const unsigned char *additional, |
size_t add_len ); |
/** |
* \brief This function updates a CTR_DRBG instance with additional |
* data and uses it to generate random data. |
* |
* This function automatically reseeds if the reseed counter is exceeded |
* or prediction resistance is enabled. |
* |
* \param p_rng The CTR_DRBG context. This must be a pointer to a |
* #mbedtls_ctr_drbg_context structure. |
* \param output The buffer to fill. |
* \param output_len The length of the buffer in bytes. |
* \param additional Additional data to update. Can be \c NULL, in which |
* case the additional data is empty regardless of |
* the value of \p add_len. |
* \param add_len The length of the additional data |
* if \p additional is not \c NULL. |
* This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT |
* and less than |
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len |
* where \c entropy_len is the entropy length |
* configured for the context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or |
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. |
*/ |
int mbedtls_ctr_drbg_random_with_add( void *p_rng, |
unsigned char *output, size_t output_len, |
const unsigned char *additional, size_t add_len ); |
/** |
* \brief This function uses CTR_DRBG to generate random data. |
* |
* This function automatically reseeds if the reseed counter is exceeded |
* or prediction resistance is enabled. |
* |
* |
* \param p_rng The CTR_DRBG context. This must be a pointer to a |
* #mbedtls_ctr_drbg_context structure. |
* \param output The buffer to fill. |
* \param output_len The length of the buffer in bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or |
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. |
*/ |
int mbedtls_ctr_drbg_random( void *p_rng, |
unsigned char *output, size_t output_len ); |
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function updates the state of the CTR_DRBG context. |
* |
* \deprecated Superseded by mbedtls_ctr_drbg_update_ret() |
* in 2.16.0. |
* |
* \note If \p add_len is greater than |
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first |
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used. |
* The remaining Bytes are silently discarded. |
* |
* \param ctx The CTR_DRBG context. |
* \param additional The data to update the state with. |
* \param add_len Length of \p additional data. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( |
mbedtls_ctr_drbg_context *ctx, |
const unsigned char *additional, |
size_t add_len ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief This function writes a seed file. |
* |
* \param ctx The CTR_DRBG context. |
* \param path The name of the file. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. |
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed |
* failure. |
*/ |
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); |
/** |
* \brief This function reads and updates a seed file. The seed |
* is added to this instance. |
* |
* \param ctx The CTR_DRBG context. |
* \param path The name of the file. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. |
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on |
* reseed failure. |
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing |
* seed file is too large. |
*/ |
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The CTR_DRBG checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_ctr_drbg_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
/* Internal functions (do not call directly) */ |
int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *, |
int (*)(void *, unsigned char *, size_t), void *, |
const unsigned char *, size_t, size_t ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* ctr_drbg.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/debug.h |
---|
0,0 → 1,267 |
/** |
* \file debug.h |
* |
* \brief Functions for controlling and providing debug output from the library. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_DEBUG_H |
#define MBEDTLS_DEBUG_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ssl.h" |
#if defined(MBEDTLS_ECP_C) |
#include "ecp.h" |
#endif |
#if defined(MBEDTLS_DEBUG_C) |
#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__ |
#define MBEDTLS_SSL_DEBUG_MSG( level, args ) \ |
mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__, \ |
MBEDTLS_DEBUG_STRIP_PARENS args ) |
#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) \ |
mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret ) |
#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) \ |
mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len ) |
#if defined(MBEDTLS_BIGNUM_C) |
#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) \ |
mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X ) |
#endif |
#if defined(MBEDTLS_ECP_C) |
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) \ |
mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X ) |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \ |
mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt ) |
#endif |
#if defined(MBEDTLS_ECDH_C) |
#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) \ |
mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr ) |
#endif |
#else /* MBEDTLS_DEBUG_C */ |
#define MBEDTLS_SSL_DEBUG_MSG( level, args ) do { } while( 0 ) |
#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) do { } while( 0 ) |
#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 ) |
#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 ) |
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) |
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) |
#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) do { } while( 0 ) |
#endif /* MBEDTLS_DEBUG_C */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Set the threshold error level to handle globally all debug output. |
* Debug messages that have a level over the threshold value are |
* discarded. |
* (Default value: 0 = No debug ) |
* |
* \param threshold theshold level of messages to filter on. Messages at a |
* higher level will be discarded. |
* - Debug levels |
* - 0 No debug |
* - 1 Error |
* - 2 State change |
* - 3 Informational |
* - 4 Verbose |
*/ |
void mbedtls_debug_set_threshold( int threshold ); |
/** |
* \brief Print a message to the debug output. This function is always used |
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl |
* context, file and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the message has occurred in |
* \param line line number the message has occurred at |
* \param format format specifier, in printf format |
* \param ... variables used by the format specifier |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *format, ... ); |
/** |
* \brief Print the return value of a function to the debug output. This |
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, |
* which supplies the ssl context, file and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the error has occurred in |
* \param line line number the error has occurred in |
* \param text the name of the function that returned the error |
* \param ret the return code value |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, int ret ); |
/** |
* \brief Output a buffer of size len bytes to the debug output. This function |
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, |
* which supplies the ssl context, file and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the error has occurred in |
* \param line line number the error has occurred in |
* \param text a name or label for the buffer being dumped. Normally the |
* variable or buffer name |
* \param buf the buffer to be outputted |
* \param len length of the buffer |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, const char *text, |
const unsigned char *buf, size_t len ); |
#if defined(MBEDTLS_BIGNUM_C) |
/** |
* \brief Print a MPI variable to the debug output. This function is always |
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the |
* ssl context, file and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the error has occurred in |
* \param line line number the error has occurred in |
* \param text a name or label for the MPI being output. Normally the |
* variable name |
* \param X the MPI variable |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_mpi *X ); |
#endif |
#if defined(MBEDTLS_ECP_C) |
/** |
* \brief Print an ECP point to the debug output. This function is always |
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the |
* ssl context, file and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the error has occurred in |
* \param line line number the error has occurred in |
* \param text a name or label for the ECP point being output. Normally the |
* variable name |
* \param X the ECP point |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_ecp_point *X ); |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* \brief Print a X.509 certificate structure to the debug output. This |
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, |
* which supplies the ssl context, file and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the error has occurred in |
* \param line line number the error has occurred in |
* \param text a name or label for the certificate being output |
* \param crt X.509 certificate structure |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_x509_crt *crt ); |
#endif |
#if defined(MBEDTLS_ECDH_C) |
typedef enum |
{ |
MBEDTLS_DEBUG_ECDH_Q, |
MBEDTLS_DEBUG_ECDH_QP, |
MBEDTLS_DEBUG_ECDH_Z, |
} mbedtls_debug_ecdh_attr; |
/** |
* \brief Print a field of the ECDH structure in the SSL context to the debug |
* output. This function is always used through the |
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file |
* and line number parameters. |
* |
* \param ssl SSL context |
* \param level error level of the debug message |
* \param file file the error has occurred in |
* \param line line number the error has occurred in |
* \param ecdh the ECDH context |
* \param attr the identifier of the attribute being output |
* |
* \attention This function is intended for INTERNAL usage within the |
* library only. |
*/ |
void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const mbedtls_ecdh_context *ecdh, |
mbedtls_debug_ecdh_attr attr ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* debug.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/des.h |
---|
0,0 → 1,358 |
/** |
* \file des.h |
* |
* \brief DES block cipher |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
* |
*/ |
#ifndef MBEDTLS_DES_H |
#define MBEDTLS_DES_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
#define MBEDTLS_DES_ENCRYPT 1 |
#define MBEDTLS_DES_DECRYPT 0 |
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ |
/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */ |
#define MBEDTLS_DES_KEY_SIZE 8 |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_DES_ALT) |
// Regular implementation |
// |
/** |
* \brief DES context structure |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
typedef struct mbedtls_des_context |
{ |
uint32_t sk[32]; /*!< DES subkeys */ |
} |
mbedtls_des_context; |
/** |
* \brief Triple-DES context structure |
*/ |
typedef struct mbedtls_des3_context |
{ |
uint32_t sk[96]; /*!< 3DES subkeys */ |
} |
mbedtls_des3_context; |
#else /* MBEDTLS_DES_ALT */ |
#include "des_alt.h" |
#endif /* MBEDTLS_DES_ALT */ |
/** |
* \brief Initialize DES context |
* |
* \param ctx DES context to be initialized |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
void mbedtls_des_init( mbedtls_des_context *ctx ); |
/** |
* \brief Clear DES context |
* |
* \param ctx DES context to be cleared |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
void mbedtls_des_free( mbedtls_des_context *ctx ); |
/** |
* \brief Initialize Triple-DES context |
* |
* \param ctx DES3 context to be initialized |
*/ |
void mbedtls_des3_init( mbedtls_des3_context *ctx ); |
/** |
* \brief Clear Triple-DES context |
* |
* \param ctx DES3 context to be cleared |
*/ |
void mbedtls_des3_free( mbedtls_des3_context *ctx ); |
/** |
* \brief Set key parity on the given key to odd. |
* |
* DES keys are 56 bits long, but each byte is padded with |
* a parity bit to allow verification. |
* |
* \param key 8-byte secret key |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ); |
/** |
* \brief Check that key parity on the given key is odd. |
* |
* DES keys are 56 bits long, but each byte is padded with |
* a parity bit to allow verification. |
* |
* \param key 8-byte secret key |
* |
* \return 0 is parity was ok, 1 if parity was not correct. |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); |
/** |
* \brief Check that key is not a weak or semi-weak DES key |
* |
* \param key 8-byte secret key |
* |
* \return 0 if no weak key was found, 1 if a weak key was identified. |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); |
/** |
* \brief DES key schedule (56-bit, encryption) |
* |
* \param ctx DES context to be initialized |
* \param key 8-byte secret key |
* |
* \return 0 |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); |
/** |
* \brief DES key schedule (56-bit, decryption) |
* |
* \param ctx DES context to be initialized |
* \param key 8-byte secret key |
* |
* \return 0 |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); |
/** |
* \brief Triple-DES key schedule (112-bit, encryption) |
* |
* \param ctx 3DES context to be initialized |
* \param key 16-byte secret key |
* |
* \return 0 |
*/ |
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ); |
/** |
* \brief Triple-DES key schedule (112-bit, decryption) |
* |
* \param ctx 3DES context to be initialized |
* \param key 16-byte secret key |
* |
* \return 0 |
*/ |
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ); |
/** |
* \brief Triple-DES key schedule (168-bit, encryption) |
* |
* \param ctx 3DES context to be initialized |
* \param key 24-byte secret key |
* |
* \return 0 |
*/ |
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ); |
/** |
* \brief Triple-DES key schedule (168-bit, decryption) |
* |
* \param ctx 3DES context to be initialized |
* \param key 24-byte secret key |
* |
* \return 0 |
*/ |
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ); |
/** |
* \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 |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, |
const unsigned char input[8], |
unsigned char output[8] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief DES-CBC buffer encryption/decryption |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the function same function again on the following |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If on the other hand you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* \param ctx DES context |
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_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 |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[8], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
/** |
* \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 mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, |
const unsigned char input[8], |
unsigned char output[8] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief 3DES-CBC buffer encryption/decryption |
* |
* \note Upon exit, the content of the IV is updated so that you can |
* call the function same function again on the following |
* block(s) of data and get the same result as if it was |
* encrypted in one call. This allows a "streaming" usage. |
* If on the other hand you need to retain the contents of the |
* IV, you should either save it manually or use the cipher |
* module instead. |
* |
* \param ctx 3DES context |
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_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 MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH |
*/ |
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[8], |
const unsigned char *input, |
unsigned char *output ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
/** |
* \brief Internal function for key expansion. |
* (Only exposed to allow overriding it, |
* see MBEDTLS_DES_SETKEY_ALT) |
* |
* \param SK Round keys |
* \param key Base key |
* |
* \warning DES is considered a weak cipher and its use constitutes a |
* security risk. We recommend considering stronger ciphers |
* instead. |
*/ |
void mbedtls_des_setkey( uint32_t SK[32], |
const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_des_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* des.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/dhm.h |
---|
0,0 → 1,1098 |
/** |
* \file dhm.h |
* |
* \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange |
* definitions and functions. |
* |
* Diffie-Hellman-Merkle (DHM) key exchange is defined in |
* <em>RFC-2631: Diffie-Hellman Key Agreement Method</em> and |
* <em>Public-Key Cryptography Standards (PKCS) #3: Diffie |
* Hellman Key Agreement Standard</em>. |
* |
* <em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for |
* Internet Key Exchange (IKE)</em> defines a number of standardized |
* Diffie-Hellman groups for IKE. |
* |
* <em>RFC-5114: Additional Diffie-Hellman Groups for Use with IETF |
* Standards</em> defines a number of standardized Diffie-Hellman |
* groups that can be used. |
* |
* \warning The security of the DHM key exchange relies on the proper choice |
* of prime modulus - optimally, it should be a safe prime. The usage |
* of non-safe primes both decreases the difficulty of the underlying |
* discrete logarithm problem and can lead to small subgroup attacks |
* leaking private exponent bits when invalid public keys are used |
* and not detected. This is especially relevant if the same DHM |
* parameters are reused for multiple key exchanges as in static DHM, |
* while the criticality of small-subgroup attacks is lower for |
* ephemeral DHM. |
* |
* \warning For performance reasons, the code does neither perform primality |
* nor safe primality tests, nor the expensive checks for invalid |
* subgroups. Moreover, even if these were performed, non-standardized |
* primes cannot be trusted because of the possibility of backdoors |
* that can't be effectively checked for. |
* |
* \warning Diffie-Hellman-Merkle is therefore a security risk when not using |
* standardized primes generated using a trustworthy ("nothing up |
* my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS |
* protocol, DH parameters need to be negotiated, so using the default |
* primes systematically is not always an option. If possible, use |
* Elliptic Curve Diffie-Hellman (ECDH), which has better performance, |
* and for which the TLS protocol mandates the use of standard |
* parameters. |
* |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_DHM_H |
#define MBEDTLS_DHM_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "bignum.h" |
/* |
* DHM Error codes |
*/ |
#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters. */ |
#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */ |
#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */ |
#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */ |
#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */ |
#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */ |
#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */ |
#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 /**< Allocation of memory failed. */ |
#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read or write of file failed. */ |
/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED -0x3500 /**< DHM hardware accelerator failed. */ |
#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 /**< Setting the modulus and generator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_DHM_ALT) |
/** |
* \brief The DHM context structure. |
*/ |
typedef struct mbedtls_dhm_context |
{ |
size_t len; /*!< The size of \p P in Bytes. */ |
mbedtls_mpi P; /*!< The prime modulus. */ |
mbedtls_mpi G; /*!< The generator. */ |
mbedtls_mpi X; /*!< Our secret value. */ |
mbedtls_mpi GX; /*!< Our public key = \c G^X mod \c P. */ |
mbedtls_mpi GY; /*!< The public key of the peer = \c G^Y mod \c P. */ |
mbedtls_mpi K; /*!< The shared secret = \c G^(XY) mod \c P. */ |
mbedtls_mpi RP; /*!< The cached value = \c R^2 mod \c P. */ |
mbedtls_mpi Vi; /*!< The blinding value. */ |
mbedtls_mpi Vf; /*!< The unblinding value. */ |
mbedtls_mpi pX; /*!< The previous \c X. */ |
} |
mbedtls_dhm_context; |
#else /* MBEDTLS_DHM_ALT */ |
#include "dhm_alt.h" |
#endif /* MBEDTLS_DHM_ALT */ |
/** |
* \brief This function initializes the DHM context. |
* |
* \param ctx The DHM context to initialize. |
*/ |
void mbedtls_dhm_init( mbedtls_dhm_context *ctx ); |
/** |
* \brief This function parses the DHM parameters in a |
* TLS ServerKeyExchange handshake message |
* (DHM modulus, generator, and public key). |
* |
* \note In a TLS handshake, this is the how the client |
* sets up its DHM context from the server's public |
* DHM key material. |
* |
* \param ctx The DHM context to use. This must be initialized. |
* \param p On input, *p must be the start of the input buffer. |
* On output, *p is updated to point to the end of the data |
* that has been read. On success, this is the first byte |
* past the end of the ServerKeyExchange parameters. |
* On error, this is the point at which an error has been |
* detected, which is usually not useful except to debug |
* failures. |
* \param end The end of the input buffer. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. |
*/ |
int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, |
unsigned char **p, |
const unsigned char *end ); |
/** |
* \brief This function generates a DHM key pair and exports its |
* public part together with the DHM parameters in the format |
* used in a TLS ServerKeyExchange handshake message. |
* |
* \note This function assumes that the DHM parameters \c ctx->P |
* and \c ctx->G have already been properly set. For that, use |
* mbedtls_dhm_set_group() below in conjunction with |
* mbedtls_mpi_read_binary() and mbedtls_mpi_read_string(). |
* |
* \note In a TLS handshake, this is the how the server generates |
* and exports its DHM key material. |
* |
* \param ctx The DHM context to use. This must be initialized |
* and have the DHM parameters set. It may or may not |
* already have imported the peer's public key. |
* \param x_size The private key size in Bytes. |
* \param olen The address at which to store the number of Bytes |
* written on success. This must not be \c NULL. |
* \param output The destination buffer. This must be a writable buffer of |
* sufficient size to hold the reduced binary presentation of |
* the modulus, the generator and the public key, each wrapped |
* with a 2-byte length field. It is the responsibility of the |
* caller to ensure that enough space is available. Refer to |
* mbedtls_mpi_size() to computing the byte-size of an MPI. |
* \param f_rng The RNG function. Must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng doesn't need a context parameter. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. |
*/ |
int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, |
unsigned char *output, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function sets the prime modulus and generator. |
* |
* \note This function can be used to set \c ctx->P, \c ctx->G |
* in preparation for mbedtls_dhm_make_params(). |
* |
* \param ctx The DHM context to configure. This must be initialized. |
* \param P The MPI holding the DHM prime modulus. This must be |
* an initialized MPI. |
* \param G The MPI holding the DHM generator. This must be an |
* initialized MPI. |
* |
* \return \c 0 if successful. |
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. |
*/ |
int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, |
const mbedtls_mpi *P, |
const mbedtls_mpi *G ); |
/** |
* \brief This function imports the raw public value of the peer. |
* |
* \note In a TLS handshake, this is the how the server imports |
* the Client's public DHM key. |
* |
* \param ctx The DHM context to use. This must be initialized and have |
* its DHM parameters set, e.g. via mbedtls_dhm_set_group(). |
* It may or may not already have generated its own private key. |
* \param input The input buffer containing the \c G^Y value of the peer. |
* This must be a readable buffer of size \p ilen Bytes. |
* \param ilen The size of the input buffer \p input in Bytes. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. |
*/ |
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, |
const unsigned char *input, size_t ilen ); |
/** |
* \brief This function creates a DHM key pair and exports |
* the raw public key in big-endian format. |
* |
* \note The destination buffer is always fully written |
* so as to contain a big-endian representation of G^X mod P. |
* If it is larger than \c ctx->len, it is padded accordingly |
* with zero-bytes at the beginning. |
* |
* \param ctx The DHM context to use. This must be initialized and |
* have the DHM parameters set. It may or may not already |
* have imported the peer's public key. |
* \param x_size The private key size in Bytes. |
* \param output The destination buffer. This must be a writable buffer of |
* size \p olen Bytes. |
* \param olen The length of the destination buffer. This must be at least |
* equal to `ctx->len` (the size of \c P). |
* \param f_rng The RNG function. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL |
* if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. |
*/ |
int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, |
unsigned char *output, size_t olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function derives and exports the shared secret |
* \c (G^Y)^X mod \c P. |
* |
* \note If \p f_rng is not \c NULL, it is used to blind the input as |
* a countermeasure against timing attacks. Blinding is used |
* only if our private key \c X is re-used, and not used |
* otherwise. We recommend always passing a non-NULL |
* \p f_rng argument. |
* |
* \param ctx The DHM context to use. This must be initialized |
* and have its own private key generated and the peer's |
* public key imported. |
* \param output The buffer to write the generated shared key to. This |
* must be a writable buffer of size \p output_size Bytes. |
* \param output_size The size of the destination buffer. This must be at |
* least the size of \c ctx->len (the size of \c P). |
* \param olen On exit, holds the actual number of Bytes written. |
* \param f_rng The RNG function, for blinding purposes. This may |
* b \c NULL if blinding isn't needed. |
* \param p_rng The RNG context. This may be \c NULL if \p f_rng |
* doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. |
*/ |
int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, |
unsigned char *output, size_t output_size, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function frees and clears the components |
* of a DHM context. |
* |
* \param ctx The DHM context to free and clear. This may be \c NULL, |
* in which case this function is a no-op. If it is not \c NULL, |
* it must point to an initialized DHM context. |
*/ |
void mbedtls_dhm_free( mbedtls_dhm_context *ctx ); |
#if defined(MBEDTLS_ASN1_PARSE_C) |
/** \ingroup x509_module */ |
/** |
* \brief This function parses DHM parameters in PEM or DER format. |
* |
* \param dhm The DHM context to import the DHM parameters into. |
* This must be initialized. |
* \param dhmin The input buffer. This must be a readable buffer of |
* length \p dhminlen Bytes. |
* \param dhminlen The size of the input buffer \p dhmin, including the |
* terminating \c NULL Byte for PEM data. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error |
* code on failure. |
*/ |
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, |
size_t dhminlen ); |
#if defined(MBEDTLS_FS_IO) |
/** \ingroup x509_module */ |
/** |
* \brief This function loads and parses DHM parameters from a file. |
* |
* \param dhm The DHM context to load the parameters to. |
* This must be initialized. |
* \param path The filename to read the DHM parameters from. |
* This must not be \c NULL. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX |
* error code on failure. |
*/ |
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The DMH checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_dhm_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
/** |
* RFC 3526, RFC 5114 and RFC 7919 standardize a number of |
* Diffie-Hellman groups, some of which are included here |
* for use within the SSL/TLS module and the user's convenience |
* when configuring the Diffie-Hellman parameters by hand |
* through \c mbedtls_ssl_conf_dh_param. |
* |
* The following lists the source of the above groups in the standards: |
* - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup |
* - RFC 3526 section 3: 2048-bit MODP Group |
* - RFC 3526 section 4: 3072-bit MODP Group |
* - RFC 3526 section 5: 4096-bit MODP Group |
* - RFC 7919 section A.1: ffdhe2048 |
* - RFC 7919 section A.2: ffdhe3072 |
* - RFC 7919 section A.3: ffdhe4096 |
* - RFC 7919 section A.4: ffdhe6144 |
* - RFC 7919 section A.5: ffdhe8192 |
* |
* The constants with suffix "_p" denote the chosen prime moduli, while |
* the constants with suffix "_g" denote the chosen generator |
* of the associated prime field. |
* |
* The constants further suffixed with "_bin" are provided in binary format, |
* while all other constants represent null-terminated strings holding the |
* hexadecimal presentation of the respective numbers. |
* |
* The primes from RFC 3526 and RFC 7919 have been generating by the following |
* trust-worthy procedure: |
* - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number |
* the first and last 64 bits are all 1, and the remaining N - 128 bits of |
* which are 0x7ff...ff. |
* - Add the smallest multiple of the first N - 129 bits of the binary expansion |
* of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string |
* such that the resulting integer is a safe-prime. |
* - The result is the respective RFC 3526 / 7919 prime, and the corresponding |
* generator is always chosen to be 2 (which is a square for these prime, |
* hence the corresponding subgroup has order (p-1)/2 and avoids leaking a |
* bit in the private exponent). |
* |
*/ |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
/** |
* \warning The origin of the primes in RFC 5114 is not documented and |
* their use therefore constitutes a security risk! |
* |
* \deprecated The hex-encoded primes from RFC 5114 are deprecated and are |
* likely to be removed in a future version of the library without |
* replacement. |
*/ |
/** |
* The hexadecimal presentation of the prime underlying the |
* 2048-bit MODP Group with 224-bit Prime Order Subgroup, as defined |
* in <em>RFC-5114: Additional Diffie-Hellman Groups for Use with |
* IETF Standards</em>. |
*/ |
#define MBEDTLS_DHM_RFC5114_MODP_2048_P \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( \ |
"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \ |
"B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \ |
"EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \ |
"9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \ |
"C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \ |
"B3BF8A317091883681286130BC8985DB1602E714415D9330" \ |
"278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \ |
"CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \ |
"BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \ |
"C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \ |
"CF9DE5384E71B81C0AC4DFFE0C10E64F" ) |
/** |
* The hexadecimal presentation of the chosen generator of the 2048-bit MODP |
* Group with 224-bit Prime Order Subgroup, as defined in <em>RFC-5114: |
* Additional Diffie-Hellman Groups for Use with IETF Standards</em>. |
*/ |
#define MBEDTLS_DHM_RFC5114_MODP_2048_G \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( \ |
"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" \ |
"74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" \ |
"AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" \ |
"C17669101999024AF4D027275AC1348BB8A762D0521BC98A" \ |
"E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" \ |
"F180EB34118E98D119529A45D6F834566E3025E316A330EF" \ |
"BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" \ |
"10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" \ |
"B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" \ |
"EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" \ |
"81BC087F2A7065B384B890D3191F2BFA" ) |
/** |
* The hexadecimal presentation of the prime underlying the 2048-bit MODP |
* Group, as defined in <em>RFC-3526: More Modular Exponential (MODP) |
* Diffie-Hellman groups for Internet Key Exchange (IKE)</em>. |
* |
* \deprecated The hex-encoded primes from RFC 3625 are deprecated and |
* superseded by the corresponding macros providing them as |
* binary constants. Their hex-encoded constants are likely |
* to be removed in a future version of the library. |
* |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_2048_P \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( \ |
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ |
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ |
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ |
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ |
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ |
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ |
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ |
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ |
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ |
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ |
"15728E5A8AACAA68FFFFFFFFFFFFFFFF" ) |
/** |
* The hexadecimal presentation of the chosen generator of the 2048-bit MODP |
* Group, as defined in <em>RFC-3526: More Modular Exponential (MODP) |
* Diffie-Hellman groups for Internet Key Exchange (IKE)</em>. |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_2048_G \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) |
/** |
* The hexadecimal presentation of the prime underlying the 3072-bit MODP |
* Group, as defined in <em>RFC-3072: More Modular Exponential (MODP) |
* Diffie-Hellman groups for Internet Key Exchange (IKE)</em>. |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_3072_P \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( \ |
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ |
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ |
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ |
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ |
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ |
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ |
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ |
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ |
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ |
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ |
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ |
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ |
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ |
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ |
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ |
"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" ) |
/** |
* The hexadecimal presentation of the chosen generator of the 3072-bit MODP |
* Group, as defined in <em>RFC-3526: More Modular Exponential (MODP) |
* Diffie-Hellman groups for Internet Key Exchange (IKE)</em>. |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_3072_G \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) |
/** |
* The hexadecimal presentation of the prime underlying the 4096-bit MODP |
* Group, as defined in <em>RFC-3526: More Modular Exponential (MODP) |
* Diffie-Hellman groups for Internet Key Exchange (IKE)</em>. |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_4096_P \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( \ |
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ |
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ |
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ |
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ |
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ |
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ |
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ |
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ |
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ |
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ |
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ |
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ |
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ |
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ |
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ |
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \ |
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \ |
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \ |
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \ |
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \ |
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \ |
"FFFFFFFFFFFFFFFF" ) |
/** |
* The hexadecimal presentation of the chosen generator of the 4096-bit MODP |
* Group, as defined in <em>RFC-3526: More Modular Exponential (MODP) |
* Diffie-Hellman groups for Internet Key Exchange (IKE)</em>. |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_4096_G \ |
MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/* |
* Trustworthy DHM parameters in binary form |
*/ |
#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ |
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ |
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ |
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ |
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ |
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ |
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ |
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ |
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ |
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ |
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ |
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ |
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ |
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ |
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ |
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ |
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ |
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ |
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ |
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ |
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ |
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ |
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ |
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ |
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ |
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ |
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ |
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ |
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ |
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ |
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ |
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ |
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ |
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ |
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ |
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ |
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ |
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ |
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ |
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ |
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ |
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ |
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ |
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ |
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ |
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ |
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ |
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ |
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ |
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ |
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ |
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ |
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ |
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ |
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ |
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ |
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ |
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ |
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ |
0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ |
0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ |
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ |
0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ |
0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ |
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ |
0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ |
0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ |
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ |
0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ |
0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ |
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ |
0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ |
0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ |
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ |
0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ |
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ |
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ |
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ |
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ |
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ |
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ |
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ |
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ |
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ |
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ |
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ |
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ |
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ |
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ |
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ |
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ |
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ |
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ |
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ |
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ |
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ |
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ |
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ |
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ |
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ |
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ |
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ |
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ |
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ |
0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ |
0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ |
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ |
0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ |
0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ |
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ |
0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ |
0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ |
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ |
0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ |
0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ |
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ |
0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ |
0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ |
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ |
0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, \ |
0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, \ |
0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, \ |
0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, \ |
0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, \ |
0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, \ |
0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, \ |
0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, \ |
0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, \ |
0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, \ |
0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, \ |
0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, \ |
0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, \ |
0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, \ |
0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, \ |
0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, \ |
0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ |
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ |
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ |
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ |
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ |
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ |
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ |
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ |
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ |
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ |
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ |
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ |
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ |
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ |
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ |
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ |
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ |
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ |
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ |
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ |
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ |
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ |
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ |
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ |
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ |
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ |
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ |
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ |
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ |
0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } |
#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ |
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ |
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ |
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ |
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ |
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ |
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ |
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ |
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ |
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ |
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ |
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ |
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ |
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ |
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ |
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ |
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ |
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ |
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ |
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ |
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ |
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ |
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ |
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ |
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ |
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ |
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ |
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ |
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ |
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ |
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ |
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ |
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ |
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ |
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ |
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ |
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ |
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ |
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ |
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ |
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ |
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ |
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ |
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ |
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ |
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ |
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ |
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ |
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ |
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ |
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ |
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ |
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ |
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ |
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ |
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ |
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ |
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ |
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ |
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ |
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ |
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ |
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ |
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ |
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ |
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ |
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ |
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ |
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ |
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ |
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ |
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ |
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ |
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ |
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ |
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ |
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ |
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ |
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ |
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ |
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ |
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ |
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ |
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ |
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ |
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ |
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ |
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ |
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ |
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ |
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ |
0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ |
0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ |
0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ |
0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ |
0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ |
0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ |
0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ |
0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ |
0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ |
0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ |
0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ |
0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ |
0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ |
0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ |
0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ |
0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ |
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ |
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ |
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ |
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ |
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ |
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ |
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ |
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ |
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ |
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ |
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ |
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ |
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ |
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ |
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ |
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ |
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ |
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ |
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ |
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ |
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ |
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ |
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ |
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ |
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ |
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ |
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ |
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ |
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ |
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ |
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ |
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ |
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ |
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ |
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ |
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ |
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ |
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ |
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ |
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ |
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ |
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ |
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ |
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ |
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ |
0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ |
0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ |
0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ |
0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ |
0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ |
0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ |
0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ |
0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ |
0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ |
0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ |
0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ |
0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ |
0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ |
0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ |
0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ |
0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ |
0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ |
0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ |
0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ |
0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ |
0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ |
0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ |
0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ |
0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ |
0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ |
0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ |
0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ |
0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ |
0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ |
0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ |
0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ |
0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ |
0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ |
0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ |
0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ |
0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ |
0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ |
0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ |
0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ |
0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ |
0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ |
0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ |
0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ |
0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ |
0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ |
0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ |
0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ |
0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 } |
#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN { \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ |
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ |
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ |
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ |
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ |
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ |
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ |
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ |
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ |
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ |
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ |
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ |
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ |
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ |
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ |
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ |
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ |
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ |
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ |
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ |
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ |
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ |
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ |
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ |
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ |
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ |
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ |
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ |
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ |
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ |
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ |
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ |
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ |
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ |
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ |
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ |
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ |
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ |
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ |
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ |
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ |
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ |
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ |
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ |
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ |
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ |
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ |
0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ |
0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ |
0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ |
0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ |
0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ |
0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ |
0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ |
0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ |
0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ |
0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ |
0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ |
0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ |
0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ |
0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ |
0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ |
0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ |
0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ |
0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ |
0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ |
0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ |
0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ |
0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ |
0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ |
0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ |
0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ |
0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ |
0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ |
0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ |
0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ |
0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ |
0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ |
0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ |
0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ |
0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ |
0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ |
0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ |
0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ |
0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ |
0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ |
0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ |
0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ |
0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ |
0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ |
0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ |
0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ |
0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ |
0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ |
0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \ |
0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \ |
0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \ |
0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \ |
0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \ |
0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \ |
0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \ |
0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \ |
0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \ |
0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \ |
0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \ |
0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \ |
0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \ |
0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \ |
0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \ |
0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \ |
0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \ |
0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \ |
0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \ |
0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \ |
0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \ |
0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \ |
0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \ |
0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \ |
0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \ |
0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \ |
0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \ |
0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \ |
0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \ |
0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \ |
0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \ |
0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \ |
0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \ |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 } |
#endif /* dhm.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ecdh.h |
---|
0,0 → 1,442 |
/** |
* \file ecdh.h |
* |
* \brief This file contains ECDH definitions and functions. |
* |
* The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous |
* key agreement protocol allowing two parties to establish a shared |
* secret over an insecure channel. Each party must have an |
* elliptic-curve public–private key pair. |
* |
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for |
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm |
* Cryptography</em>. |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ECDH_H |
#define MBEDTLS_ECDH_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ecp.h" |
/* |
* Use a backward compatible ECDH context. |
* |
* This flag is always enabled for now and future versions might add a |
* configuration option that conditionally undefines this flag. |
* The configuration option in question may have a different name. |
* |
* Features undefining this flag, must have a warning in their description in |
* config.h stating that the feature breaks backward compatibility. |
*/ |
#define MBEDTLS_ECDH_LEGACY_CONTEXT |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Defines the source of the imported EC key. |
*/ |
typedef enum |
{ |
MBEDTLS_ECDH_OURS, /**< Our key. */ |
MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ |
} mbedtls_ecdh_side; |
#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
/** |
* Defines the ECDH implementation used. |
* |
* Later versions of the library may add new variants, therefore users should |
* not make any assumptions about them. |
*/ |
typedef enum |
{ |
MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ |
MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ |
} mbedtls_ecdh_variant; |
/** |
* The context used by the default ECDH implementation. |
* |
* Later versions might change the structure of this context, therefore users |
* should not make any assumptions about the structure of |
* mbedtls_ecdh_context_mbed. |
*/ |
typedef struct mbedtls_ecdh_context_mbed |
{ |
mbedtls_ecp_group grp; /*!< The elliptic curve used. */ |
mbedtls_mpi d; /*!< The private key. */ |
mbedtls_ecp_point Q; /*!< The public key. */ |
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ |
mbedtls_mpi z; /*!< The shared secret. */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ |
#endif |
} mbedtls_ecdh_context_mbed; |
#endif |
/** |
* |
* \warning Performing multiple operations concurrently on the same |
* ECDSA context is not supported; objects of this type |
* should not be shared between multiple threads. |
* \brief The ECDH context structure. |
*/ |
typedef struct mbedtls_ecdh_context |
{ |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
mbedtls_ecp_group grp; /*!< The elliptic curve used. */ |
mbedtls_mpi d; /*!< The private key. */ |
mbedtls_ecp_point Q; /*!< The public key. */ |
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ |
mbedtls_mpi z; /*!< The shared secret. */ |
int point_format; /*!< The format of point export in TLS messages. */ |
mbedtls_ecp_point Vi; /*!< The blinding value. */ |
mbedtls_ecp_point Vf; /*!< The unblinding value. */ |
mbedtls_mpi _d; /*!< The previous \p d. */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
int restart_enabled; /*!< The flag for restartable mode. */ |
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#else |
uint8_t point_format; /*!< The format of point export in TLS messages |
as defined in RFC 4492. */ |
mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */ |
mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */ |
union |
{ |
mbedtls_ecdh_context_mbed mbed_ecdh; |
} ctx; /*!< Implementation-specific context. The |
context in use is specified by the \c var |
field. */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of |
an alternative implementation not supporting |
restartable mode must return |
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error |
if this flag is set. */ |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ |
} |
mbedtls_ecdh_context; |
/** |
* \brief This function generates an ECDH keypair on an elliptic |
* curve. |
* |
* This function performs the first of two core computations |
* implemented during the ECDH key exchange. The second core |
* computation is performed by mbedtls_ecdh_compute_shared(). |
* |
* \see ecp.h |
* |
* \param grp The ECP group to use. This must be initialized and have |
* domain parameters loaded, for example through |
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). |
* \param d The destination MPI (private key). |
* This must be initialized. |
* \param Q The destination point (public key). |
* This must be initialized. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL in case \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return Another \c MBEDTLS_ERR_ECP_XXX or |
* \c MBEDTLS_MPI_XXX error code on failure. |
*/ |
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function computes the shared secret. |
* |
* This function performs the second of two core computations |
* implemented during the ECDH key exchange. The first core |
* computation is performed by mbedtls_ecdh_gen_public(). |
* |
* \see ecp.h |
* |
* \note If \p f_rng is not NULL, it is used to implement |
* countermeasures against side-channel attacks. |
* For more information, see mbedtls_ecp_mul(). |
* |
* \param grp The ECP group to use. This must be initialized and have |
* domain parameters loaded, for example through |
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). |
* \param z The destination MPI (shared secret). |
* This must be initialized. |
* \param Q The public key from another party. |
* This must be initialized. |
* \param d Our secret exponent (private key). |
* This must be initialized. |
* \param f_rng The RNG function. This may be \c NULL if randomization |
* of intermediate results during the ECP computations is |
* not needed (discouraged). See the documentation of |
* mbedtls_ecp_mul() for more. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a |
* context argument. |
* |
* \return \c 0 on success. |
* \return Another \c MBEDTLS_ERR_ECP_XXX or |
* \c MBEDTLS_MPI_XXX error code on failure. |
*/ |
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, |
const mbedtls_ecp_point *Q, const mbedtls_mpi *d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function initializes an ECDH context. |
* |
* \param ctx The ECDH context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); |
/** |
* \brief This function sets up the ECDH context with the information |
* given. |
* |
* This function should be called after mbedtls_ecdh_init() but |
* before mbedtls_ecdh_make_params(). There is no need to call |
* this function before mbedtls_ecdh_read_params(). |
* |
* This is the first function used by a TLS server for ECDHE |
* ciphersuites. |
* |
* \param ctx The ECDH context to set up. This must be initialized. |
* \param grp_id The group id of the group to set up the context for. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, |
mbedtls_ecp_group_id grp_id ); |
/** |
* \brief This function frees a context. |
* |
* \param ctx The context to free. This may be \c NULL, in which |
* case this function does nothing. If it is not \c NULL, |
* it must point to an initialized ECDH context. |
*/ |
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ); |
/** |
* \brief This function generates an EC key pair and exports its |
* in the format used in a TLS ServerKeyExchange handshake |
* message. |
* |
* This is the second function used by a TLS server for ECDHE |
* ciphersuites. (It is called after mbedtls_ecdh_setup().) |
* |
* \see ecp.h |
* |
* \param ctx The ECDH context to use. This must be initialized |
* and bound to a group, for example via mbedtls_ecdh_setup(). |
* \param olen The address at which to store the number of Bytes written. |
* \param buf The destination buffer. This must be a writable buffer of |
* length \p blen Bytes. |
* \param blen The length of the destination buffer \p buf in Bytes. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL in case \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
*/ |
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function parses the ECDHE parameters in a |
* TLS ServerKeyExchange handshake message. |
* |
* \note In a TLS handshake, this is the how the client |
* sets up its ECDHE context from the server's public |
* ECDHE key material. |
* |
* \see ecp.h |
* |
* \param ctx The ECDHE context to use. This must be initialized. |
* \param buf On input, \c *buf must be the start of the input buffer. |
* On output, \c *buf is updated to point to the end of the |
* data that has been read. On success, this is the first byte |
* past the end of the ServerKeyExchange parameters. |
* On error, this is the point at which an error has been |
* detected, which is usually not useful except to debug |
* failures. |
* \param end The end of the input buffer. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. |
* |
*/ |
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, |
const unsigned char **buf, |
const unsigned char *end ); |
/** |
* \brief This function sets up an ECDH context from an EC key. |
* |
* It is used by clients and servers in place of the |
* ServerKeyEchange for static ECDH, and imports ECDH |
* parameters from the EC key information of a certificate. |
* |
* \see ecp.h |
* |
* \param ctx The ECDH context to set up. This must be initialized. |
* \param key The EC key to use. This must be initialized. |
* \param side Defines the source of the key. Possible values are: |
* - #MBEDTLS_ECDH_OURS: The key is ours. |
* - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. |
* |
* \return \c 0 on success. |
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
* |
*/ |
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, |
const mbedtls_ecp_keypair *key, |
mbedtls_ecdh_side side ); |
/** |
* \brief This function generates a public key and exports it |
* as a TLS ClientKeyExchange payload. |
* |
* This is the second function used by a TLS client for ECDH(E) |
* ciphersuites. |
* |
* \see ecp.h |
* |
* \param ctx The ECDH context to use. This must be initialized |
* and bound to a group, the latter usually by |
* mbedtls_ecdh_read_params(). |
* \param olen The address at which to store the number of Bytes written. |
* This must not be \c NULL. |
* \param buf The destination buffer. This must be a writable buffer |
* of length \p blen Bytes. |
* \param blen The size of the destination buffer \p buf in Bytes. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL in case \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
*/ |
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function parses and processes the ECDHE payload of a |
* TLS ClientKeyExchange message. |
* |
* This is the third function used by a TLS server for ECDH(E) |
* ciphersuites. (It is called after mbedtls_ecdh_setup() and |
* mbedtls_ecdh_make_params().) |
* |
* \see ecp.h |
* |
* \param ctx The ECDH context to use. This must be initialized |
* and bound to a group, for example via mbedtls_ecdh_setup(). |
* \param buf The pointer to the ClientKeyExchange payload. This must |
* be a readable buffer of length \p blen Bytes. |
* \param blen The length of the input buffer \p buf in Bytes. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. |
*/ |
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, |
const unsigned char *buf, size_t blen ); |
/** |
* \brief This function derives and exports the shared secret. |
* |
* This is the last function used by both TLS client |
* and servers. |
* |
* \note If \p f_rng is not NULL, it is used to implement |
* countermeasures against side-channel attacks. |
* For more information, see mbedtls_ecp_mul(). |
* |
* \see ecp.h |
* \param ctx The ECDH context to use. This must be initialized |
* and have its own private key generated and the peer's |
* public key imported. |
* \param olen The address at which to store the total number of |
* Bytes written on success. This must not be \c NULL. |
* \param buf The buffer to write the generated shared key to. This |
* must be a writable buffer of size \p blen Bytes. |
* \param blen The length of the destination buffer \p buf in Bytes. |
* \param f_rng The RNG function, for blinding purposes. This may |
* b \c NULL if blinding isn't needed. |
* \param p_rng The RNG context. This may be \c NULL if \p f_rng |
* doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
*/ |
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief This function enables restartable EC computations for this |
* context. (Default: disabled.) |
* |
* \see \c mbedtls_ecp_set_max_ops() |
* |
* \note It is not possible to safely disable restartable |
* computations once enabled, except by free-ing the context, |
* which cancels possible in-progress operations. |
* |
* \param ctx The ECDH context to use. This must be initialized. |
*/ |
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ); |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* ecdh.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ecdsa.h |
---|
0,0 → 1,606 |
/** |
* \file ecdsa.h |
* |
* \brief This file contains ECDSA definitions and functions. |
* |
* The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in |
* <em>Standards for Efficient Cryptography Group (SECG): |
* SEC1 Elliptic Curve Cryptography</em>. |
* The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve |
* Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>. |
* |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ECDSA_H |
#define MBEDTLS_ECDSA_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ecp.h" |
#include "md.h" |
/* |
* RFC-4492 page 20: |
* |
* Ecdsa-Sig-Value ::= SEQUENCE { |
* r INTEGER, |
* s INTEGER |
* } |
* |
* Size is at most |
* 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s, |
* twice that + 1 (tag) + 2 (len) for the sequence |
* (assuming ECP_MAX_BYTES is less than 126 for r and s, |
* and less than 124 (total len <= 255) for the sequence) |
*/ |
#if MBEDTLS_ECP_MAX_BYTES > 124 |
#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN" |
#endif |
/** The maximal size of an ECDSA signature in Bytes. */ |
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) ) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief The ECDSA context structure. |
* |
* \warning Performing multiple operations concurrently on the same |
* ECDSA context is not supported; objects of this type |
* should not be shared between multiple threads. |
*/ |
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Internal restart context for ecdsa_verify() |
* |
* \note Opaque struct, defined in ecdsa.c |
*/ |
typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; |
/** |
* \brief Internal restart context for ecdsa_sign() |
* |
* \note Opaque struct, defined in ecdsa.c |
*/ |
typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
/** |
* \brief Internal restart context for ecdsa_sign_det() |
* |
* \note Opaque struct, defined in ecdsa.c |
*/ |
typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; |
#endif |
/** |
* \brief General context for resuming ECDSA operations |
*/ |
typedef struct |
{ |
mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and |
shared administrative info */ |
mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */ |
mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */ |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */ |
#endif |
} mbedtls_ecdsa_restart_ctx; |
#else /* MBEDTLS_ECP_RESTARTABLE */ |
/* Now we can declare functions that take a pointer to that */ |
typedef void mbedtls_ecdsa_restart_ctx; |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/** |
* \brief This function computes the ECDSA signature of a |
* previously-hashed message. |
* |
* \note The deterministic version implemented in |
* mbedtls_ecdsa_sign_det() is usually preferred. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated |
* as defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.3, step 5. |
* |
* \see ecp.h |
* |
* \param grp The context for the elliptic curve to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param r The MPI context in which to store the first part |
* the signature. This must be initialized. |
* \param s The MPI context in which to store the second part |
* the signature. This must be initialized. |
* \param d The private signing key. This must be initialized. |
* \param buf The content to be signed. This is usually the hash of |
* the original data to be signed. This must be a readable |
* buffer of length \p blen Bytes. It may be \c NULL if |
* \p blen is zero. |
* \param blen The length of \p buf in Bytes. |
* \param f_rng The RNG function. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng doesn't need a context parameter. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX |
* or \c MBEDTLS_MPI_XXX error code on failure. |
*/ |
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, |
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
/** |
* \brief This function computes the ECDSA signature of a |
* previously-hashed message, deterministic version. |
* |
* For more information, see <em>RFC-6979: Deterministic |
* Usage of the Digital Signature Algorithm (DSA) and Elliptic |
* Curve Digital Signature Algorithm (ECDSA)</em>. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated as |
* defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.3, step 5. |
* |
* \warning Since the output of the internal RNG is always the same for |
* the same key and message, this limits the efficiency of |
* blinding and leaks information through side channels. For |
* secure behavior use mbedtls_ecdsa_sign_det_ext() instead. |
* |
* (Optimally the blinding is a random value that is different |
* on every execution. In this case the blinding is still |
* random from the attackers perspective, but is the same on |
* each execution. This means that this blinding does not |
* prevent attackers from recovering secrets by combining |
* several measurement traces, but may prevent some attacks |
* that exploit relationships between secret data.) |
* |
* \see ecp.h |
* |
* \param grp The context for the elliptic curve to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param r The MPI context in which to store the first part |
* the signature. This must be initialized. |
* \param s The MPI context in which to store the second part |
* the signature. This must be initialized. |
* \param d The private signing key. This must be initialized |
* and setup, for example through mbedtls_ecp_gen_privkey(). |
* \param buf The hashed content to be signed. This must be a readable |
* buffer of length \p blen Bytes. It may be \c NULL if |
* \p blen is zero. |
* \param blen The length of \p buf in Bytes. |
* \param md_alg The hash algorithm used to hash the original data. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX |
* error code on failure. |
*/ |
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, |
mbedtls_mpi *s, const mbedtls_mpi *d, |
const unsigned char *buf, size_t blen, |
mbedtls_md_type_t md_alg ); |
/** |
* \brief This function computes the ECDSA signature of a |
* previously-hashed message, deterministic version. |
* |
* For more information, see <em>RFC-6979: Deterministic |
* Usage of the Digital Signature Algorithm (DSA) and Elliptic |
* Curve Digital Signature Algorithm (ECDSA)</em>. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated as |
* defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.3, step 5. |
* |
* \see ecp.h |
* |
* \param grp The context for the elliptic curve to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param r The MPI context in which to store the first part |
* the signature. This must be initialized. |
* \param s The MPI context in which to store the second part |
* the signature. This must be initialized. |
* \param d The private signing key. This must be initialized |
* and setup, for example through mbedtls_ecp_gen_privkey(). |
* \param buf The hashed content to be signed. This must be a readable |
* buffer of length \p blen Bytes. It may be \c NULL if |
* \p blen is zero. |
* \param blen The length of \p buf in Bytes. |
* \param md_alg The hash algorithm used to hash the original data. |
* \param f_rng_blind The RNG function used for blinding. This must not be |
* \c NULL. |
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng doesn't need a context parameter. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX |
* error code on failure. |
*/ |
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, |
mbedtls_mpi *s, const mbedtls_mpi *d, |
const unsigned char *buf, size_t blen, |
mbedtls_md_type_t md_alg, |
int (*f_rng_blind)(void *, unsigned char *, |
size_t), |
void *p_rng_blind ); |
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ |
/** |
* \brief This function verifies the ECDSA signature of a |
* previously-hashed message. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated as |
* defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.4, step 3. |
* |
* \see ecp.h |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param buf The hashed content that was signed. This must be a readable |
* buffer of length \p blen Bytes. It may be \c NULL if |
* \p blen is zero. |
* \param blen The length of \p buf in Bytes. |
* \param Q The public key to use for verification. This must be |
* initialized and setup. |
* \param r The first integer of the signature. |
* This must be initialized. |
* \param s The second integer of the signature. |
* This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature |
* is invalid. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX |
* error code on failure for any other reason. |
*/ |
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, |
const unsigned char *buf, size_t blen, |
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, |
const mbedtls_mpi *s); |
/** |
* \brief This function computes the ECDSA signature and writes it |
* to a buffer, serialized as defined in <em>RFC-4492: |
* Elliptic Curve Cryptography (ECC) Cipher Suites for |
* Transport Layer Security (TLS)</em>. |
* |
* \warning It is not thread-safe to use the same context in |
* multiple threads. |
* |
* \note The deterministic version is used if |
* #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more |
* information, see <em>RFC-6979: Deterministic Usage |
* of the Digital Signature Algorithm (DSA) and Elliptic |
* Curve Digital Signature Algorithm (ECDSA)</em>. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated as |
* defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.3, step 5. |
* |
* \see ecp.h |
* |
* \param ctx The ECDSA context to use. This must be initialized |
* and have a group and private key bound to it, for example |
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). |
* \param md_alg The message digest that was used to hash the message. |
* \param hash The message hash to be signed. This must be a readable |
* buffer of length \p blen Bytes. |
* \param hlen The length of the hash \p hash in Bytes. |
* \param sig The buffer to which to write the signature. This must be a |
* writable buffer of length at least twice as large as the |
* size of the curve used, plus 9. For example, 73 Bytes if |
* a 256-bit curve is used. A buffer length of |
* #MBEDTLS_ECDSA_MAX_LEN is always safe. |
* \param slen The address at which to store the actual length of |
* the signature written. Must not be \c NULL. |
* \param f_rng The RNG function. This must not be \c NULL if |
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, |
* it is unused and may be set to \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't use a context. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or |
* \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hlen, |
unsigned char *sig, size_t *slen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function computes the ECDSA signature and writes it |
* to a buffer, in a restartable way. |
* |
* \see \c mbedtls_ecdsa_write_signature() |
* |
* \note This function is like \c mbedtls_ecdsa_write_signature() |
* but it can return early and restart according to the limit |
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking. |
* |
* \param ctx The ECDSA context to use. This must be initialized |
* and have a group and private key bound to it, for example |
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). |
* \param md_alg The message digest that was used to hash the message. |
* \param hash The message hash to be signed. This must be a readable |
* buffer of length \p blen Bytes. |
* \param hlen The length of the hash \p hash in Bytes. |
* \param sig The buffer to which to write the signature. This must be a |
* writable buffer of length at least twice as large as the |
* size of the curve used, plus 9. For example, 73 Bytes if |
* a 256-bit curve is used. A buffer length of |
* #MBEDTLS_ECDSA_MAX_LEN is always safe. |
* \param slen The address at which to store the actual length of |
* the signature written. Must not be \c NULL. |
* \param f_rng The RNG function. This must not be \c NULL if |
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, |
* it is unused and may be set to \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't use a context. |
* \param rs_ctx The restart context to use. This may be \c NULL to disable |
* restarting. If it is not \c NULL, it must point to an |
* initialized restart context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or |
* \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hlen, |
unsigned char *sig, size_t *slen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecdsa_restart_ctx *rs_ctx ); |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function computes an ECDSA signature and writes |
* it to a buffer, serialized as defined in <em>RFC-4492: |
* Elliptic Curve Cryptography (ECC) Cipher Suites for |
* Transport Layer Security (TLS)</em>. |
* |
* The deterministic version is defined in <em>RFC-6979: |
* Deterministic Usage of the Digital Signature Algorithm (DSA) |
* and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>. |
* |
* \warning It is not thread-safe to use the same context in |
* multiple threads. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated as |
* defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.3, step 5. |
* |
* \see ecp.h |
* |
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in |
* Mbed TLS version 2.0 and later. |
* |
* \param ctx The ECDSA context to use. This must be initialized |
* and have a group and private key bound to it, for example |
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). |
* \param hash The message hash to be signed. This must be a readable |
* buffer of length \p blen Bytes. |
* \param hlen The length of the hash \p hash in Bytes. |
* \param sig The buffer to which to write the signature. This must be a |
* writable buffer of length at least twice as large as the |
* size of the curve used, plus 9. For example, 73 Bytes if |
* a 256-bit curve is used. A buffer length of |
* #MBEDTLS_ECDSA_MAX_LEN is always safe. |
* \param slen The address at which to store the actual length of |
* the signature written. Must not be \c NULL. |
* \param md_alg The message digest that was used to hash the message. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or |
* \c MBEDTLS_ERR_ASN1_XXX error code on failure. |
*/ |
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, |
const unsigned char *hash, size_t hlen, |
unsigned char *sig, size_t *slen, |
mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED; |
#undef MBEDTLS_DEPRECATED |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ |
/** |
* \brief This function reads and verifies an ECDSA signature. |
* |
* \note If the bitlength of the message hash is larger than the |
* bitlength of the group order, then the hash is truncated as |
* defined in <em>Standards for Efficient Cryptography Group |
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section |
* 4.1.4, step 3. |
* |
* \see ecp.h |
* |
* \param ctx The ECDSA context to use. This must be initialized |
* and have a group and public key bound to it. |
* \param hash The message hash that was signed. This must be a readable |
* buffer of length \p size Bytes. |
* \param hlen The size of the hash \p hash. |
* \param sig The signature to read and verify. This must be a readable |
* buffer of length \p slen Bytes. |
* \param slen The size of \p sig in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. |
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid |
* signature in \p sig, but its length is less than \p siglen. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX |
* error code on failure for any other reason. |
*/ |
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, |
const unsigned char *hash, size_t hlen, |
const unsigned char *sig, size_t slen ); |
/** |
* \brief This function reads and verifies an ECDSA signature, |
* in a restartable way. |
* |
* \see \c mbedtls_ecdsa_read_signature() |
* |
* \note This function is like \c mbedtls_ecdsa_read_signature() |
* but it can return early and restart according to the limit |
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking. |
* |
* \param ctx The ECDSA context to use. This must be initialized |
* and have a group and public key bound to it. |
* \param hash The message hash that was signed. This must be a readable |
* buffer of length \p size Bytes. |
* \param hlen The size of the hash \p hash. |
* \param sig The signature to read and verify. This must be a readable |
* buffer of length \p slen Bytes. |
* \param slen The size of \p sig in Bytes. |
* \param rs_ctx The restart context to use. This may be \c NULL to disable |
* restarting. If it is not \c NULL, it must point to an |
* initialized restart context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. |
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid |
* signature in \p sig, but its length is less than \p siglen. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX |
* error code on failure for any other reason. |
*/ |
int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, |
const unsigned char *hash, size_t hlen, |
const unsigned char *sig, size_t slen, |
mbedtls_ecdsa_restart_ctx *rs_ctx ); |
/** |
* \brief This function generates an ECDSA keypair on the given curve. |
* |
* \see ecp.h |
* |
* \param ctx The ECDSA context to store the keypair in. |
* This must be initialized. |
* \param gid The elliptic curve to use. One of the various |
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure. |
*/ |
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
/** |
* \brief This function sets up an ECDSA context from an EC key pair. |
* |
* \see ecp.h |
* |
* \param ctx The ECDSA context to setup. This must be initialized. |
* \param key The EC key to use. This must be initialized and hold |
* a private-public key pair or a public key. In the former |
* case, the ECDSA context may be used for signature creation |
* and verification after this call. In the latter case, it |
* may be used for signature verification. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure. |
*/ |
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, |
const mbedtls_ecp_keypair *key ); |
/** |
* \brief This function initializes an ECDSA context. |
* |
* \param ctx The ECDSA context to initialize. |
* This must not be \c NULL. |
*/ |
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ); |
/** |
* \brief This function frees an ECDSA context. |
* |
* \param ctx The ECDSA context to free. This may be \c NULL, |
* in which case this function does nothing. If it |
* is not \c NULL, it must be initialized. |
*/ |
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Initialize a restart context. |
* |
* \param ctx The restart context to initialize. |
* This must not be \c NULL. |
*/ |
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ); |
/** |
* \brief Free the components of a restart context. |
* |
* \param ctx The restart context to free. This may be \c NULL, |
* in which case this function does nothing. If it |
* is not \c NULL, it must be initialized. |
*/ |
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ); |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* ecdsa.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ecjpake.h |
---|
0,0 → 1,279 |
/** |
* \file ecjpake.h |
* |
* \brief Elliptic curve J-PAKE |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ECJPAKE_H |
#define MBEDTLS_ECJPAKE_H |
/* |
* J-PAKE is a password-authenticated key exchange that allows deriving a |
* strong shared secret from a (potentially low entropy) pre-shared |
* passphrase, with forward secrecy and mutual authentication. |
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling |
* |
* This file implements the Elliptic Curve variant of J-PAKE, |
* as defined in Chapter 7.4 of the Thread v1.0 Specification, |
* available to members of the Thread Group http://threadgroup.org/ |
* |
* As the J-PAKE algorithm is inherently symmetric, so is our API. |
* Each party needs to send its first round message, in any order, to the |
* other party, then each sends its second round message, in any order. |
* The payloads are serialized in a way suitable for use in TLS, but could |
* also be use outside TLS. |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ecp.h" |
#include "md.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Roles in the EC J-PAKE exchange |
*/ |
typedef enum { |
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */ |
MBEDTLS_ECJPAKE_SERVER, /**< Server */ |
} mbedtls_ecjpake_role; |
#if !defined(MBEDTLS_ECJPAKE_ALT) |
/** |
* EC J-PAKE context structure. |
* |
* J-PAKE is a symmetric protocol, except for the identifiers used in |
* Zero-Knowledge Proofs, and the serialization of the second message |
* (KeyExchange) as defined by the Thread spec. |
* |
* In order to benefit from this symmetry, we choose a different naming |
* convetion from the Thread v1.0 spec. Correspondance is indicated in the |
* description as a pair C: client name, S: server name |
*/ |
typedef struct mbedtls_ecjpake_context |
{ |
const mbedtls_md_info_t *md_info; /**< Hash to use */ |
mbedtls_ecp_group grp; /**< Elliptic curve */ |
mbedtls_ecjpake_role role; /**< Are we client or server? */ |
int point_format; /**< Format for point export */ |
mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */ |
mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */ |
mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */ |
mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */ |
mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */ |
mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */ |
mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */ |
mbedtls_mpi s; /**< Pre-shared secret (passphrase) */ |
} mbedtls_ecjpake_context; |
#else /* MBEDTLS_ECJPAKE_ALT */ |
#include "ecjpake_alt.h" |
#endif /* MBEDTLS_ECJPAKE_ALT */ |
/** |
* \brief Initialize an ECJPAKE context. |
* |
* \param ctx The ECJPAKE context to initialize. |
* This must not be \c NULL. |
*/ |
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ); |
/** |
* \brief Set up an ECJPAKE context for use. |
* |
* \note Currently the only values for hash/curve allowed by the |
* standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1. |
* |
* \param ctx The ECJPAKE context to set up. This must be initialized. |
* \param role The role of the caller. This must be either |
* #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER. |
* \param hash The identifier of the hash function to use, |
* for example #MBEDTLS_MD_SHA256. |
* \param curve The identifier of the elliptic curve to use, |
* for example #MBEDTLS_ECP_DP_SECP256R1. |
* \param secret The pre-shared secret (passphrase). This must be |
* a readable buffer of length \p len Bytes. It need |
* only be valid for the duration of this call. |
* \param len The length of the pre-shared secret \p secret. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, |
mbedtls_ecjpake_role role, |
mbedtls_md_type_t hash, |
mbedtls_ecp_group_id curve, |
const unsigned char *secret, |
size_t len ); |
/** |
* \brief Check if an ECJPAKE context is ready for use. |
* |
* \param ctx The ECJPAKE context to check. This must be |
* initialized. |
* |
* \return \c 0 if the context is ready for use. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise. |
*/ |
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ); |
/** |
* \brief Generate and write the first round message |
* (TLS: contents of the Client/ServerHello extension, |
* excluding extension type and length bytes). |
* |
* \param ctx The ECJPAKE context to use. This must be |
* initialized and set up. |
* \param buf The buffer to write the contents to. This must be a |
* writable buffer of length \p len Bytes. |
* \param len The length of \p buf in Bytes. |
* \param olen The address at which to store the total number |
* of Bytes written to \p buf. This must not be \c NULL. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. This |
* may be \c NULL if \p f_rng doesn't use a context. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, |
unsigned char *buf, size_t len, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Read and process the first round message |
* (TLS: contents of the Client/ServerHello extension, |
* excluding extension type and length bytes). |
* |
* \param ctx The ECJPAKE context to use. This must be initialized |
* and set up. |
* \param buf The buffer holding the first round message. This must |
* be a readable buffer of length \p len Bytes. |
* \param len The length in Bytes of \p buf. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, |
const unsigned char *buf, |
size_t len ); |
/** |
* \brief Generate and write the second round message |
* (TLS: contents of the Client/ServerKeyExchange). |
* |
* \param ctx The ECJPAKE context to use. This must be initialized, |
* set up, and already have performed round one. |
* \param buf The buffer to write the round two contents to. |
* This must be a writable buffer of length \p len Bytes. |
* \param len The size of \p buf in Bytes. |
* \param olen The address at which to store the total number of Bytes |
* written to \p buf. This must not be \c NULL. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. This |
* may be \c NULL if \p f_rng doesn't use a context. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, |
unsigned char *buf, size_t len, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Read and process the second round message |
* (TLS: contents of the Client/ServerKeyExchange). |
* |
* \param ctx The ECJPAKE context to use. This must be initialized |
* and set up and already have performed round one. |
* \param buf The buffer holding the second round message. This must |
* be a readable buffer of length \p len Bytes. |
* \param len The length in Bytes of \p buf. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, |
const unsigned char *buf, |
size_t len ); |
/** |
* \brief Derive the shared secret |
* (TLS: Pre-Master Secret). |
* |
* \param ctx The ECJPAKE context to use. This must be initialized, |
* set up and have performed both round one and two. |
* \param buf The buffer to write the derived secret to. This must |
* be a writable buffer of length \p len Bytes. |
* \param len The length of \p buf in Bytes. |
* \param olen The address at which to store the total number of Bytes |
* written to \p buf. This must not be \c NULL. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. This |
* may be \c NULL if \p f_rng doesn't use a context. |
* |
* \return \c 0 if successful. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, |
unsigned char *buf, size_t len, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This clears an ECJPAKE context and frees any |
* embedded data structure. |
* |
* \param ctx The ECJPAKE context to free. This may be \c NULL, |
* in which case this function does nothing. If it is not |
* \c NULL, it must point to an initialized ECJPAKE context. |
*/ |
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if a test failed |
*/ |
int mbedtls_ecjpake_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* ecjpake.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ecp.h |
---|
0,0 → 1,1134 |
/** |
* \file ecp.h |
* |
* \brief This file provides an API for Elliptic Curves over GF(P) (ECP). |
* |
* The use of ECP in cryptography and TLS is defined in |
* <em>Standards for Efficient Cryptography Group (SECG): SEC1 |
* Elliptic Curve Cryptography</em> and |
* <em>RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites |
* for Transport Layer Security (TLS)</em>. |
* |
* <em>RFC-2409: The Internet Key Exchange (IKE)</em> defines ECP |
* group types. |
* |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ECP_H |
#define MBEDTLS_ECP_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "bignum.h" |
/* |
* ECP error codes |
*/ |
#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */ |
#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< The requested feature is not available, for example, the requested curve is not supported. */ |
#define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */ |
#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */ |
#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as ephemeral key, failed. */ |
#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ |
#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */ |
/* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< The ECP hardware accelerator failed. */ |
#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 /**< Operation in progress, call again with the same parameters to continue. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Domain-parameter identifiers: curve, subgroup, and generator. |
* |
* \note Only curves over prime fields are supported. |
* |
* \warning This library does not support validation of arbitrary domain |
* parameters. Therefore, only standardized domain parameters from trusted |
* sources should be used. See mbedtls_ecp_group_load(). |
*/ |
typedef enum |
{ |
MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */ |
MBEDTLS_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ |
MBEDTLS_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ |
MBEDTLS_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ |
MBEDTLS_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ |
MBEDTLS_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */ |
MBEDTLS_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */ |
MBEDTLS_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */ |
MBEDTLS_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */ |
MBEDTLS_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */ |
MBEDTLS_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */ |
MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ |
MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ |
MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ |
} mbedtls_ecp_group_id; |
/** |
* The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE. |
* |
* \note Montgomery curves are currently excluded. |
*/ |
#define MBEDTLS_ECP_DP_MAX 12 |
/** |
* Curve information, for use by other modules. |
*/ |
typedef struct mbedtls_ecp_curve_info |
{ |
mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ |
uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ |
uint16_t bit_size; /*!< The curve size in bits. */ |
const char *name; /*!< A human-friendly name. */ |
} mbedtls_ecp_curve_info; |
/** |
* \brief The ECP point structure, in Jacobian coordinates. |
* |
* \note All functions expect and return points satisfying |
* the following condition: <code>Z == 0</code> or |
* <code>Z == 1</code>. Other values of \p Z are |
* used only by internal functions. |
* The point is zero, or "at infinity", if <code>Z == 0</code>. |
* Otherwise, \p X and \p Y are its standard (affine) |
* coordinates. |
*/ |
typedef struct mbedtls_ecp_point |
{ |
mbedtls_mpi X; /*!< The X coordinate of the ECP point. */ |
mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */ |
mbedtls_mpi Z; /*!< The Z coordinate of the ECP point. */ |
} |
mbedtls_ecp_point; |
#if !defined(MBEDTLS_ECP_ALT) |
/* |
* default mbed TLS elliptic curve arithmetic implementation |
* |
* (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an |
* alternative implementation for the whole module and it will replace this |
* one.) |
*/ |
/** |
* \brief The ECP group structure. |
* |
* We consider two types of curve equations: |
* <ul><li>Short Weierstrass: <code>y^2 = x^3 + A x + B mod P</code> |
* (SEC1 + RFC-4492)</li> |
* <li>Montgomery: <code>y^2 = x^3 + A x^2 + x mod P</code> (Curve25519, |
* Curve448)</li></ul> |
* In both cases, the generator (\p G) for a prime-order subgroup is fixed. |
* |
* For Short Weierstrass, this subgroup is the whole curve, and its |
* cardinality is denoted by \p N. Our code requires that \p N is an |
* odd prime as mbedtls_ecp_mul() requires an odd number, and |
* mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. |
* |
* For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>, |
* which is the quantity used in the formulas. Additionally, \p nbits is |
* not the size of \p N but the required size for private keys. |
* |
* If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. |
* Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the |
* range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer |
* which is congruent mod \p P to the given MPI, and is close enough to \p pbits |
* in size, so that it may be efficiently brought in the 0..P-1 range by a few |
* additions or subtractions. Therefore, it is only an approximative modular |
* reduction. It must return 0 on success and non-zero on failure. |
* |
* \note Alternative implementations must keep the group IDs distinct. If |
* two group structures have the same ID, then they must be |
* identical. |
* |
*/ |
typedef struct mbedtls_ecp_group |
{ |
mbedtls_ecp_group_id id; /*!< An internal group identifier. */ |
mbedtls_mpi P; /*!< The prime modulus of the base field. */ |
mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For |
Montgomery curves: <code>(A + 2) / 4</code>. */ |
mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. |
For Montgomery curves: unused. */ |
mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ |
mbedtls_mpi N; /*!< The order of \p G. */ |
size_t pbits; /*!< The number of bits in \p P.*/ |
size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. |
For Montgomery curves: the number of bits in the |
private keys. */ |
unsigned int h; /*!< \internal 1 if the constants are static. */ |
int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction |
mod \p P (see above).*/ |
int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */ |
int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */ |
void *t_data; /*!< Unused. */ |
mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */ |
size_t T_size; /*!< The number of pre-computed points. */ |
} |
mbedtls_ecp_group; |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h, or define them using the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_ECP_MAX_BITS) |
/** |
* The maximum size of the groups, that is, of \c N and \c P. |
*/ |
#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ |
#endif |
#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) |
#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) |
#if !defined(MBEDTLS_ECP_WINDOW_SIZE) |
/* |
* Maximum "window" size used for point multiplication. |
* Default: 6. |
* Minimum value: 2. Maximum value: 7. |
* |
* Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) |
* points used for point multiplication. This value is directly tied to EC |
* peak memory usage, so decreasing it by one should roughly cut memory usage |
* by two (if large curves are in use). |
* |
* Reduction in size may reduce speed, but larger curves are impacted first. |
* Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): |
* w-size: 6 5 4 3 2 |
* 521 145 141 135 120 97 |
* 384 214 209 198 177 146 |
* 256 320 320 303 262 226 |
* 224 475 475 453 398 342 |
* 192 640 640 633 587 476 |
*/ |
#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ |
#endif /* MBEDTLS_ECP_WINDOW_SIZE */ |
#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) |
/* |
* Trade memory for speed on fixed-point multiplication. |
* |
* This speeds up repeated multiplication of the generator (that is, the |
* multiplication in ECDSA signatures, and half of the multiplications in |
* ECDSA verification and ECDHE) by a factor roughly 3 to 4. |
* |
* The cost is increasing EC peak memory usage by a factor roughly 2. |
* |
* Change this value to 0 to reduce peak memory usage. |
*/ |
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ |
#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ |
/* \} name SECTION: Module settings */ |
#else /* MBEDTLS_ECP_ALT */ |
#include "ecp_alt.h" |
#endif /* MBEDTLS_ECP_ALT */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Internal restart context for multiplication |
* |
* \note Opaque struct |
*/ |
typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx; |
/** |
* \brief Internal restart context for ecp_muladd() |
* |
* \note Opaque struct |
*/ |
typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx; |
/** |
* \brief General context for resuming ECC operations |
*/ |
typedef struct |
{ |
unsigned ops_done; /*!< current ops count */ |
unsigned depth; /*!< call depth (0 = top-level) */ |
mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */ |
mbedtls_ecp_restart_muladd_ctx *ma; /*!< ecp_muladd() sub-context */ |
} mbedtls_ecp_restart_ctx; |
/* |
* Operation counts for restartable functions |
*/ |
#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */ |
#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */ |
#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */ |
#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */ |
/** |
* \brief Internal; for restartable functions in other modules. |
* Check and update basic ops budget. |
* |
* \param grp Group structure |
* \param rs_ctx Restart context |
* \param ops Number of basic ops to do |
* |
* \return \c 0 if doing \p ops basic ops is still allowed, |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise. |
*/ |
int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, |
mbedtls_ecp_restart_ctx *rs_ctx, |
unsigned ops ); |
/* Utility macro for checking and updating ops budget */ |
#define MBEDTLS_ECP_BUDGET( ops ) \ |
MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, rs_ctx, \ |
(unsigned) (ops) ) ); |
#else /* MBEDTLS_ECP_RESTARTABLE */ |
#define MBEDTLS_ECP_BUDGET( ops ) /* no-op; for compatibility */ |
/* We want to declare restartable versions of existing functions anyway */ |
typedef void mbedtls_ecp_restart_ctx; |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/** |
* \brief The ECP key-pair structure. |
* |
* A generic key-pair that may be used for ECDSA and fixed ECDH, for example. |
* |
* \note Members are deliberately in the same order as in the |
* ::mbedtls_ecdsa_context structure. |
*/ |
typedef struct mbedtls_ecp_keypair |
{ |
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ |
mbedtls_mpi d; /*!< our secret value */ |
mbedtls_ecp_point Q; /*!< our public value */ |
} |
mbedtls_ecp_keypair; |
/* |
* Point formats, from RFC 4492's enum ECPointFormat |
*/ |
#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */ |
#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format. */ |
/* |
* Some other constants from RFC 4492 |
*/ |
#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Set the maximum number of basic operations done in a row. |
* |
* If more operations are needed to complete a computation, |
* #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the |
* function performing the computation. It is then the |
* caller's responsibility to either call again with the same |
* parameters until it returns 0 or an error code; or to free |
* the restart context if the operation is to be aborted. |
* |
* It is strictly required that all input parameters and the |
* restart context be the same on successive calls for the |
* same operation, but output parameters need not be the |
* same; they must not be used until the function finally |
* returns 0. |
* |
* This only applies to functions whose documentation |
* mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the |
* SSL module). For functions that accept a "restart context" |
* argument, passing NULL disables restart and makes the |
* function equivalent to the function with the same name |
* with \c _restartable removed. For functions in the ECDH |
* module, restart is disabled unless the function accepts |
* an "ECDH context" argument and |
* mbedtls_ecdh_enable_restart() was previously called on |
* that context. For function in the SSL module, restart is |
* only enabled for specific sides and key exchanges |
* (currently only for clients and ECDHE-ECDSA). |
* |
* \param max_ops Maximum number of basic operations done in a row. |
* Default: 0 (unlimited). |
* Lower (non-zero) values mean ECC functions will block for |
* a lesser maximum amount of time. |
* |
* \note A "basic operation" is defined as a rough equivalent of a |
* multiplication in GF(p) for the NIST P-256 curve. |
* As an indication, with default settings, a scalar |
* multiplication (full run of \c mbedtls_ecp_mul()) is: |
* - about 3300 basic operations for P-256 |
* - about 9400 basic operations for P-384 |
* |
* \note Very low values are not always respected: sometimes |
* functions need to block for a minimum number of |
* operations, and will do so even if max_ops is set to a |
* lower value. That minimum depends on the curve size, and |
* can be made lower by decreasing the value of |
* \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the |
* lowest effective value for various curves and values of |
* that parameter (w for short): |
* w=6 w=5 w=4 w=3 w=2 |
* P-256 208 208 160 136 124 |
* P-384 682 416 320 272 248 |
* P-521 1364 832 640 544 496 |
* |
* \note This setting is currently ignored by Curve25519. |
*/ |
void mbedtls_ecp_set_max_ops( unsigned max_ops ); |
/** |
* \brief Check if restart is enabled (max_ops != 0) |
* |
* \return \c 0 if \c max_ops == 0 (restart disabled) |
* \return \c 1 otherwise (restart enabled) |
*/ |
int mbedtls_ecp_restart_is_enabled( void ); |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/** |
* \brief This function retrieves the information defined in |
* mbedtls_ecp_curve_info() for all supported curves in order |
* of preference. |
* |
* \return A statically allocated array. The last entry is 0. |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ); |
/** |
* \brief This function retrieves the list of internal group |
* identifiers of all supported curves in the order of |
* preference. |
* |
* \return A statically allocated array, |
* terminated with MBEDTLS_ECP_DP_NONE. |
*/ |
const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ); |
/** |
* \brief This function retrieves curve information from an internal |
* group identifier. |
* |
* \param grp_id An \c MBEDTLS_ECP_DP_XXX value. |
* |
* \return The associated curve information on success. |
* \return NULL on failure. |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ); |
/** |
* \brief This function retrieves curve information from a TLS |
* NamedCurve value. |
* |
* \param tls_id An \c MBEDTLS_ECP_DP_XXX value. |
* |
* \return The associated curve information on success. |
* \return NULL on failure. |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ); |
/** |
* \brief This function retrieves curve information from a |
* human-readable name. |
* |
* \param name The human-readable name. |
* |
* \return The associated curve information on success. |
* \return NULL on failure. |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ); |
/** |
* \brief This function initializes a point as zero. |
* |
* \param pt The point to initialize. |
*/ |
void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); |
/** |
* \brief This function initializes an ECP group context |
* without loading any domain parameters. |
* |
* \note After this function is called, domain parameters |
* for various ECP groups can be loaded through the |
* mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() |
* functions. |
*/ |
void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); |
/** |
* \brief This function initializes a key pair as an invalid one. |
* |
* \param key The key pair to initialize. |
*/ |
void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ); |
/** |
* \brief This function frees the components of a point. |
* |
* \param pt The point to free. |
*/ |
void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); |
/** |
* \brief This function frees the components of an ECP group. |
* |
* \param grp The group to free. This may be \c NULL, in which |
* case this function returns immediately. If it is not |
* \c NULL, it must point to an initialized ECP group. |
*/ |
void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); |
/** |
* \brief This function frees the components of a key pair. |
* |
* \param key The key pair to free. This may be \c NULL, in which |
* case this function returns immediately. If it is not |
* \c NULL, it must point to an initialized ECP key pair. |
*/ |
void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Initialize a restart context. |
* |
* \param ctx The restart context to initialize. This must |
* not be \c NULL. |
*/ |
void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ); |
/** |
* \brief Free the components of a restart context. |
* |
* \param ctx The restart context to free. This may be \c NULL, in which |
* case this function returns immediately. If it is not |
* \c NULL, it must point to an initialized restart context. |
*/ |
void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/** |
* \brief This function copies the contents of point \p Q into |
* point \p P. |
* |
* \param P The destination point. This must be initialized. |
* \param Q The source point. This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return Another negative error code for other kinds of failure. |
*/ |
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); |
/** |
* \brief This function copies the contents of group \p src into |
* group \p dst. |
* |
* \param dst The destination group. This must be initialized. |
* \param src The source group. This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, |
const mbedtls_ecp_group *src ); |
/** |
* \brief This function sets a point to the point at infinity. |
* |
* \param pt The point to set. This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ); |
/** |
* \brief This function checks if a point is the point at infinity. |
* |
* \param pt The point to test. This must be initialized. |
* |
* \return \c 1 if the point is zero. |
* \return \c 0 if the point is non-zero. |
* \return A negative error code on failure. |
*/ |
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); |
/** |
* \brief This function compares two points. |
* |
* \note This assumes that the points are normalized. Otherwise, |
* they may compare as "not equal" even if they are. |
* |
* \param P The first point to compare. This must be initialized. |
* \param Q The second point to compare. This must be initialized. |
* |
* \return \c 0 if the points are equal. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. |
*/ |
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, |
const mbedtls_ecp_point *Q ); |
/** |
* \brief This function imports a non-zero point from two ASCII |
* strings. |
* |
* \param P The destination point. This must be initialized. |
* \param radix The numeric base of the input. |
* \param x The first affine coordinate, as a null-terminated string. |
* \param y The second affine coordinate, as a null-terminated string. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_MPI_XXX error code on failure. |
*/ |
int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, |
const char *x, const char *y ); |
/** |
* \brief This function exports a point into unsigned binary data. |
* |
* \param grp The group to which the point should belong. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param P The point to export. This must be initialized. |
* \param format The point format. This must be either |
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. |
* \param olen The address at which to store the length of |
* the output in Bytes. This must not be \c NULL. |
* \param buf The output buffer. This must be a writable buffer |
* of length \p buflen Bytes. |
* \param buflen The length of the output buffer \p buf in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer |
* is too small to hold the point. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, |
int format, size_t *olen, |
unsigned char *buf, size_t buflen ); |
/** |
* \brief This function imports a point from unsigned binary data. |
* |
* \note This function does not check that the point actually |
* belongs to the given group, see mbedtls_ecp_check_pubkey() |
* for that. |
* |
* \param grp The group to which the point should belong. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param P The destination context to import the point to. |
* This must be initialized. |
* \param buf The input buffer. This must be a readable buffer |
* of length \p ilen Bytes. |
* \param ilen The length of the input buffer \p buf in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format |
* is not implemented. |
*/ |
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *P, |
const unsigned char *buf, size_t ilen ); |
/** |
* \brief This function imports a point from a TLS ECPoint record. |
* |
* \note On function return, \p *buf is updated to point immediately |
* after the ECPoint record. |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param pt The destination point. |
* \param buf The address of the pointer to the start of the input buffer. |
* \param len The length of the buffer. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization |
* failure. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. |
*/ |
int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *pt, |
const unsigned char **buf, size_t len ); |
/** |
* \brief This function exports a point as a TLS ECPoint record |
* defined in RFC 4492, Section 5.4. |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param pt The point to be exported. This must be initialized. |
* \param format The point format to use. This must be either |
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. |
* \param olen The address at which to store the length in Bytes |
* of the data written. |
* \param buf The target buffer. This must be a writable buffer of |
* length \p blen Bytes. |
* \param blen The length of the target buffer \p buf in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. |
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer |
* is too small to hold the exported point. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, |
const mbedtls_ecp_point *pt, |
int format, size_t *olen, |
unsigned char *buf, size_t blen ); |
/** |
* \brief This function sets up an ECP group context |
* from a standardized set of domain parameters. |
* |
* \note The index should be a value of the NamedCurve enum, |
* as defined in <em>RFC-4492: Elliptic Curve Cryptography |
* (ECC) Cipher Suites for Transport Layer Security (TLS)</em>, |
* usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. |
* |
* \param grp The group context to setup. This must be initialized. |
* \param id The identifier of the domain parameter set to load. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't |
* correspond to a known group. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); |
/** |
* \brief This function sets up an ECP group context from a TLS |
* ECParameters record as defined in RFC 4492, Section 5.4. |
* |
* \note The read pointer \p buf is updated to point right after |
* the ECParameters record on exit. |
* |
* \param grp The group context to setup. This must be initialized. |
* \param buf The address of the pointer to the start of the input buffer. |
* \param len The length of the input buffer \c *buf in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. |
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not |
* recognized. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, |
const unsigned char **buf, size_t len ); |
/** |
* \brief This function extracts an elliptic curve group ID from a |
* TLS ECParameters record as defined in RFC 4492, Section 5.4. |
* |
* \note The read pointer \p buf is updated to point right after |
* the ECParameters record on exit. |
* |
* \param grp The address at which to store the group id. |
* This must not be \c NULL. |
* \param buf The address of the pointer to the start of the input buffer. |
* \param len The length of the input buffer \c *buf in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. |
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not |
* recognized. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, |
const unsigned char **buf, |
size_t len ); |
/** |
* \brief This function exports an elliptic curve as a TLS |
* ECParameters record as defined in RFC 4492, Section 5.4. |
* |
* \param grp The ECP group to be exported. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param olen The address at which to store the number of Bytes written. |
* This must not be \c NULL. |
* \param buf The buffer to write to. This must be a writable buffer |
* of length \p blen Bytes. |
* \param blen The length of the output buffer \p buf in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output |
* buffer is too small to hold the exported group. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, |
size_t *olen, |
unsigned char *buf, size_t blen ); |
/** |
* \brief This function performs a scalar multiplication of a point |
* by an integer: \p R = \p m * \p P. |
* |
* It is not thread-safe to use same group in multiple threads. |
* |
* \note To prevent timing attacks, this function |
* executes the exact same sequence of base-field |
* operations for any valid \p m. It avoids any if-branch or |
* array index depending on the value of \p m. |
* |
* \note If \p f_rng is not NULL, it is used to randomize |
* intermediate results to prevent potential timing attacks |
* targeting these results. We recommend always providing |
* a non-NULL \p f_rng. The overhead is negligible. |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param R The point in which to store the result of the calculation. |
* This must be initialized. |
* \param m The integer by which to multiply. This must be initialized. |
* \param P The point to multiply. This must be initialized. |
* \param f_rng The RNG function. This may be \c NULL if randomization |
* of intermediate results isn't desired (discouraged). |
* \param p_rng The RNG context to be passed to \p p_rng. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private |
* key, or \p P is not a valid public key. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
/** |
* \brief This function performs multiplication of a point by |
* an integer: \p R = \p m * \p P in a restartable way. |
* |
* \see mbedtls_ecp_mul() |
* |
* \note This function does the same as \c mbedtls_ecp_mul(), but |
* it can return early and restart according to the limit set |
* with \c mbedtls_ecp_set_max_ops() to reduce blocking. |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param R The point in which to store the result of the calculation. |
* This must be initialized. |
* \param m The integer by which to multiply. This must be initialized. |
* \param P The point to multiply. This must be initialized. |
* \param f_rng The RNG function. This may be \c NULL if randomization |
* of intermediate results isn't desired (discouraged). |
* \param p_rng The RNG context to be passed to \p p_rng. |
* \param rs_ctx The restart context (NULL disables restart). |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private |
* key, or \p P is not a valid public key. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ); |
/** |
* \brief This function performs multiplication and addition of two |
* points by integers: \p R = \p m * \p P + \p n * \p Q |
* |
* It is not thread-safe to use same group in multiple threads. |
* |
* \note In contrast to mbedtls_ecp_mul(), this function does not |
* guarantee a constant execution flow and timing. |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param R The point in which to store the result of the calculation. |
* This must be initialized. |
* \param m The integer by which to multiply \p P. |
* This must be initialized. |
* \param P The point to multiply by \p m. This must be initialized. |
* \param n The integer by which to multiply \p Q. |
* This must be initialized. |
* \param Q The point to be multiplied by \p n. |
* This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not |
* valid private keys, or \p P or \p Q are not valid public |
* keys. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); |
/** |
* \brief This function performs multiplication and addition of two |
* points by integers: \p R = \p m * \p P + \p n * \p Q in a |
* restartable way. |
* |
* \see \c mbedtls_ecp_muladd() |
* |
* \note This function works the same as \c mbedtls_ecp_muladd(), |
* but it can return early and restart according to the limit |
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking. |
* |
* \param grp The ECP group to use. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param R The point in which to store the result of the calculation. |
* This must be initialized. |
* \param m The integer by which to multiply \p P. |
* This must be initialized. |
* \param P The point to multiply by \p m. This must be initialized. |
* \param n The integer by which to multiply \p Q. |
* This must be initialized. |
* \param Q The point to be multiplied by \p n. |
* This must be initialized. |
* \param rs_ctx The restart context (NULL disables restart). |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not |
* valid private keys, or \p P or \p Q are not valid public |
* keys. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_muladd_restartable( |
mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
const mbedtls_mpi *n, const mbedtls_ecp_point *Q, |
mbedtls_ecp_restart_ctx *rs_ctx ); |
/** |
* \brief This function checks that a point is a valid public key |
* on this curve. |
* |
* It only checks that the point is non-zero, has |
* valid coordinates and lies on the curve. It does not verify |
* that it is indeed a multiple of \p G. This additional |
* check is computationally more expensive, is not required |
* by standards, and should not be necessary if the group |
* used has a small cofactor. In particular, it is useless for |
* the NIST groups which all have a cofactor of 1. |
* |
* \note This function uses bare components rather than an |
* ::mbedtls_ecp_keypair structure, to ease use with other |
* structures, such as ::mbedtls_ecdh_context or |
* ::mbedtls_ecdsa_context. |
* |
* \param grp The ECP group the point should belong to. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param pt The point to check. This must be initialized. |
* |
* \return \c 0 if the point is a valid public key. |
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not |
* a valid public key for the given curve. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, |
const mbedtls_ecp_point *pt ); |
/** |
* \brief This function checks that an \p mbedtls_mpi is a |
* valid private key for this curve. |
* |
* \note This function uses bare components rather than an |
* ::mbedtls_ecp_keypair structure to ease use with other |
* structures, such as ::mbedtls_ecdh_context or |
* ::mbedtls_ecdsa_context. |
* |
* \param grp The ECP group the private key should belong to. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param d The integer to check. This must be initialized. |
* |
* \return \c 0 if the point is a valid private key. |
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid |
* private key for the given curve. |
* \return Another negative error code on other kinds of failure. |
*/ |
int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, |
const mbedtls_mpi *d ); |
/** |
* \brief This function generates a private key. |
* |
* \param grp The ECP group to generate a private key for. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param d The destination MPI (secret part). This must be initialized. |
* \param f_rng The RNG function. This must not be \c NULL. |
* \param p_rng The RNG parameter to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code |
* on failure. |
*/ |
int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, |
mbedtls_mpi *d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function generates a keypair with a configurable base |
* point. |
* |
* \note This function uses bare components rather than an |
* ::mbedtls_ecp_keypair structure to ease use with other |
* structures, such as ::mbedtls_ecdh_context or |
* ::mbedtls_ecdsa_context. |
* |
* \param grp The ECP group to generate a key pair for. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param G The base point to use. This must be initialized |
* and belong to \p grp. It replaces the default base |
* point \c grp->G used by mbedtls_ecp_gen_keypair(). |
* \param d The destination MPI (secret part). |
* This must be initialized. |
* \param Q The destination point (public part). |
* This must be initialized. |
* \param f_rng The RNG function. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may |
* be \c NULL if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code |
* on failure. |
*/ |
int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, |
const mbedtls_ecp_point *G, |
mbedtls_mpi *d, mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function generates an ECP keypair. |
* |
* \note This function uses bare components rather than an |
* ::mbedtls_ecp_keypair structure to ease use with other |
* structures, such as ::mbedtls_ecdh_context or |
* ::mbedtls_ecdsa_context. |
* |
* \param grp The ECP group to generate a key pair for. |
* This must be initialized and have group parameters |
* set, for example through mbedtls_ecp_group_load(). |
* \param d The destination MPI (secret part). |
* This must be initialized. |
* \param Q The destination point (public part). |
* This must be initialized. |
* \param f_rng The RNG function. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may |
* be \c NULL if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code |
* on failure. |
*/ |
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, |
mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function generates an ECP key. |
* |
* \param grp_id The ECP group identifier. |
* \param key The destination key. This must be initialized. |
* \param f_rng The RNG function to use. This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may |
* be \c NULL if \p f_rng doesn't need a context argument. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code |
* on failure. |
*/ |
int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief This function checks that the keypair objects |
* \p pub and \p prv have the same group and the |
* same public point, and that the private key in |
* \p prv is consistent with the public key. |
* |
* \param pub The keypair structure holding the public key. This |
* must be initialized. If it contains a private key, that |
* part is ignored. |
* \param prv The keypair structure holding the full keypair. |
* This must be initialized. |
* |
* \return \c 0 on success, meaning that the keys are valid and match. |
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. |
* \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX |
* error code on calculation failure. |
*/ |
int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, |
const mbedtls_ecp_keypair *prv ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The ECP checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_ecp_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* ecp.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ecp_internal.h |
---|
0,0 → 1,301 |
/** |
* \file ecp_internal.h |
* |
* \brief Function declarations for alternative implementation of elliptic curve |
* point arithmetic. |
*/ |
/* |
* Copyright (C) 2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* |
* [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records. |
* <http://cr.yp.to/ecdh/curve25519-20060209.pdf> |
* |
* [2] CORON, Jean-S'ebastien. Resistance against differential power analysis |
* for elliptic curve cryptosystems. In : Cryptographic Hardware and |
* Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. |
* <http://link.springer.com/chapter/10.1007/3-540-48059-5_25> |
* |
* [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to |
* render ECC resistant against Side Channel Attacks. IACR Cryptology |
* ePrint Archive, 2004, vol. 2004, p. 342. |
* <http://eprint.iacr.org/2004/342.pdf> |
* |
* [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters. |
* <http://www.secg.org/sec2-v2.pdf> |
* |
* [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic |
* Curve Cryptography. |
* |
* [6] Digital Signature Standard (DSS), FIPS 186-4. |
* <http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf> |
* |
* [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer |
* Security (TLS), RFC 4492. |
* <https://tools.ietf.org/search/rfc4492> |
* |
* [8] <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html> |
* |
* [9] COHEN, Henri. A Course in Computational Algebraic Number Theory. |
* Springer Science & Business Media, 1 Aug 2000 |
*/ |
#ifndef MBEDTLS_ECP_INTERNAL_H |
#define MBEDTLS_ECP_INTERNAL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
/** |
* \brief Indicate if the Elliptic Curve Point module extension can |
* handle the group. |
* |
* \param grp The pointer to the elliptic curve group that will be the |
* basis of the cryptographic computations. |
* |
* \return Non-zero if successful. |
*/ |
unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp ); |
/** |
* \brief Initialise the Elliptic Curve Point module extension. |
* |
* If mbedtls_internal_ecp_grp_capable returns true for a |
* group, this function has to be able to initialise the |
* module for it. |
* |
* This module can be a driver to a crypto hardware |
* accelerator, for which this could be an initialise function. |
* |
* \param grp The pointer to the group the module needs to be |
* initialised for. |
* |
* \return 0 if successful. |
*/ |
int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ); |
/** |
* \brief Frees and deallocates the Elliptic Curve Point module |
* extension. |
* |
* \param grp The pointer to the group the module was initialised for. |
*/ |
void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ); |
#if defined(ECP_SHORTWEIERSTRASS) |
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) |
/** |
* \brief Randomize jacobian coordinates: |
* (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l. |
* |
* \param grp Pointer to the group representing the curve. |
* |
* \param pt The point on the curve to be randomised, given with Jacobian |
* coordinates. |
* |
* \param f_rng A function pointer to the random number generator. |
* |
* \param p_rng A pointer to the random number generator state. |
* |
* \return 0 if successful. |
*/ |
int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#endif |
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) |
/** |
* \brief Addition: R = P + Q, mixed affine-Jacobian coordinates. |
* |
* The coordinates of Q must be normalized (= affine), |
* but those of P don't need to. R is not normalized. |
* |
* This function is used only as a subrutine of |
* ecp_mul_comb(). |
* |
* Special cases: (1) P or Q is zero, (2) R is zero, |
* (3) P == Q. |
* None of these cases can happen as intermediate step in |
* ecp_mul_comb(): |
* - at each step, P, Q and R are multiples of the base |
* point, the factor being less than its order, so none of |
* them is zero; |
* - Q is an odd multiple of the base point, P an even |
* multiple, due to the choice of precomputed points in the |
* modified comb method. |
* So branches for these cases do not leak secret information. |
* |
* We accept Q->Z being unset (saving memory in tables) as |
* meaning 1. |
* |
* Cost in field operations if done by [5] 3.22: |
* 1A := 8M + 3S |
* |
* \param grp Pointer to the group representing the curve. |
* |
* \param R Pointer to a point structure to hold the result. |
* |
* \param P Pointer to the first summand, given with Jacobian |
* coordinates |
* |
* \param Q Pointer to the second summand, given with affine |
* coordinates. |
* |
* \return 0 if successful. |
*/ |
int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *R, const mbedtls_ecp_point *P, |
const mbedtls_ecp_point *Q ); |
#endif |
/** |
* \brief Point doubling R = 2 P, Jacobian coordinates. |
* |
* Cost: 1D := 3M + 4S (A == 0) |
* 4M + 4S (A == -3) |
* 3M + 6S + 1a otherwise |
* when the implementation is based on the "dbl-1998-cmo-2" |
* doubling formulas in [8] and standard optimizations are |
* applied when curve parameter A is one of { 0, -3 }. |
* |
* \param grp Pointer to the group representing the curve. |
* |
* \param R Pointer to a point structure to hold the result. |
* |
* \param P Pointer to the point that has to be doubled, given with |
* Jacobian coordinates. |
* |
* \return 0 if successful. |
*/ |
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) |
int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *R, const mbedtls_ecp_point *P ); |
#endif |
/** |
* \brief Normalize jacobian coordinates of an array of (pointers to) |
* points. |
* |
* Using Montgomery's trick to perform only one inversion mod P |
* the cost is: |
* 1N(t) := 1I + (6t - 3)M + 1S |
* (See for example Algorithm 10.3.4. in [9]) |
* |
* This function is used only as a subrutine of |
* ecp_mul_comb(). |
* |
* Warning: fails (returning an error) if one of the points is |
* zero! |
* This should never happen, see choice of w in ecp_mul_comb(). |
* |
* \param grp Pointer to the group representing the curve. |
* |
* \param T Array of pointers to the points to normalise. |
* |
* \param t_len Number of elements in the array. |
* |
* \return 0 if successful, |
* an error if one of the points is zero. |
*/ |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) |
int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *T[], size_t t_len ); |
#endif |
/** |
* \brief Normalize jacobian coordinates so that Z == 0 || Z == 1. |
* |
* Cost in field operations if done by [5] 3.2.1: |
* 1N := 1I + 3M + 1S |
* |
* \param grp Pointer to the group representing the curve. |
* |
* \param pt pointer to the point to be normalised. This is an |
* input/output parameter. |
* |
* \return 0 if successful. |
*/ |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) |
int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *pt ); |
#endif |
#endif /* ECP_SHORTWEIERSTRASS */ |
#if defined(ECP_MONTGOMERY) |
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) |
int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P, |
const mbedtls_ecp_point *Q, const mbedtls_mpi *d ); |
#endif |
/** |
* \brief Randomize projective x/z coordinates: |
* (X, Z) -> (l X, l Z) for random l |
* |
* \param grp pointer to the group representing the curve |
* |
* \param P the point on the curve to be randomised given with |
* projective coordinates. This is an input/output parameter. |
* |
* \param f_rng a function pointer to the random number generator |
* |
* \param p_rng a pointer to the random number generator state |
* |
* \return 0 if successful |
*/ |
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) |
int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#endif |
/** |
* \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1. |
* |
* \param grp pointer to the group representing the curve |
* |
* \param P pointer to the point to be normalised. This is an |
* input/output parameter. |
* |
* \return 0 if successful |
*/ |
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) |
int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *P ); |
#endif |
#endif /* ECP_MONTGOMERY */ |
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ |
#endif /* ecp_internal.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/entropy.h |
---|
0,0 → 1,291 |
/** |
* \file entropy.h |
* |
* \brief Entropy accumulator implementation |
*/ |
/* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ENTROPY_H |
#define MBEDTLS_ENTROPY_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) |
#include "sha512.h" |
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR |
#else |
#if defined(MBEDTLS_SHA256_C) |
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR |
#include "sha256.h" |
#endif |
#endif |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
#if defined(MBEDTLS_HAVEGE_C) |
#include "havege.h" |
#endif |
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */ |
#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */ |
#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */ |
#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */ |
#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */ |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES) |
#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ |
#endif |
#if !defined(MBEDTLS_ENTROPY_MAX_GATHER) |
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ |
#endif |
/* \} name SECTION: Module settings */ |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ |
#else |
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ |
#endif |
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ |
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES |
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ |
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Entropy poll callback pointer |
* |
* \param data Callback-specific data pointer |
* \param output Data to fill |
* \param len Maximum size to provide |
* \param olen The actual amount of bytes put into the buffer (Can be 0) |
* |
* \return 0 if no critical failures occurred, |
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise |
*/ |
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len, |
size_t *olen); |
/** |
* \brief Entropy source state |
*/ |
typedef struct mbedtls_entropy_source_state |
{ |
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */ |
void * p_source; /**< The callback data pointer */ |
size_t size; /**< Amount received in bytes */ |
size_t threshold; /**< Minimum bytes required before release */ |
int strong; /**< Is the source strong? */ |
} |
mbedtls_entropy_source_state; |
/** |
* \brief Entropy context structure |
*/ |
typedef struct mbedtls_entropy_context |
{ |
int accumulator_started; |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
mbedtls_sha512_context accumulator; |
#else |
mbedtls_sha256_context accumulator; |
#endif |
int source_count; |
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES]; |
#if defined(MBEDTLS_HAVEGE_C) |
mbedtls_havege_state havege_data; |
#endif |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; /*!< mutex */ |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
int initial_entropy_run; |
#endif |
} |
mbedtls_entropy_context; |
/** |
* \brief Initialize the context |
* |
* \param ctx Entropy context to initialize |
*/ |
void mbedtls_entropy_init( mbedtls_entropy_context *ctx ); |
/** |
* \brief Free the data in the context |
* |
* \param ctx Entropy context to free |
*/ |
void mbedtls_entropy_free( mbedtls_entropy_context *ctx ); |
/** |
* \brief Adds an entropy source to poll |
* (Thread-safe if MBEDTLS_THREADING_C is enabled) |
* |
* \param ctx Entropy context |
* \param f_source Entropy function |
* \param p_source Function data |
* \param threshold Minimum required from source before entropy is released |
* ( with mbedtls_entropy_func() ) (in bytes) |
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or |
* MBEDTLS_ENTROPY_SOURCE_WEAK. |
* At least one strong source needs to be added. |
* Weaker sources (such as the cycle counter) can be used as |
* a complement. |
* |
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES |
*/ |
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, |
mbedtls_entropy_f_source_ptr f_source, void *p_source, |
size_t threshold, int strong ); |
/** |
* \brief Trigger an extra gather poll for the accumulator |
* (Thread-safe if MBEDTLS_THREADING_C is enabled) |
* |
* \param ctx Entropy context |
* |
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED |
*/ |
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ); |
/** |
* \brief Retrieve entropy from the accumulator |
* (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE) |
* (Thread-safe if MBEDTLS_THREADING_C is enabled) |
* |
* \param data Entropy context |
* \param output Buffer to fill |
* \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE |
* |
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED |
*/ |
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ); |
/** |
* \brief Add data to the accumulator manually |
* (Thread-safe if MBEDTLS_THREADING_C is enabled) |
* |
* \param ctx Entropy context |
* \param data Data to add |
* \param len Length of data |
* |
* \return 0 if successful |
*/ |
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, |
const unsigned char *data, size_t len ); |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
/** |
* \brief Trigger an update of the seed file in NV by using the |
* current entropy pool. |
* |
* \param ctx Entropy context |
* |
* \return 0 if successful |
*/ |
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ); |
#endif /* MBEDTLS_ENTROPY_NV_SEED */ |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief Write a seed file |
* |
* \param ctx Entropy context |
* \param path Name of the file |
* |
* \return 0 if successful, |
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or |
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED |
*/ |
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ); |
/** |
* \brief Read and update a seed file. Seed is added to this |
* instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are |
* read from the seed file. The rest is ignored. |
* |
* \param ctx Entropy context |
* \param path Name of the file |
* |
* \return 0 if successful, |
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, |
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED |
*/ |
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* This module self-test also calls the entropy self-test, |
* mbedtls_entropy_source_self_test(); |
* |
* \return 0 if successful, or 1 if a test failed |
*/ |
int mbedtls_entropy_self_test( int verbose ); |
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
/** |
* \brief Checkup routine |
* |
* Verifies the integrity of the hardware entropy source |
* provided by the function 'mbedtls_hardware_poll()'. |
* |
* Note this is the only hardware entropy source that is known |
* at link time, and other entropy sources configured |
* dynamically at runtime by the function |
* mbedtls_entropy_add_source() will not be tested. |
* |
* \return 0 if successful, or 1 if a test failed |
*/ |
int mbedtls_entropy_source_self_test( int verbose ); |
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* entropy.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/entropy_poll.h |
---|
0,0 → 1,122 |
/** |
* \file entropy_poll.h |
* |
* \brief Platform-specific and custom entropy polling functions |
*/ |
/* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ENTROPY_POLL_H |
#define MBEDTLS_ENTROPY_POLL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* |
* Default thresholds for built-in sources, in bytes |
*/ |
#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ |
#define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */ |
#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ |
#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) |
#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ |
#endif |
/* entropy sources polls for KolibriOS */ |
int mbedtls_sysfn_3_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
int mbedtls_sysfn_26_9_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
int mbedtls_sysfn_14_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
int mbedtls_sysfn_18_4_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
int mbedtls_sysfn_37_0_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
int mbedtls_sysfn_66_3_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
int mbedtls_sysfn_68_0_poll( void *data, unsigned char *output, size_t len, size_t *olen ); |
/** |
* \brief Entropy poll callback that provides 0 entropy. |
*/ |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) |
int mbedtls_null_entropy_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ); |
#endif |
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) |
/** |
* \brief Platform-specific entropy poll callback |
*/ |
int mbedtls_platform_entropy_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ); |
#endif |
#if defined(MBEDTLS_HAVEGE_C) |
/** |
* \brief HAVEGE based entropy poll callback |
* |
* Requires an HAVEGE state as its data pointer. |
*/ |
int mbedtls_havege_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ); |
#endif |
#if defined(MBEDTLS_TIMING_C) |
/** |
* \brief mbedtls_timing_hardclock-based entropy poll callback |
*/ |
int mbedtls_hardclock_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ); |
#endif |
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
/** |
* \brief Entropy poll callback for a hardware source |
* |
* \warning This is not provided by mbed TLS! |
* See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h. |
* |
* \note This must accept NULL as its first argument. |
*/ |
int mbedtls_hardware_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ); |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
/** |
* \brief Entropy poll callback for a non-volatile seed file |
* |
* \note This must accept NULL as its first argument. |
*/ |
int mbedtls_nv_seed_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* entropy_poll.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/error.h |
---|
0,0 → 1,131 |
/** |
* \file error.h |
* |
* \brief Error to string translation |
*/ |
/* |
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_ERROR_H |
#define MBEDTLS_ERROR_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
/** |
* Error code layout. |
* |
* Currently we try to keep all error codes within the negative space of 16 |
* bits signed integers to support all platforms (-0x0001 - -0x7FFF). In |
* addition we'd like to give two layers of information on the error if |
* possible. |
* |
* For that purpose the error codes are segmented in the following manner: |
* |
* 16 bit error code bit-segmentation |
* |
* 1 bit - Unused (sign bit) |
* 3 bits - High level module ID |
* 5 bits - Module-dependent error code |
* 7 bits - Low level module errors |
* |
* For historical reasons, low-level error codes are divided in even and odd, |
* even codes were assigned first, and -1 is reserved for other errors. |
* |
* Low-level module errors (0x0002-0x007E, 0x0003-0x007F) |
* |
* Module Nr Codes assigned |
* MPI 7 0x0002-0x0010 |
* GCM 3 0x0012-0x0014 0x0013-0x0013 |
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017 |
* THREADING 3 0x001A-0x001E |
* AES 5 0x0020-0x0022 0x0021-0x0025 |
* CAMELLIA 3 0x0024-0x0026 0x0027-0x0027 |
* XTEA 2 0x0028-0x0028 0x0029-0x0029 |
* BASE64 2 0x002A-0x002C |
* OID 1 0x002E-0x002E 0x000B-0x000B |
* PADLOCK 1 0x0030-0x0030 |
* DES 2 0x0032-0x0032 0x0033-0x0033 |
* CTR_DBRG 4 0x0034-0x003A |
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F |
* NET 13 0x0042-0x0052 0x0043-0x0049 |
* ARIA 4 0x0058-0x005E |
* ASN1 7 0x0060-0x006C |
* CMAC 1 0x007A-0x007A |
* PBKDF2 1 0x007C-0x007C |
* HMAC_DRBG 4 0x0003-0x0009 |
* CCM 3 0x000D-0x0011 |
* ARC4 1 0x0019-0x0019 |
* MD2 1 0x002B-0x002B |
* MD4 1 0x002D-0x002D |
* MD5 1 0x002F-0x002F |
* RIPEMD160 1 0x0031-0x0031 |
* SHA1 1 0x0035-0x0035 0x0073-0x0073 |
* SHA256 1 0x0037-0x0037 0x0074-0x0074 |
* SHA512 1 0x0039-0x0039 0x0075-0x0075 |
* CHACHA20 3 0x0051-0x0055 |
* POLY1305 3 0x0057-0x005B |
* CHACHAPOLY 2 0x0054-0x0056 |
* PLATFORM 1 0x0070-0x0072 |
* |
* High-level module nr (3 bits - 0x0...-0x7...) |
* Name ID Nr of Errors |
* PEM 1 9 |
* PKCS#12 1 4 (Started from top) |
* X509 2 20 |
* PKCS5 2 4 (Started from top) |
* DHM 3 11 |
* PK 3 15 (Started from top) |
* RSA 4 11 |
* ECP 4 10 (Started from top) |
* MD 5 5 |
* HKDF 5 1 (Started from top) |
* CIPHER 6 8 |
* SSL 6 23 (Started from top) |
* SSL 7 32 |
* |
* Module dependent error code (5 bits 0x.00.-0x.F8.) |
*/ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Translate a mbed TLS error code into a string representation, |
* Result is truncated if necessary and always includes a terminating |
* null byte. |
* |
* \param errnum error code |
* \param buffer buffer to place representation in |
* \param buflen length of the buffer |
*/ |
void mbedtls_strerror( int errnum, char *buffer, size_t buflen ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* error.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/gcm.h |
---|
0,0 → 1,328 |
/** |
* \file gcm.h |
* |
* \brief This file contains GCM definitions and functions. |
* |
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined |
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation |
* (GCM), Natl. Inst. Stand. Technol.</em> |
* |
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for |
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>. |
* |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_GCM_H |
#define MBEDTLS_GCM_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "cipher.h" |
#include <stdint.h> |
#define MBEDTLS_GCM_ENCRYPT 1 |
#define MBEDTLS_GCM_DECRYPT 0 |
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ |
/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */ |
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_GCM_ALT) |
/** |
* \brief The GCM context structure. |
*/ |
typedef struct mbedtls_gcm_context |
{ |
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ |
uint64_t HL[16]; /*!< Precalculated HTable low. */ |
uint64_t HH[16]; /*!< Precalculated HTable high. */ |
uint64_t len; /*!< The total length of the encrypted data. */ |
uint64_t add_len; /*!< The total length of the additional data. */ |
unsigned char base_ectr[16]; /*!< The first ECTR for tag. */ |
unsigned char y[16]; /*!< The Y working value. */ |
unsigned char buf[16]; /*!< The buf working value. */ |
int mode; /*!< The operation to perform: |
#MBEDTLS_GCM_ENCRYPT or |
#MBEDTLS_GCM_DECRYPT. */ |
} |
mbedtls_gcm_context; |
#else /* !MBEDTLS_GCM_ALT */ |
#include "gcm_alt.h" |
#endif /* !MBEDTLS_GCM_ALT */ |
/** |
* \brief This function initializes the specified GCM context, |
* to make references valid, and prepares the context |
* for mbedtls_gcm_setkey() or mbedtls_gcm_free(). |
* |
* The function does not bind the GCM context to a particular |
* cipher, nor set the key. For this purpose, use |
* mbedtls_gcm_setkey(). |
* |
* \param ctx The GCM context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); |
/** |
* \brief This function associates a GCM context with a |
* cipher algorithm and a key. |
* |
* \param ctx The GCM context. This must be initialized. |
* \param cipher The 128-bit block cipher to use. |
* \param key The encryption key. This must be a readable buffer of at |
* least \p keybits bits. |
* \param keybits The key size in bits. Valid options are: |
* <ul><li>128 bits</li> |
* <li>192 bits</li> |
* <li>256 bits</li></ul> |
* |
* \return \c 0 on success. |
* \return A cipher-specific error code on failure. |
*/ |
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, |
mbedtls_cipher_id_t cipher, |
const unsigned char *key, |
unsigned int keybits ); |
/** |
* \brief This function performs GCM encryption or decryption of a buffer. |
* |
* \note For encryption, the output buffer can be the same as the |
* input buffer. For decryption, the output buffer cannot be |
* the same as input buffer. If the buffers overlap, the output |
* buffer must trail at least 8 Bytes behind the input buffer. |
* |
* \warning When this function performs a decryption, it outputs the |
* authentication tag and does not verify that the data is |
* authentic. You should use this function to perform encryption |
* only. For decryption, use mbedtls_gcm_auth_decrypt() instead. |
* |
* \param ctx The GCM context to use for encryption or decryption. This |
* must be initialized. |
* \param mode The operation to perform: |
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. |
* The ciphertext is written to \p output and the |
* authentication tag is written to \p tag. |
* - #MBEDTLS_GCM_DECRYPT to perform decryption. |
* The plaintext is written to \p output and the |
* authentication tag is written to \p tag. |
* Note that this mode is not recommended, because it does |
* not verify the authenticity of the data. For this reason, |
* you should use mbedtls_gcm_auth_decrypt() instead of |
* calling this function in decryption mode. |
* \param length The length of the input data, which is equal to the length |
* of the output data. |
* \param iv The initialization vector. This must be a readable buffer of |
* at least \p iv_len Bytes. |
* \param iv_len The length of the IV. |
* \param add The buffer holding the additional data. This must be of at |
* least that size in Bytes. |
* \param add_len The length of the additional data. |
* \param input The buffer holding the input data. If \p length is greater |
* than zero, this must be a readable buffer of at least that |
* size in Bytes. |
* \param output The buffer for holding the output data. If \p length is greater |
* than zero, this must be a writable buffer of at least that |
* size in Bytes. |
* \param tag_len The length of the tag to generate. |
* \param tag The buffer for holding the tag. This must be a readable |
* buffer of at least \p tag_len Bytes. |
* |
* \return \c 0 if the encryption or decryption was performed |
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, |
* this does not indicate that the data is authentic. |
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are |
* not valid or a cipher-specific error code if the encryption |
* or decryption failed. |
*/ |
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, |
int mode, |
size_t length, |
const unsigned char *iv, |
size_t iv_len, |
const unsigned char *add, |
size_t add_len, |
const unsigned char *input, |
unsigned char *output, |
size_t tag_len, |
unsigned char *tag ); |
/** |
* \brief This function performs a GCM authenticated decryption of a |
* buffer. |
* |
* \note For decryption, the output buffer cannot be the same as |
* input buffer. If the buffers overlap, the output buffer |
* must trail at least 8 Bytes behind the input buffer. |
* |
* \param ctx The GCM context. This must be initialized. |
* \param length The length of the ciphertext to decrypt, which is also |
* the length of the decrypted plaintext. |
* \param iv The initialization vector. This must be a readable buffer |
* of at least \p iv_len Bytes. |
* \param iv_len The length of the IV. |
* \param add The buffer holding the additional data. This must be of at |
* least that size in Bytes. |
* \param add_len The length of the additional data. |
* \param tag The buffer holding the tag to verify. This must be a |
* readable buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the tag to verify. |
* \param input The buffer holding the ciphertext. If \p length is greater |
* than zero, this must be a readable buffer of at least that |
* size. |
* \param output The buffer for holding the decrypted plaintext. If \p length |
* is greater than zero, this must be a writable buffer of at |
* least that size. |
* |
* \return \c 0 if successful and authenticated. |
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. |
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are |
* not valid or a cipher-specific error code if the decryption |
* failed. |
*/ |
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, |
size_t length, |
const unsigned char *iv, |
size_t iv_len, |
const unsigned char *add, |
size_t add_len, |
const unsigned char *tag, |
size_t tag_len, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function starts a GCM encryption or decryption |
* operation. |
* |
* \param ctx The GCM context. This must be initialized. |
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or |
* #MBEDTLS_GCM_DECRYPT. |
* \param iv The initialization vector. This must be a readable buffer of |
* at least \p iv_len Bytes. |
* \param iv_len The length of the IV. |
* \param add The buffer holding the additional data, or \c NULL |
* if \p add_len is \c 0. |
* \param add_len The length of the additional data. If \c 0, |
* \p add may be \c NULL. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, |
int mode, |
const unsigned char *iv, |
size_t iv_len, |
const unsigned char *add, |
size_t add_len ); |
/** |
* \brief This function feeds an input buffer into an ongoing GCM |
* encryption or decryption operation. |
* |
* ` The function expects input to be a multiple of 16 |
* Bytes. Only the last call before calling |
* mbedtls_gcm_finish() can be less than 16 Bytes. |
* |
* \note For decryption, the output buffer cannot be the same as |
* input buffer. If the buffers overlap, the output buffer |
* must trail at least 8 Bytes behind the input buffer. |
* |
* \param ctx The GCM context. This must be initialized. |
* \param length The length of the input data. This must be a multiple of |
* 16 except in the last call before mbedtls_gcm_finish(). |
* \param input The buffer holding the input data. If \p length is greater |
* than zero, this must be a readable buffer of at least that |
* size in Bytes. |
* \param output The buffer for holding the output data. If \p length is |
* greater than zero, this must be a writable buffer of at |
* least that size in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. |
*/ |
int mbedtls_gcm_update( mbedtls_gcm_context *ctx, |
size_t length, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function finishes the GCM operation and generates |
* the authentication tag. |
* |
* It wraps up the GCM stream, and generates the |
* tag. The tag can have a maximum length of 16 Bytes. |
* |
* \param ctx The GCM context. This must be initialized. |
* \param tag The buffer for holding the tag. This must be a readable |
* buffer of at least \p tag_len Bytes. |
* \param tag_len The length of the tag to generate. This must be at least |
* four. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. |
*/ |
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, |
unsigned char *tag, |
size_t tag_len ); |
/** |
* \brief This function clears a GCM context and the underlying |
* cipher sub-context. |
* |
* \param ctx The GCM context to clear. If this is \c NULL, the call has |
* no effect. Otherwise, this must be initialized. |
*/ |
void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The GCM checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_gcm_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* gcm.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/havege.h |
---|
0,0 → 1,83 |
/** |
* \file havege.h |
* |
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_HAVEGE_H |
#define MBEDTLS_HAVEGE_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024 |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief HAVEGE state structure |
*/ |
typedef struct mbedtls_havege_state |
{ |
int PT1, PT2, offset[2]; |
int pool[MBEDTLS_HAVEGE_COLLECT_SIZE]; |
int WALK[8192]; |
} |
mbedtls_havege_state; |
/** |
* \brief HAVEGE initialization |
* |
* \param hs HAVEGE state to be initialized |
*/ |
void mbedtls_havege_init( mbedtls_havege_state *hs ); |
/** |
* \brief Clear HAVEGE state |
* |
* \param hs HAVEGE state to be cleared |
*/ |
void mbedtls_havege_free( mbedtls_havege_state *hs ); |
/** |
* \brief HAVEGE rand function |
* |
* \param p_rng A HAVEGE state |
* \param output Buffer to fill |
* \param len Length of buffer |
* |
* \return 0 |
*/ |
int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* havege.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/hkdf.h |
---|
0,0 → 1,143 |
/** |
* \file hkdf.h |
* |
* \brief This file contains the HKDF interface. |
* |
* The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is |
* specified by RFC 5869. |
*/ |
/* |
* Copyright (C) 2016-2019, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_HKDF_H |
#define MBEDTLS_HKDF_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "md.h" |
/** |
* \name HKDF Error codes |
* \{ |
*/ |
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */ |
/* \} name */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief This is the HMAC-based Extract-and-Expand Key Derivation Function |
* (HKDF). |
* |
* \param md A hash function; md.size denotes the length of the hash |
* function output in bytes. |
* \param salt An optional salt value (a non-secret random value); |
* if the salt is not provided, a string of all zeros of |
* md.size length is used as the salt. |
* \param salt_len The length in bytes of the optional \p salt. |
* \param ikm The input keying material. |
* \param ikm_len The length in bytes of \p ikm. |
* \param info An optional context and application specific information |
* string. This can be a zero-length string. |
* \param info_len The length of \p info in bytes. |
* \param okm The output keying material of \p okm_len bytes. |
* \param okm_len The length of the output keying material in bytes. This |
* must be less than or equal to 255 * md.size bytes. |
* |
* \return 0 on success. |
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. |
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying |
* MD layer. |
*/ |
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, |
size_t salt_len, const unsigned char *ikm, size_t ikm_len, |
const unsigned char *info, size_t info_len, |
unsigned char *okm, size_t okm_len ); |
/** |
* \brief Take the input keying material \p ikm and extract from it a |
* fixed-length pseudorandom key \p prk. |
* |
* \warning This function should only be used if the security of it has been |
* studied and established in that particular context (eg. TLS 1.3 |
* key schedule). For standard HKDF security guarantees use |
* \c mbedtls_hkdf instead. |
* |
* \param md A hash function; md.size denotes the length of the |
* hash function output in bytes. |
* \param salt An optional salt value (a non-secret random value); |
* if the salt is not provided, a string of all zeros |
* of md.size length is used as the salt. |
* \param salt_len The length in bytes of the optional \p salt. |
* \param ikm The input keying material. |
* \param ikm_len The length in bytes of \p ikm. |
* \param[out] prk A pseudorandom key of at least md.size bytes. |
* |
* \return 0 on success. |
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. |
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying |
* MD layer. |
*/ |
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, |
const unsigned char *salt, size_t salt_len, |
const unsigned char *ikm, size_t ikm_len, |
unsigned char *prk ); |
/** |
* \brief Expand the supplied \p prk into several additional pseudorandom |
* keys, which is the output of the HKDF. |
* |
* \warning This function should only be used if the security of it has been |
* studied and established in that particular context (eg. TLS 1.3 |
* key schedule). For standard HKDF security guarantees use |
* \c mbedtls_hkdf instead. |
* |
* \param md A hash function; md.size denotes the length of the hash |
* function output in bytes. |
* \param prk A pseudorandom key of at least md.size bytes. \p prk is |
* usually the output from the HKDF extract step. |
* \param prk_len The length in bytes of \p prk. |
* \param info An optional context and application specific information |
* string. This can be a zero-length string. |
* \param info_len The length of \p info in bytes. |
* \param okm The output keying material of \p okm_len bytes. |
* \param okm_len The length of the output keying material in bytes. This |
* must be less than or equal to 255 * md.size bytes. |
* |
* \return 0 on success. |
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. |
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying |
* MD layer. |
*/ |
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, |
size_t prk_len, const unsigned char *info, |
size_t info_len, unsigned char *okm, size_t okm_len ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* hkdf.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/hmac_drbg.h |
---|
0,0 → 1,417 |
/** |
* \file hmac_drbg.h |
* |
* \brief The HMAC_DRBG pseudorandom generator. |
* |
* This module implements the HMAC_DRBG pseudorandom generator described |
* in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using |
* Deterministic Random Bit Generators</em>. |
*/ |
/* |
* Copyright (C) 2006-2019, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_HMAC_DRBG_H |
#define MBEDTLS_HMAC_DRBG_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "md.h" |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
/* |
* Error codes |
*/ |
#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */ |
#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */ |
#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */ |
#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */ |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) |
#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ |
#endif |
#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT) |
#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ |
#endif |
#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST) |
#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ |
#endif |
#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) |
#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ |
#endif |
/* \} name SECTION: Module settings */ |
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ |
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* HMAC_DRBG context. |
*/ |
typedef struct mbedtls_hmac_drbg_context |
{ |
/* Working state: the key K is not stored explicitly, |
* but is implied by the HMAC context */ |
mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */ |
unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ |
int reseed_counter; /*!< reseed counter */ |
/* Administrative state */ |
size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ |
int prediction_resistance; /*!< enable prediction resistance (Automatic |
reseed before every random generation) */ |
int reseed_interval; /*!< reseed interval */ |
/* Callbacks */ |
int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ |
void *p_entropy; /*!< context for the entropy function */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; |
#endif |
} mbedtls_hmac_drbg_context; |
/** |
* \brief HMAC_DRBG context initialization. |
* |
* This function makes the context ready for mbedtls_hmac_drbg_seed(), |
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). |
* |
* \param ctx HMAC_DRBG context to be initialized. |
*/ |
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); |
/** |
* \brief HMAC_DRBG initial seeding. |
* |
* Set the initial seed and set up the entropy source for future reseeds. |
* |
* A typical choice for the \p f_entropy and \p p_entropy parameters is |
* to use the entropy module: |
* - \p f_entropy is mbedtls_entropy_func(); |
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized |
* with mbedtls_entropy_init() (which registers the platform's default |
* entropy sources). |
* |
* You can provide a personalization string in addition to the |
* entropy source, to make this instantiation as unique as possible. |
* |
* \note By default, the security strength as defined by NIST is: |
* - 128 bits if \p md_info is SHA-1; |
* - 192 bits if \p md_info is SHA-224; |
* - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. |
* Note that SHA-256 is just as efficient as SHA-224. |
* The security strength can be reduced if a smaller |
* entropy length is set with |
* mbedtls_hmac_drbg_set_entropy_len(). |
* |
* \note The default entropy length is the security strength |
* (converted from bits to bytes). You can override |
* it by calling mbedtls_hmac_drbg_set_entropy_len(). |
* |
* \note During the initial seeding, this function calls |
* the entropy source to obtain a nonce |
* whose length is half the entropy length. |
* |
* \param ctx HMAC_DRBG context to be seeded. |
* \param md_info MD algorithm to use for HMAC_DRBG. |
* \param f_entropy The entropy callback, taking as arguments the |
* \p p_entropy context, the buffer to fill, and the |
* length of the buffer. |
* \p f_entropy is always called with a length that is |
* less than or equal to the entropy length. |
* \param p_entropy The entropy context to pass to \p f_entropy. |
* \param custom The personalization string. |
* This can be \c NULL, in which case the personalization |
* string is empty regardless of the value of \p len. |
* \param len The length of the personalization string. |
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT |
* and also at most |
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 |
* where \p entropy_len is the entropy length |
* described above. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is |
* invalid. |
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough |
* memory to allocate context data. |
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
* if the call to \p f_entropy failed. |
*/ |
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, |
const mbedtls_md_info_t * md_info, |
int (*f_entropy)(void *, unsigned char *, size_t), |
void *p_entropy, |
const unsigned char *custom, |
size_t len ); |
/** |
* \brief Initilisation of simpified HMAC_DRBG (never reseeds). |
* |
* This function is meant for use in algorithms that need a pseudorandom |
* input such as deterministic ECDSA. |
* |
* \param ctx HMAC_DRBG context to be initialised. |
* \param md_info MD algorithm to use for HMAC_DRBG. |
* \param data Concatenation of the initial entropy string and |
* the additional data. |
* \param data_len Length of \p data in bytes. |
* |
* \return \c 0 if successful. or |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is |
* invalid. |
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough |
* memory to allocate context data. |
*/ |
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, |
const mbedtls_md_info_t * md_info, |
const unsigned char *data, size_t data_len ); |
/** |
* \brief This function turns prediction resistance on or off. |
* The default value is off. |
* |
* \note If enabled, entropy is gathered at the beginning of |
* every call to mbedtls_hmac_drbg_random_with_add() |
* or mbedtls_hmac_drbg_random(). |
* Only use this if your entropy source has sufficient |
* throughput. |
* |
* \param ctx The HMAC_DRBG context. |
* \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. |
*/ |
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, |
int resistance ); |
/** |
* \brief This function sets the amount of entropy grabbed on each |
* seed or reseed. |
* |
* See the documentation of mbedtls_hmac_drbg_seed() for the default value. |
* |
* \param ctx The HMAC_DRBG context. |
* \param len The amount of entropy to grab, in bytes. |
*/ |
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, |
size_t len ); |
/** |
* \brief Set the reseed interval. |
* |
* The reseed interval is the number of calls to mbedtls_hmac_drbg_random() |
* or mbedtls_hmac_drbg_random_with_add() after which the entropy function |
* is called again. |
* |
* The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. |
* |
* \param ctx The HMAC_DRBG context. |
* \param interval The reseed interval. |
*/ |
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, |
int interval ); |
/** |
* \brief This function updates the state of the HMAC_DRBG context. |
* |
* \param ctx The HMAC_DRBG context. |
* \param additional The data to update the state with. |
* If this is \c NULL, there is no additional data. |
* \param add_len Length of \p additional in bytes. |
* Unused if \p additional is \c NULL. |
* |
* \return \c 0 on success, or an error from the underlying |
* hash calculation. |
*/ |
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, size_t add_len ); |
/** |
* \brief This function reseeds the HMAC_DRBG context, that is |
* extracts data from the entropy source. |
* |
* \param ctx The HMAC_DRBG context. |
* \param additional Additional data to add to the state. |
* If this is \c NULL, there is no additional data |
* and \p len should be \c 0. |
* \param len The length of the additional data. |
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT |
* and also at most |
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len |
* where \p entropy_len is the entropy length |
* (see mbedtls_hmac_drbg_set_entropy_len()). |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
* if a call to the entropy function failed. |
*/ |
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, size_t len ); |
/** |
* \brief This function updates an HMAC_DRBG instance with additional |
* data and uses it to generate random data. |
* |
* This function automatically reseeds if the reseed counter is exceeded |
* or prediction resistance is enabled. |
* |
* \param p_rng The HMAC_DRBG context. This must be a pointer to a |
* #mbedtls_hmac_drbg_context structure. |
* \param output The buffer to fill. |
* \param output_len The length of the buffer in bytes. |
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. |
* \param additional Additional data to update with. |
* If this is \c NULL, there is no additional data |
* and \p add_len should be \c 0. |
* \param add_len The length of the additional data. |
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
* if a call to the entropy source failed. |
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if |
* \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. |
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if |
* \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. |
*/ |
int mbedtls_hmac_drbg_random_with_add( void *p_rng, |
unsigned char *output, size_t output_len, |
const unsigned char *additional, |
size_t add_len ); |
/** |
* \brief This function uses HMAC_DRBG to generate random data. |
* |
* This function automatically reseeds if the reseed counter is exceeded |
* or prediction resistance is enabled. |
* |
* \param p_rng The HMAC_DRBG context. This must be a pointer to a |
* #mbedtls_hmac_drbg_context structure. |
* \param output The buffer to fill. |
* \param out_len The length of the buffer in bytes. |
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED |
* if a call to the entropy source failed. |
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if |
* \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. |
*/ |
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); |
/** |
* \brief Free an HMAC_DRBG context |
* |
* \param ctx The HMAC_DRBG context to free. |
*/ |
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); |
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function updates the state of the HMAC_DRBG context. |
* |
* \deprecated Superseded by mbedtls_hmac_drbg_update_ret() |
* in 2.16.0. |
* |
* \param ctx The HMAC_DRBG context. |
* \param additional The data to update the state with. |
* If this is \c NULL, there is no additional data. |
* \param add_len Length of \p additional in bytes. |
* Unused if \p additional is \c NULL. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( |
mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, size_t add_len ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief This function writes a seed file. |
* |
* \param ctx The HMAC_DRBG context. |
* \param path The name of the file. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. |
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed |
* failure. |
*/ |
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); |
/** |
* \brief This function reads and updates a seed file. The seed |
* is added to this instance. |
* |
* \param ctx The HMAC_DRBG context. |
* \param path The name of the file. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. |
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on |
* reseed failure. |
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing |
* seed file is too large. |
*/ |
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The HMAC_DRBG Checkup routine. |
* |
* \return \c 0 if successful. |
* \return \c 1 if the test failed. |
*/ |
int mbedtls_hmac_drbg_self_test( int verbose ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* hmac_drbg.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/md.h |
---|
0,0 → 1,470 |
/** |
* \file md.h |
* |
* \brief This file contains the generic message-digest wrapper. |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_MD_H |
#define MBEDTLS_MD_H |
#include <stddef.h> |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */ |
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ |
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */ |
/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Supported message digests. |
* |
* \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and |
* their use constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
typedef enum { |
MBEDTLS_MD_NONE=0, /**< None. */ |
MBEDTLS_MD_MD2, /**< The MD2 message digest. */ |
MBEDTLS_MD_MD4, /**< The MD4 message digest. */ |
MBEDTLS_MD_MD5, /**< The MD5 message digest. */ |
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */ |
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */ |
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */ |
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */ |
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */ |
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ |
} mbedtls_md_type_t; |
#if defined(MBEDTLS_SHA512_C) |
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ |
#else |
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */ |
#endif |
/** |
* Opaque struct defined in md_internal.h. |
*/ |
typedef struct mbedtls_md_info_t mbedtls_md_info_t; |
/** |
* The generic message-digest context. |
*/ |
typedef struct mbedtls_md_context_t |
{ |
/** Information about the associated message digest. */ |
const mbedtls_md_info_t *md_info; |
/** The digest-specific context. */ |
void *md_ctx; |
/** The HMAC part of the context. */ |
void *hmac_ctx; |
} mbedtls_md_context_t; |
/** |
* \brief This function returns the list of digests supported by the |
* generic digest module. |
* |
* \return A statically allocated array of digests. Each element |
* in the returned list is an integer belonging to the |
* message-digest enumeration #mbedtls_md_type_t. |
* The last entry is 0. |
*/ |
const int *mbedtls_md_list( void ); |
/** |
* \brief This function returns the message-digest information |
* associated with the given digest name. |
* |
* \param md_name The name of the digest to search for. |
* |
* \return The message-digest information associated with \p md_name. |
* \return NULL if the associated message-digest information is not found. |
*/ |
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ); |
/** |
* \brief This function returns the message-digest information |
* associated with the given digest type. |
* |
* \param md_type The type of digest to search for. |
* |
* \return The message-digest information associated with \p md_type. |
* \return NULL if the associated message-digest information is not found. |
*/ |
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ); |
/** |
* \brief This function initializes a message-digest context without |
* binding it to a particular message-digest algorithm. |
* |
* This function should always be called first. It prepares the |
* context for mbedtls_md_setup() for binding it to a |
* message-digest algorithm. |
*/ |
void mbedtls_md_init( mbedtls_md_context_t *ctx ); |
/** |
* \brief This function clears the internal structure of \p ctx and |
* frees any embedded internal structure, but does not free |
* \p ctx itself. |
* |
* If you have called mbedtls_md_setup() on \p ctx, you must |
* call mbedtls_md_free() when you are no longer using the |
* context. |
* Calling this function if you have previously |
* called mbedtls_md_init() and nothing else is optional. |
* You must not call this function if you have not called |
* mbedtls_md_init(). |
*/ |
void mbedtls_md_free( mbedtls_md_context_t *ctx ); |
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function selects the message digest algorithm to use, |
* and allocates internal structures. |
* |
* It should be called after mbedtls_md_init() or mbedtls_md_free(). |
* Makes it necessary to call mbedtls_md_free() later. |
* |
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0 |
* |
* \param ctx The context to set up. |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. |
*/ |
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED; |
#undef MBEDTLS_DEPRECATED |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief This function selects the message digest algorithm to use, |
* and allocates internal structures. |
* |
* It should be called after mbedtls_md_init() or |
* mbedtls_md_free(). Makes it necessary to call |
* mbedtls_md_free() later. |
* |
* \param ctx The context to set up. |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory), |
* or non-zero: HMAC is used with this context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. |
*/ |
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); |
/** |
* \brief This function clones the state of an message-digest |
* context. |
* |
* \note You must call mbedtls_md_setup() on \c dst before calling |
* this function. |
* |
* \note The two contexts must have the same type, |
* for example, both are SHA-256. |
* |
* \warning This function clones the message-digest state, not the |
* HMAC state. |
* |
* \param dst The destination context. |
* \param src The context to be cloned. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. |
*/ |
int mbedtls_md_clone( mbedtls_md_context_t *dst, |
const mbedtls_md_context_t *src ); |
/** |
* \brief This function extracts the message-digest size from the |
* message-digest information structure. |
* |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* |
* \return The size of the message-digest output in Bytes. |
*/ |
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); |
/** |
* \brief This function extracts the message-digest type from the |
* message-digest information structure. |
* |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* |
* \return The type of the message digest. |
*/ |
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ); |
/** |
* \brief This function extracts the message-digest name from the |
* message-digest information structure. |
* |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* |
* \return The name of the message digest. |
*/ |
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ); |
/** |
* \brief This function starts a message-digest computation. |
* |
* You must call this function after setting up the context |
* with mbedtls_md_setup(), and before passing data with |
* mbedtls_md_update(). |
* |
* \param ctx The generic message-digest context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_starts( mbedtls_md_context_t *ctx ); |
/** |
* \brief This function feeds an input buffer into an ongoing |
* message-digest computation. |
* |
* You must call mbedtls_md_starts() before calling this |
* function. You may call this function multiple times. |
* Afterwards, call mbedtls_md_finish(). |
* |
* \param ctx The generic message-digest context. |
* \param input The buffer holding the input data. |
* \param ilen The length of the input data. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); |
/** |
* \brief This function finishes the digest operation, |
* and writes the result to the output buffer. |
* |
* Call this function after a call to mbedtls_md_starts(), |
* followed by any number of calls to mbedtls_md_update(). |
* Afterwards, you may either clear the context with |
* mbedtls_md_free(), or call mbedtls_md_starts() to reuse |
* the context for another digest operation with the same |
* algorithm. |
* |
* \param ctx The generic message-digest context. |
* \param output The buffer for the generic message-digest checksum result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ); |
/** |
* \brief This function calculates the message-digest of a buffer, |
* with respect to a configurable message-digest algorithm |
* in a single call. |
* |
* The result is calculated as |
* Output = message_digest(input buffer). |
* |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* \param input The buffer holding the data. |
* \param ilen The length of the input data. |
* \param output The generic message-digest checksum result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, |
unsigned char *output ); |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief This function calculates the message-digest checksum |
* result of the contents of the provided file. |
* |
* The result is calculated as |
* Output = message_digest(file contents). |
* |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* \param path The input file name. |
* \param output The generic message-digest checksum result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing |
* the file pointed by \p path. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. |
*/ |
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, |
unsigned char *output ); |
#endif /* MBEDTLS_FS_IO */ |
/** |
* \brief This function sets the HMAC key and prepares to |
* authenticate a new message. |
* |
* Call this function after mbedtls_md_setup(), to use |
* the MD context for an HMAC calculation, then call |
* mbedtls_md_hmac_update() to provide the input data, and |
* mbedtls_md_hmac_finish() to get the HMAC value. |
* |
* \param ctx The message digest context containing an embedded HMAC |
* context. |
* \param key The HMAC secret key. |
* \param keylen The length of the HMAC key in Bytes. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, |
size_t keylen ); |
/** |
* \brief This function feeds an input buffer into an ongoing HMAC |
* computation. |
* |
* Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset() |
* before calling this function. |
* You may call this function multiple times to pass the |
* input piecewise. |
* Afterwards, call mbedtls_md_hmac_finish(). |
* |
* \param ctx The message digest context containing an embedded HMAC |
* context. |
* \param input The buffer holding the input data. |
* \param ilen The length of the input data. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the HMAC operation, and writes |
* the result to the output buffer. |
* |
* Call this function after mbedtls_md_hmac_starts() and |
* mbedtls_md_hmac_update() to get the HMAC value. Afterwards |
* you may either call mbedtls_md_free() to clear the context, |
* or call mbedtls_md_hmac_reset() to reuse the context with |
* the same HMAC key. |
* |
* \param ctx The message digest context containing an embedded HMAC |
* context. |
* \param output The generic HMAC checksum result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); |
/** |
* \brief This function prepares to authenticate a new message with |
* the same key as the previous HMAC operation. |
* |
* You may call this function after mbedtls_md_hmac_finish(). |
* Afterwards call mbedtls_md_hmac_update() to pass the new |
* input. |
* |
* \param ctx The message digest context containing an embedded HMAC |
* context. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ); |
/** |
* \brief This function calculates the full generic HMAC |
* on the input buffer with the provided key. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The HMAC result is calculated as |
* output = generic HMAC(hmac key, input buffer). |
* |
* \param md_info The information structure of the message-digest algorithm |
* to use. |
* \param key The HMAC secret key. |
* \param keylen The length of the HMAC secret key in Bytes. |
* \param input The buffer holding the input data. |
* \param ilen The length of the input data. |
* \param output The generic HMAC result. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification |
* failure. |
*/ |
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, |
const unsigned char *input, size_t ilen, |
unsigned char *output ); |
/* Internal use */ |
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_MD_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/md2.h |
---|
0,0 → 1,308 |
/** |
* \file md2.h |
* |
* \brief MD2 message digest algorithm (hash function) |
* |
* \warning MD2 is considered a weak message digest and its use constitutes a |
* security risk. We recommend considering stronger message digests |
* instead. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
* |
*/ |
#ifndef MBEDTLS_MD2_H |
#define MBEDTLS_MD2_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_MD2_ALT) |
// Regular implementation |
// |
/** |
* \brief MD2 context structure |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
typedef struct mbedtls_md2_context |
{ |
unsigned char cksum[16]; /*!< checksum of the data block */ |
unsigned char state[48]; /*!< intermediate digest state */ |
unsigned char buffer[16]; /*!< data block being processed */ |
size_t left; /*!< amount of data in buffer */ |
} |
mbedtls_md2_context; |
#else /* MBEDTLS_MD2_ALT */ |
#include "md2_alt.h" |
#endif /* MBEDTLS_MD2_ALT */ |
/** |
* \brief Initialize MD2 context |
* |
* \param ctx MD2 context to be initialized |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md2_init( mbedtls_md2_context *ctx ); |
/** |
* \brief Clear MD2 context |
* |
* \param ctx MD2 context to be cleared |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md2_free( mbedtls_md2_context *ctx ); |
/** |
* \brief Clone (the state of) an MD2 context |
* |
* \param dst The destination context |
* \param src The context to be cloned |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md2_clone( mbedtls_md2_context *dst, |
const mbedtls_md2_context *src ); |
/** |
* \brief MD2 context setup |
* |
* \param ctx context to be initialized |
* |
* \return 0 if successful |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ); |
/** |
* \brief MD2 process buffer |
* |
* \param ctx MD2 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \return 0 if successful |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief MD2 final digest |
* |
* \param ctx MD2 context |
* \param output MD2 checksum result |
* |
* \return 0 if successful |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, |
unsigned char output[16] ); |
/** |
* \brief MD2 process data block (internal use only) |
* |
* \param ctx MD2 context |
* |
* \return 0 if successful |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief MD2 context setup |
* |
* \deprecated Superseded by mbedtls_md2_starts_ret() in 2.7.0 |
* |
* \param ctx context to be initialized |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx ); |
/** |
* \brief MD2 process buffer |
* |
* \deprecated Superseded by mbedtls_md2_update_ret() in 2.7.0 |
* |
* \param ctx MD2 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief MD2 final digest |
* |
* \deprecated Superseded by mbedtls_md2_finish_ret() in 2.7.0 |
* |
* \param ctx MD2 context |
* \param output MD2 checksum result |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx, |
unsigned char output[16] ); |
/** |
* \brief MD2 process data block (internal use only) |
* |
* \deprecated Superseded by mbedtls_internal_md2_process() in 2.7.0 |
* |
* \param ctx MD2 context |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Output = MD2( input buffer ) |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output MD2 checksum result |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md2_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Output = MD2( input buffer ) |
* |
* \deprecated Superseded by mbedtls_md2_ret() in 2.7.0 |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output MD2 checksum result |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
* |
* \warning MD2 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md2_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_md2.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/md4.h |
---|
0,0 → 1,313 |
/** |
* \file md4.h |
* |
* \brief MD4 message digest algorithm (hash function) |
* |
* \warning MD4 is considered a weak message digest and its use constitutes a |
* security risk. We recommend considering stronger message digests |
* instead. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
* |
*/ |
#ifndef MBEDTLS_MD4_H |
#define MBEDTLS_MD4_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_MD4_ALT) |
// Regular implementation |
// |
/** |
* \brief MD4 context structure |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
typedef struct mbedtls_md4_context |
{ |
uint32_t total[2]; /*!< number of bytes processed */ |
uint32_t state[4]; /*!< intermediate digest state */ |
unsigned char buffer[64]; /*!< data block being processed */ |
} |
mbedtls_md4_context; |
#else /* MBEDTLS_MD4_ALT */ |
#include "md4_alt.h" |
#endif /* MBEDTLS_MD4_ALT */ |
/** |
* \brief Initialize MD4 context |
* |
* \param ctx MD4 context to be initialized |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md4_init( mbedtls_md4_context *ctx ); |
/** |
* \brief Clear MD4 context |
* |
* \param ctx MD4 context to be cleared |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md4_free( mbedtls_md4_context *ctx ); |
/** |
* \brief Clone (the state of) an MD4 context |
* |
* \param dst The destination context |
* \param src The context to be cloned |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md4_clone( mbedtls_md4_context *dst, |
const mbedtls_md4_context *src ); |
/** |
* \brief MD4 context setup |
* |
* \param ctx context to be initialized |
* |
* \return 0 if successful |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
*/ |
int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ); |
/** |
* \brief MD4 process buffer |
* |
* \param ctx MD4 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \return 0 if successful |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief MD4 final digest |
* |
* \param ctx MD4 context |
* \param output MD4 checksum result |
* |
* \return 0 if successful |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, |
unsigned char output[16] ); |
/** |
* \brief MD4 process data block (internal use only) |
* |
* \param ctx MD4 context |
* \param data buffer holding one block of data |
* |
* \return 0 if successful |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, |
const unsigned char data[64] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief MD4 context setup |
* |
* \deprecated Superseded by mbedtls_md4_starts_ret() in 2.7.0 |
* |
* \param ctx context to be initialized |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx ); |
/** |
* \brief MD4 process buffer |
* |
* \deprecated Superseded by mbedtls_md4_update_ret() in 2.7.0 |
* |
* \param ctx MD4 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief MD4 final digest |
* |
* \deprecated Superseded by mbedtls_md4_finish_ret() in 2.7.0 |
* |
* \param ctx MD4 context |
* \param output MD4 checksum result |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx, |
unsigned char output[16] ); |
/** |
* \brief MD4 process data block (internal use only) |
* |
* \deprecated Superseded by mbedtls_internal_md4_process() in 2.7.0 |
* |
* \param ctx MD4 context |
* \param data buffer holding one block of data |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx, |
const unsigned char data[64] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Output = MD4( input buffer ) |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output MD4 checksum result |
* |
* \return 0 if successful |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md4_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Output = MD4( input buffer ) |
* |
* \deprecated Superseded by mbedtls_md4_ret() in 2.7.0 |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output MD4 checksum result |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
* |
* \warning MD4 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md4_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_md4.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/md5.h |
---|
0,0 → 1,313 |
/** |
* \file md5.h |
* |
* \brief MD5 message digest algorithm (hash function) |
* |
* \warning MD5 is considered a weak message digest and its use constitutes a |
* security risk. We recommend considering stronger message |
* digests instead. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_MD5_H |
#define MBEDTLS_MD5_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_MD5_ALT) |
// Regular implementation |
// |
/** |
* \brief MD5 context structure |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
typedef struct mbedtls_md5_context |
{ |
uint32_t total[2]; /*!< number of bytes processed */ |
uint32_t state[4]; /*!< intermediate digest state */ |
unsigned char buffer[64]; /*!< data block being processed */ |
} |
mbedtls_md5_context; |
#else /* MBEDTLS_MD5_ALT */ |
#include "md5_alt.h" |
#endif /* MBEDTLS_MD5_ALT */ |
/** |
* \brief Initialize MD5 context |
* |
* \param ctx MD5 context to be initialized |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md5_init( mbedtls_md5_context *ctx ); |
/** |
* \brief Clear MD5 context |
* |
* \param ctx MD5 context to be cleared |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md5_free( mbedtls_md5_context *ctx ); |
/** |
* \brief Clone (the state of) an MD5 context |
* |
* \param dst The destination context |
* \param src The context to be cloned |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
void mbedtls_md5_clone( mbedtls_md5_context *dst, |
const mbedtls_md5_context *src ); |
/** |
* \brief MD5 context setup |
* |
* \param ctx context to be initialized |
* |
* \return 0 if successful |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ); |
/** |
* \brief MD5 process buffer |
* |
* \param ctx MD5 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \return 0 if successful |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief MD5 final digest |
* |
* \param ctx MD5 context |
* \param output MD5 checksum result |
* |
* \return 0 if successful |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, |
unsigned char output[16] ); |
/** |
* \brief MD5 process data block (internal use only) |
* |
* \param ctx MD5 context |
* \param data buffer holding one block of data |
* |
* \return 0 if successful |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, |
const unsigned char data[64] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief MD5 context setup |
* |
* \deprecated Superseded by mbedtls_md5_starts_ret() in 2.7.0 |
* |
* \param ctx context to be initialized |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx ); |
/** |
* \brief MD5 process buffer |
* |
* \deprecated Superseded by mbedtls_md5_update_ret() in 2.7.0 |
* |
* \param ctx MD5 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief MD5 final digest |
* |
* \deprecated Superseded by mbedtls_md5_finish_ret() in 2.7.0 |
* |
* \param ctx MD5 context |
* \param output MD5 checksum result |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx, |
unsigned char output[16] ); |
/** |
* \brief MD5 process data block (internal use only) |
* |
* \deprecated Superseded by mbedtls_internal_md5_process() in 2.7.0 |
* |
* \param ctx MD5 context |
* \param data buffer holding one block of data |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx, |
const unsigned char data[64] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Output = MD5( input buffer ) |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output MD5 checksum result |
* |
* \return 0 if successful |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md5_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Output = MD5( input buffer ) |
* |
* \deprecated Superseded by mbedtls_md5_ret() in 2.7.0 |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output MD5 checksum result |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
* |
* \warning MD5 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
int mbedtls_md5_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_md5.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/md_internal.h |
---|
0,0 → 1,117 |
/** |
* \file md_internal.h |
* |
* \brief Message digest wrappers. |
* |
* \warning This in an internal header. Do not include directly. |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_MD_WRAP_H |
#define MBEDTLS_MD_WRAP_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "md.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Message digest information. |
* Allows message digest functions to be called in a generic way. |
*/ |
struct mbedtls_md_info_t |
{ |
/** Digest identifier */ |
mbedtls_md_type_t type; |
/** Name of the message digest */ |
const char * name; |
/** Output length of the digest function in bytes */ |
int size; |
/** Block length of the digest function in bytes */ |
int block_size; |
/** Digest initialisation function */ |
int (*starts_func)( void *ctx ); |
/** Digest update function */ |
int (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); |
/** Digest finalisation function */ |
int (*finish_func)( void *ctx, unsigned char *output ); |
/** Generic digest function */ |
int (*digest_func)( const unsigned char *input, size_t ilen, |
unsigned char *output ); |
/** Allocate a new context */ |
void * (*ctx_alloc_func)( void ); |
/** Free the given context */ |
void (*ctx_free_func)( void *ctx ); |
/** Clone state from a context */ |
void (*clone_func)( void *dst, const void *src ); |
/** Internal use only */ |
int (*process_func)( void *ctx, const unsigned char *input ); |
}; |
#if defined(MBEDTLS_MD2_C) |
extern const mbedtls_md_info_t mbedtls_md2_info; |
#endif |
#if defined(MBEDTLS_MD4_C) |
extern const mbedtls_md_info_t mbedtls_md4_info; |
#endif |
#if defined(MBEDTLS_MD5_C) |
extern const mbedtls_md_info_t mbedtls_md5_info; |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
extern const mbedtls_md_info_t mbedtls_ripemd160_info; |
#endif |
#if defined(MBEDTLS_SHA1_C) |
extern const mbedtls_md_info_t mbedtls_sha1_info; |
#endif |
#if defined(MBEDTLS_SHA256_C) |
extern const mbedtls_md_info_t mbedtls_sha224_info; |
extern const mbedtls_md_info_t mbedtls_sha256_info; |
#endif |
#if defined(MBEDTLS_SHA512_C) |
extern const mbedtls_md_info_t mbedtls_sha384_info; |
extern const mbedtls_md_info_t mbedtls_sha512_info; |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_MD_WRAP_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/memory_buffer_alloc.h |
---|
0,0 → 1,153 |
/** |
* \file memory_buffer_alloc.h |
* |
* \brief Buffer-based memory allocator |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H |
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE) |
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ |
#endif |
/* \} name SECTION: Module settings */ |
#define MBEDTLS_MEMORY_VERIFY_NONE 0 |
#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0) |
#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1) |
#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | MBEDTLS_MEMORY_VERIFY_FREE) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Initialize use of stack-based memory allocator. |
* The stack-based allocator does memory management inside the |
* presented buffer and does not call calloc() and free(). |
* It sets the global mbedtls_calloc() and mbedtls_free() pointers |
* to its own functions. |
* (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if |
* MBEDTLS_THREADING_C is defined) |
* |
* \note This code is not optimized and provides a straight-forward |
* implementation of a stack-based memory allocator. |
* |
* \param buf buffer to use as heap |
* \param len size of the buffer |
*/ |
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ); |
/** |
* \brief Free the mutex for thread-safety and clear remaining memory |
*/ |
void mbedtls_memory_buffer_alloc_free( void ); |
/** |
* \brief Determine when the allocator should automatically verify the state |
* of the entire chain of headers / meta-data. |
* (Default: MBEDTLS_MEMORY_VERIFY_NONE) |
* |
* \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC, |
* MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS |
*/ |
void mbedtls_memory_buffer_set_verify( int verify ); |
#if defined(MBEDTLS_MEMORY_DEBUG) |
/** |
* \brief Print out the status of the allocated memory (primarily for use |
* after a program should have de-allocated all memory) |
* Prints out a list of 'still allocated' blocks and their stack |
* trace if MBEDTLS_MEMORY_BACKTRACE is defined. |
*/ |
void mbedtls_memory_buffer_alloc_status( void ); |
/** |
* \brief Get the peak heap usage so far |
* |
* \param max_used Peak number of bytes in use or committed. This |
* includes bytes in allocated blocks too small to split |
* into smaller blocks but larger than the requested size. |
* \param max_blocks Peak number of blocks in use, including free and used |
*/ |
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ); |
/** |
* \brief Reset peak statistics |
*/ |
void mbedtls_memory_buffer_alloc_max_reset( void ); |
/** |
* \brief Get the current heap usage |
* |
* \param cur_used Current number of bytes in use or committed. This |
* includes bytes in allocated blocks too small to split |
* into smaller blocks but larger than the requested size. |
* \param cur_blocks Current number of blocks in use, including free and used |
*/ |
void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ); |
#endif /* MBEDTLS_MEMORY_DEBUG */ |
/** |
* \brief Verifies that all headers in the memory buffer are correct |
* and contain sane values. Helps debug buffer-overflow errors. |
* |
* Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined. |
* Prints out full header information if MBEDTLS_MEMORY_DEBUG |
* is defined. (Includes stack trace information for each block if |
* MBEDTLS_MEMORY_BACKTRACE is defined as well). |
* |
* \return 0 if verified, 1 otherwise |
*/ |
int mbedtls_memory_buffer_alloc_verify( void ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if a test failed |
*/ |
int mbedtls_memory_buffer_alloc_self_test( int verbose ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* memory_buffer_alloc.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/net.h |
---|
0,0 → 1,39 |
/** |
* \file net.h |
* |
* \brief Deprecated header file that includes net_sockets.h |
* |
* \deprecated Superseded by mbedtls/net_sockets.h |
*/ |
/* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#include "net_sockets.h" |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" |
#endif /* MBEDTLS_DEPRECATED_WARNING */ |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/net_sockets.h |
---|
0,0 → 1,273 |
/** |
* \file net_sockets.h |
* |
* \brief Network sockets abstraction layer to integrate Mbed TLS into a |
* BSD-style sockets API. |
* |
* The network sockets module provides an example integration of the |
* Mbed TLS library into a BSD sockets implementation. The module is |
* intended to be an example of how Mbed TLS can be integrated into a |
* networking stack, as well as to be Mbed TLS's network integration |
* for its supported platforms. |
* |
* The module is intended only to be used with the Mbed TLS library and |
* is not intended to be used by third party application software |
* directly. |
* |
* The supported platforms are as follows: |
* * Microsoft Windows and Windows CE |
* * POSIX/Unix platforms including Linux, OS X |
* |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_NET_SOCKETS_H |
#define MBEDTLS_NET_SOCKETS_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ssl.h" |
#include <stddef.h> |
#include <stdint.h> |
#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ |
#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ |
#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ |
#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ |
#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ |
#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ |
#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ |
#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ |
#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ |
#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ |
#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ |
#define MBEDTLS_ERR_NET_POLL_FAILED -0x0047 /**< Polling the net context failed. */ |
#define MBEDTLS_ERR_NET_BAD_INPUT_DATA -0x0049 /**< Input invalid. */ |
#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ |
#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ |
#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ |
#define MBEDTLS_NET_POLL_READ 1 /**< Used in \c mbedtls_net_poll to check for pending data */ |
#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Wrapper type for sockets. |
* |
* Currently backed by just a file descriptor, but might be more in the future |
* (eg two file descriptors for combined IPv4 + IPv6 support, or additional |
* structures for hand-made UDP demultiplexing). |
*/ |
typedef struct mbedtls_net_context |
{ |
int fd; /**< The underlying file descriptor */ |
} |
mbedtls_net_context; |
/** |
* \brief Initialize a context |
* Just makes the context ready to be used or freed safely. |
* |
* \param ctx Context to initialize |
*/ |
void mbedtls_net_init( mbedtls_net_context *ctx ); |
/** |
* \brief Initiate a connection with host:port in the given protocol |
* |
* \param ctx Socket to use |
* \param host Host to connect to |
* \param port Port to connect to |
* \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP |
* |
* \return 0 if successful, or one of: |
* MBEDTLS_ERR_NET_SOCKET_FAILED, |
* MBEDTLS_ERR_NET_UNKNOWN_HOST, |
* MBEDTLS_ERR_NET_CONNECT_FAILED |
* |
* \note Sets the socket in connected mode even with UDP. |
*/ |
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); |
/** |
* \brief Create a receiving socket on bind_ip:port in the chosen |
* protocol. If bind_ip == NULL, all interfaces are bound. |
* |
* \param ctx Socket to use |
* \param bind_ip IP to bind to, can be NULL |
* \param port Port number to use |
* \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP |
* |
* \return 0 if successful, or one of: |
* MBEDTLS_ERR_NET_SOCKET_FAILED, |
* MBEDTLS_ERR_NET_BIND_FAILED, |
* MBEDTLS_ERR_NET_LISTEN_FAILED |
* |
* \note Regardless of the protocol, opens the sockets and binds it. |
* In addition, make the socket listening if protocol is TCP. |
*/ |
/*int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto );*/ |
/** |
* \brief Accept a connection from a remote client |
* |
* \param bind_ctx Relevant socket |
* \param client_ctx Will contain the connected client socket |
* \param client_ip Will contain the client IP address, can be NULL |
* \param buf_size Size of the client_ip buffer |
* \param ip_len Will receive the size of the client IP written, |
* can be NULL if client_ip is null |
* |
* \return 0 if successful, or |
* MBEDTLS_ERR_NET_ACCEPT_FAILED, or |
* MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, |
* MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to |
* non-blocking and accept() would block. |
*/ |
/*int mbedtls_net_accept( mbedtls_net_context *bind_ctx, |
mbedtls_net_context *client_ctx, |
void *client_ip, size_t buf_size, size_t *ip_len );*/ |
/** |
* \brief Check and wait for the context to be ready for read/write |
* |
* \param ctx Socket to check |
* \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and |
* MBEDTLS_NET_POLL_WRITE specifying the events |
* to wait for: |
* - If MBEDTLS_NET_POLL_READ is set, the function |
* will return as soon as the net context is available |
* for reading. |
* - If MBEDTLS_NET_POLL_WRITE is set, the function |
* will return as soon as the net context is available |
* for writing. |
* \param timeout Maximal amount of time to wait before returning, |
* in milliseconds. If \c timeout is zero, the |
* function returns immediately. If \c timeout is |
* -1u, the function blocks potentially indefinitely. |
* |
* \return Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE |
* on success or timeout, or a negative return code otherwise. |
*/ |
/*int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout );*/ |
/** |
* \brief Set the socket blocking |
* |
* \param ctx Socket to set |
* |
* \return 0 if successful, or a non-zero error code |
*/ |
/*int mbedtls_net_set_block( mbedtls_net_context *ctx );*/ |
/** |
* \brief Set the socket non-blocking |
* |
* \param ctx Socket to set |
* |
* \return 0 if successful, or a non-zero error code |
*/ |
/*int mbedtls_net_set_nonblock( mbedtls_net_context *ctx );*/ |
/** |
* \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 mbedtls_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 the number of bytes received, |
* or a non-zero error code; with a non-blocking socket, |
* MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. |
*/ |
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t 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 the number of bytes sent, |
* or a non-zero error code; with a non-blocking socket, |
* MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. |
*/ |
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); |
/** |
* \brief Read at most 'len' characters, blocking for at most |
* 'timeout' seconds. 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 |
* \param timeout Maximum number of milliseconds to wait for data |
* 0 means no timeout (wait forever) |
* |
* \return the number of bytes received, |
* or a non-zero error code: |
* MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, |
* MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. |
* |
* \note This function will block (until data becomes available or |
* timeout is reached) even if the socket is set to |
* non-blocking. Handling timeouts with non-blocking reads |
* requires a different strategy. |
*/ |
/*int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, |
uint32_t timeout );*/ |
/** |
* \brief Gracefully shutdown the connection and free associated data |
* |
* \param ctx The context to free |
*/ |
void mbedtls_net_free( mbedtls_net_context *ctx ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* net_sockets.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/nist_kw.h |
---|
0,0 → 1,186 |
/** |
* \file nist_kw.h |
* |
* \brief This file provides an API for key wrapping (KW) and key wrapping with |
* padding (KWP) as defined in NIST SP 800-38F. |
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf |
* |
* Key wrapping specifies a deterministic authenticated-encryption mode |
* of operation, according to <em>NIST SP 800-38F: Recommendation for |
* Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its |
* purpose is to protect cryptographic keys. |
* |
* Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP. |
* https://tools.ietf.org/html/rfc3394 |
* https://tools.ietf.org/html/rfc5649 |
* |
*/ |
/* |
* Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_NIST_KW_H |
#define MBEDTLS_NIST_KW_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "cipher.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
typedef enum |
{ |
MBEDTLS_KW_MODE_KW = 0, |
MBEDTLS_KW_MODE_KWP = 1 |
} mbedtls_nist_kw_mode_t; |
#if !defined(MBEDTLS_NIST_KW_ALT) |
// Regular implementation |
// |
/** |
* \brief The key wrapping context-type definition. The key wrapping context is passed |
* to the APIs called. |
* |
* \note The definition of this type may change in future library versions. |
* Don't make any assumptions on this context! |
*/ |
typedef struct { |
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ |
} mbedtls_nist_kw_context; |
#else /* MBEDTLS_NIST_key wrapping_ALT */ |
#include "nist_kw_alt.h" |
#endif /* MBEDTLS_NIST_KW_ALT */ |
/** |
* \brief This function initializes the specified key wrapping context |
* to make references valid and prepare the context |
* for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free(). |
* |
* \param ctx The key wrapping context to initialize. |
* |
*/ |
void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ); |
/** |
* \brief This function initializes the key wrapping context set in the |
* \p ctx parameter and sets the encryption key. |
* |
* \param ctx The key wrapping context. |
* \param cipher The 128-bit block cipher to use. Only AES is supported. |
* \param key The Key Encryption Key (KEK). |
* \param keybits The KEK size in bits. This must be acceptable by the cipher. |
* \param is_wrap Specify whether the operation within the context is wrapping or unwrapping |
* |
* \return \c 0 on success. |
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input. |
* \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers |
* which are not supported. |
* \return cipher-specific error code on failure of the underlying cipher. |
*/ |
int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, |
mbedtls_cipher_id_t cipher, |
const unsigned char *key, |
unsigned int keybits, |
const int is_wrap ); |
/** |
* \brief This function releases and clears the specified key wrapping context |
* and underlying cipher sub-context. |
* |
* \param ctx The key wrapping context to clear. |
*/ |
void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ); |
/** |
* \brief This function encrypts a buffer using key wrapping. |
* |
* \param ctx The key wrapping context to use for encryption. |
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) |
* \param input The buffer holding the input data. |
* \param in_len The length of the input data in Bytes. |
* The input uses units of 8 Bytes called semiblocks. |
* <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li> |
* <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul> |
* \param[out] output The buffer holding the output data. |
* <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li> |
* <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of |
* 8 bytes for KWP (15 bytes at most).</li></ul> |
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. |
* \param[in] out_size The capacity of the output buffer. |
* |
* \return \c 0 on success. |
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. |
* \return cipher-specific error code on failure of the underlying cipher. |
*/ |
int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, |
const unsigned char *input, size_t in_len, |
unsigned char *output, size_t* out_len, size_t out_size ); |
/** |
* \brief This function decrypts a buffer using key wrapping. |
* |
* \param ctx The key wrapping context to use for decryption. |
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) |
* \param input The buffer holding the input data. |
* \param in_len The length of the input data in Bytes. |
* The input uses units of 8 Bytes called semiblocks. |
* The input must be a multiple of semiblocks. |
* <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li> |
* <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul> |
* \param[out] output The buffer holding the output data. |
* The output buffer's minimal length is 8 bytes shorter than \p in_len. |
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. |
* For KWP mode, the length could be up to 15 bytes shorter than \p in_len, |
* depending on how much padding was added to the data. |
* \param[in] out_size The capacity of the output buffer. |
* |
* \return \c 0 on success. |
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. |
* \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext. |
* \return cipher-specific error code on failure of the underlying cipher. |
*/ |
int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, |
const unsigned char *input, size_t in_len, |
unsigned char *output, size_t* out_len, size_t out_size); |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
/** |
* \brief The key wrapping checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_nist_kw_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_NIST_KW_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/oid.h |
---|
0,0 → 1,607 |
/** |
* \file oid.h |
* |
* \brief Object Identifier (OID) database |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_OID_H |
#define MBEDTLS_OID_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "asn1.h" |
#include "pk.h" |
#include <stddef.h> |
#if defined(MBEDTLS_CIPHER_C) |
#include "cipher.h" |
#endif |
#if defined(MBEDTLS_MD_C) |
#include "md.h" |
#endif |
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) |
#include "x509.h" |
#endif |
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */ |
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */ |
/* |
* Top level OID tuples |
*/ |
#define MBEDTLS_OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */ |
#define MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */ |
#define MBEDTLS_OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */ |
#define MBEDTLS_OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */ |
/* |
* ISO Member bodies OID parts |
*/ |
#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */ |
#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */ |
#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \ |
MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */ |
#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */ |
#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \ |
MBEDTLS_OID_ORG_ANSI_X9_62 |
/* |
* ISO Identified organization OID parts |
*/ |
#define MBEDTLS_OID_ORG_DOD "\x06" /* {dod(6)} */ |
#define MBEDTLS_OID_ORG_OIW "\x0e" |
#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03" |
#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02" |
#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a" |
#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */ |
#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_CERTICOM |
#define MBEDTLS_OID_ORG_TELETRUST "\x24" /* teletrust(36) */ |
#define MBEDTLS_OID_TELETRUST MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_TELETRUST |
/* |
* ISO ITU OID parts |
*/ |
#define MBEDTLS_OID_ORGANIZATION "\x01" /* {organization(1)} */ |
#define MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_COUNTRY MBEDTLS_OID_COUNTRY_US MBEDTLS_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */ |
#define MBEDTLS_OID_ORG_GOV "\x65" /* {gov(101)} */ |
#define MBEDTLS_OID_GOV MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */ |
#define MBEDTLS_OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */ |
#define MBEDTLS_OID_NETSCAPE MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */ |
/* ISO arc for standard certificate and CRL extensions */ |
#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */ |
#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */ |
/** |
* Private Internet Extensions |
* { iso(1) identified-organization(3) dod(6) internet(1) |
* security(5) mechanisms(5) pkix(7) } |
*/ |
#define MBEDTLS_OID_PKIX MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x05\x05\x07" |
/* |
* Arc for standard naming attributes |
*/ |
#define MBEDTLS_OID_AT MBEDTLS_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */ |
#define MBEDTLS_OID_AT_CN MBEDTLS_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */ |
#define MBEDTLS_OID_AT_SUR_NAME MBEDTLS_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */ |
#define MBEDTLS_OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */ |
#define MBEDTLS_OID_AT_COUNTRY MBEDTLS_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */ |
#define MBEDTLS_OID_AT_LOCALITY MBEDTLS_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */ |
#define MBEDTLS_OID_AT_STATE MBEDTLS_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */ |
#define MBEDTLS_OID_AT_ORGANIZATION MBEDTLS_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */ |
#define MBEDTLS_OID_AT_ORG_UNIT MBEDTLS_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */ |
#define MBEDTLS_OID_AT_TITLE MBEDTLS_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */ |
#define MBEDTLS_OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */ |
#define MBEDTLS_OID_AT_POSTAL_CODE MBEDTLS_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */ |
#define MBEDTLS_OID_AT_GIVEN_NAME MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */ |
#define MBEDTLS_OID_AT_INITIALS MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */ |
#define MBEDTLS_OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */ |
#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */ |
#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */ |
#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */ |
#define MBEDTLS_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */ |
/* |
* OIDs for standard certificate extensions |
*/ |
#define MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */ |
#define MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */ |
#define MBEDTLS_OID_KEY_USAGE MBEDTLS_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */ |
#define MBEDTLS_OID_CERTIFICATE_POLICIES MBEDTLS_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */ |
#define MBEDTLS_OID_POLICY_MAPPINGS MBEDTLS_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */ |
#define MBEDTLS_OID_SUBJECT_ALT_NAME MBEDTLS_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */ |
#define MBEDTLS_OID_ISSUER_ALT_NAME MBEDTLS_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */ |
#define MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */ |
#define MBEDTLS_OID_BASIC_CONSTRAINTS MBEDTLS_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */ |
#define MBEDTLS_OID_NAME_CONSTRAINTS MBEDTLS_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */ |
#define MBEDTLS_OID_POLICY_CONSTRAINTS MBEDTLS_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */ |
#define MBEDTLS_OID_EXTENDED_KEY_USAGE MBEDTLS_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */ |
#define MBEDTLS_OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */ |
#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */ |
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */ |
/* |
* Netscape certificate extensions |
*/ |
#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01" |
#define MBEDTLS_OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT "\x01" |
#define MBEDTLS_OID_NS_BASE_URL MBEDTLS_OID_NS_CERT "\x02" |
#define MBEDTLS_OID_NS_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x03" |
#define MBEDTLS_OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x04" |
#define MBEDTLS_OID_NS_RENEWAL_URL MBEDTLS_OID_NS_CERT "\x07" |
#define MBEDTLS_OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CERT "\x08" |
#define MBEDTLS_OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_CERT "\x0C" |
#define MBEDTLS_OID_NS_COMMENT MBEDTLS_OID_NS_CERT "\x0D" |
#define MBEDTLS_OID_NS_DATA_TYPE MBEDTLS_OID_NETSCAPE "\x02" |
#define MBEDTLS_OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_DATA_TYPE "\x05" |
/* |
* OIDs for CRL extensions |
*/ |
#define MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_ID_CE "\x10" |
#define MBEDTLS_OID_CRL_NUMBER MBEDTLS_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */ |
/* |
* X.509 v3 Extended key usage OIDs |
*/ |
#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */ |
#define MBEDTLS_OID_KP MBEDTLS_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */ |
#define MBEDTLS_OID_SERVER_AUTH MBEDTLS_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */ |
#define MBEDTLS_OID_CLIENT_AUTH MBEDTLS_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */ |
#define MBEDTLS_OID_CODE_SIGNING MBEDTLS_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */ |
#define MBEDTLS_OID_EMAIL_PROTECTION MBEDTLS_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */ |
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */ |
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */ |
/* |
* PKCS definition OIDs |
*/ |
#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */ |
#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */ |
#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */ |
#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */ |
#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */ |
/* |
* PKCS#1 OIDs |
*/ |
#define MBEDTLS_OID_PKCS1_RSA MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ |
#define MBEDTLS_OID_PKCS1_MD2 MBEDTLS_OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */ |
#define MBEDTLS_OID_PKCS1_MD4 MBEDTLS_OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */ |
#define MBEDTLS_OID_PKCS1_MD5 MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */ |
#define MBEDTLS_OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */ |
#define MBEDTLS_OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */ |
#define MBEDTLS_OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */ |
#define MBEDTLS_OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */ |
#define MBEDTLS_OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */ |
#define MBEDTLS_OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D" |
#define MBEDTLS_OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */ |
/* RFC 4055 */ |
#define MBEDTLS_OID_RSASSA_PSS MBEDTLS_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */ |
#define MBEDTLS_OID_MGF1 MBEDTLS_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */ |
/* |
* Digest algorithms |
*/ |
#define MBEDTLS_OID_DIGEST_ALG_MD2 MBEDTLS_OID_RSA_COMPANY "\x02\x02" /**< id-mbedtls_md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */ |
#define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */ |
#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ |
#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ |
#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ |
#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ |
#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ |
#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ |
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ |
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */ |
#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */ |
#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */ |
#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */ |
/* |
* Encryption algorithms |
*/ |
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */ |
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */ |
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */ |
/* |
* Key Wrapping algorithms |
*/ |
/* |
* RFC 5649 |
*/ |
#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ |
#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */ |
#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ |
#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */ |
#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ |
#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */ |
/* |
* PKCS#5 OIDs |
*/ |
#define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */ |
#define MBEDTLS_OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */ |
#define MBEDTLS_OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */ |
/* |
* PKCS#5 PBES1 algorithms |
*/ |
#define MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */ |
#define MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */ |
#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */ |
#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */ |
#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */ |
#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */ |
/* |
* PKCS#8 OIDs |
*/ |
#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */ |
/* |
* PKCS#12 PBE OIDs |
*/ |
#define MBEDTLS_OID_PKCS12_PBE MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */ |
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */ |
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */ |
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */ |
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */ |
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */ |
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */ |
/* |
* EC key algorithms from RFC 5480 |
*/ |
/* id-ecPublicKey OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */ |
#define MBEDTLS_OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_ANSI_X9_62 "\x02\01" |
/* id-ecDH OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) |
* schemes(1) ecdh(12) } */ |
#define MBEDTLS_OID_EC_ALG_ECDH MBEDTLS_OID_CERTICOM "\x01\x0c" |
/* |
* ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2 |
*/ |
/* secp192r1 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */ |
#define MBEDTLS_OID_EC_GRP_SECP192R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x01" |
/* secp224r1 OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) curve(0) 33 } */ |
#define MBEDTLS_OID_EC_GRP_SECP224R1 MBEDTLS_OID_CERTICOM "\x00\x21" |
/* secp256r1 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */ |
#define MBEDTLS_OID_EC_GRP_SECP256R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x07" |
/* secp384r1 OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) curve(0) 34 } */ |
#define MBEDTLS_OID_EC_GRP_SECP384R1 MBEDTLS_OID_CERTICOM "\x00\x22" |
/* secp521r1 OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) curve(0) 35 } */ |
#define MBEDTLS_OID_EC_GRP_SECP521R1 MBEDTLS_OID_CERTICOM "\x00\x23" |
/* secp192k1 OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) curve(0) 31 } */ |
#define MBEDTLS_OID_EC_GRP_SECP192K1 MBEDTLS_OID_CERTICOM "\x00\x1f" |
/* secp224k1 OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) curve(0) 32 } */ |
#define MBEDTLS_OID_EC_GRP_SECP224K1 MBEDTLS_OID_CERTICOM "\x00\x20" |
/* secp256k1 OBJECT IDENTIFIER ::= { |
* iso(1) identified-organization(3) certicom(132) curve(0) 10 } */ |
#define MBEDTLS_OID_EC_GRP_SECP256K1 MBEDTLS_OID_CERTICOM "\x00\x0a" |
/* RFC 5639 4.1 |
* ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1) |
* identified-organization(3) teletrust(36) algorithm(3) signature- |
* algorithm(3) ecSign(2) 8} |
* ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1} |
* versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */ |
#define MBEDTLS_OID_EC_BRAINPOOL_V1 MBEDTLS_OID_TELETRUST "\x03\x03\x02\x08\x01\x01" |
/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */ |
#define MBEDTLS_OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x07" |
/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */ |
#define MBEDTLS_OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0B" |
/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */ |
#define MBEDTLS_OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0D" |
/* |
* SEC1 C.1 |
* |
* prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } |
* id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)} |
*/ |
#define MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62 "\x01" |
#define MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE "\x01" |
/* |
* ECDSA signature identifiers, from RFC 5480 |
*/ |
#define MBEDTLS_OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62 "\x04" /* signatures(4) */ |
#define MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */ |
/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */ |
#define MBEDTLS_OID_ECDSA_SHA1 MBEDTLS_OID_ANSI_X9_62_SIG "\x01" |
/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) |
* ecdsa-with-SHA2(3) 1 } */ |
#define MBEDTLS_OID_ECDSA_SHA224 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x01" |
/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) |
* ecdsa-with-SHA2(3) 2 } */ |
#define MBEDTLS_OID_ECDSA_SHA256 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x02" |
/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) |
* ecdsa-with-SHA2(3) 3 } */ |
#define MBEDTLS_OID_ECDSA_SHA384 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x03" |
/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { |
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) |
* ecdsa-with-SHA2(3) 4 } */ |
#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Base OID descriptor structure |
*/ |
typedef struct mbedtls_oid_descriptor_t |
{ |
const char *asn1; /*!< OID ASN.1 representation */ |
size_t asn1_len; /*!< length of asn1 */ |
const char *name; /*!< official name (e.g. from RFC) */ |
const char *description; /*!< human friendly description */ |
} mbedtls_oid_descriptor_t; |
/** |
* \brief Translate an ASN.1 OID into its numeric representation |
* (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549") |
* |
* \param buf buffer to put representation in |
* \param size size of the buffer |
* \param oid OID to translate |
* |
* \return Length of the string written (excluding final NULL) or |
* MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error |
*/ |
int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid ); |
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) |
/** |
* \brief Translate an X.509 extension OID into local values |
* |
* \param oid OID to use |
* \param ext_type place to store the extension type |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type ); |
#endif |
/** |
* \brief Translate an X.509 attribute type OID into the short name |
* (e.g. the OID for an X520 Common Name into "CN") |
* |
* \param oid OID to use |
* \param short_name place to store the string pointer |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_attr_short_name( const mbedtls_asn1_buf *oid, const char **short_name ); |
/** |
* \brief Translate PublicKeyAlgorithm OID into pk_type |
* |
* \param oid OID to use |
* \param pk_alg place to store public key algorithm |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg ); |
/** |
* \brief Translate pk_type into PublicKeyAlgorithm OID |
* |
* \param pk_alg Public key type to look for |
* \param oid place to store ASN.1 OID string pointer |
* \param olen length of the OID |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg, |
const char **oid, size_t *olen ); |
#if defined(MBEDTLS_ECP_C) |
/** |
* \brief Translate NamedCurve OID into an EC group identifier |
* |
* \param oid OID to use |
* \param grp_id place to store group id |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id ); |
/** |
* \brief Translate EC group identifier into NamedCurve OID |
* |
* \param grp_id EC group identifier |
* \param oid place to store ASN.1 OID string pointer |
* \param olen length of the OID |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id, |
const char **oid, size_t *olen ); |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_MD_C) |
/** |
* \brief Translate SignatureAlgorithm OID into md_type and pk_type |
* |
* \param oid OID to use |
* \param md_alg place to store message digest algorithm |
* \param pk_alg place to store public key algorithm |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_sig_alg( const mbedtls_asn1_buf *oid, |
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg ); |
/** |
* \brief Translate SignatureAlgorithm OID into description |
* |
* \param oid OID to use |
* \param desc place to store string pointer |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_sig_alg_desc( const mbedtls_asn1_buf *oid, const char **desc ); |
/** |
* \brief Translate md_type and pk_type into SignatureAlgorithm OID |
* |
* \param md_alg message digest algorithm |
* \param pk_alg public key algorithm |
* \param oid place to store ASN.1 OID string pointer |
* \param olen length of the OID |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, |
const char **oid, size_t *olen ); |
/** |
* \brief Translate hash algorithm OID into md_type |
* |
* \param oid OID to use |
* \param md_alg place to store message digest algorithm |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg ); |
/** |
* \brief Translate hmac algorithm OID into md_type |
* |
* \param oid OID to use |
* \param md_hmac place to store message hmac algorithm |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac ); |
#endif /* MBEDTLS_MD_C */ |
/** |
* \brief Translate Extended Key Usage OID into description |
* |
* \param oid OID to use |
* \param desc place to store string pointer |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc ); |
/** |
* \brief Translate md_type into hash algorithm OID |
* |
* \param md_alg message digest algorithm |
* \param oid place to store ASN.1 OID string pointer |
* \param olen length of the OID |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_oid_by_md( mbedtls_md_type_t md_alg, const char **oid, size_t *olen ); |
#if defined(MBEDTLS_CIPHER_C) |
/** |
* \brief Translate encryption algorithm OID into cipher_type |
* |
* \param oid OID to use |
* \param cipher_alg place to store cipher algorithm |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_cipher_alg( const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg ); |
#endif /* MBEDTLS_CIPHER_C */ |
#if defined(MBEDTLS_PKCS12_C) |
/** |
* \brief Translate PKCS#12 PBE algorithm OID into md_type and |
* cipher_type |
* |
* \param oid OID to use |
* \param md_alg place to store message digest algorithm |
* \param cipher_alg place to store cipher algorithm |
* |
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND |
*/ |
int mbedtls_oid_get_pkcs12_pbe_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg, |
mbedtls_cipher_type_t *cipher_alg ); |
#endif /* MBEDTLS_PKCS12_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* oid.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/padlock.h |
---|
0,0 → 1,128 |
/** |
* \file padlock.h |
* |
* \brief VIA PadLock ACE for HW encryption/decryption supported by some |
* processors |
* |
* \warning These functions are only for internal use by other library |
* functions; you must not call them directly. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PADLOCK_H |
#define MBEDTLS_PADLOCK_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "aes.h" |
#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ |
#if defined(__has_feature) |
#if __has_feature(address_sanitizer) |
#define MBEDTLS_HAVE_ASAN |
#endif |
#endif |
/* Some versions of ASan result in errors about not enough registers */ |
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \ |
!defined(MBEDTLS_HAVE_ASAN) |
#ifndef MBEDTLS_HAVE_X86 |
#define MBEDTLS_HAVE_X86 |
#endif |
#include <stdint.h> |
#define MBEDTLS_PADLOCK_RNG 0x000C |
#define MBEDTLS_PADLOCK_ACE 0x00C0 |
#define MBEDTLS_PADLOCK_PHE 0x0C00 |
#define MBEDTLS_PADLOCK_PMM 0x3000 |
#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15)) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Internal PadLock detection routine |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param feature The feature to detect |
* |
* \return 1 if CPU has support for the feature, 0 otherwise |
*/ |
int mbedtls_padlock_has_support( int feature ); |
/** |
* \brief Internal PadLock AES-ECB block en(de)cryption |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param ctx AES context |
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT |
* \param input 16-byte input block |
* \param output 16-byte output block |
* |
* \return 0 if success, 1 if operation failed |
*/ |
int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ); |
/** |
* \brief Internal PadLock AES-CBC buffer en(de)cryption |
* |
* \note This function is only for internal use by other library |
* functions; you must not call it directly. |
* |
* \param ctx AES context |
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_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 mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* HAVE_X86 */ |
#endif /* padlock.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/pem.h |
---|
0,0 → 1,138 |
/** |
* \file pem.h |
* |
* \brief Privacy Enhanced Mail (PEM) decoding |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PEM_H |
#define MBEDTLS_PEM_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
/** |
* \name PEM Error codes |
* These error codes are returned in case of errors reading the |
* PEM data. |
* \{ |
*/ |
#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */ |
#define MBEDTLS_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */ |
#define MBEDTLS_ERR_PEM_ALLOC_FAILED -0x1180 /**< Failed to allocate memory. */ |
#define MBEDTLS_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */ |
#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */ |
#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */ |
#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */ |
#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */ |
#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */ |
/* \} name */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) |
/** |
* \brief PEM context structure |
*/ |
typedef struct mbedtls_pem_context |
{ |
unsigned char *buf; /*!< buffer for decoded data */ |
size_t buflen; /*!< length of the buffer */ |
unsigned char *info; /*!< buffer for extra header information */ |
} |
mbedtls_pem_context; |
/** |
* \brief PEM context setup |
* |
* \param ctx context to be initialized |
*/ |
void mbedtls_pem_init( mbedtls_pem_context *ctx ); |
/** |
* \brief Read a buffer for PEM information and store the resulting |
* data into the specified context buffers. |
* |
* \param ctx context to use |
* \param header header string to seek and expect |
* \param footer footer string to seek and expect |
* \param data source data to look in (must be nul-terminated) |
* \param pwd password for decryption (can be NULL) |
* \param pwdlen length of password |
* \param use_len destination for total length used (set after header is |
* correctly read, so unless you get |
* MBEDTLS_ERR_PEM_BAD_INPUT_DATA or |
* MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is |
* the length to skip) |
* |
* \note Attempts to check password correctness by verifying if |
* the decrypted text starts with an ASN.1 sequence of |
* appropriate length |
* |
* \return 0 on success, or a specific PEM error code |
*/ |
int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer, |
const unsigned char *data, |
const unsigned char *pwd, |
size_t pwdlen, size_t *use_len ); |
/** |
* \brief PEM context memory freeing |
* |
* \param ctx context to be freed |
*/ |
void mbedtls_pem_free( mbedtls_pem_context *ctx ); |
#endif /* MBEDTLS_PEM_PARSE_C */ |
#if defined(MBEDTLS_PEM_WRITE_C) |
/** |
* \brief Write a buffer of PEM information from a DER encoded |
* buffer. |
* |
* \param header header string to write |
* \param footer footer string to write |
* \param der_data DER data to write |
* \param der_len length of the DER data |
* \param buf buffer to write to |
* \param buf_len length of output buffer |
* \param olen total length written / required (if buf_len is not enough) |
* |
* \return 0 on success, or a specific PEM or BASE64 error code. On |
* MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required |
* size. |
*/ |
int mbedtls_pem_write_buffer( const char *header, const char *footer, |
const unsigned char *der_data, size_t der_len, |
unsigned char *buf, size_t buf_len, size_t *olen ); |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* pem.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/pk.h |
---|
0,0 → 1,757 |
/** |
* \file pk.h |
* |
* \brief Public Key abstraction layer |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PK_H |
#define MBEDTLS_PK_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "md.h" |
#if defined(MBEDTLS_RSA_C) |
#include "rsa.h" |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "ecp.h" |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
#include "ecdsa.h" |
#endif |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */ |
#define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */ |
#define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_PK_FILE_IO_ERROR -0x3E00 /**< Read/write of file failed. */ |
#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80 /**< Unsupported key version */ |
#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT -0x3D00 /**< Invalid key tag or value. */ |
#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -0x3C80 /**< Key algorithm is unsupported (only RSA and EC are supported). */ |
#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED -0x3C00 /**< Private key password can't be empty. */ |
#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH -0x3B80 /**< Given private key password does not allow for correct decryption. */ |
#define MBEDTLS_ERR_PK_INVALID_PUBKEY -0x3B00 /**< The pubkey tag or value is invalid (only RSA and EC are supported). */ |
#define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 /**< The algorithm tag or value is invalid. */ |
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */ |
#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ |
#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */ |
/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Public key types |
*/ |
typedef enum { |
MBEDTLS_PK_NONE=0, |
MBEDTLS_PK_RSA, |
MBEDTLS_PK_ECKEY, |
MBEDTLS_PK_ECKEY_DH, |
MBEDTLS_PK_ECDSA, |
MBEDTLS_PK_RSA_ALT, |
MBEDTLS_PK_RSASSA_PSS, |
} mbedtls_pk_type_t; |
/** |
* \brief Options for RSASSA-PSS signature verification. |
* See \c mbedtls_rsa_rsassa_pss_verify_ext() |
*/ |
typedef struct mbedtls_pk_rsassa_pss_options |
{ |
mbedtls_md_type_t mgf1_hash_id; |
int expected_salt_len; |
} mbedtls_pk_rsassa_pss_options; |
/** |
* \brief Types for interfacing with the debug module |
*/ |
typedef enum |
{ |
MBEDTLS_PK_DEBUG_NONE = 0, |
MBEDTLS_PK_DEBUG_MPI, |
MBEDTLS_PK_DEBUG_ECP, |
} mbedtls_pk_debug_type; |
/** |
* \brief Item to send to the debug module |
*/ |
typedef struct mbedtls_pk_debug_item |
{ |
mbedtls_pk_debug_type type; |
const char *name; |
void *value; |
} mbedtls_pk_debug_item; |
/** Maximum number of item send for debugging, plus 1 */ |
#define MBEDTLS_PK_DEBUG_MAX_ITEMS 3 |
/** |
* \brief Public key information and operations |
*/ |
typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; |
/** |
* \brief Public key container |
*/ |
typedef struct mbedtls_pk_context |
{ |
const mbedtls_pk_info_t * pk_info; /**< Public key information */ |
void * pk_ctx; /**< Underlying public key context */ |
} mbedtls_pk_context; |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Context for resuming operations |
*/ |
typedef struct |
{ |
const mbedtls_pk_info_t * pk_info; /**< Public key information */ |
void * rs_ctx; /**< Underlying restart context */ |
} mbedtls_pk_restart_ctx; |
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/* Now we can declare functions that take a pointer to that */ |
typedef void mbedtls_pk_restart_ctx; |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
#if defined(MBEDTLS_RSA_C) |
/** |
* Quick access to an RSA context inside a PK context. |
* |
* \warning You must make sure the PK context actually holds an RSA context |
* before using this function! |
*/ |
static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk ) |
{ |
return( (mbedtls_rsa_context *) (pk).pk_ctx ); |
} |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
/** |
* Quick access to an EC context inside a PK context. |
* |
* \warning You must make sure the PK context actually holds an EC context |
* before using this function! |
*/ |
static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk ) |
{ |
return( (mbedtls_ecp_keypair *) (pk).pk_ctx ); |
} |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
/** |
* \brief Types for RSA-alt abstraction |
*/ |
typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen, |
const unsigned char *input, unsigned char *output, |
size_t output_max_len ); |
typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, |
const unsigned char *hash, unsigned char *sig ); |
typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx ); |
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
/** |
* \brief Return information associated with the given PK type |
* |
* \param pk_type PK type to search for. |
* |
* \return The PK info associated with the type or NULL if not found. |
*/ |
const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ); |
/** |
* \brief Initialize a #mbedtls_pk_context (as NONE). |
* |
* \param ctx The context to initialize. |
* This must not be \c NULL. |
*/ |
void mbedtls_pk_init( mbedtls_pk_context *ctx ); |
/** |
* \brief Free the components of a #mbedtls_pk_context. |
* |
* \param ctx The context to clear. It must have been initialized. |
* If this is \c NULL, this function does nothing. |
*/ |
void mbedtls_pk_free( mbedtls_pk_context *ctx ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Initialize a restart context |
* |
* \param ctx The context to initialize. |
* This must not be \c NULL. |
*/ |
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ); |
/** |
* \brief Free the components of a restart context |
* |
* \param ctx The context to clear. It must have been initialized. |
* If this is \c NULL, this function does nothing. |
*/ |
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ); |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/** |
* \brief Initialize a PK context with the information given |
* and allocates the type-specific PK subcontext. |
* |
* \param ctx Context to initialize. It must not have been set |
* up yet (type #MBEDTLS_PK_NONE). |
* \param info Information to use |
* |
* \return 0 on success, |
* MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input, |
* MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure. |
* |
* \note For contexts holding an RSA-alt key, use |
* \c mbedtls_pk_setup_rsa_alt() instead. |
*/ |
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ); |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
/** |
* \brief Initialize an RSA-alt context |
* |
* \param ctx Context to initialize. It must not have been set |
* up yet (type #MBEDTLS_PK_NONE). |
* \param key RSA key pointer |
* \param decrypt_func Decryption function |
* \param sign_func Signing function |
* \param key_len_func Function returning key length in bytes |
* |
* \return 0 on success, or MBEDTLS_ERR_PK_BAD_INPUT_DATA if the |
* context wasn't already initialized as RSA_ALT. |
* |
* \note This function replaces \c mbedtls_pk_setup() for RSA-alt. |
*/ |
int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, |
mbedtls_pk_rsa_alt_decrypt_func decrypt_func, |
mbedtls_pk_rsa_alt_sign_func sign_func, |
mbedtls_pk_rsa_alt_key_len_func key_len_func ); |
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
/** |
* \brief Get the size in bits of the underlying key |
* |
* \param ctx The context to query. It must have been initialized. |
* |
* \return Key size in bits, or 0 on error |
*/ |
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ); |
/** |
* \brief Get the length in bytes of the underlying key |
* |
* \param ctx The context to query. It must have been initialized. |
* |
* \return Key length in bytes, or 0 on error |
*/ |
static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx ) |
{ |
return( ( mbedtls_pk_get_bitlen( ctx ) + 7 ) / 8 ); |
} |
/** |
* \brief Tell if a context can do the operation given by type |
* |
* \param ctx The context to query. It must have been initialized. |
* \param type The desired type. |
* |
* \return 1 if the context can do operations on the given type. |
* \return 0 if the context cannot do the operations on the given |
* type. This is always the case for a context that has |
* been initialized but not set up, or that has been |
* cleared with mbedtls_pk_free(). |
*/ |
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ); |
/** |
* \brief Verify signature (including padding if relevant). |
* |
* \param ctx The PK context to use. It must have been set up. |
* \param md_alg Hash algorithm used (see notes) |
* \param hash Hash of the message to sign |
* \param hash_len Hash length or 0 (see notes) |
* \param sig Signature to verify |
* \param sig_len Signature length |
* |
* \return 0 on success (signature is valid), |
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid |
* signature in sig but its length is less than \p siglen, |
* or a specific error code. |
* |
* \note For RSA keys, the default padding type is PKCS#1 v1.5. |
* Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... ) |
* to verify RSASSA_PSS signatures. |
* |
* \note If hash_len is 0, then the length associated with md_alg |
* is used instead, or an error returned if it is invalid. |
* |
* \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 |
*/ |
int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ); |
/** |
* \brief Restartable version of \c mbedtls_pk_verify() |
* |
* \note Performs the same job as \c mbedtls_pk_verify(), but can |
* return early and restart according to the limit set with |
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC |
* operations. For RSA, same as \c mbedtls_pk_verify(). |
* |
* \param ctx The PK context to use. It must have been set up. |
* \param md_alg Hash algorithm used (see notes) |
* \param hash Hash of the message to sign |
* \param hash_len Hash length or 0 (see notes) |
* \param sig Signature to verify |
* \param sig_len Signature length |
* \param rs_ctx Restart context (NULL to disable restart) |
* |
* \return See \c mbedtls_pk_verify(), or |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
*/ |
int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len, |
mbedtls_pk_restart_ctx *rs_ctx ); |
/** |
* \brief Verify signature, with options. |
* (Includes verification of the padding depending on type.) |
* |
* \param type Signature type (inc. possible padding type) to verify |
* \param options Pointer to type-specific options, or NULL |
* \param ctx The PK context to use. It must have been set up. |
* \param md_alg Hash algorithm used (see notes) |
* \param hash Hash of the message to sign |
* \param hash_len Hash length or 0 (see notes) |
* \param sig Signature to verify |
* \param sig_len Signature length |
* |
* \return 0 on success (signature is valid), |
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be |
* used for this type of signatures, |
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid |
* signature in sig but its length is less than \p siglen, |
* or a specific error code. |
* |
* \note If hash_len is 0, then the length associated with md_alg |
* is used instead, or an error returned if it is invalid. |
* |
* \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 |
* |
* \note If type is MBEDTLS_PK_RSASSA_PSS, then options must point |
* to a mbedtls_pk_rsassa_pss_options structure, |
* otherwise it must be NULL. |
*/ |
int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, |
mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ); |
/** |
* \brief Make signature, including padding if relevant. |
* |
* \param ctx The PK context to use. It must have been set up |
* with a private key. |
* \param md_alg Hash algorithm used (see notes) |
* \param hash Hash of the message to sign |
* \param hash_len Hash length or 0 (see notes) |
* \param sig Place to write the signature |
* \param sig_len Number of bytes written |
* \param f_rng RNG function |
* \param p_rng RNG parameter |
* |
* \return 0 on success, or a specific error code. |
* |
* \note For RSA keys, the default padding type is PKCS#1 v1.5. |
* There is no interface in the PK module to make RSASSA-PSS |
* signatures yet. |
* |
* \note If hash_len is 0, then the length associated with md_alg |
* is used instead, or an error returned if it is invalid. |
* |
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. |
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE. |
* |
* \note In order to ensure enough space for the signature, the |
* \p sig buffer size must be of at least |
* `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. |
*/ |
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
/** |
* \brief Restartable version of \c mbedtls_pk_sign() |
* |
* \note Performs the same job as \c mbedtls_pk_sign(), but can |
* return early and restart according to the limit set with |
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC |
* operations. For RSA, same as \c mbedtls_pk_sign(). |
* |
* \note In order to ensure enough space for the signature, the |
* \p sig buffer size must be of at least |
* `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes. |
* |
* \param ctx The PK context to use. It must have been set up |
* with a private key. |
* \param md_alg Hash algorithm used (see notes) |
* \param hash Hash of the message to sign |
* \param hash_len Hash length or 0 (see notes) |
* \param sig Place to write the signature |
* \param sig_len Number of bytes written |
* \param f_rng RNG function |
* \param p_rng RNG parameter |
* \param rs_ctx Restart context (NULL to disable restart) |
* |
* \return See \c mbedtls_pk_sign(), or |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
*/ |
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
mbedtls_pk_restart_ctx *rs_ctx ); |
/** |
* \brief Decrypt message (including padding if relevant). |
* |
* \param ctx The PK context to use. It must have been set up |
* with a private key. |
* \param input Input to decrypt |
* \param ilen Input size |
* \param output Decrypted output |
* \param olen Decrypted message length |
* \param osize Size of the output buffer |
* \param f_rng RNG function |
* \param p_rng RNG parameter |
* |
* \note For RSA keys, the default padding type is PKCS#1 v1.5. |
* |
* \return 0 on success, or a specific error code. |
*/ |
int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
/** |
* \brief Encrypt message (including padding if relevant). |
* |
* \param ctx The PK context to use. It must have been set up. |
* \param input Message to encrypt |
* \param ilen Message size |
* \param output Encrypted output |
* \param olen Encrypted output length |
* \param osize Size of the output buffer |
* \param f_rng RNG function |
* \param p_rng RNG parameter |
* |
* \note For RSA keys, the default padding type is PKCS#1 v1.5. |
* |
* \return 0 on success, or a specific error code. |
*/ |
int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
/** |
* \brief Check if a public-private pair of keys matches. |
* |
* \param pub Context holding a public key. |
* \param prv Context holding a private (and public) key. |
* |
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA |
*/ |
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ); |
/** |
* \brief Export debug information |
* |
* \param ctx The PK context to use. It must have been initialized. |
* \param items Place to write debug items |
* |
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA |
*/ |
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ); |
/** |
* \brief Access the type name |
* |
* \param ctx The PK context to use. It must have been initialized. |
* |
* \return Type name on success, or "invalid PK" |
*/ |
const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx ); |
/** |
* \brief Get the key type |
* |
* \param ctx The PK context to use. It must have been initialized. |
* |
* \return Type on success. |
* \return #MBEDTLS_PK_NONE for a context that has not been set up. |
*/ |
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ); |
#if defined(MBEDTLS_PK_PARSE_C) |
/** \ingroup pk_module */ |
/** |
* \brief Parse a private key in PEM or DER format |
* |
* \param ctx The PK context to fill. It must have been initialized |
* but not set up. |
* \param key Input buffer to parse. |
* The buffer must contain the input exactly, with no |
* extra trailing material. For PEM, the buffer must |
* contain a null-terminated string. |
* \param keylen Size of \b key in bytes. |
* For PEM data, this includes the terminating null byte, |
* so \p keylen must be equal to `strlen(key) + 1`. |
* \param pwd Optional password for decryption. |
* Pass \c NULL if expecting a non-encrypted key. |
* Pass a string of \p pwdlen bytes if expecting an encrypted |
* key; a non-encrypted key will also be accepted. |
* The empty password is not supported. |
* \param pwdlen Size of the password in bytes. |
* Ignored if \p pwd is \c NULL. |
* |
* \note On entry, ctx must be empty, either freshly initialised |
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a |
* specific key type, check the result with mbedtls_pk_can_do(). |
* |
* \note The key is also checked for correctness. |
* |
* \return 0 if successful, or a specific PK or PEM error code |
*/ |
int mbedtls_pk_parse_key( mbedtls_pk_context *ctx, |
const unsigned char *key, size_t keylen, |
const unsigned char *pwd, size_t pwdlen ); |
/** \ingroup pk_module */ |
/** |
* \brief Parse a public key in PEM or DER format |
* |
* \param ctx The PK context to fill. It must have been initialized |
* but not set up. |
* \param key Input buffer to parse. |
* The buffer must contain the input exactly, with no |
* extra trailing material. For PEM, the buffer must |
* contain a null-terminated string. |
* \param keylen Size of \b key in bytes. |
* For PEM data, this includes the terminating null byte, |
* so \p keylen must be equal to `strlen(key) + 1`. |
* |
* \note On entry, ctx must be empty, either freshly initialised |
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a |
* specific key type, check the result with mbedtls_pk_can_do(). |
* |
* \note The key is also checked for correctness. |
* |
* \return 0 if successful, or a specific PK or PEM error code |
*/ |
int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, |
const unsigned char *key, size_t keylen ); |
#if defined(MBEDTLS_FS_IO) |
/** \ingroup pk_module */ |
/** |
* \brief Load and parse a private key |
* |
* \param ctx The PK context to fill. It must have been initialized |
* but not set up. |
* \param path filename to read the private key from |
* \param password Optional password to decrypt the file. |
* Pass \c NULL if expecting a non-encrypted key. |
* Pass a null-terminated string if expecting an encrypted |
* key; a non-encrypted key will also be accepted. |
* The empty password is not supported. |
* |
* \note On entry, ctx must be empty, either freshly initialised |
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a |
* specific key type, check the result with mbedtls_pk_can_do(). |
* |
* \note The key is also checked for correctness. |
* |
* \return 0 if successful, or a specific PK or PEM error code |
*/ |
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, |
const char *path, const char *password ); |
/** \ingroup pk_module */ |
/** |
* \brief Load and parse a public key |
* |
* \param ctx The PK context to fill. It must have been initialized |
* but not set up. |
* \param path filename to read the public key from |
* |
* \note On entry, ctx must be empty, either freshly initialised |
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If |
* you need a specific key type, check the result with |
* mbedtls_pk_can_do(). |
* |
* \note The key is also checked for correctness. |
* |
* \return 0 if successful, or a specific PK or PEM error code |
*/ |
int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
#endif /* MBEDTLS_PK_PARSE_C */ |
#if defined(MBEDTLS_PK_WRITE_C) |
/** |
* \brief Write a private key to a PKCS#1 or SEC1 DER structure |
* Note: data is written at the end of the buffer! Use the |
* return value to determine where you should start |
* using the buffer |
* |
* \param ctx PK context which must contain a valid private key. |
* \param buf buffer to write to |
* \param size size of the buffer |
* |
* \return length of data written if successful, or a specific |
* error code |
*/ |
int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); |
/** |
* \brief Write a public key to a SubjectPublicKeyInfo DER structure |
* Note: data is written at the end of the buffer! Use the |
* return value to determine where you should start |
* using the buffer |
* |
* \param ctx PK context which must contain a valid public or private key. |
* \param buf buffer to write to |
* \param size size of the buffer |
* |
* \return length of data written if successful, or a specific |
* error code |
*/ |
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); |
#if defined(MBEDTLS_PEM_WRITE_C) |
/** |
* \brief Write a public key to a PEM string |
* |
* \param ctx PK context which must contain a valid public or private key. |
* \param buf Buffer to write to. The output includes a |
* terminating null byte. |
* \param size Size of the buffer in bytes. |
* |
* \return 0 if successful, or a specific error code |
*/ |
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); |
/** |
* \brief Write a private key to a PKCS#1 or SEC1 PEM string |
* |
* \param ctx PK context which must contain a valid private key. |
* \param buf Buffer to write to. The output includes a |
* terminating null byte. |
* \param size Size of the buffer in bytes. |
* |
* \return 0 if successful, or a specific error code |
*/ |
int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_PK_WRITE_C */ |
/* |
* WARNING: Low-level functions. You probably do not want to use these unless |
* you are certain you do ;) |
*/ |
#if defined(MBEDTLS_PK_PARSE_C) |
/** |
* \brief Parse a SubjectPublicKeyInfo DER structure |
* |
* \param p the position in the ASN.1 data |
* \param end end of the buffer |
* \param pk The PK context to fill. It must have been initialized |
* but not set up. |
* |
* \return 0 if successful, or a specific PK error code |
*/ |
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, |
mbedtls_pk_context *pk ); |
#endif /* MBEDTLS_PK_PARSE_C */ |
#if defined(MBEDTLS_PK_WRITE_C) |
/** |
* \brief Write a subjectPublicKey to ASN.1 data |
* Note: function works backwards in data buffer |
* |
* \param p reference to current position pointer |
* \param start start of the buffer (for bounds-checking) |
* \param key PK context which must contain a valid public or private key. |
* |
* \return the length written or a negative error code |
*/ |
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, |
const mbedtls_pk_context *key ); |
#endif /* MBEDTLS_PK_WRITE_C */ |
/* |
* Internal module functions. You probably do not want to use these unless you |
* know you do. |
*/ |
#if defined(MBEDTLS_FS_IO) |
int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_PK_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/pk_internal.h |
---|
0,0 → 1,140 |
/** |
* \file pk_internal.h |
* |
* \brief Public Key abstraction layer: wrapper functions |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PK_WRAP_H |
#define MBEDTLS_PK_WRAP_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "pk.h" |
struct mbedtls_pk_info_t |
{ |
/** Public key type */ |
mbedtls_pk_type_t type; |
/** Type name */ |
const char *name; |
/** Get key size in bits */ |
size_t (*get_bitlen)( const void * ); |
/** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */ |
int (*can_do)( mbedtls_pk_type_t type ); |
/** Verify signature */ |
int (*verify_func)( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ); |
/** Make signature */ |
int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/** Verify signature (restartable) */ |
int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len, |
void *rs_ctx ); |
/** Make signature (restartable) */ |
int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, void *rs_ctx ); |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/** Decrypt message */ |
int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** Encrypt message */ |
int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** Check public-private key pair */ |
int (*check_pair_func)( const void *pub, const void *prv ); |
/** Allocate a new context */ |
void * (*ctx_alloc_func)( void ); |
/** Free the given context */ |
void (*ctx_free_func)( void *ctx ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/** Allocate the restart context */ |
void * (*rs_alloc_func)( void ); |
/** Free the restart context */ |
void (*rs_free_func)( void *rs_ctx ); |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/** Interface with the debug module */ |
void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items ); |
}; |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
/* Container for RSA-alt */ |
typedef struct |
{ |
void *key; |
mbedtls_pk_rsa_alt_decrypt_func decrypt_func; |
mbedtls_pk_rsa_alt_sign_func sign_func; |
mbedtls_pk_rsa_alt_key_len_func key_len_func; |
} mbedtls_rsa_alt_context; |
#endif |
#if defined(MBEDTLS_RSA_C) |
extern const mbedtls_pk_info_t mbedtls_rsa_info; |
#endif |
#if defined(MBEDTLS_ECP_C) |
extern const mbedtls_pk_info_t mbedtls_eckey_info; |
extern const mbedtls_pk_info_t mbedtls_eckeydh_info; |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
extern const mbedtls_pk_info_t mbedtls_ecdsa_info; |
#endif |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
extern const mbedtls_pk_info_t mbedtls_rsa_alt_info; |
#endif |
#endif /* MBEDTLS_PK_WRAP_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/pkcs11.h |
---|
0,0 → 1,177 |
/** |
* \file pkcs11.h |
* |
* \brief Wrapper for PKCS#11 library libpkcs11-helper |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PKCS11_H |
#define MBEDTLS_PKCS11_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PKCS11_C) |
#include "x509_crt.h" |
#include <pkcs11-helper-1.0/pkcs11h-certificate.h> |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Context for PKCS #11 private keys. |
*/ |
typedef struct mbedtls_pkcs11_context |
{ |
pkcs11h_certificate_t pkcs11h_cert; |
int len; |
} mbedtls_pkcs11_context; |
/** |
* Initialize a mbedtls_pkcs11_context. |
* (Just making memory references valid.) |
*/ |
void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ); |
/** |
* Fill in a mbed TLS certificate, based on the given PKCS11 helper certificate. |
* |
* \param cert X.509 certificate to fill |
* \param pkcs11h_cert PKCS #11 helper certificate |
* |
* \return 0 on success. |
*/ |
int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert ); |
/** |
* Set up a mbedtls_pkcs11_context storing the given certificate. Note that the |
* mbedtls_pkcs11_context will take over control of the certificate, freeing it when |
* done. |
* |
* \param priv_key Private key structure to fill. |
* \param pkcs11_cert PKCS #11 helper certificate |
* |
* \return 0 on success |
*/ |
int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, |
pkcs11h_certificate_t pkcs11_cert ); |
/** |
* Free the contents of the given private key context. Note that the structure |
* itself is not freed. |
* |
* \param priv_key Private key structure to cleanup |
*/ |
void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ); |
/** |
* \brief Do an RSA private key decrypt, then remove the message |
* padding |
* |
* \param ctx PKCS #11 context |
* \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature |
* \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 MBEDTLS_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 mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, |
int mode, size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ); |
/** |
* \brief Do a private RSA to sign a message digest |
* |
* \param ctx PKCS #11 context |
* \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature |
* \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) |
* \param hashlen message digest length (for MBEDTLS_MD_NONE 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 MBEDTLS_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 mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ); |
/** |
* SSL/TLS wrappers for PKCS#11 functions |
*/ |
static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen, |
const unsigned char *input, unsigned char *output, |
size_t output_max_len ) |
{ |
return mbedtls_pkcs11_decrypt( (mbedtls_pkcs11_context *) ctx, mode, olen, input, output, |
output_max_len ); |
} |
static inline int mbedtls_ssl_pkcs11_sign( void *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, |
const unsigned char *hash, unsigned char *sig ) |
{ |
((void) f_rng); |
((void) p_rng); |
return mbedtls_pkcs11_sign( (mbedtls_pkcs11_context *) ctx, mode, md_alg, |
hashlen, hash, sig ); |
} |
static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx ) |
{ |
return ( (mbedtls_pkcs11_context *) ctx )->len; |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_PKCS11_C */ |
#endif /* MBEDTLS_PKCS11_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/pkcs12.h |
---|
0,0 → 1,132 |
/** |
* \file pkcs12.h |
* |
* \brief PKCS#12 Personal Information Exchange Syntax |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PKCS12_H |
#define MBEDTLS_PKCS12_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "md.h" |
#include "cipher.h" |
#include "asn1.h" |
#include <stddef.h> |
#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 /**< Feature not available, e.g. unsupported encryption scheme. */ |
#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */ |
#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */ |
#define MBEDTLS_PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */ |
#define MBEDTLS_PKCS12_DERIVE_IV 2 /**< initialization vector */ |
#define MBEDTLS_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */ |
#define MBEDTLS_PKCS12_PBE_DECRYPT 0 |
#define MBEDTLS_PKCS12_PBE_ENCRYPT 1 |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if defined(MBEDTLS_ASN1_PARSE_C) |
/** |
* \brief PKCS12 Password Based function (encryption / decryption) |
* for pbeWithSHAAnd128BitRC4 |
* |
* \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure |
* \param mode either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT |
* \param pwd the password used (may be NULL if no password is used) |
* \param pwdlen length of the password (may be 0) |
* \param input the input data |
* \param len data length |
* \param output the output buffer |
* |
* \return 0 if successful, or a MBEDTLS_ERR_XXX code |
*/ |
int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *input, size_t len, |
unsigned char *output ); |
/** |
* \brief PKCS12 Password Based function (encryption / decryption) |
* for cipher-based and mbedtls_md-based PBE's |
* |
* \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure |
* \param mode either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT |
* \param cipher_type the cipher used |
* \param md_type the mbedtls_md used |
* \param pwd the password used (may be NULL if no password is used) |
* \param pwdlen length of the password (may be 0) |
* \param input the input data |
* \param len data length |
* \param output the output buffer |
* |
* \return 0 if successful, or a MBEDTLS_ERR_XXX code |
*/ |
int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, |
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *input, size_t len, |
unsigned char *output ); |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
/** |
* \brief The PKCS#12 derivation function uses a password and a salt |
* to produce pseudo-random bits for a particular "purpose". |
* |
* Depending on the given id, this function can produce an |
* encryption/decryption key, an nitialization vector or an |
* integrity key. |
* |
* \param data buffer to store the derived data in |
* \param datalen length to fill |
* \param pwd password to use (may be NULL if no password is used) |
* \param pwdlen length of the password (may be 0) |
* \param salt salt buffer to use |
* \param saltlen length of the salt |
* \param mbedtls_md mbedtls_md type to use during the derivation |
* \param id id that describes the purpose (can be MBEDTLS_PKCS12_DERIVE_KEY, |
* MBEDTLS_PKCS12_DERIVE_IV or MBEDTLS_PKCS12_DERIVE_MAC_KEY) |
* \param iterations number of iterations |
* |
* \return 0 if successful, or a MD, BIGNUM type error. |
*/ |
int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *salt, size_t saltlen, |
mbedtls_md_type_t mbedtls_md, int id, int iterations ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* pkcs12.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/pkcs5.h |
---|
0,0 → 1,111 |
/** |
* \file pkcs5.h |
* |
* \brief PKCS#5 functions |
* |
* \author Mathias Olsson <mathias@kompetensum.com> |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PKCS5_H |
#define MBEDTLS_PKCS5_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "asn1.h" |
#include "md.h" |
#include <stddef.h> |
#include <stdint.h> |
#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -0x2f80 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT -0x2f00 /**< Unexpected ASN.1 data. */ |
#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80 /**< Requested encryption or digest alg not available. */ |
#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00 /**< Given private key password does not allow for correct decryption. */ |
#define MBEDTLS_PKCS5_DECRYPT 0 |
#define MBEDTLS_PKCS5_ENCRYPT 1 |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if defined(MBEDTLS_ASN1_PARSE_C) |
/** |
* \brief PKCS#5 PBES2 function |
* |
* \param pbe_params the ASN.1 algorithm parameters |
* \param mode either MBEDTLS_PKCS5_DECRYPT or MBEDTLS_PKCS5_ENCRYPT |
* \param pwd password to use when generating key |
* \param pwdlen length of password |
* \param data data to process |
* \param datalen length of data |
* \param output output buffer |
* |
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. |
*/ |
int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *data, size_t datalen, |
unsigned char *output ); |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
/** |
* \brief PKCS#5 PBKDF2 using HMAC |
* |
* \param ctx Generic HMAC context |
* \param password Password to use when generating key |
* \param plen Length of password |
* \param salt Salt to use when generating key |
* \param slen Length of salt |
* \param iteration_count Iteration count |
* \param key_length Length of generated key in bytes |
* \param output Generated key. Must be at least as big as key_length |
* |
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. |
*/ |
int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, |
size_t plen, const unsigned char *salt, size_t slen, |
unsigned int iteration_count, |
uint32_t key_length, unsigned char *output ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_pkcs5_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* pkcs5.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/platform.h |
---|
0,0 → 1,369 |
/** |
* \file platform.h |
* |
* \brief This file contains the definitions and functions of the |
* Mbed TLS platform abstraction layer. |
* |
* The platform abstraction layer removes the need for the library |
* to directly link to standard C library functions or operating |
* system services, making the library easier to port and embed. |
* Application developers and users of the library can provide their own |
* implementations of these functions, or implementations specific to |
* their platform, which can be statically linked to the library or |
* dynamically configured at runtime. |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PLATFORM_H |
#define MBEDTLS_PLATFORM_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_HAVE_TIME) |
#include "platform_time.h" |
#endif |
#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */ |
#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) |
#include <stdio.h> |
#include <stdlib.h> |
#include <time.h> |
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) |
#if defined(_WIN32) |
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ |
#else |
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ |
#endif |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) |
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) |
#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) |
#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_FREE) |
#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_EXIT) |
#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_TIME) |
#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) |
#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) |
#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ |
#endif |
#if defined(MBEDTLS_FS_IO) |
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) |
#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) |
#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write |
#endif |
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) |
#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" |
#endif |
#endif /* MBEDTLS_FS_IO */ |
#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ |
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) |
#include MBEDTLS_PLATFORM_STD_MEM_HDR |
#endif |
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ |
/* \} name SECTION: Module settings */ |
/* |
* The function pointers for calloc and free. |
*/ |
#if defined(MBEDTLS_PLATFORM_MEMORY) |
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ |
defined(MBEDTLS_PLATFORM_CALLOC_MACRO) |
#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO |
#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO |
#else |
/* For size_t */ |
#include <stddef.h> |
extern void *mbedtls_calloc( size_t n, size_t size ); |
extern void mbedtls_free( void *ptr ); |
/** |
* \brief This function dynamically sets the memory-management |
* functions used by the library, during runtime. |
* |
* \param calloc_func The \c calloc function implementation. |
* \param free_func The \c free function implementation. |
* |
* \return \c 0. |
*/ |
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), |
void (*free_func)( void * ) ); |
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ |
#else /* !MBEDTLS_PLATFORM_MEMORY */ |
#define mbedtls_free free |
#define mbedtls_calloc calloc |
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ |
/* |
* The function pointers for fprintf |
*/ |
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) |
/* We need FILE * */ |
#include <stdio.h> |
extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); |
/** |
* \brief This function dynamically configures the fprintf |
* function that is called when the |
* mbedtls_fprintf() function is invoked by the library. |
* |
* \param fprintf_func The \c fprintf function implementation. |
* |
* \return \c 0. |
*/ |
int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, |
... ) ); |
#else |
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) |
#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO |
#else |
#define mbedtls_fprintf fprintf |
#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ |
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ |
/* |
* The function pointers for printf |
*/ |
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) |
extern int (*mbedtls_printf)( const char *format, ... ); |
/** |
* \brief This function dynamically configures the snprintf |
* function that is called when the mbedtls_snprintf() |
* function is invoked by the library. |
* |
* \param printf_func The \c printf function implementation. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); |
#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) |
#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO |
#else |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ |
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ |
/* |
* The function pointers for snprintf |
* |
* The snprintf implementation should conform to C99: |
* - it *must* always correctly zero-terminate the buffer |
* (except when n == 0, then it must leave the buffer untouched) |
* - however it is acceptable to return -1 instead of the required length when |
* the destination buffer is too short. |
*/ |
#if defined(_WIN32) |
/* For Windows (inc. MSYS2), we provide our own fixed implementation */ |
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); |
#endif |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) |
extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); |
/** |
* \brief This function allows configuring a custom |
* \c snprintf function pointer. |
* |
* \param snprintf_func The \c snprintf function implementation. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, |
const char * format, ... ) ); |
#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) |
#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO |
#else |
#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF |
#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ |
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ |
/* |
* The function pointers for exit |
*/ |
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) |
extern void (*mbedtls_exit)( int status ); |
/** |
* \brief This function dynamically configures the exit |
* function that is called when the mbedtls_exit() |
* function is invoked by the library. |
* |
* \param exit_func The \c exit function implementation. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); |
#else |
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) |
#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO |
#else |
#define mbedtls_exit exit |
#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ |
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ |
/* |
* The default exit values |
*/ |
#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) |
#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS |
#else |
#define MBEDTLS_EXIT_SUCCESS 0 |
#endif |
#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) |
#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE |
#else |
#define MBEDTLS_EXIT_FAILURE 1 |
#endif |
/* |
* The function pointers for reading from and writing a seed file to |
* Non-Volatile storage (NV) in a platform-independent way |
* |
* Only enabled when the NV seed entropy source is enabled |
*/ |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) |
/* Internal standard platform definitions */ |
int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); |
int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); |
#endif |
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) |
extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); |
extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); |
/** |
* \brief This function allows configuring custom seed file writing and |
* reading functions. |
* |
* \param nv_seed_read_func The seed reading function implementation. |
* \param nv_seed_write_func The seed writing function implementation. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_platform_set_nv_seed( |
int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), |
int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) |
); |
#else |
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ |
defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) |
#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO |
#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO |
#else |
#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read |
#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write |
#endif |
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ |
#endif /* MBEDTLS_ENTROPY_NV_SEED */ |
#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) |
/** |
* \brief The platform context structure. |
* |
* \note This structure may be used to assist platform-specific |
* setup or teardown operations. |
*/ |
typedef struct mbedtls_platform_context |
{ |
char dummy; /**< A placeholder member, as empty structs are not portable. */ |
} |
mbedtls_platform_context; |
#else |
#include "platform_alt.h" |
#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ |
/** |
* \brief This function performs any platform-specific initialization |
* operations. |
* |
* \note This function should be called before any other library functions. |
* |
* Its implementation is platform-specific, and unless |
* platform-specific code is provided, it does nothing. |
* |
* \note The usage and necessity of this function is dependent on the platform. |
* |
* \param ctx The platform context. |
* |
* \return \c 0 on success. |
*/ |
int mbedtls_platform_setup( mbedtls_platform_context *ctx ); |
/** |
* \brief This function performs any platform teardown operations. |
* |
* \note This function should be called after every other Mbed TLS module |
* has been correctly freed using the appropriate free function. |
* |
* Its implementation is platform-specific, and unless |
* platform-specific code is provided, it does nothing. |
* |
* \note The usage and necessity of this function is dependent on the platform. |
* |
* \param ctx The platform context. |
* |
*/ |
void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* platform.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/platform_time.h |
---|
0,0 → 1,84 |
/** |
* \file platform_time.h |
* |
* \brief mbed TLS Platform time abstraction |
*/ |
/* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PLATFORM_TIME_H |
#define MBEDTLS_PLATFORM_TIME_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
/* |
* The time_t datatype |
*/ |
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) |
typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; |
#else |
/* For time_t */ |
#include <time.h> |
typedef time_t mbedtls_time_t; |
#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ |
/* |
* The function pointers for time |
*/ |
#if defined(MBEDTLS_PLATFORM_TIME_ALT) |
extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); |
/** |
* \brief Set your own time function pointer |
* |
* \param time_func the time function implementation |
* |
* \return 0 |
*/ |
int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); |
#else |
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) |
#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO |
#else |
#define mbedtls_time time |
#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ |
#endif /* MBEDTLS_PLATFORM_TIME_ALT */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* platform_time.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/platform_util.h |
---|
0,0 → 1,198 |
/** |
* \file platform_util.h |
* |
* \brief Common and shared functions used by multiple modules in the Mbed TLS |
* library. |
*/ |
/* |
* Copyright (C) 2018, Arm Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_PLATFORM_UTIL_H |
#define MBEDTLS_PLATFORM_UTIL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#if defined(MBEDTLS_HAVE_TIME_DATE) |
#include "platform_time.h" |
#include <time.h> |
#endif /* MBEDTLS_HAVE_TIME_DATE */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if defined(MBEDTLS_CHECK_PARAMS) |
#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) |
/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert |
* (which is what our config.h suggests). */ |
#include <assert.h> |
#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ |
#if defined(MBEDTLS_PARAM_FAILED) |
/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. |
* |
* This flag can be used to check whether it is safe to assume that |
* MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). |
*/ |
#define MBEDTLS_PARAM_FAILED_ALT |
#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) |
#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) |
#define MBEDTLS_PARAM_FAILED_ALT |
#else /* MBEDTLS_PARAM_FAILED */ |
#define MBEDTLS_PARAM_FAILED( cond ) \ |
mbedtls_param_failed( #cond, __FILE__, __LINE__ ) |
/** |
* \brief User supplied callback function for parameter validation failure. |
* See #MBEDTLS_CHECK_PARAMS for context. |
* |
* This function will be called unless an alternative treatement |
* is defined through the #MBEDTLS_PARAM_FAILED macro. |
* |
* This function can return, and the operation will be aborted, or |
* alternatively, through use of setjmp()/longjmp() can resume |
* execution in the application code. |
* |
* \param failure_condition The assertion that didn't hold. |
* \param file The file where the assertion failed. |
* \param line The line in the file where the assertion failed. |
*/ |
void mbedtls_param_failed( const char *failure_condition, |
const char *file, |
int line ); |
#endif /* MBEDTLS_PARAM_FAILED */ |
/* Internal macro meant to be called only from within the library. */ |
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \ |
do { \ |
if( !(cond) ) \ |
{ \ |
MBEDTLS_PARAM_FAILED( cond ); \ |
return( ret ); \ |
} \ |
} while( 0 ) |
/* Internal macro meant to be called only from within the library. */ |
#define MBEDTLS_INTERNAL_VALIDATE( cond ) \ |
do { \ |
if( !(cond) ) \ |
{ \ |
MBEDTLS_PARAM_FAILED( cond ); \ |
return; \ |
} \ |
} while( 0 ) |
#else /* MBEDTLS_CHECK_PARAMS */ |
/* Internal macros meant to be called only from within the library. */ |
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) |
#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 ) |
#endif /* MBEDTLS_CHECK_PARAMS */ |
/* Internal helper macros for deprecating API constants. */ |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here |
* to avoid conflict with other headers which define and use |
* it, too. We might want to move all these definitions here at |
* some point for uniformity. */ |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t; |
#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ |
( (mbedtls_deprecated_string_constant_t) ( VAL ) ) |
MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; |
#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \ |
( (mbedtls_deprecated_numeric_constant_t) ( VAL ) ) |
#undef MBEDTLS_DEPRECATED |
#else /* MBEDTLS_DEPRECATED_WARNING */ |
#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL |
#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL |
#endif /* MBEDTLS_DEPRECATED_WARNING */ |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Securely zeroize a buffer |
* |
* The function is meant to wipe the data contained in a buffer so |
* that it can no longer be recovered even if the program memory |
* is later compromised. Call this function on sensitive data |
* stored on the stack before returning from a function, and on |
* sensitive data stored on the heap before freeing the heap |
* object. |
* |
* It is extremely difficult to guarantee that calls to |
* mbedtls_platform_zeroize() are not removed by aggressive |
* compiler optimizations in a portable way. For this reason, Mbed |
* TLS provides the configuration option |
* MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure |
* mbedtls_platform_zeroize() to use a suitable implementation for |
* their platform and needs |
* |
* \param buf Buffer to be zeroized |
* \param len Length of the buffer in bytes |
* |
*/ |
void mbedtls_platform_zeroize( void *buf, size_t len ); |
#if defined(MBEDTLS_HAVE_TIME_DATE) |
/** |
* \brief Platform-specific implementation of gmtime_r() |
* |
* The function is a thread-safe abstraction that behaves |
* similarly to the gmtime_r() function from Unix/POSIX. |
* |
* Mbed TLS will try to identify the underlying platform and |
* make use of an appropriate underlying implementation (e.g. |
* gmtime_r() for POSIX and gmtime_s() for Windows). If this is |
* not possible, then gmtime() will be used. In this case, calls |
* from the library to gmtime() will be guarded by the mutex |
* mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is |
* enabled. It is recommended that calls from outside the library |
* are also guarded by this mutex. |
* |
* If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will |
* unconditionally use the alternative implementation for |
* mbedtls_platform_gmtime_r() supplied by the user at compile time. |
* |
* \param tt Pointer to an object containing time (in seconds) since the |
* epoch to be converted |
* \param tm_buf Pointer to an object where the results will be stored |
* |
* \return Pointer to an object of type struct tm on success, otherwise |
* NULL |
*/ |
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, |
struct tm *tm_buf ); |
#endif /* MBEDTLS_HAVE_TIME_DATE */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_PLATFORM_UTIL_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/poly1305.h |
---|
0,0 → 1,194 |
/** |
* \file poly1305.h |
* |
* \brief This file contains Poly1305 definitions and functions. |
* |
* Poly1305 is a one-time message authenticator that can be used to |
* authenticate messages. Poly1305-AES was created by Daniel |
* Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic |
* Poly1305 algorithm (not tied to AES) was also standardized in RFC |
* 7539. |
* |
* \author Daniel King <damaki.gh@gmail.com> |
*/ |
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_POLY1305_H |
#define MBEDTLS_POLY1305_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stdint.h> |
#include <stddef.h> |
#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057 /**< Invalid input parameter(s). */ |
/* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be |
* used. */ |
#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */ |
/* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED -0x005B /**< Poly1305 hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_POLY1305_ALT) |
typedef struct mbedtls_poly1305_context |
{ |
uint32_t r[4]; /** The value for 'r' (low 128 bits of the key). */ |
uint32_t s[4]; /** The value for 's' (high 128 bits of the key). */ |
uint32_t acc[5]; /** The accumulator number. */ |
uint8_t queue[16]; /** The current partial block of data. */ |
size_t queue_len; /** The number of bytes stored in 'queue'. */ |
} |
mbedtls_poly1305_context; |
#else /* MBEDTLS_POLY1305_ALT */ |
#include "poly1305_alt.h" |
#endif /* MBEDTLS_POLY1305_ALT */ |
/** |
* \brief This function initializes the specified Poly1305 context. |
* |
* It must be the first API called before using |
* the context. |
* |
* It is usually followed by a call to |
* \c mbedtls_poly1305_starts(), then one or more calls to |
* \c mbedtls_poly1305_update(), then one call to |
* \c mbedtls_poly1305_finish(), then finally |
* \c mbedtls_poly1305_free(). |
* |
* \param ctx The Poly1305 context to initialize. This must |
* not be \c NULL. |
*/ |
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ); |
/** |
* \brief This function releases and clears the specified |
* Poly1305 context. |
* |
* \param ctx The Poly1305 context to clear. This may be \c NULL, in which |
* case this function is a no-op. If it is not \c NULL, it must |
* point to an initialized Poly1305 context. |
*/ |
void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); |
/** |
* \brief This function sets the one-time authentication key. |
* |
* \warning The key must be unique and unpredictable for each |
* invocation of Poly1305. |
* |
* \param ctx The Poly1305 context to which the key should be bound. |
* This must be initialized. |
* \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, |
const unsigned char key[32] ); |
/** |
* \brief This functions feeds an input buffer into an ongoing |
* Poly1305 computation. |
* |
* It is called between \c mbedtls_cipher_poly1305_starts() and |
* \c mbedtls_cipher_poly1305_finish(). |
* It can be called repeatedly to process a stream of data. |
* |
* \param ctx The Poly1305 context to use for the Poly1305 operation. |
* This must be initialized and bound to a key. |
* \param ilen The length of the input data in Bytes. |
* Any value is accepted. |
* \param input The buffer holding the input data. |
* This pointer can be \c NULL if `ilen == 0`. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function generates the Poly1305 Message |
* Authentication Code (MAC). |
* |
* \param ctx The Poly1305 context to use for the Poly1305 operation. |
* This must be initialized and bound to a key. |
* \param mac The buffer to where the MAC is written. This must |
* be a writable buffer of length \c 16 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, |
unsigned char mac[16] ); |
/** |
* \brief This function calculates the Poly1305 MAC of the input |
* buffer with the provided key. |
* |
* \warning The key must be unique and unpredictable for each |
* invocation of Poly1305. |
* |
* \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. |
* \param ilen The length of the input data in Bytes. |
* Any value is accepted. |
* \param input The buffer holding the input data. |
* This pointer can be \c NULL if `ilen == 0`. |
* \param mac The buffer to where the MAC is written. This must be |
* a writable buffer of length \c 16 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_poly1305_mac( const unsigned char key[32], |
const unsigned char *input, |
size_t ilen, |
unsigned char mac[16] ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The Poly1305 checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_poly1305_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_POLY1305_H */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ripemd160.h |
---|
0,0 → 1,239 |
/** |
* \file ripemd160.h |
* |
* \brief RIPE MD-160 message digest |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_RIPEMD160_H |
#define MBEDTLS_RIPEMD160_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED -0x0031 /**< RIPEMD160 hardware accelerator failed */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_RIPEMD160_ALT) |
// Regular implementation |
// |
/** |
* \brief RIPEMD-160 context structure |
*/ |
typedef struct mbedtls_ripemd160_context |
{ |
uint32_t total[2]; /*!< number of bytes processed */ |
uint32_t state[5]; /*!< intermediate digest state */ |
unsigned char buffer[64]; /*!< data block being processed */ |
} |
mbedtls_ripemd160_context; |
#else /* MBEDTLS_RIPEMD160_ALT */ |
#include "ripemd160.h" |
#endif /* MBEDTLS_RIPEMD160_ALT */ |
/** |
* \brief Initialize RIPEMD-160 context |
* |
* \param ctx RIPEMD-160 context to be initialized |
*/ |
void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ); |
/** |
* \brief Clear RIPEMD-160 context |
* |
* \param ctx RIPEMD-160 context to be cleared |
*/ |
void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ); |
/** |
* \brief Clone (the state of) an RIPEMD-160 context |
* |
* \param dst The destination context |
* \param src The context to be cloned |
*/ |
void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, |
const mbedtls_ripemd160_context *src ); |
/** |
* \brief RIPEMD-160 context setup |
* |
* \param ctx context to be initialized |
* |
* \return 0 if successful |
*/ |
int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ); |
/** |
* \brief RIPEMD-160 process buffer |
* |
* \param ctx RIPEMD-160 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
* |
* \return 0 if successful |
*/ |
int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief RIPEMD-160 final digest |
* |
* \param ctx RIPEMD-160 context |
* \param output RIPEMD-160 checksum result |
* |
* \return 0 if successful |
*/ |
int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, |
unsigned char output[20] ); |
/** |
* \brief RIPEMD-160 process data block (internal use only) |
* |
* \param ctx RIPEMD-160 context |
* \param data buffer holding one block of data |
* |
* \return 0 if successful |
*/ |
int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, |
const unsigned char data[64] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief RIPEMD-160 context setup |
* |
* \deprecated Superseded by mbedtls_ripemd160_starts_ret() in 2.7.0 |
* |
* \param ctx context to be initialized |
*/ |
MBEDTLS_DEPRECATED void mbedtls_ripemd160_starts( |
mbedtls_ripemd160_context *ctx ); |
/** |
* \brief RIPEMD-160 process buffer |
* |
* \deprecated Superseded by mbedtls_ripemd160_update_ret() in 2.7.0 |
* |
* \param ctx RIPEMD-160 context |
* \param input buffer holding the data |
* \param ilen length of the input data |
*/ |
MBEDTLS_DEPRECATED void mbedtls_ripemd160_update( |
mbedtls_ripemd160_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief RIPEMD-160 final digest |
* |
* \deprecated Superseded by mbedtls_ripemd160_finish_ret() in 2.7.0 |
* |
* \param ctx RIPEMD-160 context |
* \param output RIPEMD-160 checksum result |
*/ |
MBEDTLS_DEPRECATED void mbedtls_ripemd160_finish( |
mbedtls_ripemd160_context *ctx, |
unsigned char output[20] ); |
/** |
* \brief RIPEMD-160 process data block (internal use only) |
* |
* \deprecated Superseded by mbedtls_internal_ripemd160_process() in 2.7.0 |
* |
* \param ctx RIPEMD-160 context |
* \param data buffer holding one block of data |
*/ |
MBEDTLS_DEPRECATED void mbedtls_ripemd160_process( |
mbedtls_ripemd160_context *ctx, |
const unsigned char data[64] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Output = RIPEMD-160( input buffer ) |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output RIPEMD-160 checksum result |
* |
* \return 0 if successful |
*/ |
int mbedtls_ripemd160_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Output = RIPEMD-160( input buffer ) |
* |
* \deprecated Superseded by mbedtls_ripemd160_ret() in 2.7.0 |
* |
* \param input buffer holding the data |
* \param ilen length of the input data |
* \param output RIPEMD-160 checksum result |
*/ |
MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_ripemd160_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_ripemd160.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/rsa.h |
---|
0,0 → 1,1276 |
/** |
* \file rsa.h |
* |
* \brief This file provides an API for the RSA public-key cryptosystem. |
* |
* The RSA public-key cryptosystem is defined in <em>Public-Key |
* Cryptography Standards (PKCS) #1 v1.5: RSA Encryption</em> |
* and <em>Public-Key Cryptography Standards (PKCS) #1 v2.1: |
* RSA Cryptography Specifications</em>. |
* |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_RSA_H |
#define MBEDTLS_RSA_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "bignum.h" |
#include "md.h" |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
/* |
* RSA Error codes |
*/ |
#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */ |
#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */ |
#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the validity check of the library. */ |
#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */ |
#define MBEDTLS_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */ |
#define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */ |
#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */ |
#define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */ |
/* MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is deprecated and should not be used. |
*/ |
#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION -0x4500 /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */ |
/* MBEDTLS_ERR_RSA_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED -0x4580 /**< RSA hardware accelerator failed. */ |
/* |
* RSA constants |
*/ |
#define MBEDTLS_RSA_PUBLIC 0 /**< Request private key operation. */ |
#define MBEDTLS_RSA_PRIVATE 1 /**< Request public key operation. */ |
#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */ |
#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */ |
#define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */ |
#define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */ |
#define MBEDTLS_RSA_SALT_LEN_ANY -1 |
/* |
* The above constants may be used even if the RSA module is compile out, |
* eg for alternative (PKCS#11) RSA implemenations in the PK layers. |
*/ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_RSA_ALT) |
// Regular implementation |
// |
/** |
* \brief The RSA context structure. |
* |
* \note Direct manipulation of the members of this structure |
* is deprecated. All manipulation should instead be done through |
* the public interface functions. |
*/ |
typedef struct mbedtls_rsa_context |
{ |
int ver; /*!< Always 0.*/ |
size_t len; /*!< The size of \p N in Bytes. */ |
mbedtls_mpi N; /*!< The public modulus. */ |
mbedtls_mpi E; /*!< The public exponent. */ |
mbedtls_mpi D; /*!< The private exponent. */ |
mbedtls_mpi P; /*!< The first prime factor. */ |
mbedtls_mpi Q; /*!< The second prime factor. */ |
mbedtls_mpi DP; /*!< <code>D % (P - 1)</code>. */ |
mbedtls_mpi DQ; /*!< <code>D % (Q - 1)</code>. */ |
mbedtls_mpi QP; /*!< <code>1 / (Q % P)</code>. */ |
mbedtls_mpi RN; /*!< cached <code>R^2 mod N</code>. */ |
mbedtls_mpi RP; /*!< cached <code>R^2 mod P</code>. */ |
mbedtls_mpi RQ; /*!< cached <code>R^2 mod Q</code>. */ |
mbedtls_mpi Vi; /*!< The cached blinding value. */ |
mbedtls_mpi Vf; /*!< The cached un-blinding value. */ |
int padding; /*!< Selects padding mode: |
#MBEDTLS_RSA_PKCS_V15 for 1.5 padding and |
#MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ |
int hash_id; /*!< Hash identifier of mbedtls_md_type_t type, |
as specified in md.h for use in the MGF |
mask generating function used in the |
EME-OAEP and EMSA-PSS encodings. */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */ |
#endif |
} |
mbedtls_rsa_context; |
#else /* MBEDTLS_RSA_ALT */ |
#include "rsa_alt.h" |
#endif /* MBEDTLS_RSA_ALT */ |
/** |
* \brief This function initializes an RSA context. |
* |
* \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP |
* encryption scheme and the RSASSA-PSS signature scheme. |
* |
* \note The \p hash_id parameter is ignored when using |
* #MBEDTLS_RSA_PKCS_V15 padding. |
* |
* \note The choice of padding mode is strictly enforced for private key |
* operations, since there might be security concerns in |
* mixing padding modes. For public key operations it is |
* a default value, which can be overridden by calling specific |
* \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions. |
* |
* \note The hash selected in \p hash_id is always used for OEAP |
* encryption. For PSS signatures, it is always used for |
* making signatures, but can be overridden for verifying them. |
* If set to #MBEDTLS_MD_NONE, it is always overridden. |
* |
* \param ctx The RSA context to initialize. This must not be \c NULL. |
* \param padding The padding mode to use. This must be either |
* #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. |
* \param hash_id The hash identifier of ::mbedtls_md_type_t type, if |
* \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused |
* otherwise. |
*/ |
void mbedtls_rsa_init( mbedtls_rsa_context *ctx, |
int padding, |
int hash_id ); |
/** |
* \brief This function imports a set of core parameters into an |
* RSA context. |
* |
* \note This function can be called multiple times for successive |
* imports, if the parameters are not simultaneously present. |
* |
* Any sequence of calls to this function should be followed |
* by a call to mbedtls_rsa_complete(), which checks and |
* completes the provided information to a ready-for-use |
* public or private RSA key. |
* |
* \note See mbedtls_rsa_complete() for more information on which |
* parameters are necessary to set up a private or public |
* RSA key. |
* |
* \note The imported parameters are copied and need not be preserved |
* for the lifetime of the RSA context being set up. |
* |
* \param ctx The initialized RSA context to store the parameters in. |
* \param N The RSA modulus. This may be \c NULL. |
* \param P The first prime factor of \p N. This may be \c NULL. |
* \param Q The second prime factor of \p N. This may be \c NULL. |
* \param D The private exponent. This may be \c NULL. |
* \param E The public exponent. This may be \c NULL. |
* |
* \return \c 0 on success. |
* \return A non-zero error code on failure. |
*/ |
int mbedtls_rsa_import( mbedtls_rsa_context *ctx, |
const mbedtls_mpi *N, |
const mbedtls_mpi *P, const mbedtls_mpi *Q, |
const mbedtls_mpi *D, const mbedtls_mpi *E ); |
/** |
* \brief This function imports core RSA parameters, in raw big-endian |
* binary format, into an RSA context. |
* |
* \note This function can be called multiple times for successive |
* imports, if the parameters are not simultaneously present. |
* |
* Any sequence of calls to this function should be followed |
* by a call to mbedtls_rsa_complete(), which checks and |
* completes the provided information to a ready-for-use |
* public or private RSA key. |
* |
* \note See mbedtls_rsa_complete() for more information on which |
* parameters are necessary to set up a private or public |
* RSA key. |
* |
* \note The imported parameters are copied and need not be preserved |
* for the lifetime of the RSA context being set up. |
* |
* \param ctx The initialized RSA context to store the parameters in. |
* \param N The RSA modulus. This may be \c NULL. |
* \param N_len The Byte length of \p N; it is ignored if \p N == NULL. |
* \param P The first prime factor of \p N. This may be \c NULL. |
* \param P_len The Byte length of \p P; it ns ignored if \p P == NULL. |
* \param Q The second prime factor of \p N. This may be \c NULL. |
* \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL. |
* \param D The private exponent. This may be \c NULL. |
* \param D_len The Byte length of \p D; it is ignored if \p D == NULL. |
* \param E The public exponent. This may be \c NULL. |
* \param E_len The Byte length of \p E; it is ignored if \p E == NULL. |
* |
* \return \c 0 on success. |
* \return A non-zero error code on failure. |
*/ |
int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, |
unsigned char const *N, size_t N_len, |
unsigned char const *P, size_t P_len, |
unsigned char const *Q, size_t Q_len, |
unsigned char const *D, size_t D_len, |
unsigned char const *E, size_t E_len ); |
/** |
* \brief This function completes an RSA context from |
* a set of imported core parameters. |
* |
* To setup an RSA public key, precisely \p N and \p E |
* must have been imported. |
* |
* To setup an RSA private key, sufficient information must |
* be present for the other parameters to be derivable. |
* |
* The default implementation supports the following: |
* <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li> |
* <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul> |
* Alternative implementations need not support these. |
* |
* If this function runs successfully, it guarantees that |
* the RSA context can be used for RSA operations without |
* the risk of failure or crash. |
* |
* \warning This function need not perform consistency checks |
* for the imported parameters. In particular, parameters that |
* are not needed by the implementation might be silently |
* discarded and left unchecked. To check the consistency |
* of the key material, see mbedtls_rsa_check_privkey(). |
* |
* \param ctx The initialized RSA context holding imported parameters. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations |
* failed. |
* |
*/ |
int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); |
/** |
* \brief This function exports the core parameters of an RSA key. |
* |
* If this function runs successfully, the non-NULL buffers |
* pointed to by \p N, \p P, \p Q, \p D, and \p E are fully |
* written, with additional unused space filled leading by |
* zero Bytes. |
* |
* Possible reasons for returning |
* #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:<ul> |
* <li>An alternative RSA implementation is in use, which |
* stores the key externally, and either cannot or should |
* not export it into RAM.</li> |
* <li>A SW or HW implementation might not support a certain |
* deduction. For example, \p P, \p Q from \p N, \p D, |
* and \p E if the former are not part of the |
* implementation.</li></ul> |
* |
* If the function fails due to an unsupported operation, |
* the RSA context stays intact and remains usable. |
* |
* \param ctx The initialized RSA context. |
* \param N The MPI to hold the RSA modulus. |
* This may be \c NULL if this field need not be exported. |
* \param P The MPI to hold the first prime factor of \p N. |
* This may be \c NULL if this field need not be exported. |
* \param Q The MPI to hold the second prime factor of \p N. |
* This may be \c NULL if this field need not be exported. |
* \param D The MPI to hold the private exponent. |
* This may be \c NULL if this field need not be exported. |
* \param E The MPI to hold the public exponent. |
* This may be \c NULL if this field need not be exported. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the |
* requested parameters cannot be done due to missing |
* functionality or because of security policies. |
* \return A non-zero return code on any other failure. |
* |
*/ |
int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, |
mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, |
mbedtls_mpi *D, mbedtls_mpi *E ); |
/** |
* \brief This function exports core parameters of an RSA key |
* in raw big-endian binary format. |
* |
* If this function runs successfully, the non-NULL buffers |
* pointed to by \p N, \p P, \p Q, \p D, and \p E are fully |
* written, with additional unused space filled leading by |
* zero Bytes. |
* |
* Possible reasons for returning |
* #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:<ul> |
* <li>An alternative RSA implementation is in use, which |
* stores the key externally, and either cannot or should |
* not export it into RAM.</li> |
* <li>A SW or HW implementation might not support a certain |
* deduction. For example, \p P, \p Q from \p N, \p D, |
* and \p E if the former are not part of the |
* implementation.</li></ul> |
* If the function fails due to an unsupported operation, |
* the RSA context stays intact and remains usable. |
* |
* \note The length parameters are ignored if the corresponding |
* buffer pointers are NULL. |
* |
* \param ctx The initialized RSA context. |
* \param N The Byte array to store the RSA modulus, |
* or \c NULL if this field need not be exported. |
* \param N_len The size of the buffer for the modulus. |
* \param P The Byte array to hold the first prime factor of \p N, |
* or \c NULL if this field need not be exported. |
* \param P_len The size of the buffer for the first prime factor. |
* \param Q The Byte array to hold the second prime factor of \p N, |
* or \c NULL if this field need not be exported. |
* \param Q_len The size of the buffer for the second prime factor. |
* \param D The Byte array to hold the private exponent, |
* or \c NULL if this field need not be exported. |
* \param D_len The size of the buffer for the private exponent. |
* \param E The Byte array to hold the public exponent, |
* or \c NULL if this field need not be exported. |
* \param E_len The size of the buffer for the public exponent. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the |
* requested parameters cannot be done due to missing |
* functionality or because of security policies. |
* \return A non-zero return code on any other failure. |
*/ |
int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, |
unsigned char *N, size_t N_len, |
unsigned char *P, size_t P_len, |
unsigned char *Q, size_t Q_len, |
unsigned char *D, size_t D_len, |
unsigned char *E, size_t E_len ); |
/** |
* \brief This function exports CRT parameters of a private RSA key. |
* |
* \note Alternative RSA implementations not using CRT-parameters |
* internally can implement this function based on |
* mbedtls_rsa_deduce_opt(). |
* |
* \param ctx The initialized RSA context. |
* \param DP The MPI to hold \c D modulo `P-1`, |
* or \c NULL if it need not be exported. |
* \param DQ The MPI to hold \c D modulo `Q-1`, |
* or \c NULL if it need not be exported. |
* \param QP The MPI to hold modular inverse of \c Q modulo \c P, |
* or \c NULL if it need not be exported. |
* |
* \return \c 0 on success. |
* \return A non-zero error code on failure. |
* |
*/ |
int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, |
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ); |
/** |
* \brief This function sets padding for an already initialized RSA |
* context. See mbedtls_rsa_init() for details. |
* |
* \param ctx The initialized RSA context to be configured. |
* \param padding The padding mode to use. This must be either |
* #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. |
* \param hash_id The #MBEDTLS_RSA_PKCS_V21 hash identifier. |
*/ |
void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, |
int hash_id ); |
/** |
* \brief This function retrieves the length of RSA modulus in Bytes. |
* |
* \param ctx The initialized RSA context. |
* |
* \return The length of the RSA modulus in Bytes. |
* |
*/ |
size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ); |
/** |
* \brief This function generates an RSA keypair. |
* |
* \note mbedtls_rsa_init() must be called before this function, |
* to set up the RSA context. |
* |
* \param ctx The initialized RSA context used to hold the key. |
* \param f_rng The RNG function to be used for key generation. |
* This must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. |
* This may be \c NULL if \p f_rng doesn't need a context. |
* \param nbits The size of the public key in bits. |
* \param exponent The public exponent to use. For example, \c 65537. |
* This must be odd and greater than \c 1. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
unsigned int nbits, int exponent ); |
/** |
* \brief This function checks if a context contains at least an RSA |
* public key. |
* |
* If the function runs successfully, it is guaranteed that |
* enough information is present to perform an RSA public key |
* operation using mbedtls_rsa_public(). |
* |
* \param ctx The initialized RSA context to check. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
* |
*/ |
int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); |
/** |
* \brief This function checks if a context contains an RSA private key |
* and perform basic consistency checks. |
* |
* \note The consistency checks performed by this function not only |
* ensure that mbedtls_rsa_private() can be called successfully |
* on the given context, but that the various parameters are |
* mutually consistent with high probability, in the sense that |
* mbedtls_rsa_public() and mbedtls_rsa_private() are inverses. |
* |
* \warning This function should catch accidental misconfigurations |
* like swapping of parameters, but it cannot establish full |
* trust in neither the quality nor the consistency of the key |
* material that was used to setup the given RSA context: |
* <ul><li>Consistency: Imported parameters that are irrelevant |
* for the implementation might be silently dropped. If dropped, |
* the current function does not have access to them, |
* and therefore cannot check them. See mbedtls_rsa_complete(). |
* If you want to check the consistency of the entire |
* content of an PKCS1-encoded RSA private key, for example, you |
* should use mbedtls_rsa_validate_params() before setting |
* up the RSA context. |
* Additionally, if the implementation performs empirical checks, |
* these checks substantiate but do not guarantee consistency.</li> |
* <li>Quality: This function is not expected to perform |
* extended quality assessments like checking that the prime |
* factors are safe. Additionally, it is the responsibility of the |
* user to ensure the trustworthiness of the source of his RSA |
* parameters, which goes beyond what is effectively checkable |
* by the library.</li></ul> |
* |
* \param ctx The initialized RSA context to check. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); |
/** |
* \brief This function checks a public-private RSA key pair. |
* |
* It checks each of the contexts, and makes sure they match. |
* |
* \param pub The initialized RSA context holding the public key. |
* \param prv The initialized RSA context holding the private key. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, |
const mbedtls_rsa_context *prv ); |
/** |
* \brief This function performs an RSA public key operation. |
* |
* \param ctx The initialized RSA context to use. |
* \param input The input buffer. This must be a readable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* \param output The output buffer. This must be a writable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \note This function does not handle message padding. |
* |
* \note Make sure to set \p input[0] = 0 or ensure that |
* input is smaller than \p N. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_public( mbedtls_rsa_context *ctx, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function performs an RSA private key operation. |
* |
* \note Blinding is used if and only if a PRNG is provided. |
* |
* \note If blinding is used, both the base of exponentation |
* and the exponent are blinded, providing protection |
* against some side-channel attacks. |
* |
* \warning It is deprecated and a security risk to not provide |
* a PRNG here and thereby prevent the use of blinding. |
* Future versions of the library may enforce the presence |
* of a PRNG. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function, used for blinding. It is discouraged |
* and deprecated to pass \c NULL here, in which case |
* blinding will be omitted. |
* \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL |
* if \p f_rng is \c NULL or if \p f_rng doesn't need a context. |
* \param input The input buffer. This must be a readable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* \param output The output buffer. This must be a writable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
* |
*/ |
int mbedtls_rsa_private( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function adds the message padding, then performs an RSA |
* operation. |
* |
* It is the generic wrapper for performing a PKCS#1 encryption |
* operation using the \p mode from the context. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PUBLIC. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG to use. It is mandatory for PKCS#1 v2.1 padding |
* encoding, and for PKCS#1 v1.5 padding encoding when used |
* with \p mode set to #MBEDTLS_RSA_PUBLIC. For PKCS#1 v1.5 |
* padding encoding and \p mode set to #MBEDTLS_RSA_PRIVATE, |
* it is used for blinding and should be provided in this |
* case; see mbedtls_rsa_private() for more. |
* \param p_rng The RNG context to be passed to \p f_rng. May be |
* \c NULL if \p f_rng is \c NULL or if \p f_rng doesn't |
* need a context argument. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). |
* \param ilen The length of the plaintext in Bytes. |
* \param input The input data to encrypt. This must be a readable |
* buffer of size \p ilen Bytes. This must not be \c NULL. |
* \param output The output buffer. This must be a writable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t ilen, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function performs a PKCS#1 v1.5 encryption operation |
* (RSAES-PKCS1-v1_5-ENCRYPT). |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PUBLIC. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function to use. It is needed for padding generation |
* if \p mode is #MBEDTLS_RSA_PUBLIC. If \p mode is |
* #MBEDTLS_RSA_PRIVATE (discouraged), it is used for |
* blinding and should be provided; see mbedtls_rsa_private(). |
* \param p_rng The RNG context to be passed to \p f_rng. This may |
* be \c NULL if \p f_rng is \c NULL or if \p f_rng |
* doesn't need a context argument. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). |
* \param ilen The length of the plaintext in Bytes. |
* \param input The input data to encrypt. This must be a readable |
* buffer of size \p ilen Bytes. This must not be \c NULL. |
* \param output The output buffer. This must be a writable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t ilen, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function performs a PKCS#1 v2.1 OAEP encryption |
* operation (RSAES-OAEP-ENCRYPT). |
* |
* \note The output buffer must be as large as the size |
* of ctx->N. For example, 128 Bytes if RSA-1024 is used. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PUBLIC. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initnialized RSA context to use. |
* \param f_rng The RNG function to use. This is needed for padding |
* generation and must be provided. |
* \param p_rng The RNG context to be passed to \p f_rng. This may |
* be \c NULL if \p f_rng doesn't need a context argument. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). |
* \param label The buffer holding the custom label to use. |
* This must be a readable buffer of length \p label_len |
* Bytes. It may be \c NULL if \p label_len is \c 0. |
* \param label_len The length of the label in Bytes. |
* \param ilen The length of the plaintext buffer \p input in Bytes. |
* \param input The input data to encrypt. This must be a readable |
* buffer of size \p ilen Bytes. This must not be \c NULL. |
* \param output The output buffer. This must be a writable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
const unsigned char *label, size_t label_len, |
size_t ilen, |
const unsigned char *input, |
unsigned char *output ); |
/** |
* \brief This function performs an RSA operation, then removes the |
* message padding. |
* |
* It is the generic wrapper for performing a PKCS#1 decryption |
* operation using the \p mode from the context. |
* |
* \note The output buffer length \c output_max_len should be |
* as large as the size \p ctx->len of \p ctx->N (for example, |
* 128 Bytes if RSA-1024 is used) to be able to hold an |
* arbitrary decrypted message. If it is not large enough to |
* hold the decryption of the particular ciphertext provided, |
* the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PRIVATE. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PUBLIC and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. If \p mode is |
* #MBEDTLS_RSA_PUBLIC, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). |
* \param olen The address at which to store the length of |
* the plaintext. This must not be \c NULL. |
* \param input The ciphertext buffer. This must be a readable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* \param output The buffer used to hold the plaintext. This must |
* be a writable buffer of length \p output_max_len Bytes. |
* \param output_max_len The length in Bytes of the output buffer \p output. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ); |
/** |
* \brief This function performs a PKCS#1 v1.5 decryption |
* operation (RSAES-PKCS1-v1_5-DECRYPT). |
* |
* \note The output buffer length \c output_max_len should be |
* as large as the size \p ctx->len of \p ctx->N, for example, |
* 128 Bytes if RSA-1024 is used, to be able to hold an |
* arbitrary decrypted message. If it is not large enough to |
* hold the decryption of the particular ciphertext provided, |
* the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PRIVATE. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PUBLIC and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. If \p mode is |
* #MBEDTLS_RSA_PUBLIC, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). |
* \param olen The address at which to store the length of |
* the plaintext. This must not be \c NULL. |
* \param input The ciphertext buffer. This must be a readable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* \param output The buffer used to hold the plaintext. This must |
* be a writable buffer of length \p output_max_len Bytes. |
* \param output_max_len The length in Bytes of the output buffer \p output. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
* |
*/ |
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ); |
/** |
* \brief This function performs a PKCS#1 v2.1 OAEP decryption |
* operation (RSAES-OAEP-DECRYPT). |
* |
* \note The output buffer length \c output_max_len should be |
* as large as the size \p ctx->len of \p ctx->N, for |
* example, 128 Bytes if RSA-1024 is used, to be able to |
* hold an arbitrary decrypted message. If it is not |
* large enough to hold the decryption of the particular |
* ciphertext provided, the function returns |
* #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PRIVATE. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PUBLIC and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. If \p mode is |
* #MBEDTLS_RSA_PUBLIC, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). |
* \param label The buffer holding the custom label to use. |
* This must be a readable buffer of length \p label_len |
* Bytes. It may be \c NULL if \p label_len is \c 0. |
* \param label_len The length of the label in Bytes. |
* \param olen The address at which to store the length of |
* the plaintext. This must not be \c NULL. |
* \param input The ciphertext buffer. This must be a readable buffer |
* of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* \param output The buffer used to hold the plaintext. This must |
* be a writable buffer of length \p output_max_len Bytes. |
* \param output_max_len The length in Bytes of the output buffer \p output. |
* |
* \return \c 0 on success. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
const unsigned char *label, size_t label_len, |
size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ); |
/** |
* \brief This function performs a private RSA operation to sign |
* a message digest using PKCS#1. |
* |
* It is the generic wrapper for performing a PKCS#1 |
* signature using the \p mode from the context. |
* |
* \note The \p sig buffer must be as large as the size |
* of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. |
* |
* \note For PKCS#1 v2.1 encoding, see comments on |
* mbedtls_rsa_rsassa_pss_sign() for details on |
* \p md_alg and \p hash_id. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PRIVATE. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PUBLIC and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function to use. If the padding mode is PKCS#1 v2.1, |
* this must be provided. If the padding mode is PKCS#1 v1.5 and |
* \p mode is #MBEDTLS_RSA_PRIVATE, it is used for blinding |
* and should be provided; see mbedtls_rsa_private() for more |
* more. It is ignored otherwise. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL |
* if \p f_rng is \c NULL or doesn't need a context argument. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param sig The buffer to hold the signature. This must be a writable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. A buffer length of |
* #MBEDTLS_MPI_MAX_SIZE is always safe. |
* |
* \return \c 0 if the signing operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ); |
/** |
* \brief This function performs a PKCS#1 v1.5 signature |
* operation (RSASSA-PKCS1-v1_5-SIGN). |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PRIVATE. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PUBLIC and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. If \p mode is |
* #MBEDTLS_RSA_PUBLIC, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL |
* if \p f_rng is \c NULL or doesn't need a context argument. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param sig The buffer to hold the signature. This must be a writable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. A buffer length of |
* #MBEDTLS_MPI_MAX_SIZE is always safe. |
* |
* \return \c 0 if the signing operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ); |
/** |
* \brief This function performs a PKCS#1 v2.1 PSS signature |
* operation (RSASSA-PSS-SIGN). |
* |
* \note The \p hash_id in the RSA context is the one used for the |
* encoding. \p md_alg in the function call is the type of hash |
* that is encoded. According to <em>RFC-3447: Public-Key |
* Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography |
* Specifications</em> it is advised to keep both hashes the |
* same. |
* |
* \note This function always uses the maximum possible salt size, |
* up to the length of the payload hash. This choice of salt |
* size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 |
* v2.2) §9.1.1 step 3. Furthermore this function enforces a |
* minimum salt size which is the hash size minus 2 bytes. If |
* this minimum size is too large given the key size (the salt |
* size, plus the hash size, plus 2 bytes must be no more than |
* the key size in bytes), this function returns |
* #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PRIVATE. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PUBLIC and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA context to use. |
* \param f_rng The RNG function. It must not be \c NULL. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL |
* if \p f_rng doesn't need a context argument. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param sig The buffer to hold the signature. This must be a writable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. A buffer length of |
* #MBEDTLS_MPI_MAX_SIZE is always safe. |
* |
* \return \c 0 if the signing operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ); |
/** |
* \brief This function performs a public RSA operation and checks |
* the message digest. |
* |
* This is the generic wrapper for performing a PKCS#1 |
* verification using the mode from the context. |
* |
* \note For PKCS#1 v2.1 encoding, see comments on |
* mbedtls_rsa_rsassa_pss_verify() about \p md_alg and |
* \p hash_id. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* set to #MBEDTLS_RSA_PUBLIC. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA public key context to use. |
* \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. Otherwise, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* This is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param sig The buffer holding the signature. This must be a readable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 if the verify operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
const unsigned char *sig ); |
/** |
* \brief This function performs a PKCS#1 v1.5 verification |
* operation (RSASSA-PKCS1-v1_5-VERIFY). |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* set to #MBEDTLS_RSA_PUBLIC. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA public key context to use. |
* \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. Otherwise, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* This is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param sig The buffer holding the signature. This must be a readable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 if the verify operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
const unsigned char *sig ); |
/** |
* \brief This function performs a PKCS#1 v2.1 PSS verification |
* operation (RSASSA-PSS-VERIFY). |
* |
* The hash function for the MGF mask generating function |
* is that specified in the RSA context. |
* |
* \note The \p hash_id in the RSA context is the one used for the |
* verification. \p md_alg in the function call is the type of |
* hash that is verified. According to <em>RFC-3447: Public-Key |
* Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography |
* Specifications</em> it is advised to keep both hashes the |
* same. If \p hash_id in the RSA context is unset, |
* the \p md_alg from the function call is used. |
* |
* \deprecated It is deprecated and discouraged to call this function |
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library |
* are likely to remove the \p mode argument and have it |
* implicitly set to #MBEDTLS_RSA_PUBLIC. |
* |
* \note Alternative implementations of RSA need not support |
* mode being set to #MBEDTLS_RSA_PRIVATE and might instead |
* return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. |
* |
* \param ctx The initialized RSA public key context to use. |
* \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. Otherwise, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* This is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param sig The buffer holding the signature. This must be a readable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 if the verify operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
const unsigned char *sig ); |
/** |
* \brief This function performs a PKCS#1 v2.1 PSS verification |
* operation (RSASSA-PSS-VERIFY). |
* |
* The hash function for the MGF mask generating function |
* is that specified in \p mgf1_hash_id. |
* |
* \note The \p sig buffer must be as large as the size |
* of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. |
* |
* \note The \p hash_id in the RSA context is ignored. |
* |
* \param ctx The initialized RSA public key context to use. |
* \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, |
* this is used for blinding and should be provided; see |
* mbedtls_rsa_private() for more. Otherwise, it is ignored. |
* \param p_rng The RNG context to be passed to \p f_rng. This may be |
* \c NULL if \p f_rng is \c NULL or doesn't need a context. |
* \param mode The mode of operation. This must be either |
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. |
* \param md_alg The message-digest algorithm used to hash the original data. |
* Use #MBEDTLS_MD_NONE for signing raw data. |
* \param hashlen The length of the message digest. |
* This is only used if \p md_alg is #MBEDTLS_MD_NONE. |
* \param hash The buffer holding the message digest or raw data. |
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable |
* buffer of length \p hashlen Bytes. If \p md_alg is not |
* #MBEDTLS_MD_NONE, it must be a readable buffer of length |
* the size of the hash corresponding to \p md_alg. |
* \param mgf1_hash_id The message digest used for mask generation. |
* \param expected_salt_len The length of the salt used in padding. Use |
* #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. |
* \param sig The buffer holding the signature. This must be a readable |
* buffer of length \c ctx->len Bytes. For example, \c 256 Bytes |
* for an 2048-bit RSA modulus. |
* |
* \return \c 0 if the verify operation was successful. |
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. |
*/ |
int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
mbedtls_md_type_t mgf1_hash_id, |
int expected_salt_len, |
const unsigned char *sig ); |
/** |
* \brief This function copies the components of an RSA context. |
* |
* \param dst The destination context. This must be initialized. |
* \param src The source context. This must be initialized. |
* |
* \return \c 0 on success. |
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. |
*/ |
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ); |
/** |
* \brief This function frees the components of an RSA key. |
* |
* \param ctx The RSA context to free. May be \c NULL, in which case |
* this function is a no-op. If it is not \c NULL, it must |
* point to an initialized RSA context. |
*/ |
void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The RSA checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_rsa_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* rsa.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/rsa_internal.h |
---|
0,0 → 1,228 |
/** |
* \file rsa_internal.h |
* |
* \brief Context-independent RSA helper functions |
* |
* This module declares some RSA-related helper functions useful when |
* implementing the RSA interface. These functions are provided in a separate |
* compilation unit in order to make it easy for designers of alternative RSA |
* implementations to use them in their own code, as it is conceived that the |
* functionality they provide will be necessary for most complete |
* implementations. |
* |
* End-users of Mbed TLS who are not providing their own alternative RSA |
* implementations should not use these functions directly, and should instead |
* use only the functions declared in rsa.h. |
* |
* The interface provided by this module will be maintained through LTS (Long |
* Term Support) branches of Mbed TLS, but may otherwise be subject to change, |
* and must be considered an internal interface of the library. |
* |
* There are two classes of helper functions: |
* |
* (1) Parameter-generating helpers. These are: |
* - mbedtls_rsa_deduce_primes |
* - mbedtls_rsa_deduce_private_exponent |
* - mbedtls_rsa_deduce_crt |
* Each of these functions takes a set of core RSA parameters and |
* generates some other, or CRT related parameters. |
* |
* (2) Parameter-checking helpers. These are: |
* - mbedtls_rsa_validate_params |
* - mbedtls_rsa_validate_crt |
* They take a set of core or CRT related RSA parameters and check their |
* validity. |
* |
*/ |
/* |
* Copyright (C) 2006-2017, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
* |
*/ |
#ifndef MBEDTLS_RSA_INTERNAL_H |
#define MBEDTLS_RSA_INTERNAL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "bignum.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Compute RSA prime moduli P, Q from public modulus N=PQ |
* and a pair of private and public key. |
* |
* \note This is a 'static' helper function not operating on |
* an RSA context. Alternative implementations need not |
* overwrite it. |
* |
* \param N RSA modulus N = PQ, with P, Q to be found |
* \param E RSA public exponent |
* \param D RSA private exponent |
* \param P Pointer to MPI holding first prime factor of N on success |
* \param Q Pointer to MPI holding second prime factor of N on success |
* |
* \return |
* - 0 if successful. In this case, P and Q constitute a |
* factorization of N. |
* - A non-zero error code otherwise. |
* |
* \note It is neither checked that P, Q are prime nor that |
* D, E are modular inverses wrt. P-1 and Q-1. For that, |
* use the helper function \c mbedtls_rsa_validate_params. |
* |
*/ |
int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, mbedtls_mpi const *E, |
mbedtls_mpi const *D, |
mbedtls_mpi *P, mbedtls_mpi *Q ); |
/** |
* \brief Compute RSA private exponent from |
* prime moduli and public key. |
* |
* \note This is a 'static' helper function not operating on |
* an RSA context. Alternative implementations need not |
* overwrite it. |
* |
* \param P First prime factor of RSA modulus |
* \param Q Second prime factor of RSA modulus |
* \param E RSA public exponent |
* \param D Pointer to MPI holding the private exponent on success. |
* |
* \return |
* - 0 if successful. In this case, D is set to a simultaneous |
* modular inverse of E modulo both P-1 and Q-1. |
* - A non-zero error code otherwise. |
* |
* \note This function does not check whether P and Q are primes. |
* |
*/ |
int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, |
mbedtls_mpi const *Q, |
mbedtls_mpi const *E, |
mbedtls_mpi *D ); |
/** |
* \brief Generate RSA-CRT parameters |
* |
* \note This is a 'static' helper function not operating on |
* an RSA context. Alternative implementations need not |
* overwrite it. |
* |
* \param P First prime factor of N |
* \param Q Second prime factor of N |
* \param D RSA private exponent |
* \param DP Output variable for D modulo P-1 |
* \param DQ Output variable for D modulo Q-1 |
* \param QP Output variable for the modular inverse of Q modulo P. |
* |
* \return 0 on success, non-zero error code otherwise. |
* |
* \note This function does not check whether P, Q are |
* prime and whether D is a valid private exponent. |
* |
*/ |
int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, |
const mbedtls_mpi *D, mbedtls_mpi *DP, |
mbedtls_mpi *DQ, mbedtls_mpi *QP ); |
/** |
* \brief Check validity of core RSA parameters |
* |
* \note This is a 'static' helper function not operating on |
* an RSA context. Alternative implementations need not |
* overwrite it. |
* |
* \param N RSA modulus N = PQ |
* \param P First prime factor of N |
* \param Q Second prime factor of N |
* \param D RSA private exponent |
* \param E RSA public exponent |
* \param f_rng PRNG to be used for primality check, or NULL |
* \param p_rng PRNG context for f_rng, or NULL |
* |
* \return |
* - 0 if the following conditions are satisfied |
* if all relevant parameters are provided: |
* - P prime if f_rng != NULL (%) |
* - Q prime if f_rng != NULL (%) |
* - 1 < N = P * Q |
* - 1 < D, E < N |
* - D and E are modular inverses modulo P-1 and Q-1 |
* (%) This is only done if MBEDTLS_GENPRIME is defined. |
* - A non-zero error code otherwise. |
* |
* \note The function can be used with a restricted set of arguments |
* to perform specific checks only. E.g., calling it with |
* (-,P,-,-,-) and a PRNG amounts to a primality check for P. |
*/ |
int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, |
const mbedtls_mpi *Q, const mbedtls_mpi *D, |
const mbedtls_mpi *E, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Check validity of RSA CRT parameters |
* |
* \note This is a 'static' helper function not operating on |
* an RSA context. Alternative implementations need not |
* overwrite it. |
* |
* \param P First prime factor of RSA modulus |
* \param Q Second prime factor of RSA modulus |
* \param D RSA private exponent |
* \param DP MPI to check for D modulo P-1 |
* \param DQ MPI to check for D modulo P-1 |
* \param QP MPI to check for the modular inverse of Q modulo P. |
* |
* \return |
* - 0 if the following conditions are satisfied: |
* - D = DP mod P-1 if P, D, DP != NULL |
* - Q = DQ mod P-1 if P, D, DQ != NULL |
* - QP = Q^-1 mod P if P, Q, QP != NULL |
* - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed, |
* potentially including \c MBEDTLS_ERR_MPI_XXX if some |
* MPI calculations failed. |
* - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient |
* data was provided to check DP, DQ or QP. |
* |
* \note The function can be used with a restricted set of arguments |
* to perform specific checks only. E.g., calling it with the |
* parameters (P, -, D, DP, -, -) will check DP = D mod P-1. |
*/ |
int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, |
const mbedtls_mpi *D, const mbedtls_mpi *DP, |
const mbedtls_mpi *DQ, const mbedtls_mpi *QP ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* rsa_internal.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/sha1.h |
---|
0,0 → 1,354 |
/** |
* \file sha1.h |
* |
* \brief This file contains SHA-1 definitions and functions. |
* |
* The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in |
* <em>FIPS 180-4: Secure Hash Standard (SHS)</em>. |
* |
* \warning SHA-1 is considered a weak message digest and its use constitutes |
* a security risk. We recommend considering stronger message |
* digests instead. |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SHA1_H |
#define MBEDTLS_SHA1_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED -0x0035 /**< SHA-1 hardware accelerator failed */ |
#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA -0x0073 /**< SHA-1 input data was malformed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_SHA1_ALT) |
// Regular implementation |
// |
/** |
* \brief The SHA-1 context structure. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
*/ |
typedef struct mbedtls_sha1_context |
{ |
uint32_t total[2]; /*!< The number of Bytes processed. */ |
uint32_t state[5]; /*!< The intermediate digest state. */ |
unsigned char buffer[64]; /*!< The data block being processed. */ |
} |
mbedtls_sha1_context; |
#else /* MBEDTLS_SHA1_ALT */ |
#include "sha1_alt.h" |
#endif /* MBEDTLS_SHA1_ALT */ |
/** |
* \brief This function initializes a SHA-1 context. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param ctx The SHA-1 context to initialize. |
* This must not be \c NULL. |
* |
*/ |
void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); |
/** |
* \brief This function clears a SHA-1 context. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param ctx The SHA-1 context to clear. This may be \c NULL, |
* in which case this function does nothing. If it is |
* not \c NULL, it must point to an initialized |
* SHA-1 context. |
* |
*/ |
void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); |
/** |
* \brief This function clones the state of a SHA-1 context. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param dst The SHA-1 context to clone to. This must be initialized. |
* \param src The SHA-1 context to clone from. This must be initialized. |
* |
*/ |
void mbedtls_sha1_clone( mbedtls_sha1_context *dst, |
const mbedtls_sha1_context *src ); |
/** |
* \brief This function starts a SHA-1 checksum calculation. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param ctx The SHA-1 context to initialize. This must be initialized. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
* |
*/ |
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ); |
/** |
* \brief This function feeds an input buffer into an ongoing SHA-1 |
* checksum calculation. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param ctx The SHA-1 context. This must be initialized |
* and have a hash operation started. |
* \param input The buffer holding the input data. |
* This must be a readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data \p input in Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the SHA-1 operation, and writes |
* the result to the output buffer. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param ctx The SHA-1 context to use. This must be initialized and |
* have a hash operation started. |
* \param output The SHA-1 checksum result. This must be a writable |
* buffer of length \c 20 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, |
unsigned char output[20] ); |
/** |
* \brief SHA-1 process data block (internal use only). |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param ctx The SHA-1 context to use. This must be initialized. |
* \param data The data block being processed. This must be a |
* readable buffer of length \c 64 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
* |
*/ |
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, |
const unsigned char data[64] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function starts a SHA-1 checksum calculation. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0. |
* |
* \param ctx The SHA-1 context to initialize. This must be initialized. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); |
/** |
* \brief This function feeds an input buffer into an ongoing SHA-1 |
* checksum calculation. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0. |
* |
* \param ctx The SHA-1 context. This must be initialized and |
* have a hash operation started. |
* \param input The buffer holding the input data. |
* This must be a readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data \p input in Bytes. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the SHA-1 operation, and writes |
* the result to the output buffer. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0. |
* |
* \param ctx The SHA-1 context. This must be initialized and |
* have a hash operation started. |
* \param output The SHA-1 checksum result. |
* This must be a writable buffer of length \c 20 Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, |
unsigned char output[20] ); |
/** |
* \brief SHA-1 process data block (internal use only). |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0. |
* |
* \param ctx The SHA-1 context. This must be initialized. |
* \param data The data block being processed. |
* This must be a readable buffer of length \c 64 bytes. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, |
const unsigned char data[64] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief This function calculates the SHA-1 checksum of a buffer. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The SHA-1 result is calculated as |
* output = SHA-1(input buffer). |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \param input The buffer holding the input data. |
* This must be a readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data \p input in Bytes. |
* \param output The SHA-1 checksum result. |
* This must be a writable buffer of length \c 20 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
* |
*/ |
int mbedtls_sha1_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function calculates the SHA-1 checksum of a buffer. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The SHA-1 result is calculated as |
* output = SHA-1(input buffer). |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \deprecated Superseded by mbedtls_sha1_ret() in 2.7.0 |
* |
* \param input The buffer holding the input data. |
* This must be a readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data \p input in Bytes. |
* \param output The SHA-1 checksum result. This must be a writable |
* buffer of size \c 20 Bytes. |
* |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The SHA-1 checkup routine. |
* |
* \warning SHA-1 is considered a weak message digest and its use |
* constitutes a security risk. We recommend considering |
* stronger message digests instead. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
* |
*/ |
int mbedtls_sha1_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_sha1.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/sha256.h |
---|
0,0 → 1,299 |
/** |
* \file sha256.h |
* |
* \brief This file contains SHA-224 and SHA-256 definitions and functions. |
* |
* The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic |
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>. |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SHA256_H |
#define MBEDTLS_SHA256_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED -0x0037 /**< SHA-256 hardware accelerator failed */ |
#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA -0x0074 /**< SHA-256 input data was malformed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_SHA256_ALT) |
// Regular implementation |
// |
/** |
* \brief The SHA-256 context structure. |
* |
* The structure is used both for SHA-256 and for SHA-224 |
* checksum calculations. The choice between these two is |
* made in the call to mbedtls_sha256_starts_ret(). |
*/ |
typedef struct mbedtls_sha256_context |
{ |
uint32_t total[2]; /*!< The number of Bytes processed. */ |
uint32_t state[8]; /*!< The intermediate digest state. */ |
unsigned char buffer[64]; /*!< The data block being processed. */ |
int is224; /*!< Determines which function to use: |
0: Use SHA-256, or 1: Use SHA-224. */ |
} |
mbedtls_sha256_context; |
#else /* MBEDTLS_SHA256_ALT */ |
#include "sha256_alt.h" |
#endif /* MBEDTLS_SHA256_ALT */ |
/** |
* \brief This function initializes a SHA-256 context. |
* |
* \param ctx The SHA-256 context to initialize. This must not be \c NULL. |
*/ |
void mbedtls_sha256_init( mbedtls_sha256_context *ctx ); |
/** |
* \brief This function clears a SHA-256 context. |
* |
* \param ctx The SHA-256 context to clear. This may be \c NULL, in which |
* case this function returns immediately. If it is not \c NULL, |
* it must point to an initialized SHA-256 context. |
*/ |
void mbedtls_sha256_free( mbedtls_sha256_context *ctx ); |
/** |
* \brief This function clones the state of a SHA-256 context. |
* |
* \param dst The destination context. This must be initialized. |
* \param src The context to clone. This must be initialized. |
*/ |
void mbedtls_sha256_clone( mbedtls_sha256_context *dst, |
const mbedtls_sha256_context *src ); |
/** |
* \brief This function starts a SHA-224 or SHA-256 checksum |
* calculation. |
* |
* \param ctx The context to use. This must be initialized. |
* \param is224 This determines which function to use. This must be |
* either \c 0 for SHA-256, or \c 1 for SHA-224. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); |
/** |
* \brief This function feeds an input buffer into an ongoing |
* SHA-256 checksum calculation. |
* |
* \param ctx The SHA-256 context. This must be initialized |
* and have a hash operation started. |
* \param input The buffer holding the data. This must be a readable |
* buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the SHA-256 operation, and writes |
* the result to the output buffer. |
* |
* \param ctx The SHA-256 context. This must be initialized |
* and have a hash operation started. |
* \param output The SHA-224 or SHA-256 checksum result. |
* This must be a writable buffer of length \c 32 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, |
unsigned char output[32] ); |
/** |
* \brief This function processes a single data block within |
* the ongoing SHA-256 computation. This function is for |
* internal use only. |
* |
* \param ctx The SHA-256 context. This must be initialized. |
* \param data The buffer holding one block of data. This must |
* be a readable buffer of length \c 64 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, |
const unsigned char data[64] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function starts a SHA-224 or SHA-256 checksum |
* calculation. |
* |
* \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0. |
* |
* \param ctx The context to use. This must be initialized. |
* \param is224 Determines which function to use. This must be |
* either \c 0 for SHA-256, or \c 1 for SHA-224. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, |
int is224 ); |
/** |
* \brief This function feeds an input buffer into an ongoing |
* SHA-256 checksum calculation. |
* |
* \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0. |
* |
* \param ctx The SHA-256 context to use. This must be |
* initialized and have a hash operation started. |
* \param input The buffer holding the data. This must be a readable |
* buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the SHA-256 operation, and writes |
* the result to the output buffer. |
* |
* \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0. |
* |
* \param ctx The SHA-256 context. This must be initialized and |
* have a hash operation started. |
* \param output The SHA-224 or SHA-256 checksum result. This must be |
* a writable buffer of length \c 32 Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, |
unsigned char output[32] ); |
/** |
* \brief This function processes a single data block within |
* the ongoing SHA-256 computation. This function is for |
* internal use only. |
* |
* \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0. |
* |
* \param ctx The SHA-256 context. This must be initialized. |
* \param data The buffer holding one block of data. This must be |
* a readable buffer of size \c 64 Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, |
const unsigned char data[64] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief This function calculates the SHA-224 or SHA-256 |
* checksum of a buffer. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The SHA-256 result is calculated as |
* output = SHA-256(input buffer). |
* |
* \param input The buffer holding the data. This must be a readable |
* buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* \param output The SHA-224 or SHA-256 checksum result. This must |
* be a writable buffer of length \c 32 Bytes. |
* \param is224 Determines which function to use. This must be |
* either \c 0 for SHA-256, or \c 1 for SHA-224. |
*/ |
int mbedtls_sha256_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[32], |
int is224 ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function calculates the SHA-224 or SHA-256 checksum |
* of a buffer. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The SHA-256 result is calculated as |
* output = SHA-256(input buffer). |
* |
* \deprecated Superseded by mbedtls_sha256_ret() in 2.7.0. |
* |
* \param input The buffer holding the data. This must be a readable |
* buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* \param output The SHA-224 or SHA-256 checksum result. This must be |
* a writable buffer of length \c 32 Bytes. |
* \param is224 Determines which function to use. This must be either |
* \c 0 for SHA-256, or \c 1 for SHA-224. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, |
size_t ilen, |
unsigned char output[32], |
int is224 ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The SHA-224 and SHA-256 checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_sha256_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_sha256.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/sha512.h |
---|
0,0 → 1,302 |
/** |
* \file sha512.h |
* \brief This file contains SHA-384 and SHA-512 definitions and functions. |
* |
* The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic |
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>. |
*/ |
/* |
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SHA512_H |
#define MBEDTLS_SHA512_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
/* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED -0x0039 /**< SHA-512 hardware accelerator failed */ |
#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA -0x0075 /**< SHA-512 input data was malformed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_SHA512_ALT) |
// Regular implementation |
// |
/** |
* \brief The SHA-512 context structure. |
* |
* The structure is used both for SHA-384 and for SHA-512 |
* checksum calculations. The choice between these two is |
* made in the call to mbedtls_sha512_starts_ret(). |
*/ |
typedef struct mbedtls_sha512_context |
{ |
uint64_t total[2]; /*!< The number of Bytes processed. */ |
uint64_t state[8]; /*!< The intermediate digest state. */ |
unsigned char buffer[128]; /*!< The data block being processed. */ |
int is384; /*!< Determines which function to use: |
0: Use SHA-512, or 1: Use SHA-384. */ |
} |
mbedtls_sha512_context; |
#else /* MBEDTLS_SHA512_ALT */ |
#include "sha512_alt.h" |
#endif /* MBEDTLS_SHA512_ALT */ |
/** |
* \brief This function initializes a SHA-512 context. |
* |
* \param ctx The SHA-512 context to initialize. This must |
* not be \c NULL. |
*/ |
void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); |
/** |
* \brief This function clears a SHA-512 context. |
* |
* \param ctx The SHA-512 context to clear. This may be \c NULL, |
* in which case this function does nothing. If it |
* is not \c NULL, it must point to an initialized |
* SHA-512 context. |
*/ |
void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); |
/** |
* \brief This function clones the state of a SHA-512 context. |
* |
* \param dst The destination context. This must be initialized. |
* \param src The context to clone. This must be initialized. |
*/ |
void mbedtls_sha512_clone( mbedtls_sha512_context *dst, |
const mbedtls_sha512_context *src ); |
/** |
* \brief This function starts a SHA-384 or SHA-512 checksum |
* calculation. |
* |
* \param ctx The SHA-512 context to use. This must be initialized. |
* \param is384 Determines which function to use. This must be |
* either \c for SHA-512, or \c 1 for SHA-384. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); |
/** |
* \brief This function feeds an input buffer into an ongoing |
* SHA-512 checksum calculation. |
* |
* \param ctx The SHA-512 context. This must be initialized |
* and have a hash operation started. |
* \param input The buffer holding the input data. This must |
* be a readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the SHA-512 operation, and writes |
* the result to the output buffer. This function is for |
* internal use only. |
* |
* \param ctx The SHA-512 context. This must be initialized |
* and have a hash operation started. |
* \param output The SHA-384 or SHA-512 checksum result. |
* This must be a writable buffer of length \c 64 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, |
unsigned char output[64] ); |
/** |
* \brief This function processes a single data block within |
* the ongoing SHA-512 computation. |
* |
* \param ctx The SHA-512 context. This must be initialized. |
* \param data The buffer holding one block of data. This |
* must be a readable buffer of length \c 128 Bytes. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, |
const unsigned char data[128] ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function starts a SHA-384 or SHA-512 checksum |
* calculation. |
* |
* \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0 |
* |
* \param ctx The SHA-512 context to use. This must be initialized. |
* \param is384 Determines which function to use. This must be either |
* \c 0 for SHA-512 or \c 1 for SHA-384. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, |
int is384 ); |
/** |
* \brief This function feeds an input buffer into an ongoing |
* SHA-512 checksum calculation. |
* |
* \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0. |
* |
* \param ctx The SHA-512 context. This must be initialized |
* and have a hash operation started. |
* \param input The buffer holding the data. This must be a readable |
* buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, |
const unsigned char *input, |
size_t ilen ); |
/** |
* \brief This function finishes the SHA-512 operation, and writes |
* the result to the output buffer. |
* |
* \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0. |
* |
* \param ctx The SHA-512 context. This must be initialized |
* and have a hash operation started. |
* \param output The SHA-384 or SHA-512 checksum result. This must |
* be a writable buffer of size \c 64 Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, |
unsigned char output[64] ); |
/** |
* \brief This function processes a single data block within |
* the ongoing SHA-512 computation. This function is for |
* internal use only. |
* |
* \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0. |
* |
* \param ctx The SHA-512 context. This must be initialized. |
* \param data The buffer holding one block of data. This must be |
* a readable buffer of length \c 128 Bytes. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha512_process( |
mbedtls_sha512_context *ctx, |
const unsigned char data[128] ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief This function calculates the SHA-512 or SHA-384 |
* checksum of a buffer. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The SHA-512 result is calculated as |
* output = SHA-512(input buffer). |
* |
* \param input The buffer holding the input data. This must be |
* a readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* \param output The SHA-384 or SHA-512 checksum result. |
* This must be a writable buffer of length \c 64 Bytes. |
* \param is384 Determines which function to use. This must be either |
* \c 0 for SHA-512, or \c 1 for SHA-384. |
* |
* \return \c 0 on success. |
* \return A negative error code on failure. |
*/ |
int mbedtls_sha512_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[64], |
int is384 ); |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief This function calculates the SHA-512 or SHA-384 |
* checksum of a buffer. |
* |
* The function allocates the context, performs the |
* calculation, and frees the context. |
* |
* The SHA-512 result is calculated as |
* output = SHA-512(input buffer). |
* |
* \deprecated Superseded by mbedtls_sha512_ret() in 2.7.0 |
* |
* \param input The buffer holding the data. This must be a |
* readable buffer of length \p ilen Bytes. |
* \param ilen The length of the input data in Bytes. |
* \param output The SHA-384 or SHA-512 checksum result. This must |
* be a writable buffer of length \c 64 Bytes. |
* \param is384 Determines which function to use. This must be either |
* \c 0 for SHA-512, or \c 1 for SHA-384. |
*/ |
MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, |
size_t ilen, |
unsigned char output[64], |
int is384 ); |
#undef MBEDTLS_DEPRECATED |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief The SHA-384 or SHA-512 checkup routine. |
* |
* \return \c 0 on success. |
* \return \c 1 on failure. |
*/ |
int mbedtls_sha512_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_sha512.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ssl.h |
---|
0,0 → 1,3264 |
/** |
* \file ssl.h |
* |
* \brief SSL/TLS functions. |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SSL_H |
#define MBEDTLS_SSL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "bignum.h" |
#include "ecp.h" |
#include "ssl_ciphersuites.h" |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
#include "x509_crt.h" |
#include "x509_crl.h" |
#endif |
#if defined(MBEDTLS_DHM_C) |
#include "dhm.h" |
#endif |
#if defined(MBEDTLS_ECDH_C) |
#include "ecdh.h" |
#endif |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library" |
#endif |
#if defined(MBEDTLS_DEPRECATED_REMOVED) |
#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set" |
#endif |
#include "zlib.h" |
#endif |
#if defined(MBEDTLS_HAVE_TIME) |
#include "platform_time.h" |
#endif |
/* |
* SSL Error codes |
*/ |
#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 /**< The requested feature is not available. */ |
#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA -0x7100 /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_SSL_INVALID_MAC -0x7180 /**< Verification of the message MAC failed. */ |
#define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 /**< An invalid SSL record was received. */ |
#define MBEDTLS_ERR_SSL_CONN_EOF -0x7280 /**< The connection indicated an EOF. */ |
#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER -0x7300 /**< An unknown cipher was received. */ |
#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 /**< The server has no ciphersuites in common with the client. */ |
#define MBEDTLS_ERR_SSL_NO_RNG -0x7400 /**< No RNG was provided to the SSL module. */ |
#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 /**< No client certification received from the client, but required by the authentication mode. */ |
#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 /**< Our own certificate(s) is/are too large to send in an SSL message. */ |
#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 /**< The own certificate is not set, but needed by the server. */ |
#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 /**< The own private key or pre-shared key is not set, but needed. */ |
#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 /**< No CA Chain is set, but required to operate. */ |
#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 /**< An unexpected message was received from our peer. */ |
#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */ |
#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED -0x7800 /**< Verification of our peer failed. */ |
#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 /**< The peer notified us that the connection is going to be closed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO -0x7900 /**< Processing of the ClientHello handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO -0x7980 /**< Processing of the ServerHello handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE -0x7A00 /**< Processing of the Certificate handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0x7A80 /**< Processing of the CertificateRequest handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 /**< Processing of the ServerKeyExchange handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 /**< Processing of the ServerHelloDone handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 /**< Processing of the ClientKeyExchange handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 /**< Processing of the CertificateVerify handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */ |
#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */ |
#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00 /**< Memory allocation failed */ |
#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -0x7F80 /**< Hardware acceleration function returned with error */ |
#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 /**< Hardware acceleration function skipped / left alone data */ |
#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED -0x6F00 /**< Processing of the compression / decompression failed */ |
#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 /**< Handshake protocol not within min/max boundaries */ |
#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */ |
#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */ |
#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ |
#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unknown identity received (eg, PSK identity) */ |
#define MBEDTLS_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */ |
#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */ |
#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */ |
#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */ |
#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */ |
#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */ |
#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< No data of requested type currently available on underlying transport. */ |
#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ |
#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ |
#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ |
#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */ |
#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */ |
#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */ |
#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ |
#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ |
#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */ |
#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */ |
/* |
* Various constants |
*/ |
#define MBEDTLS_SSL_MAJOR_VERSION_3 3 |
#define MBEDTLS_SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */ |
#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ |
#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ |
#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ |
#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ |
#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ |
#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ |
/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c |
* NONE must be zero so that memset()ing structure to zero works */ |
#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ |
#define MBEDTLS_SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */ |
#define MBEDTLS_SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ |
#define MBEDTLS_SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ |
#define MBEDTLS_SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ |
#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ |
#define MBEDTLS_SSL_IS_CLIENT 0 |
#define MBEDTLS_SSL_IS_SERVER 1 |
#define MBEDTLS_SSL_IS_NOT_FALLBACK 0 |
#define MBEDTLS_SSL_IS_FALLBACK 1 |
#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 |
#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 |
#define MBEDTLS_SSL_ETM_DISABLED 0 |
#define MBEDTLS_SSL_ETM_ENABLED 1 |
#define MBEDTLS_SSL_COMPRESS_NULL 0 |
#define MBEDTLS_SSL_COMPRESS_DEFLATE 1 |
#define MBEDTLS_SSL_VERIFY_NONE 0 |
#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 |
#define MBEDTLS_SSL_VERIFY_REQUIRED 2 |
#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ |
#define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 |
#define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 |
#define MBEDTLS_SSL_RENEGOTIATION_DISABLED 0 |
#define MBEDTLS_SSL_RENEGOTIATION_ENABLED 1 |
#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED 0 |
#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED 1 |
#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -1 |
#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT 16 |
#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION 0 |
#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION 1 |
#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE 2 |
#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED 0 |
#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1 |
#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */ |
#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0 |
#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1 |
#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED 0 |
#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED 1 |
#define MBEDTLS_SSL_ARC4_ENABLED 0 |
#define MBEDTLS_SSL_ARC4_DISABLED 1 |
#define MBEDTLS_SSL_PRESET_DEFAULT 0 |
#define MBEDTLS_SSL_PRESET_SUITEB 2 |
#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 |
#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 |
/* |
* Default range for DTLS retransmission timer value, in milliseconds. |
* RFC 6347 4.2.4.1 says from 1 second to 60 seconds. |
*/ |
#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000 |
#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000 |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME) |
#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ |
#endif |
/* |
* Maximum fragment length in bytes, |
* determines the size of each of the two internal I/O buffers. |
* |
* Note: the RFC defines the default size of SSL / TLS messages. If you |
* change the value here, other clients / servers may not be able to |
* communicate with you anymore. Only change this value if you control |
* both sides of the connection and have it reduced at both sides, or |
* if you're using the Max Fragment Length extension and you know all your |
* peers are using it too! |
*/ |
#if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN) |
#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ |
#endif |
#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) |
#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN |
#endif |
#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) |
#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN |
#endif |
/* |
* Maximum number of heap-allocated bytes for the purpose of |
* DTLS handshake message reassembly and future message buffering. |
*/ |
#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) |
#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 |
#endif |
/* \} name SECTION: Module settings */ |
/* |
* Length of the verify data for secure renegotiation |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 36 |
#else |
#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12 |
#endif |
/* |
* Signaling ciphersuite values (SCSV) |
*/ |
#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ |
#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< RFC 7507 section 2 */ |
/* |
* Supported Signature and Hash algorithms (For TLS 1.2) |
* RFC 5246 section 7.4.1.4.1 |
*/ |
#define MBEDTLS_SSL_HASH_NONE 0 |
#define MBEDTLS_SSL_HASH_MD5 1 |
#define MBEDTLS_SSL_HASH_SHA1 2 |
#define MBEDTLS_SSL_HASH_SHA224 3 |
#define MBEDTLS_SSL_HASH_SHA256 4 |
#define MBEDTLS_SSL_HASH_SHA384 5 |
#define MBEDTLS_SSL_HASH_SHA512 6 |
#define MBEDTLS_SSL_SIG_ANON 0 |
#define MBEDTLS_SSL_SIG_RSA 1 |
#define MBEDTLS_SSL_SIG_ECDSA 3 |
/* |
* Client Certificate Types |
* RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 |
*/ |
#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN 1 |
#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN 64 |
/* |
* Message, alert and handshake types |
*/ |
#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC 20 |
#define MBEDTLS_SSL_MSG_ALERT 21 |
#define MBEDTLS_SSL_MSG_HANDSHAKE 22 |
#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 |
#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 |
#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 |
#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */ |
#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */ |
#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */ |
#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */ |
#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */ |
#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */ |
#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */ |
#define MBEDTLS_SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */ |
#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */ |
#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */ |
#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */ |
#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */ |
#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */ |
#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */ |
#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */ |
#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */ |
#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */ |
#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */ |
#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */ |
#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ |
#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ |
#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ |
#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */ |
#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ |
#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ |
#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ |
#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ |
#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ |
#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ |
#define MBEDTLS_SSL_HS_HELLO_REQUEST 0 |
#define MBEDTLS_SSL_HS_CLIENT_HELLO 1 |
#define MBEDTLS_SSL_HS_SERVER_HELLO 2 |
#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 |
#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 |
#define MBEDTLS_SSL_HS_CERTIFICATE 11 |
#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 |
#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13 |
#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE 14 |
#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY 15 |
#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE 16 |
#define MBEDTLS_SSL_HS_FINISHED 20 |
/* |
* TLS extensions |
*/ |
#define MBEDTLS_TLS_EXT_SERVERNAME 0 |
#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME 0 |
#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH 1 |
#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC 4 |
#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10 |
#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS 11 |
#define MBEDTLS_TLS_EXT_SIG_ALG 13 |
#define MBEDTLS_TLS_EXT_ALPN 16 |
#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ |
#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */ |
#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 |
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ |
#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 |
/* |
* Size defines |
*/ |
#if !defined(MBEDTLS_PSK_MAX_LEN) |
#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */ |
#endif |
/* Dummy type used only for its size */ |
union mbedtls_ssl_premaster_secret |
{ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE |
+ MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 3 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES |
+ MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */ |
#endif |
}; |
#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* |
* SSL state machine |
*/ |
typedef enum |
{ |
MBEDTLS_SSL_HELLO_REQUEST, |
MBEDTLS_SSL_CLIENT_HELLO, |
MBEDTLS_SSL_SERVER_HELLO, |
MBEDTLS_SSL_SERVER_CERTIFICATE, |
MBEDTLS_SSL_SERVER_KEY_EXCHANGE, |
MBEDTLS_SSL_CERTIFICATE_REQUEST, |
MBEDTLS_SSL_SERVER_HELLO_DONE, |
MBEDTLS_SSL_CLIENT_CERTIFICATE, |
MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, |
MBEDTLS_SSL_CERTIFICATE_VERIFY, |
MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, |
MBEDTLS_SSL_CLIENT_FINISHED, |
MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, |
MBEDTLS_SSL_SERVER_FINISHED, |
MBEDTLS_SSL_FLUSH_BUFFERS, |
MBEDTLS_SSL_HANDSHAKE_WRAPUP, |
MBEDTLS_SSL_HANDSHAKE_OVER, |
MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, |
MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, |
} |
mbedtls_ssl_states; |
/** |
* \brief Callback type: send data on the network. |
* |
* \note That callback may be either blocking or non-blocking. |
* |
* \param ctx Context for the send callback (typically a file descriptor) |
* \param buf Buffer holding the data to send |
* \param len Length of the data to send |
* |
* \return The callback must return the number of bytes sent if any, |
* or a non-zero error code. |
* If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE |
* must be returned when the operation would block. |
* |
* \note The callback is allowed to send fewer bytes than requested. |
* It must always return the number of bytes actually sent. |
*/ |
typedef int mbedtls_ssl_send_t( void *ctx, |
const unsigned char *buf, |
size_t len ); |
/** |
* \brief Callback type: receive data from the network. |
* |
* \note That callback may be either blocking or non-blocking. |
* |
* \param ctx Context for the receive callback (typically a file |
* descriptor) |
* \param buf Buffer to write the received data to |
* \param len Length of the receive buffer |
* |
* \return The callback must return the number of bytes received, |
* or a non-zero error code. |
* If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ |
* must be returned when the operation would block. |
* |
* \note The callback may receive fewer bytes than the length of the |
* buffer. It must always return the number of bytes actually |
* received and written to the buffer. |
*/ |
typedef int mbedtls_ssl_recv_t( void *ctx, |
unsigned char *buf, |
size_t len ); |
/** |
* \brief Callback type: receive data from the network, with timeout |
* |
* \note That callback must block until data is received, or the |
* timeout delay expires, or the operation is interrupted by a |
* signal. |
* |
* \param ctx Context for the receive callback (typically a file descriptor) |
* \param buf Buffer to write the received data to |
* \param len Length of the receive buffer |
* \param timeout Maximum nomber of millisecondes to wait for data |
* 0 means no timeout (potentially waiting forever) |
* |
* \return The callback must return the number of bytes received, |
* or a non-zero error code: |
* \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, |
* \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. |
* |
* \note The callback may receive fewer bytes than the length of the |
* buffer. It must always return the number of bytes actually |
* received and written to the buffer. |
*/ |
typedef int mbedtls_ssl_recv_timeout_t( void *ctx, |
unsigned char *buf, |
size_t len, |
uint32_t timeout ); |
/** |
* \brief Callback type: set a pair of timers/delays to watch |
* |
* \param ctx Context pointer |
* \param int_ms Intermediate delay in milliseconds |
* \param fin_ms Final delay in milliseconds |
* 0 cancels the current timer. |
* |
* \note This callback must at least store the necessary information |
* for the associated \c mbedtls_ssl_get_timer_t callback to |
* return correct information. |
* |
* \note If using a event-driven style of programming, an event must |
* be generated when the final delay is passed. The event must |
* cause a call to \c mbedtls_ssl_handshake() with the proper |
* SSL context to be scheduled. Care must be taken to ensure |
* that at most one such call happens at a time. |
* |
* \note Only one timer at a time must be running. Calling this |
* function while a timer is running must cancel it. Cancelled |
* timers must not generate any event. |
*/ |
typedef void mbedtls_ssl_set_timer_t( void * ctx, |
uint32_t int_ms, |
uint32_t fin_ms ); |
/** |
* \brief Callback type: get status of timers/delays |
* |
* \param ctx Context pointer |
* |
* \return This callback must return: |
* -1 if cancelled (fin_ms == 0), |
* 0 if none of the delays have passed, |
* 1 if only the intermediate delay has passed, |
* 2 if the final delay has passed. |
*/ |
typedef int mbedtls_ssl_get_timer_t( void * ctx ); |
/* Defined below */ |
typedef struct mbedtls_ssl_session mbedtls_ssl_session; |
typedef struct mbedtls_ssl_context mbedtls_ssl_context; |
typedef struct mbedtls_ssl_config mbedtls_ssl_config; |
/* Defined in ssl_internal.h */ |
typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; |
typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; |
typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; |
#endif |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* \brief Callback type: start external signature operation. |
* |
* This callback is called during an SSL handshake to start |
* a signature decryption operation using an |
* external processor. The parameter \p cert contains |
* the public key; it is up to the callback function to |
* determine how to access the associated private key. |
* |
* This function typically sends or enqueues a request, and |
* does not wait for the operation to complete. This allows |
* the handshake step to be non-blocking. |
* |
* The parameters \p ssl and \p cert are guaranteed to remain |
* valid throughout the handshake. On the other hand, this |
* function must save the contents of \p hash if the value |
* is needed for later processing, because the \p hash buffer |
* is no longer valid after this function returns. |
* |
* This function may call mbedtls_ssl_set_async_operation_data() |
* to store an operation context for later retrieval |
* by the resume or cancel callback. |
* |
* \note For RSA signatures, this function must produce output |
* that is consistent with PKCS#1 v1.5 in the same way as |
* mbedtls_rsa_pkcs1_sign(). Before the private key operation, |
* apply the padding steps described in RFC 8017, section 9.2 |
* "EMSA-PKCS1-v1_5" as follows. |
* - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 |
* encoding, treating \p hash as the DigestInfo to be |
* padded. In other words, apply EMSA-PKCS1-v1_5 starting |
* from step 3, with `T = hash` and `tLen = hash_len`. |
* - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 |
* encoding, treating \p hash as the hash to be encoded and |
* padded. In other words, apply EMSA-PKCS1-v1_5 starting |
* from step 2, with `digestAlgorithm` obtained by calling |
* mbedtls_oid_get_oid_by_md() on \p md_alg. |
* |
* \note For ECDSA signatures, the output format is the DER encoding |
* `Ecdsa-Sig-Value` defined in |
* [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). |
* |
* \param ssl The SSL connection instance. It should not be |
* modified other than via |
* mbedtls_ssl_set_async_operation_data(). |
* \param cert Certificate containing the public key. |
* In simple cases, this is one of the pointers passed to |
* mbedtls_ssl_conf_own_cert() when configuring the SSL |
* connection. However, if other callbacks are used, this |
* property may not hold. For example, if an SNI callback |
* is registered with mbedtls_ssl_conf_sni(), then |
* this callback determines what certificate is used. |
* \param md_alg Hash algorithm. |
* \param hash Buffer containing the hash. This buffer is |
* no longer valid when the function returns. |
* \param hash_len Size of the \c hash buffer in bytes. |
* |
* \return 0 if the operation was started successfully and the SSL |
* stack should call the resume callback immediately. |
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation |
* was started successfully and the SSL stack should return |
* immediately without calling the resume callback yet. |
* \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external |
* processor does not support this key. The SSL stack will |
* use the private key object instead. |
* \return Any other error indicates a fatal failure and is |
* propagated up the call chain. The callback should |
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b> |
* use \c MBEDTLS_ERR_SSL_xxx error codes except as |
* directed in the documentation of this callback. |
*/ |
typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl, |
mbedtls_x509_crt *cert, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, |
size_t hash_len ); |
/** |
* \brief Callback type: start external decryption operation. |
* |
* This callback is called during an SSL handshake to start |
* an RSA decryption operation using an |
* external processor. The parameter \p cert contains |
* the public key; it is up to the callback function to |
* determine how to access the associated private key. |
* |
* This function typically sends or enqueues a request, and |
* does not wait for the operation to complete. This allows |
* the handshake step to be non-blocking. |
* |
* The parameters \p ssl and \p cert are guaranteed to remain |
* valid throughout the handshake. On the other hand, this |
* function must save the contents of \p input if the value |
* is needed for later processing, because the \p input buffer |
* is no longer valid after this function returns. |
* |
* This function may call mbedtls_ssl_set_async_operation_data() |
* to store an operation context for later retrieval |
* by the resume or cancel callback. |
* |
* \warning RSA decryption as used in TLS is subject to a potential |
* timing side channel attack first discovered by Bleichenbacher |
* in 1998. This attack can be remotely exploitable |
* in practice. To avoid this attack, you must ensure that |
* if the callback performs an RSA decryption, the time it |
* takes to execute and return the result does not depend |
* on whether the RSA decryption succeeded or reported |
* invalid padding. |
* |
* \param ssl The SSL connection instance. It should not be |
* modified other than via |
* mbedtls_ssl_set_async_operation_data(). |
* \param cert Certificate containing the public key. |
* In simple cases, this is one of the pointers passed to |
* mbedtls_ssl_conf_own_cert() when configuring the SSL |
* connection. However, if other callbacks are used, this |
* property may not hold. For example, if an SNI callback |
* is registered with mbedtls_ssl_conf_sni(), then |
* this callback determines what certificate is used. |
* \param input Buffer containing the input ciphertext. This buffer |
* is no longer valid when the function returns. |
* \param input_len Size of the \p input buffer in bytes. |
* |
* \return 0 if the operation was started successfully and the SSL |
* stack should call the resume callback immediately. |
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation |
* was started successfully and the SSL stack should return |
* immediately without calling the resume callback yet. |
* \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external |
* processor does not support this key. The SSL stack will |
* use the private key object instead. |
* \return Any other error indicates a fatal failure and is |
* propagated up the call chain. The callback should |
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b> |
* use \c MBEDTLS_ERR_SSL_xxx error codes except as |
* directed in the documentation of this callback. |
*/ |
typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl, |
mbedtls_x509_crt *cert, |
const unsigned char *input, |
size_t input_len ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
/** |
* \brief Callback type: resume external operation. |
* |
* This callback is called during an SSL handshake to resume |
* an external operation started by the |
* ::mbedtls_ssl_async_sign_t or |
* ::mbedtls_ssl_async_decrypt_t callback. |
* |
* This function typically checks the status of a pending |
* request or causes the request queue to make progress, and |
* does not wait for the operation to complete. This allows |
* the handshake step to be non-blocking. |
* |
* This function may call mbedtls_ssl_get_async_operation_data() |
* to retrieve an operation context set by the start callback. |
* It may call mbedtls_ssl_set_async_operation_data() to modify |
* this context. |
* |
* Note that when this function returns a status other than |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any |
* resources associated with the operation. |
* |
* \param ssl The SSL connection instance. It should not be |
* modified other than via |
* mbedtls_ssl_set_async_operation_data(). |
* \param output Buffer containing the output (signature or decrypted |
* data) on success. |
* \param output_len On success, number of bytes written to \p output. |
* \param output_size Size of the \p output buffer in bytes. |
* |
* \return 0 if output of the operation is available in the |
* \p output buffer. |
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation |
* is still in progress. Subsequent requests for progress |
* on the SSL connection will call the resume callback |
* again. |
* \return Any other error means that the operation is aborted. |
* The SSL handshake is aborted. The callback should |
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b> |
* use \c MBEDTLS_ERR_SSL_xxx error codes except as |
* directed in the documentation of this callback. |
*/ |
typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl, |
unsigned char *output, |
size_t *output_len, |
size_t output_size ); |
/** |
* \brief Callback type: cancel external operation. |
* |
* This callback is called if an SSL connection is closed |
* while an asynchronous operation is in progress. Note that |
* this callback is not called if the |
* ::mbedtls_ssl_async_resume_t callback has run and has |
* returned a value other than |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case |
* the asynchronous operation has already completed. |
* |
* This function may call mbedtls_ssl_get_async_operation_data() |
* to retrieve an operation context set by the start callback. |
* |
* \param ssl The SSL connection instance. It should not be |
* modified. |
*/ |
typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
/* |
* This structure is used for storing current session data. |
*/ |
struct mbedtls_ssl_session |
{ |
#if defined(MBEDTLS_HAVE_TIME) |
mbedtls_time_t start; /*!< starting time */ |
#endif |
int ciphersuite; /*!< chosen ciphersuite */ |
int compression; /*!< chosen compression */ |
size_t id_len; /*!< session id length */ |
unsigned char id[32]; /*!< session identifier */ |
unsigned char master[48]; /*!< the master secret */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
uint32_t verify_result; /*!< verification result */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) |
unsigned char *ticket; /*!< RFC 5077 session ticket */ |
size_t ticket_len; /*!< session ticket length */ |
uint32_t ticket_lifetime; /*!< ticket lifetime hint */ |
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
int trunc_hmac; /*!< flag for truncated hmac activation */ |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
int encrypt_then_mac; /*!< flag for EtM activation */ |
#endif |
}; |
/** |
* SSL/TLS configuration to be shared between mbedtls_ssl_context structures. |
*/ |
struct mbedtls_ssl_config |
{ |
/* Group items by size (largest first) to minimize padding overhead */ |
/* |
* Pointers |
*/ |
const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version */ |
/** Callback for printing debug output */ |
void (*f_dbg)(void *, int, const char *, int, const char *); |
void *p_dbg; /*!< context for the debug function */ |
/** Callback for getting (pseudo-)random numbers */ |
int (*f_rng)(void *, unsigned char *, size_t); |
void *p_rng; /*!< context for the RNG function */ |
/** Callback to retrieve a session from the cache */ |
int (*f_get_cache)(void *, mbedtls_ssl_session *); |
/** Callback to store a session into the cache */ |
int (*f_set_cache)(void *, const mbedtls_ssl_session *); |
void *p_cache; /*!< context for cache callbacks */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
/** Callback for setting cert according to SNI extension */ |
int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); |
void *p_sni; /*!< context for SNI callback */ |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** Callback to customize X.509 certificate chain verification */ |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); |
void *p_vrfy; /*!< context for X.509 verify calllback */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
/** Callback to retrieve PSK key from identity */ |
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); |
void *p_psk; /*!< context for PSK callback */ |
#endif |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
/** Callback to create & write a cookie for ClientHello veirifcation */ |
int (*f_cookie_write)( void *, unsigned char **, unsigned char *, |
const unsigned char *, size_t ); |
/** Callback to verify validity of a ClientHello cookie */ |
int (*f_cookie_check)( void *, const unsigned char *, size_t, |
const unsigned char *, size_t ); |
void *p_cookie; /*!< context for the cookie callbacks */ |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) |
/** Callback to create & write a session ticket */ |
int (*f_ticket_write)( void *, const mbedtls_ssl_session *, |
unsigned char *, const unsigned char *, size_t *, uint32_t * ); |
/** Callback to parse a session ticket into a session structure */ |
int (*f_ticket_parse)( void *, mbedtls_ssl_session *, unsigned char *, size_t); |
void *p_ticket; /*!< context for the ticket callbacks */ |
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_EXPORT_KEYS) |
/** Callback to export key block and master secret */ |
int (*f_export_keys)( void *, const unsigned char *, |
const unsigned char *, size_t, size_t, size_t ); |
void *p_export_keys; /*!< context for key export callback */ |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ |
mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ |
mbedtls_x509_crt *ca_chain; /*!< trusted CAs */ |
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */ |
mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */ |
mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */ |
void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
const int *sig_hashes; /*!< allowed signature hashes */ |
#endif |
#if defined(MBEDTLS_ECP_C) |
const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ |
#endif |
#if defined(MBEDTLS_DHM_C) |
mbedtls_mpi dhm_P; /*!< prime modulus for DHM */ |
mbedtls_mpi dhm_G; /*!< generator for DHM */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
unsigned char *psk; /*!< pre-shared key. This field should |
only be set via |
mbedtls_ssl_conf_psk() */ |
size_t psk_len; /*!< length of the pre-shared key. This |
field should only be set via |
mbedtls_ssl_conf_psk() */ |
unsigned char *psk_identity; /*!< identity for PSK negotiation. This |
field should only be set via |
mbedtls_ssl_conf_psk() */ |
size_t psk_identity_len;/*!< length of identity. This field should |
only be set via |
mbedtls_ssl_conf_psk() */ |
#endif |
#if defined(MBEDTLS_SSL_ALPN) |
const char **alpn_list; /*!< ordered list of protocols */ |
#endif |
/* |
* Numerical settings (int then char) |
*/ |
uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
uint32_t hs_timeout_min; /*!< initial value of the handshake |
retransmission timeout (ms) */ |
uint32_t hs_timeout_max; /*!< maximum value of the handshake |
retransmission timeout (ms) */ |
#endif |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
int renego_max_records; /*!< grace period for renegotiation */ |
unsigned char renego_period[8]; /*!< value of the record counters |
that triggers renegotiation */ |
#endif |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) |
unsigned int badmac_limit; /*!< limit of records with a bad MAC */ |
#endif |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) |
unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ |
#endif |
unsigned char max_major_ver; /*!< max. major version used */ |
unsigned char max_minor_ver; /*!< max. minor version used */ |
unsigned char min_major_ver; /*!< min. major version used */ |
unsigned char min_minor_ver; /*!< min. minor version used */ |
/* |
* Flags (bitfields) |
*/ |
unsigned int endpoint : 1; /*!< 0: client, 1: server */ |
unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */ |
unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */ |
/* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ |
unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */ |
#if defined(MBEDTLS_ARC4_C) |
unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */ |
#endif |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
unsigned int mfl_code : 3; /*!< desired fragment length */ |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */ |
#endif |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
unsigned int extended_ms : 1; /*!< negotiate extended master secret? */ |
#endif |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
unsigned int anti_replay : 1; /*!< detect and prevent replay? */ |
#endif |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */ |
#endif |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */ |
#endif |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */ |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
unsigned int session_tickets : 1; /*!< use session tickets? */ |
#endif |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) |
unsigned int fallback : 1; /*!< is this a fallback? */ |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in |
Certificate Request messages? */ |
#endif |
}; |
struct mbedtls_ssl_context |
{ |
const mbedtls_ssl_config *conf; /*!< configuration information */ |
/* |
* Miscellaneous |
*/ |
int state; /*!< SSL handshake: current state */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
int renego_status; /*!< Initial, in progress, pending? */ |
int renego_records_seen; /*!< Records since renego request, or with DTLS, |
number of retransmissions of request if |
renego_max_records is < 0 */ |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */ |
int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) |
unsigned badmac_seen; /*!< records with a bad MAC received */ |
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ |
mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ |
mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ |
mbedtls_ssl_recv_timeout_t *f_recv_timeout; |
/*!< Callback for network receive with timeout */ |
void *p_bio; /*!< context for I/O operations */ |
/* |
* Session layer |
*/ |
mbedtls_ssl_session *session_in; /*!< current session data (in) */ |
mbedtls_ssl_session *session_out; /*!< current session data (out) */ |
mbedtls_ssl_session *session; /*!< negotiated session data */ |
mbedtls_ssl_session *session_negotiate; /*!< session data in negotiation */ |
mbedtls_ssl_handshake_params *handshake; /*!< params required only during |
the handshake process */ |
/* |
* Record layer transformations |
*/ |
mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */ |
mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */ |
mbedtls_ssl_transform *transform; /*!< negotiated transform params */ |
mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */ |
/* |
* Timers |
*/ |
void *p_timer; /*!< context for the timer callbacks */ |
mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ |
mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ |
/* |
* Record layer (incoming data) |
*/ |
unsigned char *in_buf; /*!< input buffer */ |
unsigned char *in_ctr; /*!< 64-bit incoming message counter |
TLS: maintained by us |
DTLS: read from peer */ |
unsigned char *in_hdr; /*!< start of record header */ |
unsigned char *in_len; /*!< two-bytes message length field */ |
unsigned char *in_iv; /*!< ivlen-byte IV */ |
unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ |
unsigned char *in_offt; /*!< read offset in application data */ |
int in_msgtype; /*!< record header: message type */ |
size_t in_msglen; /*!< record header: message length */ |
size_t in_left; /*!< amount of data read so far */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
uint16_t in_epoch; /*!< DTLS epoch for incoming records */ |
size_t next_record_offset; /*!< offset of the next record in datagram |
(equal to in_left if none) */ |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
uint64_t in_window_top; /*!< last validated record seq_num */ |
uint64_t in_window; /*!< bitmask for replay detection */ |
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ |
size_t in_hslen; /*!< current handshake message length, |
including the handshake header */ |
int nb_zero; /*!< # of 0-length encrypted messages */ |
int keep_current_message; /*!< drop or reuse current message |
on next call to record layer? */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
uint8_t disable_datagram_packing; /*!< Disable packing multiple records |
* within a single datagram. */ |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* |
* Record layer (outgoing data) |
*/ |
unsigned char *out_buf; /*!< output buffer */ |
unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ |
unsigned char *out_hdr; /*!< start of record header */ |
unsigned char *out_len; /*!< two-bytes message length field */ |
unsigned char *out_iv; /*!< ivlen-byte IV */ |
unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ |
int out_msgtype; /*!< record header: message type */ |
size_t out_msglen; /*!< record header: message length */ |
size_t out_left; /*!< amount of data not yet written */ |
unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
unsigned char *compress_buf; /*!< zlib data buffer */ |
#endif /* MBEDTLS_ZLIB_SUPPORT */ |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
signed char split_done; /*!< current record already splitted? */ |
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ |
/* |
* PKI layer |
*/ |
int client_auth; /*!< flag for client auth. */ |
/* |
* User settings |
*/ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
char *hostname; /*!< expected peer CN for verification |
(and SNI if available) */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_ALPN) |
const char *alpn_chosen; /*!< negotiated protocol */ |
#endif /* MBEDTLS_SSL_ALPN */ |
/* |
* Information for DTLS hello verify |
*/ |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
unsigned char *cli_id; /*!< transport-level ID of the client */ |
size_t cli_id_len; /*!< length of cli_id */ |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ |
/* |
* Secure renegotiation |
*/ |
/* needed to know when to send extension on server */ |
int secure_renegotiation; /*!< does peer support legacy or |
secure renegotiation */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
size_t verify_data_len; /*!< length of verify data stored */ |
char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ |
char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
}; |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
#define MBEDTLS_SSL_CHANNEL_OUTBOUND 0 |
#define MBEDTLS_SSL_CHANNEL_INBOUND 1 |
extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl, |
const unsigned char *key_enc, const unsigned char *key_dec, |
size_t keylen, |
const unsigned char *iv_enc, const unsigned char *iv_dec, |
size_t ivlen, |
const unsigned char *mac_enc, const unsigned char *mac_dec, |
size_t maclen); |
extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction); |
extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl); |
extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl); |
extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl); |
extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl); |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
/** |
* \brief Return the name of the ciphersuite associated with the |
* given ID |
* |
* \param ciphersuite_id SSL ciphersuite ID |
* |
* \return a string containing the ciphersuite name |
*/ |
const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ); |
/** |
* \brief Return the ID of the ciphersuite associated with the |
* given name |
* |
* \param ciphersuite_name SSL ciphersuite name |
* |
* \return the ID with the ciphersuite or 0 if not found |
*/ |
int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ); |
/** |
* \brief Initialize an SSL context |
* Just makes the context ready for mbedtls_ssl_setup() or |
* mbedtls_ssl_free() |
* |
* \param ssl SSL context |
*/ |
void mbedtls_ssl_init( mbedtls_ssl_context *ssl ); |
/** |
* \brief Set up an SSL context for use |
* |
* \note No copy of the configuration context is made, it can be |
* shared by many mbedtls_ssl_context structures. |
* |
* \warning The conf structure will be accessed during the session. |
* It must not be modified or freed as long as the session |
* is active. |
* |
* \warning This function must be called exactly once per context. |
* Calling mbedtls_ssl_setup again is not supported, even |
* if no session is active. |
* |
* \param ssl SSL context |
* \param conf SSL configuration to use |
* |
* \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if |
* memory allocation failed |
*/ |
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, |
const mbedtls_ssl_config *conf ); |
/** |
* \brief Reset an already initialized SSL context for re-use |
* while retaining application-set variables, function |
* pointers and data. |
* |
* \param ssl SSL context |
* \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED, |
MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or |
* MBEDTLS_ERR_SSL_COMPRESSION_FAILED |
*/ |
int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ); |
/** |
* \brief Set the current endpoint type |
* |
* \param conf SSL configuration |
* \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER |
*/ |
void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ); |
/** |
* \brief Set the transport type (TLS or DTLS). |
* Default: TLS |
* |
* \note For DTLS, you must either provide a recv callback that |
* doesn't block, or one that handles timeouts, see |
* \c mbedtls_ssl_set_bio(). You also need to provide timer |
* callbacks with \c mbedtls_ssl_set_timer_cb(). |
* |
* \param conf SSL configuration |
* \param transport transport type: |
* MBEDTLS_SSL_TRANSPORT_STREAM for TLS, |
* MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS. |
*/ |
void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); |
/** |
* \brief Set the certificate verification mode |
* Default: NONE on server, REQUIRED on client |
* |
* \param conf SSL configuration |
* \param authmode can be: |
* |
* MBEDTLS_SSL_VERIFY_NONE: peer certificate is not checked |
* (default on server) |
* (insecure on client) |
* |
* MBEDTLS_SSL_VERIFY_OPTIONAL: peer certificate is checked, however the |
* handshake continues even if verification failed; |
* mbedtls_ssl_get_verify_result() can be called after the |
* handshake is complete. |
* |
* MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, |
* handshake is aborted if verification failed. |
* (default on client) |
* |
* \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. |
* With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at |
* the right time(s), which may not be obvious, while REQUIRED always perform |
* the verification as soon as possible. For example, REQUIRED was protecting |
* against the "triple handshake" attack even before it was found. |
*/ |
void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* \brief Set the verification callback (Optional). |
* |
* If set, the verify callback is called for each |
* certificate in the chain. For implementation |
* information, please see \c mbedtls_x509_crt_verify() |
* |
* \param conf SSL configuration |
* \param f_vrfy verification function |
* \param p_vrfy verification parameter |
*/ |
void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
/** |
* \brief Set the random number generator callback |
* |
* \param conf SSL configuration |
* \param f_rng RNG function |
* \param p_rng RNG parameter |
*/ |
void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Set the debug callback |
* |
* The callback has the following argument: |
* void * opaque context for the callback |
* int debug level |
* const char * file name |
* int line number |
* const char * message |
* |
* \param conf SSL configuration |
* \param f_dbg debug function |
* \param p_dbg debug parameter |
*/ |
void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, |
void (*f_dbg)(void *, int, const char *, int, const char *), |
void *p_dbg ); |
/** |
* \brief Set the underlying BIO callbacks for write, read and |
* read-with-timeout. |
* |
* \param ssl SSL context |
* \param p_bio parameter (context) shared by BIO callbacks |
* \param f_send write callback |
* \param f_recv read callback |
* \param f_recv_timeout blocking read callback with timeout. |
* |
* \note One of f_recv or f_recv_timeout can be NULL, in which case |
* the other is used. If both are non-NULL, f_recv_timeout is |
* used and f_recv is ignored (as if it were NULL). |
* |
* \note The two most common use cases are: |
* - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL |
* - blocking I/O, f_recv == NULL, f_recv_timout != NULL |
* |
* \note For DTLS, you need to provide either a non-NULL |
* f_recv_timeout callback, or a f_recv that doesn't block. |
* |
* \note See the documentations of \c mbedtls_ssl_sent_t, |
* \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for |
* the conventions those callbacks must follow. |
* |
* \note On some platforms, net_sockets.c provides |
* \c mbedtls_net_send(), \c mbedtls_net_recv() and |
* \c mbedtls_net_recv_timeout() that are suitable to be used |
* here. |
*/ |
void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, |
void *p_bio, |
mbedtls_ssl_send_t *f_send, |
mbedtls_ssl_recv_t *f_recv, |
mbedtls_ssl_recv_timeout_t *f_recv_timeout ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/** |
* \brief Set the Maximum Tranport Unit (MTU). |
* Special value: 0 means unset (no limit). |
* This represents the maximum size of a datagram payload |
* handled by the transport layer (usually UDP) as determined |
* by the network link and stack. In practice, this controls |
* the maximum size datagram the DTLS layer will pass to the |
* \c f_send() callback set using \c mbedtls_ssl_set_bio(). |
* |
* \note The limit on datagram size is converted to a limit on |
* record payload by subtracting the current overhead of |
* encapsulation and encryption/authentication if any. |
* |
* \note This can be called at any point during the connection, for |
* example when a Path Maximum Transfer Unit (PMTU) |
* estimate becomes available from other sources, |
* such as lower (or higher) protocol layers. |
* |
* \note This setting only controls the size of the packets we send, |
* and does not restrict the size of the datagrams we're |
* willing to receive. Client-side, you can request the |
* server to use smaller records with \c |
* mbedtls_ssl_conf_max_frag_len(). |
* |
* \note If both a MTU and a maximum fragment length have been |
* configured (or negotiated with the peer), the resulting |
* lower limit on record payload (see first note) is used. |
* |
* \note This can only be used to decrease the maximum size |
* of datagrams (hence records, see first note) sent. It |
* cannot be used to increase the maximum size of records over |
* the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. |
* |
* \note Values lower than the current record layer expansion will |
* result in an error when trying to send data. |
* |
* \note Using record compression together with a non-zero MTU value |
* will result in an error when trying to send data. |
* |
* \param ssl SSL context |
* \param mtu Value of the path MTU in bytes |
*/ |
void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/** |
* \brief Set the timeout period for mbedtls_ssl_read() |
* (Default: no timeout.) |
* |
* \param conf SSL configuration context |
* \param timeout Timeout value in milliseconds. |
* Use 0 for no timeout (default). |
* |
* \note With blocking I/O, this will only work if a non-NULL |
* \c f_recv_timeout was set with \c mbedtls_ssl_set_bio(). |
* With non-blocking I/O, this will only work if timer |
* callbacks were set with \c mbedtls_ssl_set_timer_cb(). |
* |
* \note With non-blocking I/O, you may also skip this function |
* altogether and handle timeouts at the application layer. |
*/ |
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); |
/** |
* \brief Set the timer callbacks (Mandatory for DTLS.) |
* |
* \param ssl SSL context |
* \param p_timer parameter (context) shared by timer callbacks |
* \param f_set_timer set timer callback |
* \param f_get_timer get timer callback. Must return: |
* |
* \note See the documentation of \c mbedtls_ssl_set_timer_t and |
* \c mbedtls_ssl_get_timer_t for the conventions this pair of |
* callbacks must follow. |
* |
* \note On some platforms, timing.c provides |
* \c mbedtls_timing_set_delay() and |
* \c mbedtls_timing_get_delay() that are suitable for using |
* here, except if using an event-driven style. |
* |
* \note See also the "DTLS tutorial" article in our knowledge base. |
* https://tls.mbed.org/kb/how-to/dtls-tutorial |
*/ |
void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, |
void *p_timer, |
mbedtls_ssl_set_timer_t *f_set_timer, |
mbedtls_ssl_get_timer_t *f_get_timer ); |
/** |
* \brief Callback type: generate and write session ticket |
* |
* \note This describes what a callback implementation should do. |
* This callback should generate an encrypted and |
* authenticated ticket for the session and write it to the |
* output buffer. Here, ticket means the opaque ticket part |
* of the NewSessionTicket structure of RFC 5077. |
* |
* \param p_ticket Context for the callback |
* \param session SSL session to be written in the ticket |
* \param start Start of the output buffer |
* \param end End of the output buffer |
* \param tlen On exit, holds the length written |
* \param lifetime On exit, holds the lifetime of the ticket in seconds |
* |
* \return 0 if successful, or |
* a specific MBEDTLS_ERR_XXX code. |
*/ |
typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, |
const mbedtls_ssl_session *session, |
unsigned char *start, |
const unsigned char *end, |
size_t *tlen, |
uint32_t *lifetime ); |
#if defined(MBEDTLS_SSL_EXPORT_KEYS) |
/** |
* \brief Callback type: Export key block and master secret |
* |
* \note This is required for certain uses of TLS, e.g. EAP-TLS |
* (RFC 5216) and Thread. The key pointers are ephemeral and |
* therefore must not be stored. The master secret and keys |
* should not be used directly except as an input to a key |
* derivation function. |
* |
* \param p_expkey Context for the callback |
* \param ms Pointer to master secret (fixed length: 48 bytes) |
* \param kb Pointer to key block, see RFC 5246 section 6.3 |
* (variable length: 2 * maclen + 2 * keylen + 2 * ivlen). |
* \param maclen MAC length |
* \param keylen Key length |
* \param ivlen IV length |
* |
* \return 0 if successful, or |
* a specific MBEDTLS_ERR_XXX code. |
*/ |
typedef int mbedtls_ssl_export_keys_t( void *p_expkey, |
const unsigned char *ms, |
const unsigned char *kb, |
size_t maclen, |
size_t keylen, |
size_t ivlen ); |
#endif /* MBEDTLS_SSL_EXPORT_KEYS */ |
/** |
* \brief Callback type: parse and load session ticket |
* |
* \note This describes what a callback implementation should do. |
* This callback should parse a session ticket as generated |
* by the corresponding mbedtls_ssl_ticket_write_t function, |
* and, if the ticket is authentic and valid, load the |
* session. |
* |
* \note The implementation is allowed to modify the first len |
* bytes of the input buffer, eg to use it as a temporary |
* area for the decrypted ticket contents. |
* |
* \param p_ticket Context for the callback |
* \param session SSL session to be loaded |
* \param buf Start of the buffer containing the ticket |
* \param len Length of the ticket. |
* |
* \return 0 if successful, or |
* MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or |
* MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or |
* any other non-zero code for other failures. |
*/ |
typedef int mbedtls_ssl_ticket_parse_t( void *p_ticket, |
mbedtls_ssl_session *session, |
unsigned char *buf, |
size_t len ); |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) |
/** |
* \brief Configure SSL session ticket callbacks (server only). |
* (Default: none.) |
* |
* \note On server, session tickets are enabled by providing |
* non-NULL callbacks. |
* |
* \note On client, use \c mbedtls_ssl_conf_session_tickets(). |
* |
* \param conf SSL configuration context |
* \param f_ticket_write Callback for writing a ticket |
* \param f_ticket_parse Callback for parsing a ticket |
* \param p_ticket Context shared by the two callbacks |
*/ |
void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, |
mbedtls_ssl_ticket_write_t *f_ticket_write, |
mbedtls_ssl_ticket_parse_t *f_ticket_parse, |
void *p_ticket ); |
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_EXPORT_KEYS) |
/** |
* \brief Configure key export callback. |
* (Default: none.) |
* |
* \note See \c mbedtls_ssl_export_keys_t. |
* |
* \param conf SSL configuration context |
* \param f_export_keys Callback for exporting keys |
* \param p_export_keys Context for the callback |
*/ |
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, |
mbedtls_ssl_export_keys_t *f_export_keys, |
void *p_export_keys ); |
#endif /* MBEDTLS_SSL_EXPORT_KEYS */ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
/** |
* \brief Configure asynchronous private key operation callbacks. |
* |
* \param conf SSL configuration context |
* \param f_async_sign Callback to start a signature operation. See |
* the description of ::mbedtls_ssl_async_sign_t |
* for more information. This may be \c NULL if the |
* external processor does not support any signature |
* operation; in this case the private key object |
* associated with the certificate will be used. |
* \param f_async_decrypt Callback to start a decryption operation. See |
* the description of ::mbedtls_ssl_async_decrypt_t |
* for more information. This may be \c NULL if the |
* external processor does not support any decryption |
* operation; in this case the private key object |
* associated with the certificate will be used. |
* \param f_async_resume Callback to resume an asynchronous operation. See |
* the description of ::mbedtls_ssl_async_resume_t |
* for more information. This may not be \c NULL unless |
* \p f_async_sign and \p f_async_decrypt are both |
* \c NULL. |
* \param f_async_cancel Callback to cancel an asynchronous operation. See |
* the description of ::mbedtls_ssl_async_cancel_t |
* for more information. This may be \c NULL if |
* no cleanup is needed. |
* \param config_data A pointer to configuration data which can be |
* retrieved with |
* mbedtls_ssl_conf_get_async_config_data(). The |
* library stores this value without dereferencing it. |
*/ |
void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf, |
mbedtls_ssl_async_sign_t *f_async_sign, |
mbedtls_ssl_async_decrypt_t *f_async_decrypt, |
mbedtls_ssl_async_resume_t *f_async_resume, |
mbedtls_ssl_async_cancel_t *f_async_cancel, |
void *config_data ); |
/** |
* \brief Retrieve the configuration data set by |
* mbedtls_ssl_conf_async_private_cb(). |
* |
* \param conf SSL configuration context |
* \return The configuration data set by |
* mbedtls_ssl_conf_async_private_cb(). |
*/ |
void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ); |
/** |
* \brief Retrieve the asynchronous operation user context. |
* |
* \note This function may only be called while a handshake |
* is in progress. |
* |
* \param ssl The SSL context to access. |
* |
* \return The asynchronous operation user context that was last |
* set during the current handshake. If |
* mbedtls_ssl_set_async_operation_data() has not yet been |
* called during the current handshake, this function returns |
* \c NULL. |
*/ |
void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ); |
/** |
* \brief Retrieve the asynchronous operation user context. |
* |
* \note This function may only be called while a handshake |
* is in progress. |
* |
* \param ssl The SSL context to access. |
* \param ctx The new value of the asynchronous operation user context. |
* Call mbedtls_ssl_get_async_operation_data() later during the |
* same handshake to retrieve this value. |
*/ |
void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, |
void *ctx ); |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
/** |
* \brief Callback type: generate a cookie |
* |
* \param ctx Context for the callback |
* \param p Buffer to write to, |
* must be updated to point right after the cookie |
* \param end Pointer to one past the end of the output buffer |
* \param info Client ID info that was passed to |
* \c mbedtls_ssl_set_client_transport_id() |
* \param ilen Length of info in bytes |
* |
* \return The callback must return 0 on success, |
* or a negative error code. |
*/ |
typedef int mbedtls_ssl_cookie_write_t( void *ctx, |
unsigned char **p, unsigned char *end, |
const unsigned char *info, size_t ilen ); |
/** |
* \brief Callback type: verify a cookie |
* |
* \param ctx Context for the callback |
* \param cookie Cookie to verify |
* \param clen Length of cookie |
* \param info Client ID info that was passed to |
* \c mbedtls_ssl_set_client_transport_id() |
* \param ilen Length of info in bytes |
* |
* \return The callback must return 0 if cookie is valid, |
* or a negative error code. |
*/ |
typedef int mbedtls_ssl_cookie_check_t( void *ctx, |
const unsigned char *cookie, size_t clen, |
const unsigned char *info, size_t ilen ); |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
/** |
* \brief Register callbacks for DTLS cookies |
* (Server only. DTLS only.) |
* |
* Default: dummy callbacks that fail, in order to force you to |
* register working callbacks (and initialize their context). |
* |
* To disable HelloVerifyRequest, register NULL callbacks. |
* |
* \warning Disabling hello verification allows your server to be used |
* for amplification in DoS attacks against other hosts. |
* Only disable if you known this can't happen in your |
* particular environment. |
* |
* \note See comments on \c mbedtls_ssl_handshake() about handling |
* the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected |
* on the first handshake attempt when this is enabled. |
* |
* \note This is also necessary to handle client reconnection from |
* the same port as described in RFC 6347 section 4.2.8 (only |
* the variant with cookies is supported currently). See |
* comments on \c mbedtls_ssl_read() for details. |
* |
* \param conf SSL configuration |
* \param f_cookie_write Cookie write callback |
* \param f_cookie_check Cookie check callback |
* \param p_cookie Context for both callbacks |
*/ |
void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, |
mbedtls_ssl_cookie_write_t *f_cookie_write, |
mbedtls_ssl_cookie_check_t *f_cookie_check, |
void *p_cookie ); |
/** |
* \brief Set client's transport-level identification info. |
* (Server only. DTLS only.) |
* |
* This is usually the IP address (and port), but could be |
* anything identify the client depending on the underlying |
* network stack. Used for HelloVerifyRequest with DTLS. |
* This is *not* used to route the actual packets. |
* |
* \param ssl SSL context |
* \param info Transport-level info identifying the client (eg IP + port) |
* \param ilen Length of info in bytes |
* |
* \note An internal copy is made, so the info buffer can be reused. |
* |
* \return 0 on success, |
* MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client, |
* MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory. |
*/ |
int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, |
const unsigned char *info, |
size_t ilen ); |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
/** |
* \brief Enable or disable anti-replay protection for DTLS. |
* (DTLS only, no effect on TLS.) |
* Default: enabled. |
* |
* \param conf SSL configuration |
* \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. |
* |
* \warning Disabling this is a security risk unless the application |
* protocol handles duplicated packets in a safe way. You |
* should not disable this without careful consideration. |
* However, if your application already detects duplicated |
* packets and needs information about them to adjust its |
* transmission strategy, then you'll want to disable this. |
*/ |
void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); |
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) |
/** |
* \brief Set a limit on the number of records with a bad MAC |
* before terminating the connection. |
* (DTLS only, no effect on TLS.) |
* Default: 0 (disabled). |
* |
* \param conf SSL configuration |
* \param limit Limit, or 0 to disable. |
* |
* \note If the limit is N, then the connection is terminated when |
* the Nth non-authentic record is seen. |
* |
* \note Records with an invalid header are not counted, only the |
* ones going through the authentication-decryption phase. |
* |
* \note This is a security trade-off related to the fact that it's |
* often relatively easy for an active attacker ot inject UDP |
* datagrams. On one hand, setting a low limit here makes it |
* easier for such an attacker to forcibly terminated a |
* connection. On the other hand, a high limit or no limit |
* might make us waste resources checking authentication on |
* many bogus packets. |
*/ |
void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ); |
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/** |
* \brief Allow or disallow packing of multiple handshake records |
* within a single datagram. |
* |
* \param ssl The SSL context to configure. |
* \param allow_packing This determines whether datagram packing may |
* be used or not. A value of \c 0 means that every |
* record will be sent in a separate datagram; a |
* value of \c 1 means that, if space permits, |
* multiple handshake messages (including CCS) belonging to |
* a single flight may be packed within a single datagram. |
* |
* \note This is enabled by default and should only be disabled |
* for test purposes, or if datagram packing causes |
* interoperability issues with peers that don't support it. |
* |
* \note Allowing datagram packing reduces the network load since |
* there's less overhead if multiple messages share the same |
* datagram. Also, it increases the handshake efficiency |
* since messages belonging to a single datagram will not |
* be reordered in transit, and so future message buffering |
* or flight retransmission (if no buffering is used) as |
* means to deal with reordering are needed less frequently. |
* |
* \note Application records are not affected by this option and |
* are currently always sent in separate datagrams. |
* |
*/ |
void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, |
unsigned allow_packing ); |
/** |
* \brief Set retransmit timeout values for the DTLS handshake. |
* (DTLS only, no effect on TLS.) |
* |
* \param conf SSL configuration |
* \param min Initial timeout value in milliseconds. |
* Default: 1000 (1 second). |
* \param max Maximum timeout value in milliseconds. |
* Default: 60000 (60 seconds). |
* |
* \note Default values are from RFC 6347 section 4.2.4.1. |
* |
* \note The 'min' value should typically be slightly above the |
* expected round-trip time to your peer, plus whatever time |
* it takes for the peer to process the message. For example, |
* if your RTT is about 600ms and you peer needs up to 1s to |
* do the cryptographic operations in the handshake, then you |
* should set 'min' slightly above 1600. Lower values of 'min' |
* might cause spurious resends which waste network resources, |
* while larger value of 'min' will increase overall latency |
* on unreliable network links. |
* |
* \note The more unreliable your network connection is, the larger |
* your max / min ratio needs to be in order to achieve |
* reliable handshakes. |
* |
* \note Messages are retransmitted up to log2(ceil(max/min)) times. |
* For example, if min = 1s and max = 5s, the retransmit plan |
* goes: send ... 1s -> resend ... 2s -> resend ... 4s -> |
* resend ... 5s -> give up and return a timeout error. |
*/ |
void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if defined(MBEDTLS_SSL_SRV_C) |
/** |
* \brief Set the session cache callbacks (server-side only) |
* If not set, no session resuming is done (except if session |
* tickets are enabled too). |
* |
* The session cache has the responsibility to check for stale |
* entries based on timeout. See RFC 5246 for recommendations. |
* |
* Warning: session.peer_cert is cleared by the SSL/TLS layer on |
* connection shutdown, so do not cache the pointer! Either set |
* it to NULL or make a full copy of the certificate. |
* |
* The get callback is called once during the initial handshake |
* to enable session resuming. The get function has the |
* following parameters: (void *parameter, mbedtls_ssl_session *session) |
* If a valid entry is found, it should fill the master of |
* the session object with the cached values and return 0, |
* return 1 otherwise. Optionally peer_cert can be set as well |
* if it is properly present in cache entry. |
* |
* The set callback is called once during the initial handshake |
* to enable session resuming after the entire handshake has |
* been finished. The set function has the following parameters: |
* (void *parameter, const mbedtls_ssl_session *session). The function |
* should create a cache entry for future retrieval based on |
* the data in the session structure and should keep in mind |
* that the mbedtls_ssl_session object presented (and all its referenced |
* data) is cleared by the SSL/TLS layer when the connection is |
* terminated. It is recommended to add metadata to determine if |
* an entry is still valid in the future. Return 0 if |
* successfully cached, return 1 otherwise. |
* |
* \param conf SSL configuration |
* \param p_cache parmater (context) for both callbacks |
* \param f_get_cache session get callback |
* \param f_set_cache session set callback |
*/ |
void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, |
void *p_cache, |
int (*f_get_cache)(void *, mbedtls_ssl_session *), |
int (*f_set_cache)(void *, const mbedtls_ssl_session *) ); |
#endif /* MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_CLI_C) |
/** |
* \brief Request resumption of session (client-side only) |
* Session data is copied from presented session structure. |
* |
* \param ssl SSL context |
* \param session session context |
* |
* \return 0 if successful, |
* MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, |
* MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or |
* arguments are otherwise invalid |
* |
* \sa mbedtls_ssl_get_session() |
*/ |
int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ); |
#endif /* MBEDTLS_SSL_CLI_C */ |
/** |
* \brief Set the list of allowed ciphersuites and the preference |
* order. First in the list has the highest preference. |
* (Overrides all version-specific lists) |
* |
* The ciphersuites array is not copied, and must remain |
* valid for the lifetime of the ssl_config. |
* |
* Note: The server uses its own preferences |
* over the preference of the client unless |
* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! |
* |
* \param conf SSL configuration |
* \param ciphersuites 0-terminated list of allowed ciphersuites |
*/ |
void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, |
const int *ciphersuites ); |
/** |
* \brief Set the list of allowed ciphersuites and the |
* preference order for a specific version of the protocol. |
* (Only useful on the server side) |
* |
* The ciphersuites array is not copied, and must remain |
* valid for the lifetime of the ssl_config. |
* |
* \param conf SSL configuration |
* \param ciphersuites 0-terminated list of allowed ciphersuites |
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 |
* supported) |
* \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, |
* MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, |
* MBEDTLS_SSL_MINOR_VERSION_3 supported) |
* |
* \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 |
* and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 |
*/ |
void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, |
const int *ciphersuites, |
int major, int minor ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* \brief Set the X.509 security profile used for verification |
* |
* \note The restrictions are enforced for all certificates in the |
* chain. However, signatures in the handshake are not covered |
* by this setting but by \b mbedtls_ssl_conf_sig_hashes(). |
* |
* \param conf SSL configuration |
* \param profile Profile to use |
*/ |
void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, |
const mbedtls_x509_crt_profile *profile ); |
/** |
* \brief Set the data required to verify peer certificate |
* |
* \note See \c mbedtls_x509_crt_verify() for notes regarding the |
* parameters ca_chain (maps to trust_ca for that function) |
* and ca_crl. |
* |
* \param conf SSL configuration |
* \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) |
* \param ca_crl trusted CA CRLs |
*/ |
void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, |
mbedtls_x509_crt *ca_chain, |
mbedtls_x509_crl *ca_crl ); |
/** |
* \brief Set own certificate chain and private key |
* |
* \note own_cert should contain in order from the bottom up your |
* certificate chain. The top certificate (self-signed) |
* can be omitted. |
* |
* \note On server, this function can be called multiple times to |
* provision more than one cert/key pair (eg one ECDSA, one |
* RSA with SHA-256, one RSA with SHA-1). An adequate |
* certificate will be selected according to the client's |
* advertised capabilities. In case multiple certificates are |
* adequate, preference is given to the one set by the first |
* call to this function, then second, etc. |
* |
* \note On client, only the first call has any effect. That is, |
* only one client certificate can be provisioned. The |
* server's preferences in its CertficateRequest message will |
* be ignored and our only cert will be sent regardless of |
* whether it matches those preferences - the server can then |
* decide what it wants to do with it. |
* |
* \note The provided \p pk_key needs to match the public key in the |
* first certificate in \p own_cert, or all handshakes using |
* that certificate will fail. It is your responsibility |
* to ensure that; this function will not perform any check. |
* You may use mbedtls_pk_check_pair() in order to perform |
* this check yourself, but be aware that this function can |
* be computationally expensive on some key types. |
* |
* \param conf SSL configuration |
* \param own_cert own public certificate chain |
* \param pk_key own private key |
* |
* \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED |
*/ |
int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, |
mbedtls_x509_crt *own_cert, |
mbedtls_pk_context *pk_key ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
/** |
* \brief Set the Pre Shared Key (PSK) and the expected identity name |
* |
* \note This is mainly useful for clients. Servers will usually |
* want to use \c mbedtls_ssl_conf_psk_cb() instead. |
* |
* \note Currently clients can only register one pre-shared key. |
* In other words, the servers' identity hint is ignored. |
* Support for setting multiple PSKs on clients and selecting |
* one based on the identity hint is not a planned feature but |
* feedback is welcomed. |
* |
* \param conf SSL configuration |
* \param psk pointer to the pre-shared key |
* \param psk_len pre-shared key length |
* \param psk_identity pointer to the pre-shared key identity |
* \param psk_identity_len identity key length |
* |
* \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED |
*/ |
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, |
const unsigned char *psk, size_t psk_len, |
const unsigned char *psk_identity, size_t psk_identity_len ); |
/** |
* \brief Set the Pre Shared Key (PSK) for the current handshake |
* |
* \note This should only be called inside the PSK callback, |
* ie the function passed to \c mbedtls_ssl_conf_psk_cb(). |
* |
* \param ssl SSL context |
* \param psk pointer to the pre-shared key |
* \param psk_len pre-shared key length |
* |
* \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED |
*/ |
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, |
const unsigned char *psk, size_t psk_len ); |
/** |
* \brief Set the PSK callback (server-side only). |
* |
* If set, the PSK callback is called for each |
* handshake where a PSK ciphersuite was negotiated. |
* The caller provides the identity received and wants to |
* receive the actual PSK data and length. |
* |
* The callback has the following parameters: (void *parameter, |
* mbedtls_ssl_context *ssl, const unsigned char *psk_identity, |
* size_t identity_len) |
* If a valid PSK identity is found, the callback should use |
* \c mbedtls_ssl_set_hs_psk() on the ssl context to set the |
* correct PSK and return 0. |
* Any other return value will result in a denied PSK identity. |
* |
* \note If you set a PSK callback using this function, then you |
* don't need to set a PSK key and identity using |
* \c mbedtls_ssl_conf_psk(). |
* |
* \param conf SSL configuration |
* \param f_psk PSK identity function |
* \param p_psk PSK identity parameter |
*/ |
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, |
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, |
size_t), |
void *p_psk ); |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
#define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
#else |
#define MBEDTLS_DEPRECATED |
#endif |
/** |
* \brief Set the Diffie-Hellman public P and G values, |
* read as hexadecimal strings (server-side only) |
* (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]) |
* |
* \param conf SSL configuration |
* \param dhm_P Diffie-Hellman-Merkle modulus |
* \param dhm_G Diffie-Hellman-Merkle generator |
* |
* \deprecated Superseded by \c mbedtls_ssl_conf_dh_param_bin. |
* |
* \return 0 if successful |
*/ |
MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, |
const char *dhm_P, |
const char *dhm_G ); |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/** |
* \brief Set the Diffie-Hellman public P and G values |
* from big-endian binary presentations. |
* (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN) |
* |
* \param conf SSL configuration |
* \param dhm_P Diffie-Hellman-Merkle modulus in big-endian binary form |
* \param P_len Length of DHM modulus |
* \param dhm_G Diffie-Hellman-Merkle generator in big-endian binary form |
* \param G_len Length of DHM generator |
* |
* \return 0 if successful |
*/ |
int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, |
const unsigned char *dhm_P, size_t P_len, |
const unsigned char *dhm_G, size_t G_len ); |
/** |
* \brief Set the Diffie-Hellman public P and G values, |
* read from existing context (server-side only) |
* |
* \param conf SSL configuration |
* \param dhm_ctx Diffie-Hellman-Merkle context |
* |
* \return 0 if successful |
*/ |
int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ); |
#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */ |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) |
/** |
* \brief Set the minimum length for Diffie-Hellman parameters. |
* (Client-side only.) |
* (Default: 1024 bits.) |
* |
* \param conf SSL configuration |
* \param bitlen Minimum bit length of the DHM prime |
*/ |
void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, |
unsigned int bitlen ); |
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_ECP_C) |
/** |
* \brief Set the allowed curves in order of preference. |
* (Default: all defined curves.) |
* |
* On server: this only affects selection of the ECDHE curve; |
* the curves used for ECDH and ECDSA are determined by the |
* list of available certificates instead. |
* |
* On client: this affects the list of curves offered for any |
* use. The server can override our preference order. |
* |
* Both sides: limits the set of curves accepted for use in |
* ECDHE and in the peer's end-entity certificate. |
* |
* \note This has no influence on which curves are allowed inside the |
* certificate chains, see \c mbedtls_ssl_conf_cert_profile() |
* for that. For the end-entity certificate however, the key |
* will be accepted only if it is allowed both by this list |
* and by the cert profile. |
* |
* \note This list should be ordered by decreasing preference |
* (preferred curve first). |
* |
* \param conf SSL configuration |
* \param curves Ordered list of allowed curves, |
* terminated by MBEDTLS_ECP_DP_NONE. |
*/ |
void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, |
const mbedtls_ecp_group_id *curves ); |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/** |
* \brief Set the allowed hashes for signatures during the handshake. |
* (Default: all available hashes except MD5.) |
* |
* \note This only affects which hashes are offered and can be used |
* for signatures during the handshake. Hashes for message |
* authentication and the TLS PRF are controlled by the |
* ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes |
* used for certificate signature are controlled by the |
* verification profile, see \c mbedtls_ssl_conf_cert_profile(). |
* |
* \note This list should be ordered by decreasing preference |
* (preferred hash first). |
* |
* \param conf SSL configuration |
* \param hashes Ordered list of allowed signature hashes, |
* terminated by \c MBEDTLS_MD_NONE. |
*/ |
void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, |
const int *hashes ); |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* \brief Set or reset the hostname to check against the received |
* server certificate. It sets the ServerName TLS extension, |
* too, if that extension is enabled. (client-side only) |
* |
* \param ssl SSL context |
* \param hostname the server hostname, may be NULL to clear hostname |
* \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. |
* |
* \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on |
* allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on |
* too long input hostname. |
* |
* Hostname set to the one provided on success (cleared |
* when NULL). On allocation failure hostname is cleared. |
* On too long input failure, old hostname is unchanged. |
*/ |
int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
/** |
* \brief Set own certificate and key for the current handshake |
* |
* \note Same as \c mbedtls_ssl_conf_own_cert() but for use within |
* the SNI callback. |
* |
* \param ssl SSL context |
* \param own_cert own public certificate chain |
* \param pk_key own private key |
* |
* \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED |
*/ |
int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, |
mbedtls_x509_crt *own_cert, |
mbedtls_pk_context *pk_key ); |
/** |
* \brief Set the data required to verify peer certificate for the |
* current handshake |
* |
* \note Same as \c mbedtls_ssl_conf_ca_chain() but for use within |
* the SNI callback. |
* |
* \param ssl SSL context |
* \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) |
* \param ca_crl trusted CA CRLs |
*/ |
void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, |
mbedtls_x509_crt *ca_chain, |
mbedtls_x509_crl *ca_crl ); |
/** |
* \brief Set authmode for the current handshake. |
* |
* \note Same as \c mbedtls_ssl_conf_authmode() but for use within |
* the SNI callback. |
* |
* \param ssl SSL context |
* \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or |
* MBEDTLS_SSL_VERIFY_REQUIRED |
*/ |
void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, |
int authmode ); |
/** |
* \brief Set server side ServerName TLS extension callback |
* (optional, server-side only). |
* |
* If set, the ServerName callback is called whenever the |
* server receives a ServerName TLS extension from the client |
* during a handshake. The ServerName callback has the |
* following parameters: (void *parameter, mbedtls_ssl_context *ssl, |
* const unsigned char *hostname, size_t len). If a suitable |
* certificate is found, the callback must set the |
* certificate(s) and key(s) to use with \c |
* mbedtls_ssl_set_hs_own_cert() (can be called repeatedly), |
* and may optionally adjust the CA and associated CRL with \c |
* mbedtls_ssl_set_hs_ca_chain() as well as the client |
* authentication mode with \c mbedtls_ssl_set_hs_authmode(), |
* then must return 0. If no matching name is found, the |
* callback must either set a default cert, or |
* return non-zero to abort the handshake at this point. |
* |
* \param conf SSL configuration |
* \param f_sni verification function |
* \param p_sni verification parameter |
*/ |
void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, |
int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, |
size_t), |
void *p_sni ); |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
/** |
* \brief Set the EC J-PAKE password for current handshake. |
* |
* \note An internal copy is made, and destroyed as soon as the |
* handshake is completed, or when the SSL context is reset or |
* freed. |
* |
* \note The SSL context needs to be already set up. The right place |
* to call this function is between \c mbedtls_ssl_setup() or |
* \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). |
* |
* \param ssl SSL context |
* \param pw EC J-PAKE password (pre-shared secret) |
* \param pw_len length of pw in bytes |
* |
* \return 0 on success, or a negative error code. |
*/ |
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, |
const unsigned char *pw, |
size_t pw_len ); |
#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_ALPN) |
/** |
* \brief Set the supported Application Layer Protocols. |
* |
* \param conf SSL configuration |
* \param protos Pointer to a NULL-terminated list of supported protocols, |
* in decreasing preference order. The pointer to the list is |
* recorded by the library for later reference as required, so |
* the lifetime of the table must be atleast as long as the |
* lifetime of the SSL configuration structure. |
* |
* \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA. |
*/ |
int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ); |
/** |
* \brief Get the name of the negotiated Application Layer Protocol. |
* This function should be called after the handshake is |
* completed. |
* |
* \param ssl SSL context |
* |
* \return Protcol name, or NULL if no protocol was negotiated. |
*/ |
const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); |
#endif /* MBEDTLS_SSL_ALPN */ |
/** |
* \brief Set the maximum supported version sent from the client side |
* and/or accepted at the server side |
* (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION) |
* |
* \note This ignores ciphersuites from higher versions. |
* |
* \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and |
* MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 |
* |
* \param conf SSL configuration |
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) |
* \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, |
* MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, |
* MBEDTLS_SSL_MINOR_VERSION_3 supported) |
*/ |
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ); |
/** |
* \brief Set the minimum accepted SSL/TLS protocol version |
* (Default: TLS 1.0) |
* |
* \note Input outside of the SSL_MAX_XXXXX_VERSION and |
* SSL_MIN_XXXXX_VERSION range is ignored. |
* |
* \note MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided. |
* |
* \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and |
* MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 |
* |
* \param conf SSL configuration |
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) |
* \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, |
* MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, |
* MBEDTLS_SSL_MINOR_VERSION_3 supported) |
*/ |
void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ); |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) |
/** |
* \brief Set the fallback flag (client-side only). |
* (Default: MBEDTLS_SSL_IS_NOT_FALLBACK). |
* |
* \note Set to MBEDTLS_SSL_IS_FALLBACK when preparing a fallback |
* connection, that is a connection with max_version set to a |
* lower value than the value you're willing to use. Such |
* fallback connections are not recommended but are sometimes |
* necessary to interoperate with buggy (version-intolerant) |
* servers. |
* |
* \warning You should NOT set this to MBEDTLS_SSL_IS_FALLBACK for |
* non-fallback connections! This would appear to work for a |
* while, then cause failures when the server is upgraded to |
* support a newer TLS version. |
* |
* \param conf SSL configuration |
* \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK |
*/ |
void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ); |
#endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
/** |
* \brief Enable or disable Encrypt-then-MAC |
* (Default: MBEDTLS_SSL_ETM_ENABLED) |
* |
* \note This should always be enabled, it is a security |
* improvement, and should not cause any interoperability |
* issue (used only if the peer supports it too). |
* |
* \param conf SSL configuration |
* \param etm MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED |
*/ |
void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ); |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
/** |
* \brief Enable or disable Extended Master Secret negotiation. |
* (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED) |
* |
* \note This should always be enabled, it is a security fix to the |
* protocol, and should not cause any interoperability issue |
* (used only if the peer supports it too). |
* |
* \param conf SSL configuration |
* \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED |
*/ |
void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ); |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_ARC4_C) |
/** |
* \brief Disable or enable support for RC4 |
* (Default: MBEDTLS_SSL_ARC4_DISABLED) |
* |
* \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465 |
* for security reasons. Use at your own risk. |
* |
* \note This function is deprecated and will likely be removed in |
* a future version of the library. |
* RC4 is disabled by default at compile time and needs to be |
* actively enabled for use with legacy systems. |
* |
* \param conf SSL configuration |
* \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED |
*/ |
void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_SSL_SRV_C) |
/** |
* \brief Whether to send a list of acceptable CAs in |
* CertificateRequest messages. |
* (Default: do send) |
* |
* \param conf SSL configuration |
* \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or |
* MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED |
*/ |
void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, |
char cert_req_ca_list ); |
#endif /* MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
/** |
* \brief Set the maximum fragment length to emit and/or negotiate. |
* (Typical: the smaller of #MBEDTLS_SSL_IN_CONTENT_LEN and |
* #MBEDTLS_SSL_OUT_CONTENT_LEN, usually `2^14` bytes) |
* (Server: set maximum fragment length to emit, |
* usually negotiated by the client during handshake) |
* (Client: set maximum fragment length to emit *and* |
* negotiate with the server during handshake) |
* (Default: #MBEDTLS_SSL_MAX_FRAG_LEN_NONE) |
* |
* \note On the client side, the maximum fragment length extension |
* *will not* be used, unless the maximum fragment length has |
* been set via this function to a value different than |
* #MBEDTLS_SSL_MAX_FRAG_LEN_NONE. |
* |
* \note This sets the maximum length for a record's payload, |
* excluding record overhead that will be added to it, see |
* \c mbedtls_ssl_get_record_expansion(). |
* |
* \note With TLS, this currently only affects ApplicationData (sent |
* with \c mbedtls_ssl_read()), not handshake messages. |
* With DTLS, this affects both ApplicationData and handshake. |
* |
* \note For DTLS, it is also possible to set a limit for the total |
* size of daragrams passed to the transport layer, including |
* record overhead, see \c mbedtls_ssl_set_mtu(). |
* |
* \param conf SSL configuration |
* \param mfl_code Code for maximum fragment length (allowed values: |
* MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024, |
* MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096) |
* |
* \return 0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA |
*/ |
int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ); |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
/** |
* \brief Activate negotiation of truncated HMAC |
* (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED) |
* |
* \param conf SSL configuration |
* \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or |
* MBEDTLS_SSL_TRUNC_HMAC_DISABLED) |
*/ |
void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ); |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
/** |
* \brief Enable / Disable 1/n-1 record splitting |
* (Default: MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED) |
* |
* \note Only affects SSLv3 and TLS 1.0, not higher versions. |
* Does not affect non-CBC ciphersuites in any version. |
* |
* \param conf SSL configuration |
* \param split MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or |
* MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED |
*/ |
void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ); |
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) |
/** |
* \brief Enable / Disable session tickets (client only). |
* (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.) |
* |
* \note On server, use \c mbedtls_ssl_conf_session_tickets_cb(). |
* |
* \param conf SSL configuration |
* \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or |
* MBEDTLS_SSL_SESSION_TICKETS_DISABLED) |
*/ |
void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ); |
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
/** |
* \brief Enable / Disable renegotiation support for connection when |
* initiated by peer |
* (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED) |
* |
* \warning It is recommended to always disable renegotation unless you |
* know you need it and you know what you're doing. In the |
* past, there have been several issues associated with |
* renegotiation or a poor understanding of its properties. |
* |
* \note Server-side, enabling renegotiation also makes the server |
* susceptible to a resource DoS by a malicious client. |
* |
* \param conf SSL configuration |
* \param renegotiation Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or |
* MBEDTLS_SSL_RENEGOTIATION_DISABLED) |
*/ |
void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ); |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/** |
* \brief Prevent or allow legacy renegotiation. |
* (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) |
* |
* MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to |
* be established even if the peer does not support |
* secure renegotiation, but does not allow renegotiation |
* to take place if not secure. |
* (Interoperable and secure option) |
* |
* MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations |
* with non-upgraded peers. Allowing legacy renegotiation |
* makes the connection vulnerable to specific man in the |
* middle attacks. (See RFC 5746) |
* (Most interoperable and least secure option) |
* |
* MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections |
* if peer does not support secure renegotiation. Results |
* in interoperability issues with non-upgraded peers |
* that do not support renegotiation altogether. |
* (Most secure option, interoperability issues) |
* |
* \param conf SSL configuration |
* \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, |
* SSL_ALLOW_LEGACY_RENEGOTIATION or |
* MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) |
*/ |
void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
/** |
* \brief Enforce renegotiation requests. |
* (Default: enforced, max_records = 16) |
* |
* When we request a renegotiation, the peer can comply or |
* ignore the request. This function allows us to decide |
* whether to enforce our renegotiation requests by closing |
* the connection if the peer doesn't comply. |
* |
* However, records could already be in transit from the peer |
* when the request is emitted. In order to increase |
* reliability, we can accept a number of records before the |
* expected handshake records. |
* |
* The optimal value is highly dependent on the specific usage |
* scenario. |
* |
* \note With DTLS and server-initiated renegotiation, the |
* HelloRequest is retransmited every time mbedtls_ssl_read() times |
* out or receives Application Data, until: |
* - max_records records have beens seen, if it is >= 0, or |
* - the number of retransmits that would happen during an |
* actual handshake has been reached. |
* Please remember the request might be lost a few times |
* if you consider setting max_records to a really low value. |
* |
* \warning On client, the grace period can only happen during |
* mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate() |
* which always behave as if max_record was 0. The reason is, |
* if we receive application data from the server, we need a |
* place to write it, which only happens during mbedtls_ssl_read(). |
* |
* \param conf SSL configuration |
* \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to |
* enforce renegotiation, or a non-negative value to enforce |
* it but allow for a grace period of max_records records. |
*/ |
void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ); |
/** |
* \brief Set record counter threshold for periodic renegotiation. |
* (Default: 2^48 - 1) |
* |
* Renegotiation is automatically triggered when a record |
* counter (outgoing or ingoing) crosses the defined |
* threshold. The default value is meant to prevent the |
* connection from being closed when the counter is about to |
* reached its maximal value (it is not allowed to wrap). |
* |
* Lower values can be used to enforce policies such as "keys |
* must be refreshed every N packets with cipher X". |
* |
* The renegotiation period can be disabled by setting |
* conf->disable_renegotiation to |
* MBEDTLS_SSL_RENEGOTIATION_DISABLED. |
* |
* \note When the configured transport is |
* MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation |
* period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM, |
* the maximum renegotiation period is 2^64 - 1. |
* |
* \param conf SSL configuration |
* \param period The threshold value: a big-endian 64-bit number. |
*/ |
void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, |
const unsigned char period[8] ); |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/** |
* \brief Check if there is data already read from the |
* underlying transport but not yet processed. |
* |
* \param ssl SSL context |
* |
* \return 0 if nothing's pending, 1 otherwise. |
* |
* \note This is different in purpose and behaviour from |
* \c mbedtls_ssl_get_bytes_avail in that it considers |
* any kind of unprocessed data, not only unread |
* application data. If \c mbedtls_ssl_get_bytes |
* returns a non-zero value, this function will |
* also signal pending data, but the converse does |
* not hold. For example, in DTLS there might be |
* further records waiting to be processed from |
* the current underlying transport's datagram. |
* |
* \note If this function returns 1 (data pending), this |
* does not imply that a subsequent call to |
* \c mbedtls_ssl_read will provide any data; |
* e.g., the unprocessed data might turn out |
* to be an alert or a handshake message. |
* |
* \note This function is useful in the following situation: |
* If the SSL/TLS module successfully returns from an |
* operation - e.g. a handshake or an application record |
* read - and you're awaiting incoming data next, you |
* must not immediately idle on the underlying transport |
* to have data ready, but you need to check the value |
* of this function first. The reason is that the desired |
* data might already be read but not yet processed. |
* If, in contrast, a previous call to the SSL/TLS module |
* returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary |
* to call this function, as the latter error code entails |
* that all internal data has been processed. |
* |
*/ |
int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ); |
/** |
* \brief Return the number of application data bytes |
* remaining to be read from the current record. |
* |
* \param ssl SSL context |
* |
* \return How many bytes are available in the application |
* data record read buffer. |
* |
* \note When working over a datagram transport, this is |
* useful to detect the current datagram's boundary |
* in case \c mbedtls_ssl_read has written the maximal |
* amount of data fitting into the input buffer. |
* |
*/ |
size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ); |
/** |
* \brief Return the result of the certificate verification |
* |
* \param ssl The SSL context to use. |
* |
* \return \c 0 if the certificate verification was successful. |
* \return \c -1u if the result is not available. This may happen |
* e.g. if the handshake aborts early, or a verification |
* callback returned a fatal error. |
* \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX |
* and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h. |
*/ |
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ); |
/** |
* \brief Return the name of the current ciphersuite |
* |
* \param ssl SSL context |
* |
* \return a string containing the ciphersuite name |
*/ |
const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ); |
/** |
* \brief Return the current SSL version (SSLv3/TLSv1/etc) |
* |
* \param ssl SSL context |
* |
* \return a string containing the SSL version |
*/ |
const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ); |
/** |
* \brief Return the (maximum) number of bytes added by the record |
* layer: header + encryption/MAC overhead (inc. padding) |
* |
* \note This function is not available (always returns an error) |
* when record compression is enabled. |
* |
* \param ssl SSL context |
* |
* \return Current maximum record expansion in bytes, or |
* MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if compression is |
* enabled, which makes expansion much less predictable |
*/ |
int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
/** |
* \brief Return the maximum fragment length (payload, in bytes). |
* This is the value negotiated with peer if any, |
* or the locally configured value. |
* |
* \sa mbedtls_ssl_conf_max_frag_len() |
* \sa mbedtls_ssl_get_max_record_payload() |
* |
* \param ssl SSL context |
* |
* \return Current maximum fragment length. |
*/ |
size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ); |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
/** |
* \brief Return the current maximum outgoing record payload in bytes. |
* This takes into account the config.h setting \c |
* MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated |
* max fragment length extension if used, and for DTLS the |
* path MTU as configured and current record expansion. |
* |
* \note With DTLS, \c mbedtls_ssl_write() will return an error if |
* called with a larger length value. |
* With TLS, \c mbedtls_ssl_write() will fragment the input if |
* necessary and return the number of bytes written; it is up |
* to the caller to call \c mbedtls_ssl_write() again in |
* order to send the remaining bytes if any. |
* |
* \note This function is not available (always returns an error) |
* when record compression is enabled. |
* |
* \sa mbedtls_ssl_set_mtu() |
* \sa mbedtls_ssl_get_max_frag_len() |
* \sa mbedtls_ssl_get_record_expansion() |
* |
* \param ssl SSL context |
* |
* \return Current maximum payload for an outgoing record, |
* or a negative error code. |
*/ |
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* \brief Return the peer certificate from the current connection |
* |
* Note: Can be NULL in case no certificate was sent during |
* the handshake. Different calls for the same connection can |
* return the same or different pointers for the same |
* certificate and even a different certificate altogether. |
* The peer cert CAN change in a single connection if |
* renegotiation is performed. |
* |
* \param ssl SSL context |
* |
* \return the current peer certificate |
*/ |
const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_CLI_C) |
/** |
* \brief Save session in order to resume it later (client-side only) |
* Session data is copied to presented session structure. |
* |
* |
* \param ssl SSL context |
* \param session session context |
* |
* \return 0 if successful, |
* MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, |
* MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or |
* arguments are otherwise invalid. |
* |
* \note Only the server certificate is copied, and not the full chain, |
* so you should not attempt to validate the certificate again |
* by calling \c mbedtls_x509_crt_verify() on it. |
* Instead, you should use the results from the verification |
* in the original handshake by calling \c mbedtls_ssl_get_verify_result() |
* after loading the session again into a new SSL context |
* using \c mbedtls_ssl_set_session(). |
* |
* \note Once the session object is not needed anymore, you should |
* free it by calling \c mbedtls_ssl_session_free(). |
* |
* \sa mbedtls_ssl_set_session() |
*/ |
int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session ); |
#endif /* MBEDTLS_SSL_CLI_C */ |
/** |
* \brief Perform the SSL handshake |
* |
* \param ssl SSL context |
* |
* \return \c 0 if successful. |
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE |
* if the handshake is incomplete and waiting for data to |
* be available for reading from or writing to the underlying |
* transport - in this case you must call this function again |
* when the underlying transport is ready for the operation. |
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous |
* operation is in progress (see |
* mbedtls_ssl_conf_async_private_cb()) - in this case you |
* must call this function again when the operation is ready. |
* \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic |
* operation is in progress (see mbedtls_ecp_set_max_ops()) - |
* in this case you must call this function again to complete |
* the handshake when you're done attending other tasks. |
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use |
* and the client did not demonstrate reachability yet - in |
* this case you must stop using the context (see below). |
* \return Another SSL error code - in this case you must stop using |
* the context (see below). |
* |
* \warning If this function returns something other than |
* \c 0, |
* #MBEDTLS_ERR_SSL_WANT_READ, |
* #MBEDTLS_ERR_SSL_WANT_WRITE, |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, |
* you must stop using the SSL context for reading or writing, |
* and either free it or call \c mbedtls_ssl_session_reset() |
* on it before re-using it for a new connection; the current |
* connection must be closed. |
* |
* \note If DTLS is in use, then you may choose to handle |
* #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging |
* purposes, as it is an expected return value rather than an |
* actual error, but you still need to reset/free the context. |
* |
* \note Remarks regarding event-driven DTLS: |
* If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram |
* from the underlying transport layer is currently being processed, |
* and it is safe to idle until the timer or the underlying transport |
* signal a new event. This is not true for a successful handshake, |
* in which case the datagram of the underlying transport that is |
* currently being processed might or might not contain further |
* DTLS records. |
*/ |
int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); |
/** |
* \brief Perform a single step of the SSL handshake |
* |
* \note The state of the context (ssl->state) will be at |
* the next state after this function returns \c 0. Do not |
* call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. |
* |
* \param ssl SSL context |
* |
* \return See mbedtls_ssl_handshake(). |
* |
* \warning If this function returns something other than \c 0, |
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using |
* the SSL context for reading or writing, and either free it |
* or call \c mbedtls_ssl_session_reset() on it before |
* re-using it for a new connection; the current connection |
* must be closed. |
*/ |
int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
/** |
* \brief Initiate an SSL renegotiation on the running connection. |
* Client: perform the renegotiation right now. |
* Server: request renegotiation, which will be performed |
* during the next call to mbedtls_ssl_read() if honored by |
* client. |
* |
* \param ssl SSL context |
* |
* \return 0 if successful, or any mbedtls_ssl_handshake() return |
* value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't |
* happen during a renegotiation. |
* |
* \warning If this function returns something other than \c 0, |
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using |
* the SSL context for reading or writing, and either free it |
* or call \c mbedtls_ssl_session_reset() on it before |
* re-using it for a new connection; the current connection |
* must be closed. |
* |
*/ |
int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/** |
* \brief Read at most 'len' application data bytes |
* |
* \param ssl SSL context |
* \param buf buffer that will hold the data |
* \param len maximum number of bytes to read |
* |
* \return The (positive) number of bytes read if successful. |
* \return \c 0 if the read end of the underlying transport was closed |
* - in this case you must stop using the context (see below). |
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE |
* if the handshake is incomplete and waiting for data to |
* be available for reading from or writing to the underlying |
* transport - in this case you must call this function again |
* when the underlying transport is ready for the operation. |
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous |
* operation is in progress (see |
* mbedtls_ssl_conf_async_private_cb()) - in this case you |
* must call this function again when the operation is ready. |
* \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic |
* operation is in progress (see mbedtls_ecp_set_max_ops()) - |
* in this case you must call this function again to complete |
* the handshake when you're done attending other tasks. |
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server |
* side of a DTLS connection and the client is initiating a |
* new connection using the same source port. See below. |
* \return Another SSL error code - in this case you must stop using |
* the context (see below). |
* |
* \warning If this function returns something other than |
* a positive value, |
* #MBEDTLS_ERR_SSL_WANT_READ, |
* #MBEDTLS_ERR_SSL_WANT_WRITE, |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or |
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, |
* you must stop using the SSL context for reading or writing, |
* and either free it or call \c mbedtls_ssl_session_reset() |
* on it before re-using it for a new connection; the current |
* connection must be closed. |
* |
* \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT |
* (which can only happen server-side), it means that a client |
* is initiating a new connection using the same source port. |
* You can either treat that as a connection close and wait |
* for the client to resend a ClientHello, or directly |
* continue with \c mbedtls_ssl_handshake() with the same |
* context (as it has been reset internally). Either way, you |
* must make sure this is seen by the application as a new |
* connection: application state, if any, should be reset, and |
* most importantly the identity of the client must be checked |
* again. WARNING: not validating the identity of the client |
* again, or not transmitting the new identity to the |
* application layer, would allow authentication bypass! |
* |
* \note Remarks regarding event-driven DTLS: |
* - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram |
* from the underlying transport layer is currently being processed, |
* and it is safe to idle until the timer or the underlying transport |
* signal a new event. |
* - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was |
* initially available on the underlying transport, as this data may have |
* been only e.g. duplicated messages or a renegotiation request. |
* Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even |
* when reacting to an incoming-data event from the underlying transport. |
* - On success, the datagram of the underlying transport that is currently |
* being processed may contain further DTLS records. You should call |
* \c mbedtls_ssl_check_pending to check for remaining records. |
* |
*/ |
int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ); |
/** |
* \brief Try to write exactly 'len' application data bytes |
* |
* \warning This function will do partial writes in some cases. If the |
* return value is non-negative but less than length, the |
* function must be called again with updated arguments: |
* buf + ret, len - ret (if ret is the return value) until |
* it returns a value equal to the last 'len' argument. |
* |
* \param ssl SSL context |
* \param buf buffer holding the data |
* \param len how many bytes must be written |
* |
* \return The (non-negative) number of bytes actually written if |
* successful (may be less than \p len). |
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE |
* if the handshake is incomplete and waiting for data to |
* be available for reading from or writing to the underlying |
* transport - in this case you must call this function again |
* when the underlying transport is ready for the operation. |
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous |
* operation is in progress (see |
* mbedtls_ssl_conf_async_private_cb()) - in this case you |
* must call this function again when the operation is ready. |
* \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic |
* operation is in progress (see mbedtls_ecp_set_max_ops()) - |
* in this case you must call this function again to complete |
* the handshake when you're done attending other tasks. |
* \return Another SSL error code - in this case you must stop using |
* the context (see below). |
* |
* \warning If this function returns something other than |
* a non-negative value, |
* #MBEDTLS_ERR_SSL_WANT_READ, |
* #MBEDTLS_ERR_SSL_WANT_WRITE, |
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or |
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, |
* you must stop using the SSL context for reading or writing, |
* and either free it or call \c mbedtls_ssl_session_reset() |
* on it before re-using it for a new connection; the current |
* connection must be closed. |
* |
* \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ, |
* it must be called later with the *same* arguments, |
* until it returns a value greater that or equal to 0. When |
* the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be |
* some partial data in the output buffer, however this is not |
* yet sent. |
* |
* \note If the requested length is greater than the maximum |
* fragment length (either the built-in limit or the one set |
* or negotiated with the peer), then: |
* - with TLS, less bytes than requested are written. |
* - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. |
* \c mbedtls_ssl_get_max_frag_len() may be used to query the |
* active maximum fragment length. |
* |
* \note Attempting to write 0 bytes will result in an empty TLS |
* application record being sent. |
*/ |
int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ); |
/** |
* \brief Send an alert message |
* |
* \param ssl SSL context |
* \param level The alert level of the message |
* (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL) |
* \param message The alert message (SSL_ALERT_MSG_*) |
* |
* \return 0 if successful, or a specific SSL error code. |
* |
* \note If this function returns something other than 0 or |
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using |
* the SSL context for reading or writing, and either free it or |
* call \c mbedtls_ssl_session_reset() on it before re-using it |
* for a new connection; the current connection must be closed. |
*/ |
int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, |
unsigned char level, |
unsigned char message ); |
/** |
* \brief Notify the peer that the connection is being closed |
* |
* \param ssl SSL context |
* |
* \return 0 if successful, or a specific SSL error code. |
* |
* \note If this function returns something other than 0 or |
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using |
* the SSL context for reading or writing, and either free it or |
* call \c mbedtls_ssl_session_reset() on it before re-using it |
* for a new connection; the current connection must be closed. |
*/ |
int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); |
/** |
* \brief Free referenced items in an SSL context and clear memory |
* |
* \param ssl SSL context |
*/ |
void mbedtls_ssl_free( mbedtls_ssl_context *ssl ); |
/** |
* \brief Initialize an SSL configuration context |
* Just makes the context ready for |
* mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). |
* |
* \note You need to call mbedtls_ssl_config_defaults() unless you |
* manually set all of the relevant fields yourself. |
* |
* \param conf SSL configuration context |
*/ |
void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); |
/** |
* \brief Load reasonnable default SSL configuration values. |
* (You need to call mbedtls_ssl_config_init() first.) |
* |
* \param conf SSL configuration context |
* \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER |
* \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or |
* MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS |
* \param preset a MBEDTLS_SSL_PRESET_XXX value |
* |
* \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. |
* |
* \return 0 if successful, or |
* MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error. |
*/ |
int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, |
int endpoint, int transport, int preset ); |
/** |
* \brief Free an SSL configuration context |
* |
* \param conf SSL configuration context |
*/ |
void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ); |
/** |
* \brief Initialize SSL session structure |
* |
* \param session SSL session |
*/ |
void mbedtls_ssl_session_init( mbedtls_ssl_session *session ); |
/** |
* \brief Free referenced items in an SSL session including the |
* peer certificate and clear memory |
* |
* \note A session object can be freed even if the SSL context |
* that was used to retrieve the session is still in use. |
* |
* \param session SSL session |
*/ |
void mbedtls_ssl_session_free( mbedtls_ssl_session *session ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* ssl.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ssl_cache.h |
---|
0,0 → 1,152 |
/** |
* \file ssl_cache.h |
* |
* \brief SSL session cache implementation |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SSL_CACHE_H |
#define MBEDTLS_SSL_CACHE_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ssl.h" |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT) |
#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ |
#endif |
#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES) |
#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ |
#endif |
/* \} name SECTION: Module settings */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
typedef struct mbedtls_ssl_cache_context mbedtls_ssl_cache_context; |
typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry; |
/** |
* \brief This structure is used for storing cache entries |
*/ |
struct mbedtls_ssl_cache_entry |
{ |
#if defined(MBEDTLS_HAVE_TIME) |
mbedtls_time_t timestamp; /*!< entry timestamp */ |
#endif |
mbedtls_ssl_session session; /*!< entry session */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
mbedtls_x509_buf peer_cert; /*!< entry peer_cert */ |
#endif |
mbedtls_ssl_cache_entry *next; /*!< chain pointer */ |
}; |
/** |
* \brief Cache context |
*/ |
struct mbedtls_ssl_cache_context |
{ |
mbedtls_ssl_cache_entry *chain; /*!< start of the chain */ |
int timeout; /*!< cache entry timeout */ |
int max_entries; /*!< maximum entries */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; /*!< mutex */ |
#endif |
}; |
/** |
* \brief Initialize an SSL cache context |
* |
* \param cache SSL cache context |
*/ |
void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ); |
/** |
* \brief Cache get callback implementation |
* (Thread-safe if MBEDTLS_THREADING_C is enabled) |
* |
* \param data SSL cache context |
* \param session session to retrieve entry for |
*/ |
int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ); |
/** |
* \brief Cache set callback implementation |
* (Thread-safe if MBEDTLS_THREADING_C is enabled) |
* |
* \param data SSL cache context |
* \param session session to store entry for |
*/ |
int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ); |
#if defined(MBEDTLS_HAVE_TIME) |
/** |
* \brief Set the cache timeout |
* (Default: MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT (1 day)) |
* |
* A timeout of 0 indicates no timeout. |
* |
* \param cache SSL cache context |
* \param timeout cache entry timeout in seconds |
*/ |
void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ); |
#endif /* MBEDTLS_HAVE_TIME */ |
/** |
* \brief Set the maximum number of cache entries |
* (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) |
* |
* \param cache SSL cache context |
* \param max cache entry maximum |
*/ |
void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ); |
/** |
* \brief Free referenced items in a cache context and clear memory |
* |
* \param cache SSL cache context |
*/ |
void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* ssl_cache.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ssl_ciphersuites.h |
---|
0,0 → 1,542 |
/** |
* \file ssl_ciphersuites.h |
* |
* \brief SSL Ciphersuites for mbed TLS |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SSL_CIPHERSUITES_H |
#define MBEDTLS_SSL_CIPHERSUITES_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "pk.h" |
#include "cipher.h" |
#include "md.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* |
* Supported ciphersuites (Official IANA names) |
*/ |
#define MBEDTLS_TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */ |
#define MBEDTLS_TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */ |
#define MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 0x04 |
#define MBEDTLS_TLS_RSA_WITH_RC4_128_SHA 0x05 |
#define MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A |
#define MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16 |
#define MBEDTLS_TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */ |
#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA 0x2F |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 |
#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA 0x35 |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 |
#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */ |
#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 |
#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 |
#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 |
#define MBEDTLS_TLS_PSK_WITH_RC4_128_SHA 0x8A |
#define MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B |
#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA 0x8C |
#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA 0x8D |
#define MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E |
#define MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 |
#define MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA 0x92 |
#define MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93 |
#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 |
#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 |
#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE |
#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF |
#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ |
#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 |
#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 |
#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 |
#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ |
#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ |
#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ |
#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 |
#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 |
#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 |
#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 |
#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 |
#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ |
#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ |
/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ |
/* RFC 7905 */ |
#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ |
#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ |
#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ |
#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ |
#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ |
/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. |
* Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below |
*/ |
typedef enum { |
MBEDTLS_KEY_EXCHANGE_NONE = 0, |
MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_KEY_EXCHANGE_ECJPAKE, |
} mbedtls_key_exchange_type_t; |
/* Key exchanges using a certificate */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED |
#endif |
/* Key exchanges allowing client certificate requests */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED |
#endif |
/* Key exchanges involving server signature in ServerKeyExchange */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED |
#endif |
/* Key exchanges using ECDH */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED |
#endif |
/* Key exchanges that don't involve ephemeral keys */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED |
#endif |
/* Key exchanges that involve ephemeral keys */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED |
#endif |
/* Key exchanges using a PSK */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED |
#endif |
/* Key exchanges using DHE */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED |
#endif |
/* Key exchanges using ECDHE */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED |
#endif |
typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; |
#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ |
#define MBEDTLS_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag, |
eg for CCM_8 */ |
#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ |
/** |
* \brief This structure is used for storing ciphersuite information |
*/ |
struct mbedtls_ssl_ciphersuite_t |
{ |
int id; |
const char * name; |
mbedtls_cipher_type_t cipher; |
mbedtls_md_type_t mac; |
mbedtls_key_exchange_type_t key_exchange; |
int min_major_ver; |
int min_minor_ver; |
int max_major_ver; |
int max_minor_ver; |
unsigned char flags; |
}; |
const int *mbedtls_ssl_list_ciphersuites( void ); |
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name ); |
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id ); |
#if defined(MBEDTLS_PK_C) |
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); |
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ); |
#endif |
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ); |
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ); |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) |
static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_DHE_PSK: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
case MBEDTLS_KEY_EXCHANGE_ECJPAKE: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) |
static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: |
case MBEDTLS_KEY_EXCHANGE_RSA: |
case MBEDTLS_KEY_EXCHANGE_PSK: |
case MBEDTLS_KEY_EXCHANGE_RSA_PSK: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) |
static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ |
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_RSA: |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) |
static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_DHE_PSK: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) |
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* ssl_ciphersuites.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ssl_cookie.h |
---|
0,0 → 1,117 |
/** |
* \file ssl_cookie.h |
* |
* \brief DTLS cookie callbacks implementation |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SSL_COOKIE_H |
#define MBEDTLS_SSL_COOKIE_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ssl.h" |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
/** |
* \name SECTION: Module settings |
* |
* The configuration options you can set for this module are in this section. |
* Either change them in config.h or define them on the compiler command line. |
* \{ |
*/ |
#ifndef MBEDTLS_SSL_COOKIE_TIMEOUT |
#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ |
#endif |
/* \} name SECTION: Module settings */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Context for the default cookie functions. |
*/ |
typedef struct mbedtls_ssl_cookie_ctx |
{ |
mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */ |
#if !defined(MBEDTLS_HAVE_TIME) |
unsigned long serial; /*!< serial number for expiration */ |
#endif |
unsigned long timeout; /*!< timeout delay, in seconds if HAVE_TIME, |
or in number of tickets issued */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; |
#endif |
} mbedtls_ssl_cookie_ctx; |
/** |
* \brief Initialize cookie context |
*/ |
void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ); |
/** |
* \brief Setup cookie context (generate keys) |
*/ |
int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
/** |
* \brief Set expiration delay for cookies |
* (Default MBEDTLS_SSL_COOKIE_TIMEOUT) |
* |
* \param ctx Cookie contex |
* \param delay Delay, in seconds if HAVE_TIME, or in number of cookies |
* issued in the meantime. |
* 0 to disable expiration (NOT recommended) |
*/ |
void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ); |
/** |
* \brief Free cookie context |
*/ |
void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ); |
/** |
* \brief Generate cookie, see \c mbedtls_ssl_cookie_write_t |
*/ |
mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write; |
/** |
* \brief Verify cookie, see \c mbedtls_ssl_cookie_write_t |
*/ |
mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check; |
#ifdef __cplusplus |
} |
#endif |
#endif /* ssl_cookie.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ssl_internal.h |
---|
0,0 → 1,784 |
/** |
* \file ssl_internal.h |
* |
* \brief Internal functions shared by the SSL modules |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SSL_INTERNAL_H |
#define MBEDTLS_SSL_INTERNAL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "ssl.h" |
#include "cipher.h" |
#if defined(MBEDTLS_MD5_C) |
#include "md5.h" |
#endif |
#if defined(MBEDTLS_SHA1_C) |
#include "sha1.h" |
#endif |
#if defined(MBEDTLS_SHA256_C) |
#include "sha256.h" |
#endif |
#if defined(MBEDTLS_SHA512_C) |
#include "sha512.h" |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
#include "ecjpake.h" |
#endif |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
/* Determine minimum supported version */ |
#define MBEDTLS_SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 |
#else |
#if defined(MBEDTLS_SSL_PROTO_TLS1) |
#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 |
#else |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) |
#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 |
#else |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1 */ |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 |
#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 |
/* Determine maximum supported version */ |
#define MBEDTLS_SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 |
#else |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) |
#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 |
#else |
#if defined(MBEDTLS_SSL_PROTO_TLS1) |
#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 |
#else |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1 */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
/* Shorthand for restartable ECC */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) && \ |
defined(MBEDTLS_SSL_CLI_C) && \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
#define MBEDTLS_SSL__ECP_RESTARTABLE |
#endif |
#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 |
#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ |
#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ |
#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */ |
/* |
* DTLS retransmission states, see RFC 6347 4.2.4 |
* |
* The SENDING state is merged in PREPARING for initial sends, |
* but is distinct for resends. |
* |
* Note: initial state is wrong for server, but is not used anyway. |
*/ |
#define MBEDTLS_SSL_RETRANS_PREPARING 0 |
#define MBEDTLS_SSL_RETRANS_SENDING 1 |
#define MBEDTLS_SSL_RETRANS_WAITING 2 |
#define MBEDTLS_SSL_RETRANS_FINISHED 3 |
/* |
* Allow extra bytes for record, authentication and encryption overhead: |
* counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) |
* and allow for a maximum of 1024 of compression expansion if |
* enabled. |
*/ |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
#define MBEDTLS_SSL_COMPRESSION_ADD 1024 |
#else |
#define MBEDTLS_SSL_COMPRESSION_ADD 0 |
#endif |
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC) |
/* Ciphersuites using HMAC */ |
#if defined(MBEDTLS_SHA512_C) |
#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ |
#elif defined(MBEDTLS_SHA256_C) |
#define MBEDTLS_SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ |
#else |
#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ |
#endif |
#else |
/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ |
#define MBEDTLS_SSL_MAC_ADD 16 |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#define MBEDTLS_SSL_PADDING_ADD 256 |
#else |
#define MBEDTLS_SSL_PADDING_ADD 0 |
#endif |
#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \ |
MBEDTLS_MAX_IV_LENGTH + \ |
MBEDTLS_SSL_MAC_ADD + \ |
MBEDTLS_SSL_PADDING_ADD \ |
) |
#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ |
( MBEDTLS_SSL_IN_CONTENT_LEN ) ) |
#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ |
( MBEDTLS_SSL_OUT_CONTENT_LEN ) ) |
/* The maximum number of buffered handshake messages. */ |
#define MBEDTLS_SSL_MAX_BUFFERED_HS 4 |
/* Maximum length we can advertise as our max content length for |
RFC 6066 max_fragment_length extension negotiation purposes |
(the lesser of both sizes, if they are unequal.) |
*/ |
#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \ |
(MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \ |
? ( MBEDTLS_SSL_OUT_CONTENT_LEN ) \ |
: ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ |
) |
/* |
* Check that we obey the standard's message size bounds |
*/ |
#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384 |
#error "Bad configuration - record content too large." |
#endif |
#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN |
#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." |
#endif |
#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN |
#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." |
#endif |
#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 |
#error "Bad configuration - incoming protected record payload too large." |
#endif |
#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 |
#error "Bad configuration - outgoing protected record payload too large." |
#endif |
/* Calculate buffer sizes */ |
/* Note: Even though the TLS record header is only 5 bytes |
long, we're internally using 8 bytes to store the |
implicit sequence number. */ |
#define MBEDTLS_SSL_HEADER_LEN 13 |
#define MBEDTLS_SSL_IN_BUFFER_LEN \ |
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) ) |
#define MBEDTLS_SSL_OUT_BUFFER_LEN \ |
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) ) |
#ifdef MBEDTLS_ZLIB_SUPPORT |
/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */ |
#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \ |
( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN ) \ |
? MBEDTLS_SSL_IN_BUFFER_LEN \ |
: MBEDTLS_SSL_OUT_BUFFER_LEN \ |
) |
#endif |
/* |
* TLS extension flags (for extensions with outgoing ServerHello content |
* that need it (e.g. for RENEGOTIATION_INFO the server already knows because |
* of state of the renegotiation flag, so no indicator is required) |
*/ |
#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) |
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* |
* Abstraction for a grid of allowed signature-hash-algorithm pairs. |
*/ |
struct mbedtls_ssl_sig_hash_set_t |
{ |
/* At the moment, we only need to remember a single suitable |
* hash algorithm per signature algorithm. As long as that's |
* the case - and we don't need a general lookup function - |
* we can implement the sig-hash-set as a map from signatures |
* to hash algorithms. */ |
mbedtls_md_type_t rsa; |
mbedtls_md_type_t ecdsa; |
}; |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
/* |
* This structure contains the parameters only needed during handshake. |
*/ |
struct mbedtls_ssl_handshake_params |
{ |
/* |
* Handshake specific crypto variables |
*/ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */ |
#endif |
#if defined(MBEDTLS_DHM_C) |
mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ |
#endif |
#if defined(MBEDTLS_ECDH_C) |
mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ |
#if defined(MBEDTLS_SSL_CLI_C) |
unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ |
size_t ecjpake_cache_len; /*!< Length of cached data */ |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
unsigned char *psk; /*!< PSK from the callback */ |
size_t psk_len; /*!< Length of PSK from callback */ |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
int sni_authmode; /*!< authmode from SNI callback */ |
mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ |
mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ |
mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
int ecrs_enabled; /*!< Handshake supports EC restart? */ |
mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */ |
enum { /* this complements ssl->state with info on intra-state operations */ |
ssl_ecrs_none = 0, /*!< nothing going on (yet) */ |
ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */ |
ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */ |
ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */ |
ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */ |
} ecrs_state; /*!< current (or last) operation */ |
size_t ecrs_n; /*!< place for saving a length */ |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ |
unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ |
unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie |
Srv: unused */ |
unsigned char verify_cookie_len; /*!< Cli: cookie length |
Srv: flag for sending a cookie */ |
uint32_t retransmit_timeout; /*!< Current value of timeout */ |
unsigned char retransmit_state; /*!< Retransmission state */ |
mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ |
mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ |
unsigned char *cur_msg_p; /*!< Position in current message */ |
unsigned int in_flight_start_seq; /*!< Minimum message sequence in the |
flight being received */ |
mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for |
resending messages */ |
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter |
for resending messages */ |
struct |
{ |
size_t total_bytes_buffered; /*!< Cumulative size of heap allocated |
* buffers used for message buffering. */ |
uint8_t seen_ccs; /*!< Indicates if a CCS message has |
* been seen in the current flight. */ |
struct mbedtls_ssl_hs_buffer |
{ |
unsigned is_valid : 1; |
unsigned is_fragmented : 1; |
unsigned is_complete : 1; |
unsigned char *data; |
size_t data_len; |
} hs[MBEDTLS_SSL_MAX_BUFFERED_HS]; |
struct |
{ |
unsigned char *data; |
size_t len; |
unsigned epoch; |
} future_record; |
} buffering; |
uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */ |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* |
* Checksum contexts |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
mbedtls_md5_context fin_md5; |
mbedtls_sha1_context fin_sha1; |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
mbedtls_sha256_context fin_sha256; |
#endif |
#if defined(MBEDTLS_SHA512_C) |
mbedtls_sha512_context fin_sha512; |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); |
void (*calc_verify)(mbedtls_ssl_context *, unsigned char *); |
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); |
int (*tls_prf)(const unsigned char *, size_t, const char *, |
const unsigned char *, size_t, |
unsigned char *, size_t); |
size_t pmslen; /*!< premaster length */ |
unsigned char randbytes[64]; /*!< random bytes */ |
unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; |
/*!< premaster secret */ |
int resume; /*!< session resume indicator*/ |
int max_major_ver; /*!< max. major version client*/ |
int max_minor_ver; /*!< max. minor version client*/ |
int cli_exts; /*!< client extension presence*/ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
int new_session_ticket; /*!< use NewSessionTicket? */ |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
int extended_ms; /*!< use Extended Master Secret? */ |
#endif |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */ |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
/** Asynchronous operation context. This field is meant for use by the |
* asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start, |
* mbedtls_ssl_config::f_async_decrypt_start, |
* mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel). |
* The library does not use it internally. */ |
void *user_async_ctx; |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
}; |
typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; |
/* |
* This structure contains a full set of runtime transform parameters |
* either in negotiation or active. |
*/ |
struct mbedtls_ssl_transform |
{ |
/* |
* Session specific crypto layer |
*/ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; |
/*!< Chosen cipersuite_info */ |
unsigned int keylen; /*!< symmetric key length (bytes) */ |
size_t minlen; /*!< min. ciphertext length */ |
size_t ivlen; /*!< IV length */ |
size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ |
size_t maclen; /*!< MAC length */ |
unsigned char iv_enc[16]; /*!< IV (encryption) */ |
unsigned char iv_dec[16]; /*!< IV (decryption) */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
/* Needed only for SSL v3.0 secret */ |
unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */ |
unsigned char mac_dec[20]; /*!< SSL v3.0 secret (dec) */ |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */ |
mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */ |
mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ |
mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ |
/* |
* Session specific compression layer |
*/ |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
z_stream ctx_deflate; /*!< compression context */ |
z_stream ctx_inflate; /*!< decompression context */ |
#endif |
}; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/* |
* List of certificate + private key pairs |
*/ |
struct mbedtls_ssl_key_cert |
{ |
mbedtls_x509_crt *cert; /*!< cert */ |
mbedtls_pk_context *key; /*!< private key */ |
mbedtls_ssl_key_cert *next; /*!< next key/cert pair */ |
}; |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* |
* List of handshake messages kept around for resending |
*/ |
struct mbedtls_ssl_flight_item |
{ |
unsigned char *p; /*!< message, including handshake headers */ |
size_t len; /*!< length of p */ |
unsigned char type; /*!< type of the message: handshake or CCS */ |
mbedtls_ssl_flight_item *next; /*!< next handshake message(s) */ |
}; |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* Find an entry in a signature-hash set matching a given hash algorithm. */ |
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, |
mbedtls_pk_type_t sig_alg ); |
/* Add a signature-hash-pair to a signature-hash set */ |
void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, |
mbedtls_pk_type_t sig_alg, |
mbedtls_md_type_t md_alg ); |
/* Allow exactly one hash algorithm for each signature. */ |
void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, |
mbedtls_md_type_t md_alg ); |
/* Setup an empty signature-hash set */ |
static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set ) |
{ |
mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
/** |
* \brief Free referenced items in an SSL transform context and clear |
* memory |
* |
* \param transform SSL transform context |
*/ |
void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ); |
/** |
* \brief Free referenced items in an SSL handshake context and clear |
* memory |
* |
* \param ssl SSL context |
*/ |
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); |
void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); |
void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); |
void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); |
/** |
* \brief Update record layer |
* |
* This function roughly separates the implementation |
* of the logic of (D)TLS from the implementation |
* of the secure transport. |
* |
* \param ssl The SSL context to use. |
* \param update_hs_digest This indicates if the handshake digest |
* should be automatically updated in case |
* a handshake message is found. |
* |
* \return 0 or non-zero error code. |
* |
* \note A clarification on what is called 'record layer' here |
* is in order, as many sensible definitions are possible: |
* |
* The record layer takes as input an untrusted underlying |
* transport (stream or datagram) and transforms it into |
* a serially multiplexed, secure transport, which |
* conceptually provides the following: |
* |
* (1) Three datagram based, content-agnostic transports |
* for handshake, alert and CCS messages. |
* (2) One stream- or datagram-based transport |
* for application data. |
* (3) Functionality for changing the underlying transform |
* securing the contents. |
* |
* The interface to this functionality is given as follows: |
* |
* a Updating |
* [Currently implemented by mbedtls_ssl_read_record] |
* |
* Check if and on which of the four 'ports' data is pending: |
* Nothing, a controlling datagram of type (1), or application |
* data (2). In any case data is present, internal buffers |
* provide access to the data for the user to process it. |
* Consumption of type (1) datagrams is done automatically |
* on the next update, invalidating that the internal buffers |
* for previous datagrams, while consumption of application |
* data (2) is user-controlled. |
* |
* b Reading of application data |
* [Currently manual adaption of ssl->in_offt pointer] |
* |
* As mentioned in the last paragraph, consumption of data |
* is different from the automatic consumption of control |
* datagrams (1) because application data is treated as a stream. |
* |
* c Tracking availability of application data |
* [Currently manually through decreasing ssl->in_msglen] |
* |
* For efficiency and to retain datagram semantics for |
* application data in case of DTLS, the record layer |
* provides functionality for checking how much application |
* data is still available in the internal buffer. |
* |
* d Changing the transformation securing the communication. |
* |
* Given an opaque implementation of the record layer in the |
* above sense, it should be possible to implement the logic |
* of (D)TLS on top of it without the need to know anything |
* about the record layer's internals. This is done e.g. |
* in all the handshake handling functions, and in the |
* application data reading function mbedtls_ssl_read. |
* |
* \note The above tries to give a conceptual picture of the |
* record layer, but the current implementation deviates |
* from it in some places. For example, our implementation of |
* the update functionality through mbedtls_ssl_read_record |
* discards datagrams depending on the current state, which |
* wouldn't fall under the record layer's responsibility |
* following the above definition. |
* |
*/ |
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, |
unsigned update_hs_digest ); |
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); |
int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); |
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ); |
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info ); |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); |
#endif |
#if defined(MBEDTLS_PK_C) |
unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ); |
unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ); |
mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); |
#endif |
mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); |
unsigned char mbedtls_ssl_hash_from_md_alg( int md ); |
int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); |
#if defined(MBEDTLS_ECP_C) |
int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, |
mbedtls_md_type_t md ); |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_key_cert *key_cert; |
if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) |
key_cert = ssl->handshake->key_cert; |
else |
key_cert = ssl->conf->key_cert; |
return( key_cert == NULL ? NULL : key_cert->key ); |
} |
static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_key_cert *key_cert; |
if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) |
key_cert = ssl->handshake->key_cert; |
else |
key_cert = ssl->conf->key_cert; |
return( key_cert == NULL ? NULL : key_cert->cert ); |
} |
/* |
* Check usage of a certificate wrt extensions: |
* keyUsage, extendedKeyUsage (later), and nSCertType (later). |
* |
* Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we |
* check a cert we received from them)! |
* |
* Return 0 if everything is OK, -1 if not. |
*/ |
int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, |
const mbedtls_ssl_ciphersuite_t *ciphersuite, |
int cert_endpoint, |
uint32_t *flags ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
void mbedtls_ssl_write_version( int major, int minor, int transport, |
unsigned char ver[2] ); |
void mbedtls_ssl_read_version( int *major, int *minor, int transport, |
const unsigned char ver[2] ); |
static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
return( 13 ); |
#else |
((void) ssl); |
#endif |
return( 5 ); |
} |
static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
return( 12 ); |
#else |
((void) ssl); |
#endif |
return( 4 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ); |
void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ); |
#endif |
/* Visible for testing purposes only */ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ); |
void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); |
#endif |
/* constant-time buffer comparison */ |
static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) |
{ |
size_t i; |
volatile const unsigned char *A = (volatile const unsigned char *) a; |
volatile const unsigned char *B = (volatile const unsigned char *) b; |
volatile unsigned char diff = 0; |
for( i = 0; i < n; i++ ) |
{ |
/* Read volatile data in order before computing diff. |
* This avoids IAR compiler warning: |
* 'the order of volatile accesses is undefined ..' */ |
unsigned char x = A[i], y = B[i]; |
diff |= x ^ y; |
} |
return( diff ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, |
unsigned char *output, |
unsigned char *data, size_t data_len ); |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, |
unsigned char *hash, size_t *hashlen, |
unsigned char *data, size_t data_len, |
mbedtls_md_type_t md_alg ); |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* ssl_internal.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/ssl_ticket.h |
---|
0,0 → 1,144 |
/** |
* \file ssl_ticket.h |
* |
* \brief TLS server ticket callbacks implementation |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_SSL_TICKET_H |
#define MBEDTLS_SSL_TICKET_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
/* |
* This implementation of the session ticket callbacks includes key |
* management, rotating the keys periodically in order to preserve forward |
* secrecy, when MBEDTLS_HAVE_TIME is defined. |
*/ |
#include "ssl.h" |
#include "cipher.h" |
#if defined(MBEDTLS_THREADING_C) |
#include "threading.h" |
#endif |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \brief Information for session ticket protection |
*/ |
typedef struct mbedtls_ssl_ticket_key |
{ |
unsigned char name[4]; /*!< random key identifier */ |
uint32_t generation_time; /*!< key generation timestamp (seconds) */ |
mbedtls_cipher_context_t ctx; /*!< context for auth enc/decryption */ |
} |
mbedtls_ssl_ticket_key; |
/** |
* \brief Context for session ticket handling functions |
*/ |
typedef struct mbedtls_ssl_ticket_context |
{ |
mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */ |
unsigned char active; /*!< index of the currently active key */ |
uint32_t ticket_lifetime; /*!< lifetime of tickets in seconds */ |
/** Callback for getting (pseudo-)random numbers */ |
int (*f_rng)(void *, unsigned char *, size_t); |
void *p_rng; /*!< context for the RNG function */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; |
#endif |
} |
mbedtls_ssl_ticket_context; |
/** |
* \brief Initialize a ticket context. |
* (Just make it ready for mbedtls_ssl_ticket_setup() |
* or mbedtls_ssl_ticket_free().) |
* |
* \param ctx Context to be initialized |
*/ |
void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ); |
/** |
* \brief Prepare context to be actually used |
* |
* \param ctx Context to be set up |
* \param f_rng RNG callback function |
* \param p_rng RNG callback context |
* \param cipher AEAD cipher to use for ticket protection. |
* Recommended value: MBEDTLS_CIPHER_AES_256_GCM. |
* \param lifetime Tickets lifetime in seconds |
* Recommended value: 86400 (one day). |
* |
* \note It is highly recommended to select a cipher that is at |
* least as strong as the the strongest ciphersuite |
* supported. Usually that means a 256-bit key. |
* |
* \note The lifetime of the keys is twice the lifetime of tickets. |
* It is recommended to pick a reasonnable lifetime so as not |
* to negate the benefits of forward secrecy. |
* |
* \return 0 if successful, |
* or a specific MBEDTLS_ERR_XXX error code |
*/ |
int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
mbedtls_cipher_type_t cipher, |
uint32_t lifetime ); |
/** |
* \brief Implementation of the ticket write callback |
* |
* \note See \c mbedtls_ssl_ticket_write_t for description |
*/ |
mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write; |
/** |
* \brief Implementation of the ticket parse callback |
* |
* \note See \c mbedtls_ssl_ticket_parse_t for description |
*/ |
mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse; |
/** |
* \brief Free a context's content and zeroize it. |
* |
* \param ctx Context to be cleaned up |
*/ |
void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* ssl_ticket.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/threading.h |
---|
0,0 → 1,124 |
/** |
* \file threading.h |
* |
* \brief Threading abstraction layer |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_THREADING_H |
#define MBEDTLS_THREADING_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stdlib.h> |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be |
* used. */ |
#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ |
#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ |
#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ |
#if defined(MBEDTLS_THREADING_PTHREAD) |
#include <pthread.h> |
typedef struct mbedtls_threading_mutex_t |
{ |
pthread_mutex_t mutex; |
char is_valid; |
} mbedtls_threading_mutex_t; |
#endif |
#if defined(MBEDTLS_THREADING_ALT) |
/* You should define the mbedtls_threading_mutex_t type in your header */ |
#include "threading_alt.h" |
/** |
* \brief Set your alternate threading implementation function |
* pointers and initialize global mutexes. If used, this |
* function must be called once in the main thread before any |
* other mbed TLS function is called, and |
* mbedtls_threading_free_alt() must be called once in the main |
* thread after all other mbed TLS functions. |
* |
* \note mutex_init() and mutex_free() don't return a status code. |
* If mutex_init() fails, it should leave its argument (the |
* mutex) in a state such that mutex_lock() will fail when |
* called with this argument. |
* |
* \param mutex_init the init function implementation |
* \param mutex_free the free function implementation |
* \param mutex_lock the lock function implementation |
* \param mutex_unlock the unlock function implementation |
*/ |
void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), |
void (*mutex_free)( mbedtls_threading_mutex_t * ), |
int (*mutex_lock)( mbedtls_threading_mutex_t * ), |
int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ); |
/** |
* \brief Free global mutexes. |
*/ |
void mbedtls_threading_free_alt( void ); |
#endif /* MBEDTLS_THREADING_ALT */ |
#if defined(MBEDTLS_THREADING_C) |
/* |
* The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock |
* |
* All these functions are expected to work or the result will be undefined. |
*/ |
extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex ); |
extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex ); |
extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex ); |
extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); |
/* |
* Global mutexes |
*/ |
#if defined(MBEDTLS_FS_IO) |
extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; |
#endif |
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) |
/* This mutex may or may not be used in the default definition of |
* mbedtls_platform_gmtime_r(), but in order to determine that, |
* we need to check POSIX features, hence modify _POSIX_C_SOURCE. |
* With the current approach, this declaration is orphaned, lacking |
* an accompanying definition, in case mbedtls_platform_gmtime_r() |
* doesn't need it, but that's not a problem. */ |
extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; |
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ |
#endif /* MBEDTLS_THREADING_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* threading.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/timing.h |
---|
0,0 → 1,155 |
/** |
* \file timing.h |
* |
* \brief Portable interface to timeouts and to the CPU cycle counter |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_TIMING_H |
#define MBEDTLS_TIMING_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stdint.h> |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_TIMING_ALT) |
// Regular implementation |
// |
/** |
* \brief timer structure |
*/ |
struct mbedtls_timing_hr_time |
{ |
unsigned char opaque[32]; |
}; |
/** |
* \brief Context for mbedtls_timing_set/get_delay() |
*/ |
typedef struct mbedtls_timing_delay_context |
{ |
struct mbedtls_timing_hr_time timer; |
uint32_t int_ms; |
uint32_t fin_ms; |
} mbedtls_timing_delay_context; |
#else /* MBEDTLS_TIMING_ALT */ |
#include "timing_alt.h" |
#endif /* MBEDTLS_TIMING_ALT */ |
extern volatile int mbedtls_timing_alarmed; |
/** |
* \brief Return the CPU cycle counter value |
* |
* \warning This is only a best effort! Do not rely on this! |
* In particular, it is known to be unreliable on virtual |
* machines. |
* |
* \note This value starts at an unspecified origin and |
* may wrap around. |
*/ |
unsigned long mbedtls_timing_hardclock( void ); |
/** |
* \brief Return the elapsed time in milliseconds |
* |
* \param val points to a timer structure |
* \param reset If 0, query the elapsed time. Otherwise (re)start the timer. |
* |
* \return Elapsed time since the previous reset in ms. When |
* restarting, this is always 0. |
* |
* \note To initialize a timer, call this function with reset=1. |
* |
* Determining the elapsed time and resetting the timer is not |
* atomic on all platforms, so after the sequence |
* `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 = |
* get_timer(0) }` the value time1+time2 is only approximately |
* the delay since the first reset. |
*/ |
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ); |
/** |
* \brief Setup an alarm clock |
* |
* \param seconds delay before the "mbedtls_timing_alarmed" flag is set |
* (must be >=0) |
* |
* \warning Only one alarm at a time is supported. In a threaded |
* context, this means one for the whole process, not one per |
* thread. |
*/ |
void mbedtls_set_alarm( int seconds ); |
/** |
* \brief Set a pair of delays to watch |
* (See \c mbedtls_timing_get_delay().) |
* |
* \param data Pointer to timing data. |
* Must point to a valid \c mbedtls_timing_delay_context struct. |
* \param int_ms First (intermediate) delay in milliseconds. |
* The effect if int_ms > fin_ms is unspecified. |
* \param fin_ms Second (final) delay in milliseconds. |
* Pass 0 to cancel the current delay. |
* |
* \note To set a single delay, either use \c mbedtls_timing_set_timer |
* directly or use this function with int_ms == fin_ms. |
*/ |
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ); |
/** |
* \brief Get the status of delays |
* (Memory helper: number of delays passed.) |
* |
* \param data Pointer to timing data |
* Must point to a valid \c mbedtls_timing_delay_context struct. |
* |
* \return -1 if cancelled (fin_ms = 0), |
* 0 if none of the delays are passed, |
* 1 if only the intermediate delay is passed, |
* 2 if the final delay is passed. |
*/ |
int mbedtls_timing_get_delay( void *data ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if a test failed |
*/ |
int mbedtls_timing_self_test( int verbose ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* timing.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/version.h |
---|
0,0 → 1,114 |
/** |
* \file version.h |
* |
* \brief Run-time version information |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* This set of compile-time defines and run-time variables can be used to |
* determine the version number of the mbed TLS library used. |
*/ |
#ifndef MBEDTLS_VERSION_H |
#define MBEDTLS_VERSION_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
/** |
* The version number x.y.z is split into three parts. |
* Major, Minor, Patchlevel |
*/ |
#define MBEDTLS_VERSION_MAJOR 2 |
#define MBEDTLS_VERSION_MINOR 16 |
#define MBEDTLS_VERSION_PATCH 6 |
/** |
* The single version number has the following structure: |
* MMNNPP00 |
* Major version | Minor version | Patch version |
*/ |
#define MBEDTLS_VERSION_NUMBER 0x02100600 |
#define MBEDTLS_VERSION_STRING "2.16.6" |
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.6" |
#if defined(MBEDTLS_VERSION_C) |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Get the version number. |
* |
* \return The constructed version number in the format |
* MMNNPP00 (Major, Minor, Patch). |
*/ |
unsigned int mbedtls_version_get_number( void ); |
/** |
* 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 mbedtls_version_get_string( char *string ); |
/** |
* Get the full version string ("mbed TLS x.y.z"). |
* |
* \param string The string that will receive the value. The mbed TLS version |
* string will use 18 bytes AT MOST including a terminating |
* null byte. |
* (So the buffer should be at least 18 bytes to receive this |
* version string). |
*/ |
void mbedtls_version_get_string_full( char *string ); |
/** |
* \brief Check if support for a feature was compiled into this |
* mbed TLS binary. This allows you to see at runtime if the |
* library was for instance compiled with or without |
* Multi-threading support. |
* |
* \note only checks against defines in the sections "System |
* support", "mbed TLS modules" and "mbed TLS feature |
* support" in config.h |
* |
* \param feature The string for the define to check (e.g. "MBEDTLS_AES_C") |
* |
* \return 0 if the feature is present, |
* -1 if the feature is not present and |
* -2 if support for feature checking as a whole was not |
* compiled in. |
*/ |
int mbedtls_version_check_feature( const char *feature ); |
#ifdef __cplusplus |
} |
#endif |
#endif /* MBEDTLS_VERSION_C */ |
#endif /* version.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/x509.h |
---|
0,0 → 1,339 |
/** |
* \file x509.h |
* |
* \brief X.509 generic defines and structures |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_X509_H |
#define MBEDTLS_X509_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "asn1.h" |
#include "pk.h" |
#if defined(MBEDTLS_RSA_C) |
#include "rsa.h" |
#endif |
/** |
* \addtogroup x509_module |
* \{ |
*/ |
#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA) |
/** |
* Maximum number of intermediate CAs in a verification chain. |
* That is, maximum length of the chain, excluding the end-entity certificate |
* and the trusted root certificate. |
* |
* Set this to a low value to prevent an adversary from making you waste |
* resources verifying an overlong certificate chain. |
*/ |
#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 |
#endif |
/** |
* \name X509 Error codes |
* \{ |
*/ |
#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */ |
#define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 /**< Requested OID is unknown. */ |
#define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */ |
#define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 /**< The CRT/CRL/CSR version element is invalid. */ |
#define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */ |
#define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */ |
#define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */ |
#define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */ |
#define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 /**< The signature tag or value invalid. */ |
#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 /**< The extension tag or value is invalid. */ |
#define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 /**< CRT/CRL/CSR has an unsupported version number. */ |
#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 /**< Signature algorithm (oid) is unsupported. */ |
#define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */ |
#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */ |
#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 /**< Format not recognized as DER or PEM. */ |
#define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */ |
#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ |
#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ |
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ |
#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ |
/* \} name */ |
/** |
* \name X509 Verify codes |
* \{ |
*/ |
/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */ |
#define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ |
#define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ |
#define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ |
#define MBEDTLS_X509_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */ |
#define MBEDTLS_X509_BADCRL_NOT_TRUSTED 0x10 /**< The CRL is not correctly signed by the trusted CA. */ |
#define MBEDTLS_X509_BADCRL_EXPIRED 0x20 /**< The CRL is expired. */ |
#define MBEDTLS_X509_BADCERT_MISSING 0x40 /**< Certificate was missing. */ |
#define MBEDTLS_X509_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ |
#define MBEDTLS_X509_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ |
#define MBEDTLS_X509_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ |
#define MBEDTLS_X509_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ |
#define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ |
#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ |
#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ |
#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */ |
#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ |
#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */ |
#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ |
#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ |
#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ |
/* \} name */ |
/* \} addtogroup x509_module */ |
/* |
* X.509 v3 Key Usage Extension flags |
* Reminder: update x509_info_key_usage() when adding new flags. |
*/ |
#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ |
#define MBEDTLS_X509_KU_NON_REPUDIATION (0x40) /* bit 1 */ |
#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ |
#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ |
#define MBEDTLS_X509_KU_KEY_AGREEMENT (0x08) /* bit 4 */ |
#define MBEDTLS_X509_KU_KEY_CERT_SIGN (0x04) /* bit 5 */ |
#define MBEDTLS_X509_KU_CRL_SIGN (0x02) /* bit 6 */ |
#define MBEDTLS_X509_KU_ENCIPHER_ONLY (0x01) /* bit 7 */ |
#define MBEDTLS_X509_KU_DECIPHER_ONLY (0x8000) /* bit 8 */ |
/* |
* Netscape certificate types |
* (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html) |
*/ |
#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ |
#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ |
/* |
* X.509 extension types |
* |
* Comments refer to the status for using certificates. Status can be |
* different for writing certificates or reading CRLs or CSRs. |
*/ |
#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0) |
#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1) |
#define MBEDTLS_X509_EXT_KEY_USAGE (1 << 2) |
#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES (1 << 3) |
#define MBEDTLS_X509_EXT_POLICY_MAPPINGS (1 << 4) |
#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME (1 << 5) /* Supported (DNS) */ |
#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME (1 << 6) |
#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7) |
#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS (1 << 8) /* Supported */ |
#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS (1 << 9) |
#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS (1 << 10) |
#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE (1 << 11) |
#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12) |
#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13) |
#define MBEDTLS_X509_EXT_FRESHEST_CRL (1 << 14) |
#define MBEDTLS_X509_EXT_NS_CERT_TYPE (1 << 16) |
/* |
* Storage format identifiers |
* Recognized formats: PEM and DER |
*/ |
#define MBEDTLS_X509_FORMAT_DER 1 |
#define MBEDTLS_X509_FORMAT_PEM 2 |
#define MBEDTLS_X509_MAX_DN_NAME_SIZE 256 /**< Maximum value size of a DN entry */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \addtogroup x509_module |
* \{ */ |
/** |
* \name Structures for parsing X.509 certificates, CRLs and CSRs |
* \{ |
*/ |
/** |
* Type-length-value structure that allows for ASN1 using DER. |
*/ |
typedef mbedtls_asn1_buf mbedtls_x509_buf; |
/** |
* Container for ASN1 bit strings. |
*/ |
typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring; |
/** |
* Container for ASN1 named information objects. |
* It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.). |
*/ |
typedef mbedtls_asn1_named_data mbedtls_x509_name; |
/** |
* Container for a sequence of ASN.1 items |
*/ |
typedef mbedtls_asn1_sequence mbedtls_x509_sequence; |
/** Container for date and time (precision in seconds). */ |
typedef struct mbedtls_x509_time |
{ |
int year, mon, day; /**< Date. */ |
int hour, min, sec; /**< Time. */ |
} |
mbedtls_x509_time; |
/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ |
/** \} addtogroup x509_module */ |
/** |
* \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 length of the string written (not including the |
* terminated nul byte), or a negative error code. |
*/ |
int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ); |
/** |
* \brief Store the certificate serial 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 serial The X509 serial to represent |
* |
* \return The length of the string written (not including the |
* terminated nul byte), or a negative error code. |
*/ |
int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ); |
/** |
* \brief Check a given mbedtls_x509_time against the system time |
* and tell if it's in the past. |
* |
* \note Intended usage is "if( is_past( valid_to ) ) ERROR". |
* Hence the return value of 1 if on internal errors. |
* |
* \param to mbedtls_x509_time to check |
* |
* \return 1 if the given time is in the past or an error occurred, |
* 0 otherwise. |
*/ |
int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); |
/** |
* \brief Check a given mbedtls_x509_time against the system time |
* and tell if it's in the future. |
* |
* \note Intended usage is "if( is_future( valid_from ) ) ERROR". |
* Hence the return value of 1 if on internal errors. |
* |
* \param from mbedtls_x509_time to check |
* |
* \return 1 if the given time is in the future or an error occurred, |
* 0 otherwise. |
*/ |
int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_x509_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
/* |
* Internal module functions. You probably do not want to use these unless you |
* know you do. |
*/ |
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, |
mbedtls_x509_name *cur ); |
int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *alg ); |
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, |
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, |
int *salt_len ); |
#endif |
int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); |
int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, |
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, |
void **sig_opts ); |
int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, |
mbedtls_x509_time *t ); |
int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *serial ); |
int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *ext, int tag ); |
int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, |
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, |
const void *sig_opts ); |
int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); |
int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); |
int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, |
int critical, const unsigned char *val, |
size_t val_len ); |
int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, |
mbedtls_asn1_named_data *first ); |
int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, |
mbedtls_asn1_named_data *first ); |
int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, |
const char *oid, size_t oid_len, |
unsigned char *sig, size_t size ); |
#define MBEDTLS_X509_SAFE_SNPRINTF \ |
do { \ |
if( ret < 0 || (size_t) ret >= n ) \ |
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); \ |
\ |
n -= (size_t) ret; \ |
p += (size_t) ret; \ |
} while( 0 ) |
#ifdef __cplusplus |
} |
#endif |
#endif /* x509.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/x509_crl.h |
---|
0,0 → 1,176 |
/** |
* \file x509_crl.h |
* |
* \brief X.509 certificate revocation list parsing |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_X509_CRL_H |
#define MBEDTLS_X509_CRL_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "x509.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \addtogroup x509_module |
* \{ */ |
/** |
* \name Structures and functions for parsing CRLs |
* \{ |
*/ |
/** |
* Certificate revocation list entry. |
* Contains the CA-specific serial numbers and revocation dates. |
*/ |
typedef struct mbedtls_x509_crl_entry |
{ |
mbedtls_x509_buf raw; |
mbedtls_x509_buf serial; |
mbedtls_x509_time revocation_date; |
mbedtls_x509_buf entry_ext; |
struct mbedtls_x509_crl_entry *next; |
} |
mbedtls_x509_crl_entry; |
/** |
* Certificate revocation list structure. |
* Every CRL may have multiple entries. |
*/ |
typedef struct mbedtls_x509_crl |
{ |
mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ |
mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ |
int version; /**< CRL version (1=v1, 2=v2) */ |
mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ |
mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ |
mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ |
mbedtls_x509_time this_update; |
mbedtls_x509_time next_update; |
mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */ |
mbedtls_x509_buf crl_ext; |
mbedtls_x509_buf sig_oid2; |
mbedtls_x509_buf sig; |
mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ |
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ |
void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ |
struct mbedtls_x509_crl *next; |
} |
mbedtls_x509_crl; |
/** |
* \brief Parse a DER-encoded CRL and append it to the chained list |
* |
* \param chain points to the start of the chain |
* \param buf buffer holding the CRL data in DER format |
* \param buflen size of the buffer |
* (including the terminating null byte for PEM data) |
* |
* \return 0 if successful, or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, |
const unsigned char *buf, size_t buflen ); |
/** |
* \brief Parse one or more CRLs and append them to the chained list |
* |
* \note Multiple CRLs are accepted only if using PEM format |
* |
* \param chain points to the start of the chain |
* \param buf buffer holding the CRL data in PEM or DER format |
* \param buflen size of the buffer |
* (including the terminating null byte for PEM data) |
* |
* \return 0 if successful, or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ); |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief Load one or more CRLs and append them to the chained list |
* |
* \note Multiple CRLs are accepted only if using PEM format |
* |
* \param chain points to the start of the chain |
* \param path filename to read the CRLs from (in PEM or DER encoding) |
* |
* \return 0 if successful, or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
/** |
* \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 crl The X509 CRL to represent |
* |
* \return The length of the string written (not including the |
* terminated nul byte), or a negative error code. |
*/ |
int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, |
const mbedtls_x509_crl *crl ); |
/** |
* \brief Initialize a CRL (chain) |
* |
* \param crl CRL chain to initialize |
*/ |
void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ); |
/** |
* \brief Unallocate all CRL data |
* |
* \param crl CRL chain to free |
*/ |
void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ); |
/* \} name */ |
/* \} addtogroup x509_module */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_x509_crl.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/x509_crt.h |
---|
0,0 → 1,787 |
/** |
* \file x509_crt.h |
* |
* \brief X.509 certificate parsing and writing |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_X509_CRT_H |
#define MBEDTLS_X509_CRT_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "x509.h" |
#include "x509_crl.h" |
/** |
* \addtogroup x509_module |
* \{ |
*/ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \name Structures and functions for parsing and writing X.509 certificates |
* \{ |
*/ |
/** |
* Container for an X.509 certificate. The certificate may be chained. |
*/ |
typedef struct mbedtls_x509_crt |
{ |
mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ |
mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ |
int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ |
mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ |
mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */ |
mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ |
mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ |
mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ |
mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ |
mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ |
mbedtls_x509_time valid_to; /**< End time of certificate validity. */ |
mbedtls_pk_context pk; /**< Container for the public key context. */ |
mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ |
mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ |
mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ |
mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */ |
int ext_types; /**< Bit string containing detected and parsed extensions */ |
int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ |
int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ |
unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ |
mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ |
unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ |
mbedtls_x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ |
mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ |
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ |
void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ |
struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ |
} |
mbedtls_x509_crt; |
/** |
* Build flag from an algorithm/curve identifier (pk, md, ecp) |
* Since 0 is always XXX_NONE, ignore it. |
*/ |
#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( (id) - 1 ) ) |
/** |
* Security profile for certificate verification. |
* |
* All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). |
*/ |
typedef struct mbedtls_x509_crt_profile |
{ |
uint32_t allowed_mds; /**< MDs for signatures */ |
uint32_t allowed_pks; /**< PK algs for signatures */ |
uint32_t allowed_curves; /**< Elliptic curves for ECDSA */ |
uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */ |
} |
mbedtls_x509_crt_profile; |
#define MBEDTLS_X509_CRT_VERSION_1 0 |
#define MBEDTLS_X509_CRT_VERSION_2 1 |
#define MBEDTLS_X509_CRT_VERSION_3 2 |
#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 |
#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 |
#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN ) |
#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 |
#endif |
/** |
* Container for writing a certificate (CRT) |
*/ |
typedef struct mbedtls_x509write_cert |
{ |
int version; |
mbedtls_mpi serial; |
mbedtls_pk_context *subject_key; |
mbedtls_pk_context *issuer_key; |
mbedtls_asn1_named_data *subject; |
mbedtls_asn1_named_data *issuer; |
mbedtls_md_type_t md_alg; |
char not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; |
char not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; |
mbedtls_asn1_named_data *extensions; |
} |
mbedtls_x509write_cert; |
/** |
* Item in a verification chain: cert and flags for it |
*/ |
typedef struct { |
mbedtls_x509_crt *crt; |
uint32_t flags; |
} mbedtls_x509_crt_verify_chain_item; |
/** |
* Max size of verification chain: end-entity + intermediates + trusted root |
*/ |
#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) |
/** |
* Verification chain as built by \c mbedtls_crt_verify_chain() |
*/ |
typedef struct |
{ |
mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]; |
unsigned len; |
} mbedtls_x509_crt_verify_chain; |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Context for resuming X.509 verify operations |
*/ |
typedef struct |
{ |
/* for check_signature() */ |
mbedtls_pk_restart_ctx pk; |
/* for find_parent_in() */ |
mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */ |
mbedtls_x509_crt *fallback_parent; |
int fallback_signature_is_good; |
/* for find_parent() */ |
int parent_is_trusted; /* -1 if find_parent is not in progress */ |
/* for verify_chain() */ |
enum { |
x509_crt_rs_none, |
x509_crt_rs_find_parent, |
} in_progress; /* none if no operation is in progress */ |
int self_cnt; |
mbedtls_x509_crt_verify_chain ver_chain; |
} mbedtls_x509_crt_restart_ctx; |
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/* Now we can declare functions that take a pointer to that */ |
typedef void mbedtls_x509_crt_restart_ctx; |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/** |
* Default security profile. Should provide a good balance between security |
* and compatibility with current deployments. |
*/ |
extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default; |
/** |
* Expected next default profile. Recommended for new deployments. |
* Currently targets a 128-bit security level, except for RSA-2048. |
*/ |
extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next; |
/** |
* NSA Suite B profile. |
*/ |
extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; |
/** |
* \brief Parse a single DER formatted certificate and add it |
* to the chained list. |
* |
* \param chain points to the start of the chain |
* \param buf buffer holding the certificate DER data |
* \param buflen size of the buffer |
* |
* \return 0 if successful, or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, |
size_t buflen ); |
/** |
* \brief Parse one DER-encoded or one or more concatenated PEM-encoded |
* certificates and add them to the chained list. |
* |
* For CRTs in PEM encoding, the function parses permissively: |
* if at least one certificate can be parsed, the function |
* returns the number of certificates for which parsing failed |
* (hence \c 0 if all certificates were parsed successfully). |
* If no certificate could be parsed, the function returns |
* the first (negative) error encountered during parsing. |
* |
* PEM encoded certificates may be interleaved by other data |
* such as human readable descriptions of their content, as |
* long as the certificates are enclosed in the PEM specific |
* '-----{BEGIN/END} CERTIFICATE-----' delimiters. |
* |
* \param chain The chain to which to add the parsed certificates. |
* \param buf The buffer holding the certificate data in PEM or DER format. |
* For certificates in PEM encoding, this may be a concatenation |
* of multiple certificates; for DER encoding, the buffer must |
* comprise exactly one certificate. |
* \param buflen The size of \p buf, including the terminating \c NULL byte |
* in case of PEM encoded data. |
* |
* \return \c 0 if all certificates were parsed successfully. |
* \return The (positive) number of certificates that couldn't |
* be parsed if parsing was partly successful (see above). |
* \return A negative X509 or PEM error code otherwise. |
* |
*/ |
int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ); |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief Load one or more certificates and add them |
* to the chained list. Parses permissively. If some |
* certificates can be parsed, the result is the number |
* of failed certificates it encountered. If none complete |
* correctly, the first error is returned. |
* |
* \param chain points to the start of the chain |
* \param path filename to read the certificates from |
* |
* \return 0 if all certificates parsed successfully, a positive number |
* if partly successful or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ); |
/** |
* \brief Load one or more certificate files from a path and add them |
* to the chained list. Parses permissively. If some |
* certificates can be parsed, the result is the number |
* of failed certificates it encountered. If none complete |
* correctly, the first error is returned. |
* |
* \param chain points to the start of the chain |
* \param path directory / folder to read the certificate files from |
* |
* \return 0 if all certificates parsed successfully, a positive number |
* if partly successful or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
/** |
* \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 length of the string written (not including the |
* terminated nul byte), or a negative error code. |
*/ |
int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, |
const mbedtls_x509_crt *crt ); |
/** |
* \brief Returns an informational string about the |
* verification status of a certificate. |
* |
* \param buf Buffer to write to |
* \param size Maximum size of buffer |
* \param prefix A line prefix |
* \param flags Verification flags created by mbedtls_x509_crt_verify() |
* |
* \return The length of the string written (not including the |
* terminated nul byte), or a negative error code. |
*/ |
int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, |
uint32_t flags ); |
/** |
* \brief Verify the certificate signature |
* |
* The verify callback is a user-supplied callback that |
* can clear / modify / add flags for a certificate. If set, |
* the verification callback is called for each |
* certificate in the chain (from the trust-ca down to the |
* presented crt). The parameters for the callback are: |
* (void *parameter, mbedtls_x509_crt *crt, int certificate_depth, |
* int *flags). With the flags representing current flags for |
* that specific certificate and the certificate depth from |
* the bottom (Peer cert depth = 0). |
* |
* All flags left after returning from the callback |
* are also returned to the application. The function should |
* return 0 for anything (including invalid certificates) |
* other than fatal error, as a non-zero return code |
* immediately aborts the verification process. For fatal |
* errors, a specific error code should be used (different |
* from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not |
* be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR |
* can be used if no better code is available. |
* |
* \note In case verification failed, the results can be displayed |
* using \c mbedtls_x509_crt_verify_info() |
* |
* \note Same as \c mbedtls_x509_crt_verify_with_profile() with the |
* default security profile. |
* |
* \note It is your responsibility to provide up-to-date CRLs for |
* all trusted CAs. If no CRL is provided for the CA that was |
* used to sign the certificate, CRL verification is skipped |
* silently, that is *without* setting any flag. |
* |
* \note The \c trust_ca list can contain two types of certificates: |
* (1) those of trusted root CAs, so that certificates |
* chaining up to those CAs will be trusted, and (2) |
* self-signed end-entity certificates to be trusted (for |
* specific peers you know) - in that case, the self-signed |
* certificate doesn't need to have the CA bit set. |
* |
* \param crt a certificate (chain) to be verified |
* \param trust_ca the list of trusted CAs (see note above) |
* \param ca_crl the list of CRLs for trusted CAs (see note above) |
* \param cn expected Common Name (can be set to |
* NULL if the CN must not be verified) |
* \param flags result of the verification |
* \param f_vrfy verification function |
* \param p_vrfy verification parameter |
* |
* \return 0 (and flags set to 0) if the chain was verified and valid, |
* MBEDTLS_ERR_X509_CERT_VERIFY_FAILED if the chain was verified |
* but found to be invalid, in which case *flags will have one |
* or more MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX |
* flags set, or another error (and flags set to 0xffffffff) |
* in case of a fatal error encountered during the |
* verification process. |
*/ |
int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const char *cn, uint32_t *flags, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ); |
/** |
* \brief Verify the certificate signature according to profile |
* |
* \note Same as \c mbedtls_x509_crt_verify(), but with explicit |
* security profile. |
* |
* \note The restrictions on keys (RSA minimum size, allowed curves |
* for ECDSA) apply to all certificates: trusted root, |
* intermediate CAs if any, and end entity certificate. |
* |
* \param crt a certificate (chain) to be verified |
* \param trust_ca the list of trusted CAs |
* \param ca_crl the list of CRLs for trusted CAs |
* \param profile security profile for verification |
* \param cn expected Common Name (can be set to |
* NULL if the CN must not be verified) |
* \param flags result of the verification |
* \param f_vrfy verification function |
* \param p_vrfy verification parameter |
* |
* \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED |
* in which case *flags will have one or more |
* MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX flags |
* set, |
* or another error in case of a fatal error encountered |
* during the verification process. |
*/ |
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const mbedtls_x509_crt_profile *profile, |
const char *cn, uint32_t *flags, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ); |
/** |
* \brief Restartable version of \c mbedtls_crt_verify_with_profile() |
* |
* \note Performs the same job as \c mbedtls_crt_verify_with_profile() |
* but can return early and restart according to the limit |
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking. |
* |
* \param crt a certificate (chain) to be verified |
* \param trust_ca the list of trusted CAs |
* \param ca_crl the list of CRLs for trusted CAs |
* \param profile security profile for verification |
* \param cn expected Common Name (can be set to |
* NULL if the CN must not be verified) |
* \param flags result of the verification |
* \param f_vrfy verification function |
* \param p_vrfy verification parameter |
* \param rs_ctx restart context (NULL to disable restart) |
* |
* \return See \c mbedtls_crt_verify_with_profile(), or |
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
* operations was reached: see \c mbedtls_ecp_set_max_ops(). |
*/ |
int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const mbedtls_x509_crt_profile *profile, |
const char *cn, uint32_t *flags, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy, |
mbedtls_x509_crt_restart_ctx *rs_ctx ); |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
/** |
* \brief Check usage of certificate against keyUsage extension. |
* |
* \param crt Leaf certificate used. |
* \param usage Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
* before using the certificate to perform an RSA key |
* exchange). |
* |
* \note Except for decipherOnly and encipherOnly, a bit set in the |
* usage argument means this bit MUST be set in the |
* certificate. For decipherOnly and encipherOnly, it means |
* that bit MAY be set. |
* |
* \return 0 is these uses of the certificate are allowed, |
* MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension |
* is present but does not match the usage argument. |
* |
* \note You should only call this function on leaf certificates, on |
* (intermediate) CAs the keyUsage extension is automatically |
* checked by \c mbedtls_x509_crt_verify(). |
*/ |
int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, |
unsigned int usage ); |
#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */ |
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) |
/** |
* \brief Check usage of certificate against extendedKeyUsage. |
* |
* \param crt Leaf certificate used. |
* \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or |
* MBEDTLS_OID_CLIENT_AUTH). |
* \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()). |
* |
* \return 0 if this use of the certificate is allowed, |
* MBEDTLS_ERR_X509_BAD_INPUT_DATA if not. |
* |
* \note Usually only makes sense on leaf certificates. |
*/ |
int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, |
const char *usage_oid, |
size_t usage_len ); |
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ |
#if defined(MBEDTLS_X509_CRL_PARSE_C) |
/** |
* \brief Verify the certificate revocation status |
* |
* \param crt a certificate to be verified |
* \param crl the CRL to verify against |
* |
* \return 1 if the certificate is revoked, 0 otherwise |
* |
*/ |
int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ); |
#endif /* MBEDTLS_X509_CRL_PARSE_C */ |
/** |
* \brief Initialize a certificate (chain) |
* |
* \param crt Certificate chain to initialize |
*/ |
void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ); |
/** |
* \brief Unallocate all certificate data |
* |
* \param crt Certificate chain to free |
*/ |
void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/** |
* \brief Initialize a restart context |
*/ |
void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ); |
/** |
* \brief Free the components of a restart context |
*/ |
void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
/* \} name */ |
/* \} addtogroup x509_module */ |
#if defined(MBEDTLS_X509_CRT_WRITE_C) |
/** |
* \brief Initialize a CRT writing context |
* |
* \param ctx CRT context to initialize |
*/ |
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ); |
/** |
* \brief Set the verion for a Certificate |
* Default: MBEDTLS_X509_CRT_VERSION_3 |
* |
* \param ctx CRT context to use |
* \param version version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or |
* MBEDTLS_X509_CRT_VERSION_3) |
*/ |
void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ); |
/** |
* \brief Set the serial number for a Certificate. |
* |
* \param ctx CRT context to use |
* \param serial serial number to set |
* |
* \return 0 if successful |
*/ |
int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ); |
/** |
* \brief Set the validity period for a Certificate |
* Timestamps should be in string format for UTC timezone |
* i.e. "YYYYMMDDhhmmss" |
* e.g. "20131231235959" for December 31st 2013 |
* at 23:59:59 |
* |
* \param ctx CRT context to use |
* \param not_before not_before timestamp |
* \param not_after not_after timestamp |
* |
* \return 0 if timestamp was parsed successfully, or |
* a specific error code |
*/ |
int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, |
const char *not_after ); |
/** |
* \brief Set the issuer name for a Certificate |
* Issuer names should contain a comma-separated list |
* of OID types and values: |
* e.g. "C=UK,O=ARM,CN=mbed TLS CA" |
* |
* \param ctx CRT context to use |
* \param issuer_name issuer name to set |
* |
* \return 0 if issuer name was parsed successfully, or |
* a specific error code |
*/ |
int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, |
const char *issuer_name ); |
/** |
* \brief Set the subject name for a Certificate |
* Subject names should contain a comma-separated list |
* of OID types and values: |
* e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" |
* |
* \param ctx CRT context to use |
* \param subject_name subject name to set |
* |
* \return 0 if subject name was parsed successfully, or |
* a specific error code |
*/ |
int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, |
const char *subject_name ); |
/** |
* \brief Set the subject public key for the certificate |
* |
* \param ctx CRT context to use |
* \param key public key to include |
*/ |
void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); |
/** |
* \brief Set the issuer key used for signing the certificate |
* |
* \param ctx CRT context to use |
* \param key private key to sign with |
*/ |
void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); |
/** |
* \brief Set the MD algorithm to use for the signature |
* (e.g. MBEDTLS_MD_SHA1) |
* |
* \param ctx CRT context to use |
* \param md_alg MD algorithm to use |
*/ |
void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ); |
/** |
* \brief Generic function to add to or replace an extension in the |
* CRT |
* |
* \param ctx CRT context to use |
* \param oid OID of the extension |
* \param oid_len length of the OID |
* \param critical if the extension is critical (per the RFC's definition) |
* \param val value of the extension OCTET STRING |
* \param val_len length of the value data |
* |
* \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, |
const char *oid, size_t oid_len, |
int critical, |
const unsigned char *val, size_t val_len ); |
/** |
* \brief Set the basicConstraints extension for a CRT |
* |
* \param ctx CRT context to use |
* \param is_ca is this a CA certificate |
* \param max_pathlen maximum length of certificate chains below this |
* certificate (only for CA certificates, -1 is |
* inlimited) |
* |
* \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, |
int is_ca, int max_pathlen ); |
#if defined(MBEDTLS_SHA1_C) |
/** |
* \brief Set the subjectKeyIdentifier extension for a CRT |
* Requires that mbedtls_x509write_crt_set_subject_key() has been |
* called before |
* |
* \param ctx CRT context to use |
* |
* \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ); |
/** |
* \brief Set the authorityKeyIdentifier extension for a CRT |
* Requires that mbedtls_x509write_crt_set_issuer_key() has been |
* called before |
* |
* \param ctx CRT context to use |
* |
* \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ); |
#endif /* MBEDTLS_SHA1_C */ |
/** |
* \brief Set the Key Usage Extension flags |
* (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) |
* |
* \param ctx CRT context to use |
* \param key_usage key usage flags to set |
* |
* \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, |
unsigned int key_usage ); |
/** |
* \brief Set the Netscape Cert Type flags |
* (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) |
* |
* \param ctx CRT context to use |
* \param ns_cert_type Netscape Cert Type flags to set |
* |
* \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, |
unsigned char ns_cert_type ); |
/** |
* \brief Free the contents of a CRT write context |
* |
* \param ctx CRT context to free |
*/ |
void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ); |
/** |
* \brief Write a built up certificate to a X509 DER structure |
* Note: data is written at the end of the buffer! Use the |
* return value to determine where you should start |
* using the buffer |
* |
* \param ctx certificate to write away |
* \param buf buffer to write to |
* \param size size of the buffer |
* \param f_rng RNG function (for signature, see note) |
* \param p_rng RNG parameter |
* |
* \return length of data written if successful, or a specific |
* error code |
* |
* \note f_rng may be NULL if RSA is used for signature and the |
* signature is made offline (otherwise f_rng is desirable |
* for countermeasures against timing attacks). |
* ECDSA signatures always require a non-NULL f_rng. |
*/ |
int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#if defined(MBEDTLS_PEM_WRITE_C) |
/** |
* \brief Write a built up certificate to a X509 PEM string |
* |
* \param ctx certificate to write away |
* \param buf buffer to write to |
* \param size size of the buffer |
* \param f_rng RNG function (for signature, see note) |
* \param p_rng RNG parameter |
* |
* \return 0 if successful, or a specific error code |
* |
* \note f_rng may be NULL if RSA is used for signature and the |
* signature is made offline (otherwise f_rng is desirable |
* for countermeasures against timing attacks). |
* ECDSA signatures always require a non-NULL f_rng. |
*/ |
int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_X509_CRT_WRITE_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_x509_crt.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/x509_csr.h |
---|
0,0 → 1,309 |
/** |
* \file x509_csr.h |
* |
* \brief X.509 certificate signing request parsing and writing |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_X509_CSR_H |
#define MBEDTLS_X509_CSR_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "x509.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* \addtogroup x509_module |
* \{ */ |
/** |
* \name Structures and functions for X.509 Certificate Signing Requests (CSR) |
* \{ |
*/ |
/** |
* Certificate Signing Request (CSR) structure. |
*/ |
typedef struct mbedtls_x509_csr |
{ |
mbedtls_x509_buf raw; /**< The raw CSR data (DER). */ |
mbedtls_x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */ |
int version; /**< CSR version (1=v1). */ |
mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). */ |
mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ |
mbedtls_pk_context pk; /**< Container for the public key context. */ |
mbedtls_x509_buf sig_oid; |
mbedtls_x509_buf sig; |
mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ |
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ |
void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ |
} |
mbedtls_x509_csr; |
/** |
* Container for writing a CSR |
*/ |
typedef struct mbedtls_x509write_csr |
{ |
mbedtls_pk_context *key; |
mbedtls_asn1_named_data *subject; |
mbedtls_md_type_t md_alg; |
mbedtls_asn1_named_data *extensions; |
} |
mbedtls_x509write_csr; |
#if defined(MBEDTLS_X509_CSR_PARSE_C) |
/** |
* \brief Load a Certificate Signing Request (CSR) in DER format |
* |
* \note CSR attributes (if any) are currently silently ignored. |
* |
* \param csr CSR context to fill |
* \param buf buffer holding the CRL data |
* \param buflen size of the buffer |
* |
* \return 0 if successful, or a specific X509 error code |
*/ |
int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, |
const unsigned char *buf, size_t buflen ); |
/** |
* \brief Load a Certificate Signing Request (CSR), DER or PEM format |
* |
* \note See notes for \c mbedtls_x509_csr_parse_der() |
* |
* \param csr CSR context to fill |
* \param buf buffer holding the CRL data |
* \param buflen size of the buffer |
* (including the terminating null byte for PEM data) |
* |
* \return 0 if successful, or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ); |
#if defined(MBEDTLS_FS_IO) |
/** |
* \brief Load a Certificate Signing Request (CSR) |
* |
* \note See notes for \c mbedtls_x509_csr_parse() |
* |
* \param csr CSR context to fill |
* \param path filename to read the CSR from |
* |
* \return 0 if successful, or a specific X509 or PEM error code |
*/ |
int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ); |
#endif /* MBEDTLS_FS_IO */ |
/** |
* \brief Returns an informational string about the |
* CSR. |
* |
* \param buf Buffer to write to |
* \param size Maximum size of buffer |
* \param prefix A line prefix |
* \param csr The X509 CSR to represent |
* |
* \return The length of the string written (not including the |
* terminated nul byte), or a negative error code. |
*/ |
int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, |
const mbedtls_x509_csr *csr ); |
/** |
* \brief Initialize a CSR |
* |
* \param csr CSR to initialize |
*/ |
void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ); |
/** |
* \brief Unallocate all CSR data |
* |
* \param csr CSR to free |
*/ |
void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ); |
#endif /* MBEDTLS_X509_CSR_PARSE_C */ |
/* \} name */ |
/* \} addtogroup x509_module */ |
#if defined(MBEDTLS_X509_CSR_WRITE_C) |
/** |
* \brief Initialize a CSR context |
* |
* \param ctx CSR context to initialize |
*/ |
void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ); |
/** |
* \brief Set the subject name for a CSR |
* Subject names should contain a comma-separated list |
* of OID types and values: |
* e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" |
* |
* \param ctx CSR context to use |
* \param subject_name subject name to set |
* |
* \return 0 if subject name was parsed successfully, or |
* a specific error code |
*/ |
int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, |
const char *subject_name ); |
/** |
* \brief Set the key for a CSR (public key will be included, |
* private key used to sign the CSR when writing it) |
* |
* \param ctx CSR context to use |
* \param key Asymetric key to include |
*/ |
void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ); |
/** |
* \brief Set the MD algorithm to use for the signature |
* (e.g. MBEDTLS_MD_SHA1) |
* |
* \param ctx CSR context to use |
* \param md_alg MD algorithm to use |
*/ |
void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ); |
/** |
* \brief Set the Key Usage Extension flags |
* (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) |
* |
* \param ctx CSR context to use |
* \param key_usage key usage flags to set |
* |
* \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED |
* |
* \note The <code>decipherOnly</code> flag from the Key Usage |
* extension is represented by bit 8 (i.e. |
* <code>0x8000</code>), which cannot typically be represented |
* in an unsigned char. Therefore, the flag |
* <code>decipherOnly</code> (i.e. |
* #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this |
* function. |
*/ |
int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ); |
/** |
* \brief Set the Netscape Cert Type flags |
* (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) |
* |
* \param ctx CSR context to use |
* \param ns_cert_type Netscape Cert Type flags to set |
* |
* \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, |
unsigned char ns_cert_type ); |
/** |
* \brief Generic function to add to or replace an extension in the |
* CSR |
* |
* \param ctx CSR context to use |
* \param oid OID of the extension |
* \param oid_len length of the OID |
* \param val value of the extension OCTET STRING |
* \param val_len length of the value data |
* |
* \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED |
*/ |
int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, |
const char *oid, size_t oid_len, |
const unsigned char *val, size_t val_len ); |
/** |
* \brief Free the contents of a CSR context |
* |
* \param ctx CSR context to free |
*/ |
void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ); |
/** |
* \brief Write a CSR (Certificate Signing Request) to a |
* DER structure |
* Note: data is written at the end of the buffer! Use the |
* return value to determine where you should start |
* using the buffer |
* |
* \param ctx CSR to write away |
* \param buf buffer to write to |
* \param size size of the buffer |
* \param f_rng RNG function (for signature, see note) |
* \param p_rng RNG parameter |
* |
* \return length of data written if successful, or a specific |
* error code |
* |
* \note f_rng may be NULL if RSA is used for signature and the |
* signature is made offline (otherwise f_rng is desirable |
* for countermeasures against timing attacks). |
* ECDSA signatures always require a non-NULL f_rng. |
*/ |
int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#if defined(MBEDTLS_PEM_WRITE_C) |
/** |
* \brief Write a CSR (Certificate Signing Request) to a |
* PEM string |
* |
* \param ctx CSR to write away |
* \param buf buffer to write to |
* \param size size of the buffer |
* \param f_rng RNG function (for signature, see note) |
* \param p_rng RNG parameter |
* |
* \return 0 if successful, or a specific error code |
* |
* \note f_rng may be NULL if RSA is used for signature and the |
* signature is made offline (otherwise f_rng is desirable |
* for countermeasures against timing attacks). |
* ECDSA signatures always require a non-NULL f_rng. |
*/ |
int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ); |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_X509_CSR_WRITE_C */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* mbedtls_x509_csr.h */ |
/programs/develop/libraries/kos_mbedtls/include/mbedtls/xtea.h |
---|
0,0 → 1,141 |
/** |
* \file xtea.h |
* |
* \brief XTEA block cipher (32-bit) |
*/ |
/* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#ifndef MBEDTLS_XTEA_H |
#define MBEDTLS_XTEA_H |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <stddef.h> |
#include <stdint.h> |
#define MBEDTLS_XTEA_ENCRYPT 1 |
#define MBEDTLS_XTEA_DECRYPT 0 |
#define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */ |
/* MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED is deprecated and should not be used. */ |
#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED -0x0029 /**< XTEA hardware accelerator failed. */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if !defined(MBEDTLS_XTEA_ALT) |
// Regular implementation |
// |
/** |
* \brief XTEA context structure |
*/ |
typedef struct mbedtls_xtea_context |
{ |
uint32_t k[4]; /*!< key */ |
} |
mbedtls_xtea_context; |
#else /* MBEDTLS_XTEA_ALT */ |
#include "xtea_alt.h" |
#endif /* MBEDTLS_XTEA_ALT */ |
/** |
* \brief Initialize XTEA context |
* |
* \param ctx XTEA context to be initialized |
*/ |
void mbedtls_xtea_init( mbedtls_xtea_context *ctx ); |
/** |
* \brief Clear XTEA context |
* |
* \param ctx XTEA context to be cleared |
*/ |
void mbedtls_xtea_free( mbedtls_xtea_context *ctx ); |
/** |
* \brief XTEA key schedule |
* |
* \param ctx XTEA context to be initialized |
* \param key the secret key |
*/ |
void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ); |
/** |
* \brief XTEA cipher function |
* |
* \param ctx XTEA context |
* \param mode MBEDTLS_XTEA_ENCRYPT or MBEDTLS_XTEA_DECRYPT |
* \param input 8-byte input block |
* \param output 8-byte output block |
* |
* \return 0 if successful |
*/ |
int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, |
int mode, |
const unsigned char input[8], |
unsigned char output[8] ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/** |
* \brief XTEA CBC cipher function |
* |
* \param ctx XTEA context |
* \param mode MBEDTLS_XTEA_ENCRYPT or MBEDTLS_XTEA_DECRYPT |
* \param length the length of input, multiple of 8 |
* \param iv initialization vector for CBC mode |
* \param input input block |
* \param output output block |
* |
* \return 0 if successful, |
* MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH if the length % 8 != 0 |
*/ |
int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[8], |
const unsigned char *input, |
unsigned char *output); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_SELF_TEST) |
/** |
* \brief Checkup routine |
* |
* \return 0 if successful, or 1 if the test failed |
*/ |
int mbedtls_xtea_self_test( int verbose ); |
#endif /* MBEDTLS_SELF_TEST */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* xtea.h */ |
/programs/develop/libraries/kos_mbedtls/kosnet/Makefile |
---|
0,0 → 1,37 |
NEWLIB_INCLUDES=D:\KOSSDK\newlib\libc\include |
CC = kos32-gcc |
AR = kos32-ar |
CFLAGS ?= -O2 |
WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement |
LDFLAGS ?= |
LOCAL_CFLAGS = $(WARNING_CFLAGS) -I $(NEWLIB_INCLUDES) -I include -D_FILE_OFFSET_BITS=64 |
LOCAL_LDFLAGS = |
AR_DASH ?= - |
ARFLAGS = $(AR_DASH)src |
OBJS= socket.o network.o dlfcn.o |
.PHONY: all static clean |
all: static |
static: libkosnet.a |
libkosnet.a: $(OBJS) |
echo " AR $@" |
$(AR) $(ARFLAGS) $@ $(OBJS) |
.c.o: |
echo " CC $<" |
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c $< |
clean: |
ifndef WINDOWS |
rm -f *.o libkosnet.a |
else |
del /Q /F *.o libkosnet.a |
endif |
/programs/develop/libraries/kos_mbedtls/kosnet/dlfcn.c |
---|
0,0 → 1,92 |
#include <stdlib.h> |
#include <string.h> |
#include "kosnet/dlfcn.h" |
#include "kosnet/kos32sys1.h" |
typedef struct { |
char *name; |
void *ptr; |
} KosExp; |
typedef struct { |
void **importNames; |
char * libraryName; |
} KosImp; |
static int __attribute__ ((stdcall)) dll_Load(KosImp *importTableEntry); |
static const char *__error; |
static int __attribute__ ((stdcall)) dll_Load(KosImp *importTableEntry) { |
for (; importTableEntry->importNames; importTableEntry++) { |
char libPath[256] = "/sys/lib/"; |
KosExp *exports = NULL; |
void **libImports = importTableEntry->importNames; |
strcat(libPath, importTableEntry->libraryName); |
if (!(exports = dlopen(libPath, 0))) { return 1; } |
for (; *libImports; libImports++) { |
if (!(*libImports = dlsym(exports, *libImports))) { return 1; } |
} |
} |
return 0; |
} |
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlopen.html |
// Current implementation fully ignores "mode" parameter |
void *dlopen(const char *name, int mode) { |
KosExp *exports = NULL; |
// load library using syscall |
asm volatile ("int $0x40":"=a"(exports):"a"(68), "b"(19), "c"(name)); |
if (!exports) { |
char libPath[256] = "/sys/lib/"; |
strcat(libPath, name); |
asm volatile ("int $0x40":"=a"(exports):"a"(68), "b"(19), "c"(libPath)); |
if (!exports) { |
__error = "Library not found in \"/sys/lib/\" nor current folder"; |
return NULL; |
} |
} |
// call anything starting with "lib_" |
for (KosExp *export = exports; export->name; export++) { |
if (!memcmp(export->name, "lib_", 4)) { |
asm volatile ( |
"call *%4" :: |
"a"(0), |
"b"(0), |
"c"(0), |
"d"(dll_Load), |
"r"(export->ptr)); |
// was asm volatile ("call *%4" ::"a"(sysmalloc),"b"(sysfree),"c"(sysrealloc),"d"(dll_Load),"r"(export->ptr)); |
} |
} |
return exports; |
} |
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlsym.html |
void *dlsym(void *handle, const char *name) { |
KosExp *exp = handle; |
for (; exp->name; exp++) { |
if (!strcmp(exp->name, name)) { |
return exp->ptr; |
} |
} |
__error = "Symbol not found"; |
return NULL; |
} |
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlclose.html |
int dlclose(void *handle) { |
return 0; |
} |
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlerror.html |
char *dlerror(void) { |
char *ret = __error ? strdup(__error) : NULL; |
__error = NULL; |
return ret; |
} |
/programs/develop/libraries/kos_mbedtls/kosnet/include/kosnet/dlfcn.h |
---|
0,0 → 1,14 |
#ifndef _DLFCN_H |
#define _DLFCN_H |
#define RTLD_LAZY 0x00001 |
#define RTLD_NOW 0x00002 |
#define RTLD_GLOBAL 0x00100 |
#define RTLD_LOCAL 0 |
int dlclose(void *handle); |
char *dlerror(void); |
void *dlopen(const char *name, int mode); |
void *dlsym(void *restrict handle, const char *restrict name); |
#endif |
/programs/develop/libraries/kos_mbedtls/kosnet/include/kosnet/kos32sys1.h |
---|
0,0 → 1,836 |
#ifndef __KOS_32_SYS_H__ |
#define __KOS_32_SYS_H__ |
#include <stddef.h> |
#include <stdarg.h> |
typedef unsigned int uint32_t; |
typedef int int32_t; |
typedef unsigned char uint8_t; |
typedef unsigned short int uint16_t; |
typedef unsigned long long uint64_t; |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define TYPE_3_BORDER_WIDTH 5 |
#define WIN_STATE_MINIMIZED 0x02 |
#define WIN_STATE_ROLLED 0x04 |
#define POS_SCREEN 0 |
#define POS_WINDOW 1 |
#define IPC_NOBUFFER 1 |
#define IPC_LOCKED 2 |
#define IPC_OVERFLOW 3 |
#define IPC_NOPID 4 |
#define SHM_OPEN 0x00 |
#define SHM_OPEN_ALWAYS 0x04 |
#define SHM_CREATE 0x08 |
#define SHM_READ 0x00 |
#define SHM_WRITE 0x01 |
// for clipboard funtions |
#define UTF 0 |
#define CP866 1 |
#define CP1251 2 |
#define TEXT 0 |
#define IMAGE 1 |
#define RAW 2 |
//Read/Write data as type (int char, etc.) at address "addr" with offset "offset". eg DATA(int, buff, 8); |
#define DATA(type, addr, offset) *((type*)((uint8_t*)addr+offset)) |
typedef struct { |
uint8_t blue; |
uint8_t green; |
uint8_t red; |
}RGB; |
typedef unsigned int color_t; |
typedef union __attribute__((packed)) pos_t |
{ |
uint32_t val; |
struct |
{ |
short x; |
short y; |
}; |
} pos_t; |
typedef union __attribute__((packed)) oskey_t |
{ |
uint32_t val; |
struct |
{ |
uint8_t state; |
uint8_t code; |
uint16_t ctrl_key; |
}; |
} oskey_t; |
typedef struct |
{ |
unsigned handle; |
unsigned io_code; |
void *input; |
int inp_size; |
void *output; |
int out_size; |
}ioctl_t; |
typedef union |
{ |
struct |
{ |
void *data; |
size_t size; |
} x; |
unsigned long long raw; |
}ufile_t; |
struct kolibri_system_colors { |
color_t frame_area; |
color_t grab_bar; |
color_t grab_bar_button; |
color_t grab_button_text; |
color_t grab_text; |
color_t work_area; |
color_t work_button; |
color_t work_button_text; |
color_t work_text; |
color_t work_graph; |
}; |
struct blit_call |
{ |
int dstx; |
int dsty; |
int w; |
int h; |
int srcx; |
int srcy; |
int srcw; |
int srch; |
void *bitmap; |
int stride; |
}; |
struct ipc_message |
{ |
uint32_t pid; // PID of sending thread |
uint32_t datalen; // data bytes |
char data[0]; // data begin |
}; |
struct ipc_buffer |
{ |
uint32_t lock; // nonzero is locked |
uint32_t used; // used bytes in buffer |
struct ipc_message data[0]; // data begin |
}; |
static inline void begin_draw(void) |
{ |
__asm__ __volatile__( |
"int $0x40" ::"a"(12),"b"(1)); |
}; |
static inline |
void end_draw(void) |
{ |
__asm__ __volatile__( |
"int $0x40" ::"a"(12),"b"(2)); |
}; |
static inline |
void sys_create_window(int x, int y, int w, int h, const char *name, |
color_t workcolor, uint32_t style) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(0), |
"b"((x << 16) | ((w-1) & 0xFFFF)), |
"c"((y << 16) | ((h-1) & 0xFFFF)), |
"d"((style << 24) | (workcolor & 0xFFFFFF)), |
"D"(name), |
"S"(0) : "memory"); |
}; |
static inline |
void sys_change_window(int new_x, int new_y, int new_w, int new_h) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(67), "b"(new_x), "c"(new_y), "d"(new_w),"S"(new_h) |
); |
} |
static inline |
void define_button(uint32_t x_w, uint32_t y_h, uint32_t id, uint32_t color) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(8), |
"b"(x_w), |
"c"(y_h), |
"d"(id), |
"S"(color)); |
}; |
static inline |
void draw_line(int xs, int ys, int xe, int ye, color_t color) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(38), "d"(color), |
"b"((xs << 16) | xe), |
"c"((ys << 16) | ye)); |
} |
static inline |
void draw_bar(int x, int y, int w, int h, color_t color) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(13), "d"(color), |
"b"((x << 16) | w), |
"c"((y << 16) | h)); |
} |
static inline |
void draw_bitmap(void *bitmap, int x, int y, int w, int h) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(7), "b"(bitmap), |
"c"((w << 16) | h), |
"d"((x << 16) | y)); |
} |
static inline |
void draw_text_sys(const char *text, int x, int y, int len, color_t color) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(4),"d"(text), |
"b"((x << 16) | y), |
"S"(len),"c"(color) |
:"memory"); |
} |
static inline |
void draw_text_sys_bg(const char *text, int x, int y, int len, color_t color, color_t bg) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(4),"d"(text), |
"b"((x << 16) | y), |
"S"(len),"c"(color), "D"(bg) |
:"memory"); |
} |
static inline |
uint32_t get_skin_height(void) |
{ |
uint32_t height; |
__asm__ __volatile__( |
"int $0x40 \n\t" |
:"=a"(height) |
:"a"(48),"b"(4)); |
return height; |
}; |
static inline |
pos_t get_mouse_pos(int origin) |
{ |
pos_t val; |
__asm__ __volatile__( |
"int $0x40 \n\t" |
"rol $16, %%eax" |
:"=a"(val) |
:"a"(37),"b"(origin)); |
return val; |
} |
static inline |
uint32_t get_mouse_buttons(void) |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(37),"b"(2)); |
return val; |
}; |
static inline |
uint32_t get_mouse_wheels(void) |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40 \n\t" |
:"=a"(val) |
:"a"(37),"b"(7)); |
return val; |
}; |
static inline uint32_t load_cursor(void *path, uint32_t flags) |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(37), "b"(4), "c"(path), "d"(flags)); |
return val; |
} |
static inline uint32_t set_cursor(uint32_t cursor) |
{ |
uint32_t old; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(old) |
:"a"(37), "b"(5), "c"(cursor)); |
return old; |
}; |
static inline int destroy_cursor(uint32_t cursor) |
{ |
int ret; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(ret) |
:"a"(37), "b"(6), "c"(cursor) |
:"memory"); |
return ret; |
}; |
static inline |
uint32_t wait_for_event(uint32_t time) |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(23), "b"(time)); |
return val; |
}; |
static inline uint32_t check_os_event() |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(11)); |
return val; |
}; |
static inline uint32_t get_os_event() |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(10)); |
return val; |
}; |
static inline |
uint32_t get_tick_count(void) |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(26),"b"(9)); |
return val; |
}; |
static inline |
uint64_t get_ns_count(void) |
{ |
uint64_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=A"(val) |
:"a"(26), "b"(10)); |
return val; |
}; |
static inline oskey_t get_key(void) |
{ |
oskey_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(2)); |
return val; |
} |
static inline |
uint32_t get_os_button() |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(17)); |
return val>>8; |
}; |
static inline uint32_t get_service(char *name) |
{ |
uint32_t retval = 0; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(retval) |
:"a"(68),"b"(16),"c"(name) |
:"memory"); |
return retval; |
}; |
static inline int call_service(ioctl_t *io) |
{ |
int retval; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(retval) |
:"a"(68),"b"(17),"c"(io) |
:"memory","cc"); |
return retval; |
}; |
static inline void yield(void) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(68), "b"(1)); |
}; |
static inline void delay(uint32_t time) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(5), "b"(time) |
:"memory"); |
}; |
static inline |
void *user_alloc(size_t size) |
{ |
void *val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(68),"b"(12),"c"(size)); |
return val; |
} |
static inline |
int user_free(void *mem) |
{ |
int val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(68),"b"(13),"c"(mem)); |
return val; |
} |
static inline |
void* user_realloc(void *mem, size_t size) |
{ |
void *val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(68),"b"(20),"c"(size),"d"(mem) |
:"memory"); |
return val; |
}; |
static inline |
int *user_unmap(void *base, size_t offset, size_t size) |
{ |
int *val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(68),"b"(26),"c"(base),"d"(offset),"S"(size)); |
return val; |
}; |
static inline ufile_t load_file(const char *path) |
{ |
ufile_t uf; |
__asm__ __volatile__ ( |
"int $0x40" |
:"=A"(uf.raw) |
:"a" (68), "b"(27),"c"(path)); |
return uf; |
}; |
static inline int GetScreenSize() |
{ |
int retval; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(retval) |
:"a"(61), "b"(1)); |
return retval; |
} |
static inline void get_proc_info(char *info) |
{ |
__asm__ __volatile__( |
"int $0x40" |
: |
:"a"(9), "b"(info), "c"(-1) |
:"memory"); |
}; |
static inline void Blit(void *bitmap, int dst_x, int dst_y, |
int src_x, int src_y, int w, int h, |
int src_w, int src_h, int stride) |
{ |
volatile struct blit_call bc; |
bc.dstx = dst_x; |
bc.dsty = dst_y; |
bc.w = w; |
bc.h = h; |
bc.srcx = src_x; |
bc.srcy = src_y; |
bc.srcw = src_w; |
bc.srch = src_h; |
bc.stride = stride; |
bc.bitmap = bitmap; |
__asm__ __volatile__( |
"int $0x40" |
::"a"(73),"b"(0),"c"(&bc.dstx)); |
}; |
// newlib exclusive |
#ifndef __TINYC__ |
int create_thread(int (*proc)(void *param), void *param, int stack_size); |
void* load_library(const char *name); |
void* get_proc_address(void *handle, const char *proc_name); |
void enumerate_libraries(int (*callback)(void *handle, const char* name, |
uint32_t base, uint32_t size, void *user_data), |
void *user_data); |
#endif |
// May be next section need to be added in newlibc |
enum KOLIBRI_GUI_EVENTS { |
KOLIBRI_EVENT_NONE = 0, /* Event queue is empty */ |
KOLIBRI_EVENT_REDRAW = 1, /* Window and window elements should be redrawn */ |
KOLIBRI_EVENT_KEY = 2, /* A key on the keyboard was pressed */ |
KOLIBRI_EVENT_BUTTON = 3, /* A button was clicked with the mouse */ |
KOLIBRI_EVENT_DESKTOP = 5, /* Desktop redraw finished */ |
KOLIBRI_EVENT_MOUSE = 6, /* Mouse activity (movement, button press) was detected */ |
KOLIBRI_EVENT_IPC = 7, /* Interprocess communication notify */ |
KOLIBRI_EVENT_NETWORK = 8, /* Network event */ |
KOLIBRI_EVENT_DEBUG = 9, /* Debug subsystem event */ |
KOLIBRI_EVENT_IRQBEGIN = 16 /* 16..31 IRQ0..IRQ15 interrupt =IRQBEGIN+IRQn */ |
}; |
// copied from /programs/system/shell/system/kolibri.c |
// fn's returned -1 as syserror, 1 as error, 0 as OK |
static inline |
int kol_clip_num() |
{ |
register uint32_t val; |
asm volatile ("int $0x40":"=a"(val):"a"(54), "b"(0)); |
return val; |
} |
static inline |
char* kol_clip_get(int n) |
// returned buffer must be freed by user_free() |
{ |
register char* val; |
asm volatile ("int $0x40":"=a"(val):"a"(54), "b"(1), "c"(n)); |
return val; |
} |
static inline |
int kol_clip_set(int n, char buffer[]) |
{ |
register uint32_t val; |
asm volatile ("int $0x40":"=a"(val):"a"(54), "b"(2), "c"(n), "d"(buffer)); |
return val; |
} |
static inline |
int kol_clip_pop() |
{ |
register uint32_t val; |
asm volatile ("int $0x40":"=a"(val):"a"(54), "b"(3)); |
return val; |
} |
static inline |
int kol_clip_unlock() |
{ |
register uint32_t val; |
asm volatile ("int $0x40":"=a"(val):"a"(54), "b"(4)); |
return val; |
} |
static inline void get_system_colors(struct kolibri_system_colors *color_table) |
{ |
__asm__ volatile ("int $0x40" |
: |
:"a"(48),"b"(3),"c"(color_table),"d"(40) |
); |
/* color_table should point to the system color table */ |
} |
static inline void debug_board_write_byte(const char ch){ |
__asm__ __volatile__( |
"int $0x40" |
: |
:"a"(63), "b"(1), "c"(ch)); |
} |
static inline void draw_number_sys(int32_t number, int x, int y, int len, color_t color){ |
register uint32_t fmt; |
fmt = len << 16 | 0x80000000; // no leading zeros + width |
// fmt = len << 16 | 0x00000000; // leading zeros + width |
__asm__ __volatile__( |
"int $0x40" |
: |
:"a"(47), "b"(fmt), "c"(number), "d"((x << 16) | y), "S"(color)); |
} |
static inline void draw_number_sys_bg(int32_t number, int x, int y, int len, color_t color, color_t bg){ |
register uint32_t fmt; |
fmt = len << 16 | 0x80000000; // no leading zeros + width |
// fmt = len << 16 | 0x00000000; // leading zeros + width |
__asm__ __volatile__( |
"int $0x40" |
: |
:"a"(47), "b"(fmt), "c"(number), "d"((x << 16) | y), "S"(color), "D"(bg)); |
} |
static inline |
uint32_t get_mouse_eventstate(void) |
{ |
uint32_t val; |
__asm__ __volatile__( |
"int $0x40" |
:"=a"(val) |
:"a"(37),"b"(3)); |
return val; |
}; |
static inline |
uint32_t set_event_mask(uint32_t mask) |
{ |
register uint32_t val; |
asm volatile ("int $0x40":"=a"(val):"a"(40), "b"(mask)); |
return val; |
} |
typedef void (*thread_proc)(void*); |
static inline |
int start_thread(thread_proc proc, char* stack_top) |
{ |
register int val; |
asm volatile ("int $0x40":"=a"(val):"a"(51), "b"(1), "c"(proc), "d"(stack_top)); |
return val; |
} |
static inline |
void kos_exit() |
{ |
asm volatile ("int $0x40"::"a"(-1)); |
} |
static inline void focus_window(int slot){ |
asm volatile ("int $0x40"::"a"(18), "b"(3), "c"(slot)); |
} |
static inline int get_thread_slot(int tid){ |
register int val; |
asm volatile ("int $0x40":"=a"(val):"a"(18), "b"(21), "c"(tid)); |
return val; |
} |
static inline void set_current_folder(char* dir){ |
asm volatile ("int $0x40"::"a"(30), "b"(1), "c"(dir)); |
} |
static inline int get_current_folder(char* buf, int bufsize){ |
register int val; |
asm volatile ("int $0x40":"=a"(val):"a"(30), "b"(2), "c"(buf), "d"(bufsize)); |
return val; |
} |
static inline |
void ipc_set_area(void* buf, int bufsize){ |
asm volatile ("int $0x40"::"a"(60), "b"(1), "c"(buf), "d"(bufsize)); |
} |
static inline |
int ipc_send_message(int pid_reciever, void *data, int datalen) { |
register int val; |
asm volatile ("int $0x40":"=a"(val):"a"(60), "b"(2), "c"(pid_reciever), "d"(data), "S"(datalen)); |
return val; |
} |
static inline |
void* shm_open(char *shm_name, int msize, int flags, int *retsz){ |
register int val, cod; |
asm volatile ("int $0x40":"=a"(val),"=d"(cod):"a"(68), "b"(22), "c"(shm_name), "d"(msize), "S"(flags)); |
if(retsz) *retsz = cod; // errcode if NULL or memsize when open |
return (void*)val; |
} |
static inline |
void shm_close(char *shm_name){ |
asm volatile ("int $0x40"::"a"(68), "b"(23), "c"(shm_name)); |
} |
static inline |
int start_app(char *app_name, char *args){ |
register int val; |
struct file_op_t |
{ |
uint32_t fn; |
uint32_t flags; |
char* args; |
uint32_t res1, res2; |
char zero; |
char* app_name __attribute__((packed)); |
} file_op; |
memset(&file_op, 0, sizeof(file_op)); |
file_op.fn = 7; |
file_op.args = args; |
file_op.app_name = app_name; |
asm volatile ("int $0x40":"=a"(val):"a"(70), "b"(&file_op)); |
return val; |
} |
//added nonstatic inline because incomfortabre stepping in in debugger |
void __attribute__ ((noinline)) debug_board_write_str(const char* str); |
void __attribute__ ((noinline)) debug_board_printf(const char *format,...); |
/* copy body to only one project file |
void __attribute__ ((noinline)) debug_board_write_str(const char* str){ |
while(*str) |
debug_board_write_byte(*str++); |
} |
void __attribute__ ((noinline)) debug_board_printf(const char *format,...) |
{ |
va_list ap; |
char log_board[300]; |
va_start (ap, format); |
vsnprintf(log_board, sizeof log_board, format, ap); |
va_end(ap); |
debug_board_write_str(log_board); |
} |
*/ |
// TinyC don't support aliasing of static inline funcs, but support #define :) |
#ifndef __TINYC__ |
static inline void BeginDraw(void) __attribute__ ((alias ("begin_draw"))); |
static inline void EndDraw(void) __attribute__ ((alias ("end_draw"))); |
static inline void DrawWindow(int x, int y, int w, int h, const char *name, |
color_t workcolor, uint32_t style) |
__attribute__ ((alias ("sys_create_window"))); |
static inline void DefineButton(void) __attribute__ ((alias ("define_button"))); |
static inline void DrawLine(int xs, int ys, int xe, int ye, color_t color) |
__attribute__ ((alias ("draw_line"))); |
static inline void DrawBar(int x, int y, int w, int h, color_t color) |
__attribute__ ((alias ("draw_bar"))); |
static inline void DrawBitmap(void *bitmap, int x, int y, int w, int h) |
__attribute__ ((alias ("draw_bitmap"))); |
static inline uint32_t GetSkinHeight(void) __attribute__ ((alias ("get_skin_height"))); |
static inline pos_t GetMousePos(int origin) __attribute__ ((alias ("get_mouse_pos"))); |
static inline uint32_t GetMouseButtons(void) __attribute__ ((alias ("get_mouse_buttons"))); |
static inline uint32_t GetMouseWheels(void) __attribute__ ((alias ("get_mouse_wheels"))); |
static inline uint32_t LoadCursor(void *path, uint32_t flags) __attribute__ ((alias ("load_cursor"))); |
static inline uint32_t SetCursor(uint32_t cursor) __attribute__ ((alias ("set_cursor"))); |
static inline int DestroyCursor(uint32_t cursor) __attribute__ ((alias ("destroy_cursor"))); |
static inline uint32_t GetOsEvent(void) __attribute__ ((alias ("get_os_event"))); |
static inline void *UserAlloc(size_t size) __attribute__ ((alias ("user_alloc"))); |
static inline int UserFree(void *mem) __attribute__ ((alias ("user_free"))); |
static inline void* UserRealloc(void *mem, size_t size) __attribute__ ((alias ("user_realloc"))); |
static inline int *UserUnmap(void *base, size_t offset, size_t size) __attribute__ ((alias ("user_unmap"))); |
static inline ufile_t LoadFile(const char *path) __attribute__ ((alias ("load_file"))); |
static inline void GetProcInfo(char *info) __attribute__ ((alias ("get_proc_info"))); |
#else |
#define BeginDraw begin_draw |
#define EndDraw end_draw |
#define DrawWindow sys_create_window |
#define DefineButton define_button |
#define DrawLine draw_line |
#define DrawBar draw_bar |
#define DrawBitmap draw_bitmap |
#define GetSkinHeight get_skin_height |
#define GetMousePos get_mouse_pos |
#define GetMouseButtons get_mouse_buttons |
#define GetMouseWheels get_mouse_wheels |
#define LoadCursor load_cursor |
#define SetCursor set_cursor |
#define DestroyCursor destroy_cursor |
#define GetOsEvent get_os_event |
#define UserAlloc user_alloc |
#define UserFree user_free |
#define UserRealloc user_realloc |
#define UserUnmap user_unmap |
#define LoadFile load_file |
#define GetProcInfo get_proc_info |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif |
/programs/develop/libraries/kos_mbedtls/kosnet/include/kosnet/network.h |
---|
0,0 → 1,54 |
#ifndef __NETWORK_H |
#define __NETWORK_H |
#include "kosnet/socket.h" |
#define EAI_ADDRFAMILY 1 |
#define EAI_AGAIN 2 |
#define EAI_BADFLAGS 3 |
#define EAI_FAIL 4 |
#define EAI_FAMILY 5 |
#define EAI_MEMORY 6 |
#define EAI_NONAME 8 |
#define EAI_SERVICE 9 |
#define EAI_SOCKTYPE 10 |
#define EAI_BADHINTS 12 |
#define EAI_PROTOCOL 13 |
#define EAI_OVERFLOW 14 |
// Flags for addrinfo |
#define AI_PASSIVE 1 |
#define AI_CANONNAME 2 |
#define AI_NUMERICHOST 4 |
#define AI_NUMERICSERV 8 |
#define AI_ADDRCONFIG 0x400 |
#pragma pack(push, 1) |
struct ARP_entry{ |
unsigned int IP; |
unsigned char MAC[6]; |
unsigned short status; |
unsigned short TTL; |
}; |
#pragma pack(pop) |
#pragma pack(push, 1) |
struct addrinfo { |
int ai_flags; |
int ai_family; |
int ai_socktype; |
int ai_protocol; |
int ai_addrlen; |
char *ai_canonname; |
sockaddr *ai_addr; |
struct addrinfo *ai_next; |
}; |
#pragma pack(pop) |
extern int load_network_obj(); |
extern int (*inet_addr)(const char* hostname) __attribute__ ((stdcall)); |
extern char* (*inet_ntoa)(int ip_addr) __attribute__ ((stdcall)); |
extern int (*getaddrinfo)(const char* hostname, const char* servname, const struct addrinfo* hints, struct addrinfo** res) __attribute__ ((stdcall)); |
extern void (*freeaddrinfo)(struct addrinfo* ai) __attribute__ ((stdcall)); |
#endif |
/programs/develop/libraries/kos_mbedtls/kosnet/include/kosnet/socket.h |
---|
0,0 → 1,107 |
#ifndef __SOCKET_H |
#define __SOCKET_H |
#include <stddef.h> |
// Socket Types |
#define SOCK_STREAM 1 |
#define SOCK_DGRAM 2 |
#define SOCK_RAW 3 |
// IP protocols |
#define IPPROTO_IP 0 |
#define IPPROTO_ICMP 1 |
#define IPPROTO_TCP 6 |
#define IPPROTO_UDP 17 |
#define IPPROTO_RAW 255 |
// IP options |
#define IP_TTL 2 |
// Address families |
#define AF_UNSPEC 0 |
#define AF_LOCAL 1 |
#define AF_INET4 2 // IPv4 |
#define AF_INET6 10 // IPv6 |
#define PF_UNSPEC AF_UNSPEC |
#define PF_LOCAL AF_LOCAL |
#define PF_INET4 AF_INET4 |
#define PF_INET6 AF_INET6 |
// internal definition |
#define AI_SUPPORTED 0x40F |
// for system function 76 |
#define API_ETH (0<<16) |
#define API_IPv4 (1<<16) |
#define API_ICMP (2<<16) |
#define API_UDP (3<<16) |
#define API_TCP (4<<16) |
#define API_ARP (5<<16) |
#define API_PPPOE (6<<16) |
// Socket flags for user calls |
#define MSG_NOFLAG 0 |
#define MSG_PEEK 0x02 |
#define MSG_DONTWAIT 0x40 |
// Socket levels |
#define SOL_SOCKET 0xffff |
//Socket options |
#define SO_BINDTODEVICE (1<<9) |
#define SO_NONBLOCK (1<<31) |
// Error Codes |
#define ENOBUFS 1 |
#define EINPROGRESS 2 |
#define EOPNOTSUPP 4 |
#define EWOULDBLOCK 6 |
#define ENOTCONN 9 |
#define EALREADY 10 |
#define EINVALUE 11 |
#define EMSGSIZE 12 |
#define ENOMEM 18 |
#define EADDRINUSE 20 |
#define ECONNREFUSED 61 |
#define ECONNRESET 52 |
#define EISCONN 56 |
#define ETIMEDOUT 60 |
#define ECONNABORTED 53 |
#define PORT(X) (X<<8) |
extern int err_code; |
#pragma pack(push,1) |
typedef struct{ |
unsigned short sin_family; |
unsigned short sin_port; |
unsigned int sin_addr; |
unsigned long long sin_zero; |
}sockaddr; |
#pragma pack(pop) |
#pragma pack(push,1) |
typedef struct{ |
unsigned int level; |
unsigned int optionname; |
unsigned int optlenght; |
unsigned char options; |
}optstruct; |
#pragma pack(pop) |
int socket(int domain, int type, int protocol); |
int closesocket(int socket); |
int bind(int socket, const sockaddr *addres, int addres_len); |
int listen(int socket, int backlog); |
int connect(int socket, const sockaddr* address, int socket_len); |
int accept(int socket, const sockaddr* address, int address_len); |
int send(int socket, const void *message, size_t msg_len, int flag); |
int recv(int socket, void *buffer, size_t buff_len, int flag); |
int setsockopt(int socket,const optstruct* opt); |
int getsockopt(int socket, optstruct* opt); |
int socketpair(int *sock1, int *sock2); |
#endif |
/programs/develop/libraries/kos_mbedtls/kosnet/network.c |
---|
0,0 → 1,21 |
#include "kosnet/network.h" |
#include "kosnet/dlfcn.h" |
int (*inet_addr)(const char* hostname) __attribute__ ((stdcall)); |
char* (*inet_ntoa)(int ip_addr) __attribute__ ((stdcall)); |
int (*getaddrinfo)(const char* hostname, const char* servname, const struct addrinfo* hints, struct addrinfo** res) __attribute__ ((stdcall)); |
void (*freeaddrinfo)(struct addrinfo* ai) __attribute__ ((stdcall)); |
int load_network_obj() { |
void *network_lib = dlopen("/sys/lib/network.obj", RTLD_GLOBAL); |
if (network_lib == NULL) { |
return -1; |
} |
inet_addr = dlsym(network_lib, "inet_addr"); |
inet_ntoa = dlsym(network_lib, "inet_ntoa"); |
getaddrinfo = dlsym(network_lib, "getaddrinfo"); |
freeaddrinfo = dlsym(network_lib, "freeaddrinfo"); |
dlclose(network_lib); |
return 0; |
} |
/programs/develop/libraries/kos_mbedtls/kosnet/sample/Makefile |
---|
0,0 → 1,24 |
NEWLIB_INCLUDES=D:\KOSSDK\newlib\libc\include |
APP_DYNAMIC_LDS=D:\KOSSDK\newlib/app-dynamic.lds |
LIBDIR=D:\KOSSDK\kos32-msys-5.4.0\win32\lib |
MAIN_TARGET=libkosnet_demo |
CC=kos32-gcc |
LD=kos32-ld |
OBJCOPY=kos32-objcopy |
CCFLAGS=-c -fomit-frame-pointer -I $(NEWLIB_INCLUDES) -I../include -Wall -Wextra |
LDFLAGS=-call_shared -nostdlib --subsystem console -T $(APP_DYNAMIC_LDS) --image-base 0 -L $(LIBDIR) -L ../ -lkosnet -lgcc -lapp -lc.dll |
all: libkosnet_demo |
libkosnet_demo: libkosnet_demo.o |
$(LD) libkosnet_demo.o -o $(MAIN_TARGET) $(LDFLAGS) |
$(OBJCOPY) $(MAIN_TARGET) -O binary |
libkosnet_demo.o: libkosnet_demo.c |
$(CC) $(CCFLAGS) libkosnet_demo.c -o libkosnet_demo.o |
clean: |
del *.o |
del $(MAIN_TARGET) |
/programs/develop/libraries/kos_mbedtls/kosnet/sample/libkosnet_demo |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/programs/develop/libraries/kos_mbedtls/kosnet/sample/libkosnet_demo.c |
---|
0,0 → 1,60 |
#include "kosnet/network.h" |
#include <string.h> |
#include <stdio.h> |
#include <stdlib.h> |
int main() { |
load_network_obj(); |
char *host = "kolibrios.org"; |
int port = 80; |
printf("Connecting to %s on port %d\n", host, port); |
struct addrinfo *addr_info; |
char port_str[16]; sprintf(port_str, "%d", port); |
struct addrinfo hints; |
memset(&hints, 0, sizeof(hints)); |
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 doesnt matter |
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets |
if (getaddrinfo(host, port_str, 0, &addr_info) != 0) { |
printf("Host %s not found!\n", host); |
freeaddrinfo(addr_info); |
exit(-1); |
} |
printf("IP address of %s is %s\n", host, inet_ntoa(addr_info->ai_addr->sin_addr)); |
//printf("Host port = %d\n", addr_info->ai_addr->sin_port >> 8); |
char request[256]; |
sprintf(request, "GET /en/ HTTP/1.1\r\nHost: %s\r\n\r\n", host); |
printf("request = %s\n", request); |
int sock = socket(AF_INET4, SOCK_STREAM, IPPROTO_TCP); |
puts("Connecting...\n"); |
if (connect(sock, addr_info->ai_addr, addr_info->ai_addrlen) != 0) { |
printf("Connection failed, err_code = %d\n", err_code); |
exit(err_code); |
} |
puts("Connected successfully\n"); |
puts("Sending request...\n"); |
if (send(sock, request, strlen(request), MSG_NOFLAG) == -1) { |
printf("Sending failed, err_code = %d\n", err_code); |
exit(err_code); |
} |
puts("Request sended successfully, waiting for response...\n"); |
char buf[512 + 1]; |
if (recv(sock, buf, 512, MSG_NOFLAG) == -1) { |
printf("Receive failed, err_code = %d\n", err_code); |
exit(err_code); |
} |
printf("Response = %s\n", buf); |
freeaddrinfo(addr_info); |
closesocket(sock); |
puts("\n goodbye)\n"); |
return 0; |
} |
/programs/develop/libraries/kos_mbedtls/kosnet/sample/run_img.bat |
---|
0,0 → 1,0 |
qemu-system-i386 -m 256 -fda ../../test_kos_images/kolibri.img -boot a -vga vmware -net nic,model=rtl8139 -net user -soundhw ac97 -usb -usbdevice tablet -drive file=fat:rw:. |
/programs/develop/libraries/kos_mbedtls/kosnet/socket.c |
---|
0,0 → 1,124 |
#include "kosnet/socket.h" |
int err_code = 0; |
int socket(int domain, int type, int protocol) |
{ |
int socket; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(socket) |
:"a"(75), "b"(0), "c"(domain), "d"(type), "S"(protocol) |
); |
return socket; |
} |
int closesocket(int socket) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(1), "c"(socket) |
); |
return status; |
} |
int bind(int socket, const sockaddr *addres, int addres_len) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(2), "c"(socket), "d"(addres), "S"(addres_len) |
); |
return status; |
} |
int listen(int socket, int backlog) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(3), "c"(socket), "d"(backlog) |
); |
return status; |
} |
int connect(int socket,const sockaddr* address, int socket_len) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(4), "c"(socket), "d"(address), "S"(socket_len) |
); |
return status; |
} |
int accept(int socket, const sockaddr *address, int address_len) |
{ |
int new_socket; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(new_socket) |
:"a"(75), "b"(5), "c"(socket), "d"(address), "S"(address_len) |
); |
return new_socket; |
} |
int send(int socket, const void *message, size_t msg_len, int flag) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(6), "c"(socket), "d"(message), "S"(msg_len), "D"(flag) |
); |
return status; |
} |
int recv(int socket, void *buffer, size_t buff_len, int flag) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(7), "c"(socket), "d"(buffer), "S"(buff_len), "D"(flag) |
); |
return status; |
} |
int setsockopt(int socket,const optstruct* opt) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(8), "c"(socket),"d"(opt) |
); |
return status; |
} |
int getsockopt(int socket, optstruct* opt) |
{ |
int status; |
asm volatile( |
"int $0x40" |
:"=b"(err_code), "=a"(status) |
:"a"(75), "b"(9), "c"(socket),"d"(opt) |
); |
return status; |
} |
int socketpair(int *socket1, int *socket2) |
{ |
asm volatile( |
"int $0x40" |
:"=b"(*socket2), "=a"(*socket1) |
:"a"(75), "b"(10) |
); |
err_code=*socket2; |
return *socket1; |
} |
/programs/develop/libraries/kos_mbedtls/library/.gitignore |
---|
0,0 → 1,0 |
*.o |
/programs/develop/libraries/kos_mbedtls/library/CMakeLists.txt |
---|
0,0 → 1,187 |
option(USE_STATIC_MBEDTLS_LIBRARY "Build mbed TLS static library." ON) |
option(USE_SHARED_MBEDTLS_LIBRARY "Build mbed TLS shared library." OFF) |
option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF) |
set(src_crypto |
aes.c |
aesni.c |
arc4.c |
aria.c |
asn1parse.c |
asn1write.c |
base64.c |
bignum.c |
blowfish.c |
camellia.c |
ccm.c |
chacha20.c |
chachapoly.c |
cipher.c |
cipher_wrap.c |
cmac.c |
ctr_drbg.c |
des.c |
dhm.c |
ecdh.c |
ecdsa.c |
ecjpake.c |
ecp.c |
ecp_curves.c |
entropy.c |
entropy_poll.c |
error.c |
gcm.c |
havege.c |
hkdf.c |
hmac_drbg.c |
md.c |
md2.c |
md4.c |
md5.c |
md_wrap.c |
memory_buffer_alloc.c |
nist_kw.c |
oid.c |
padlock.c |
pem.c |
pk.c |
pk_wrap.c |
pkcs12.c |
pkcs5.c |
pkparse.c |
pkwrite.c |
platform.c |
platform_util.c |
poly1305.c |
ripemd160.c |
rsa.c |
rsa_internal.c |
sha1.c |
sha256.c |
sha512.c |
threading.c |
timing.c |
version.c |
version_features.c |
xtea.c |
) |
set(src_x509 |
certs.c |
pkcs11.c |
x509.c |
x509_create.c |
x509_crl.c |
x509_crt.c |
x509_csr.c |
x509write_crt.c |
x509write_csr.c |
) |
set(src_tls |
debug.c |
net_sockets.c |
ssl_cache.c |
ssl_ciphersuites.c |
ssl_cli.c |
ssl_cookie.c |
ssl_srv.c |
ssl_ticket.c |
ssl_tls.c |
) |
if(CMAKE_COMPILER_IS_GNUCC) |
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes") |
endif(CMAKE_COMPILER_IS_GNUCC) |
if(CMAKE_COMPILER_IS_CLANG) |
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code") |
endif(CMAKE_COMPILER_IS_CLANG) |
if(UNSAFE_BUILD) |
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error") |
set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_ASAN} -Wno-error") |
set(CMAKE_C_FLAGS_ASANDBG "${CMAKE_C_FLAGS_ASANDBG} -Wno-error") |
endif(UNSAFE_BUILD) |
if(WIN32) |
set(libs ${libs} ws2_32) |
endif(WIN32) |
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") |
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>") |
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>") |
SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>") |
SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>") |
endif() |
if(HAIKU) |
set(libs ${libs} network) |
endif(HAIKU) |
if(USE_PKCS11_HELPER_LIBRARY) |
set(libs ${libs} pkcs11-helper) |
endif(USE_PKCS11_HELPER_LIBRARY) |
if(ENABLE_ZLIB_SUPPORT) |
set(libs ${libs} ${ZLIB_LIBRARIES}) |
endif(ENABLE_ZLIB_SUPPORT) |
if(LINK_WITH_PTHREAD) |
set(libs ${libs} pthread) |
endif() |
if (NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY) |
message(FATAL_ERROR "Need to choose static or shared mbedtls build!") |
endif(NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY) |
if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY) |
set(mbedtls_static_target "mbedtls_static") |
set(mbedx509_static_target "mbedx509_static") |
set(mbedcrypto_static_target "mbedcrypto_static") |
elseif(USE_STATIC_MBEDTLS_LIBRARY) |
set(mbedtls_static_target "mbedtls") |
set(mbedx509_static_target "mbedx509") |
set(mbedcrypto_static_target "mbedcrypto") |
endif() |
if(USE_STATIC_MBEDTLS_LIBRARY) |
add_library(${mbedcrypto_static_target} STATIC ${src_crypto}) |
set_target_properties(${mbedcrypto_static_target} PROPERTIES OUTPUT_NAME mbedcrypto) |
target_link_libraries(${mbedcrypto_static_target} ${libs}) |
add_library(${mbedx509_static_target} STATIC ${src_x509}) |
set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509) |
target_link_libraries(${mbedx509_static_target} ${libs} ${mbedcrypto_static_target}) |
add_library(${mbedtls_static_target} STATIC ${src_tls}) |
set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls) |
target_link_libraries(${mbedtls_static_target} ${libs} ${mbedx509_static_target}) |
install(TARGETS ${mbedtls_static_target} ${mbedx509_static_target} ${mbedcrypto_static_target} |
DESTINATION ${LIB_INSTALL_DIR} |
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) |
endif(USE_STATIC_MBEDTLS_LIBRARY) |
if(USE_SHARED_MBEDTLS_LIBRARY) |
add_library(mbedcrypto SHARED ${src_crypto}) |
set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.6 SOVERSION 3) |
target_link_libraries(mbedcrypto ${libs}) |
add_library(mbedx509 SHARED ${src_x509}) |
set_target_properties(mbedx509 PROPERTIES VERSION 2.16.6 SOVERSION 0) |
target_link_libraries(mbedx509 ${libs} mbedcrypto) |
add_library(mbedtls SHARED ${src_tls}) |
set_target_properties(mbedtls PROPERTIES VERSION 2.16.6 SOVERSION 12) |
target_link_libraries(mbedtls ${libs} mbedx509) |
install(TARGETS mbedtls mbedx509 mbedcrypto |
DESTINATION ${LIB_INSTALL_DIR} |
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) |
endif(USE_SHARED_MBEDTLS_LIBRARY) |
add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls) |
if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY) |
add_dependencies(lib mbedcrypto_static mbedx509_static mbedtls_static) |
endif() |
/programs/develop/libraries/kos_mbedtls/library/Makefile |
---|
0,0 → 1,92 |
# Also see "include/mbedtls/config.h" |
NEWLIB_INCLUDES=D:\KOSSDK\newlib\libc\include |
KOSNET_INCLUDES=../kosnet/include |
CC = kos32-gcc |
AR = kos32-ar |
CFLAGS ?= -O2 |
WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement |
LDFLAGS ?= |
LOCAL_CFLAGS = $(WARNING_CFLAGS) -I $(NEWLIB_INCLUDES) -I../include -I $(KOSNET_INCLUDES) -D_FILE_OFFSET_BITS=64 |
LOCAL_LDFLAGS = |
ifdef DEBUG |
LOCAL_CFLAGS += -g3 |
endif |
# Set AR_DASH= (empty string) to use an ar implementation that does not accept |
# the - prefix for command line options (e.g. llvm-ar) |
AR_DASH ?= - |
ARFLAGS = $(AR_DASH)src |
OBJS_CRYPTO= aes.o aesni.o arc4.o \ |
aria.o asn1parse.o asn1write.o \ |
base64.o bignum.o blowfish.o \ |
camellia.o ccm.o chacha20.o \ |
chachapoly.o cipher.o cipher_wrap.o \ |
cmac.o ctr_drbg.o des.o \ |
dhm.o ecdh.o ecdsa.o \ |
ecjpake.o ecp.o \ |
ecp_curves.o entropy.o entropy_poll.o \ |
error.o gcm.o havege.o \ |
hkdf.o \ |
hmac_drbg.o md.o md2.o \ |
md4.o md5.o md_wrap.o \ |
memory_buffer_alloc.o nist_kw.o \ |
oid.o padlock.o pem.o \ |
pk.o pk_wrap.o pkcs12.o \ |
pkcs5.o pkparse.o pkwrite.o \ |
platform.o platform_util.o poly1305.o \ |
ripemd160.o rsa_internal.o rsa.o \ |
sha1.o sha256.o sha512.o \ |
threading.o timing.o version.o \ |
version_features.o xtea.o |
OBJS_X509= certs.o pkcs11.o x509.o \ |
x509_create.o x509_crl.o x509_crt.o \ |
x509_csr.o x509write_crt.o x509write_csr.o |
OBJS_TLS= debug.o net_sockets.o \ |
ssl_cache.o ssl_ciphersuites.o \ |
ssl_cli.o ssl_cookie.o \ |
ssl_srv.o ssl_ticket.o \ |
ssl_tls.o |
.SILENT: |
.PHONY: all static clean |
all: static |
static: libmbedcrypto.a libmbedx509.a libmbedtls.a |
# tls |
libmbedtls.a: $(OBJS_TLS) |
echo " AR $@" |
$(AR) $(ARFLAGS) $@ $(OBJS_TLS) |
# x509 |
libmbedx509.a: $(OBJS_X509) |
echo " AR $@" |
$(AR) $(ARFLAGS) $@ $(OBJS_X509) |
# crypto |
libmbedcrypto.a: $(OBJS_CRYPTO) |
echo " AR $@" |
$(AR) $(ARFLAGS) $@ $(OBJS_CRYPTO) |
.c.o: |
echo " CC $<" |
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c $< |
clean: |
ifndef WINDOWS |
rm -f *.o libmbed* |
else |
del /Q /F *.o libmbed* |
endif |
/programs/develop/libraries/kos_mbedtls/library/aes.c |
---|
0,0 → 1,2235 |
/* |
* FIPS-197 compliant AES implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen. |
* |
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf |
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_AES_C) |
#include <string.h> |
#include "mbedtls/aes.h" |
#include "mbedtls/platform.h" |
#include "mbedtls/platform_util.h" |
#if defined(MBEDTLS_PADLOCK_C) |
#include "mbedtls/padlock.h" |
#endif |
#if defined(MBEDTLS_AESNI_C) |
#include "mbedtls/aesni.h" |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_AES_ALT) |
/* Parameter validation macros based on platform_util.h */ |
#define AES_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA ) |
#define AES_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* 32-bit integer manipulation macros (little endian) |
*/ |
#ifndef GET_UINT32_LE |
#define GET_UINT32_LE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] ) \ |
| ( (uint32_t) (b)[(i) + 1] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 3] << 24 ); \ |
} |
#endif |
#ifndef PUT_UINT32_LE |
#define PUT_UINT32_LE(n,b,i) \ |
{ \ |
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ |
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ |
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ |
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ |
} |
#endif |
#if defined(MBEDTLS_PADLOCK_C) && \ |
( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) |
static int aes_padlock_ace = -1; |
#endif |
#if defined(MBEDTLS_AES_ROM_TABLES) |
/* |
* Forward S-box |
*/ |
static const unsigned char FSb[256] = |
{ |
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, |
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, |
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, |
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, |
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, |
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, |
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, |
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, |
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, |
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, |
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, |
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, |
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, |
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, |
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, |
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, |
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, |
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, |
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, |
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, |
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, |
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, |
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, |
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, |
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, |
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, |
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, |
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, |
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, |
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, |
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, |
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 |
}; |
/* |
* Forward tables |
*/ |
#define FT \ |
\ |
V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ |
V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ |
V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ |
V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ |
V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ |
V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ |
V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ |
V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ |
V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ |
V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ |
V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ |
V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ |
V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ |
V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ |
V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ |
V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ |
V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ |
V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ |
V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ |
V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ |
V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ |
V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ |
V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ |
V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ |
V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ |
V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ |
V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ |
V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ |
V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ |
V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ |
V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ |
V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ |
V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ |
V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ |
V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ |
V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ |
V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ |
V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ |
V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ |
V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ |
V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ |
V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ |
V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ |
V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ |
V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ |
V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ |
V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ |
V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ |
V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ |
V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ |
V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ |
V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ |
V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ |
V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ |
V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ |
V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ |
V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ |
V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ |
V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ |
V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ |
V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ |
V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ |
V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ |
V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) |
#define V(a,b,c,d) 0x##a##b##c##d |
static const uint32_t FT0[256] = { FT }; |
#undef V |
#if !defined(MBEDTLS_AES_FEWER_TABLES) |
#define V(a,b,c,d) 0x##b##c##d##a |
static const uint32_t FT1[256] = { FT }; |
#undef V |
#define V(a,b,c,d) 0x##c##d##a##b |
static const uint32_t FT2[256] = { FT }; |
#undef V |
#define V(a,b,c,d) 0x##d##a##b##c |
static const uint32_t FT3[256] = { FT }; |
#undef V |
#endif /* !MBEDTLS_AES_FEWER_TABLES */ |
#undef FT |
/* |
* Reverse S-box |
*/ |
static const unsigned char RSb[256] = |
{ |
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, |
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, |
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, |
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, |
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, |
0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, |
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, |
0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, |
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, |
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, |
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, |
0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, |
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, |
0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, |
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, |
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, |
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, |
0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, |
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, |
0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, |
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, |
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, |
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, |
0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, |
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, |
0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, |
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, |
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, |
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, |
0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, |
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, |
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D |
}; |
/* |
* Reverse tables |
*/ |
#define RT \ |
\ |
V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ |
V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ |
V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ |
V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ |
V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ |
V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ |
V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ |
V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ |
V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ |
V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ |
V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ |
V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ |
V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ |
V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ |
V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ |
V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ |
V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ |
V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ |
V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ |
V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ |
V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ |
V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ |
V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ |
V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ |
V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ |
V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ |
V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ |
V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ |
V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ |
V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ |
V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ |
V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ |
V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ |
V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ |
V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ |
V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ |
V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ |
V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ |
V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ |
V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ |
V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ |
V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ |
V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ |
V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ |
V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ |
V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ |
V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ |
V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ |
V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ |
V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ |
V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ |
V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ |
V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ |
V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ |
V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ |
V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ |
V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ |
V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ |
V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ |
V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ |
V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ |
V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ |
V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ |
V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) |
#define V(a,b,c,d) 0x##a##b##c##d |
static const uint32_t RT0[256] = { RT }; |
#undef V |
#if !defined(MBEDTLS_AES_FEWER_TABLES) |
#define V(a,b,c,d) 0x##b##c##d##a |
static const uint32_t RT1[256] = { RT }; |
#undef V |
#define V(a,b,c,d) 0x##c##d##a##b |
static const uint32_t RT2[256] = { RT }; |
#undef V |
#define V(a,b,c,d) 0x##d##a##b##c |
static const uint32_t RT3[256] = { RT }; |
#undef V |
#endif /* !MBEDTLS_AES_FEWER_TABLES */ |
#undef RT |
/* |
* Round constants |
*/ |
static const uint32_t RCON[10] = |
{ |
0x00000001, 0x00000002, 0x00000004, 0x00000008, |
0x00000010, 0x00000020, 0x00000040, 0x00000080, |
0x0000001B, 0x00000036 |
}; |
#else /* MBEDTLS_AES_ROM_TABLES */ |
/* |
* Forward S-box & tables |
*/ |
static unsigned char FSb[256]; |
static uint32_t FT0[256]; |
#if !defined(MBEDTLS_AES_FEWER_TABLES) |
static uint32_t FT1[256]; |
static uint32_t FT2[256]; |
static uint32_t FT3[256]; |
#endif /* !MBEDTLS_AES_FEWER_TABLES */ |
/* |
* Reverse S-box & tables |
*/ |
static unsigned char RSb[256]; |
static uint32_t RT0[256]; |
#if !defined(MBEDTLS_AES_FEWER_TABLES) |
static uint32_t RT1[256]; |
static uint32_t RT2[256]; |
static uint32_t RT3[256]; |
#endif /* !MBEDTLS_AES_FEWER_TABLES */ |
/* |
* Round constants |
*/ |
static uint32_t RCON[10]; |
/* |
* Tables generation code |
*/ |
#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) |
#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) |
#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) |
static int aes_init_done = 0; |
static void aes_gen_tables( void ) |
{ |
int i, x, y, z; |
int pow[256]; |
int log[256]; |
/* |
* compute pow and log tables over GF(2^8) |
*/ |
for( i = 0, x = 1; i < 256; i++ ) |
{ |
pow[i] = x; |
log[x] = i; |
x = ( x ^ XTIME( x ) ) & 0xFF; |
} |
/* |
* calculate the round constants |
*/ |
for( i = 0, x = 1; i < 10; i++ ) |
{ |
RCON[i] = (uint32_t) x; |
x = XTIME( x ) & 0xFF; |
} |
/* |
* generate the forward and reverse S-boxes |
*/ |
FSb[0x00] = 0x63; |
RSb[0x63] = 0x00; |
for( i = 1; i < 256; i++ ) |
{ |
x = pow[255 - log[i]]; |
y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; |
x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; |
x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; |
x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; |
x ^= y ^ 0x63; |
FSb[i] = (unsigned char) x; |
RSb[x] = (unsigned char) i; |
} |
/* |
* generate the forward and reverse tables |
*/ |
for( i = 0; i < 256; i++ ) |
{ |
x = FSb[i]; |
y = XTIME( x ) & 0xFF; |
z = ( y ^ x ) & 0xFF; |
FT0[i] = ( (uint32_t) y ) ^ |
( (uint32_t) x << 8 ) ^ |
( (uint32_t) x << 16 ) ^ |
( (uint32_t) z << 24 ); |
#if !defined(MBEDTLS_AES_FEWER_TABLES) |
FT1[i] = ROTL8( FT0[i] ); |
FT2[i] = ROTL8( FT1[i] ); |
FT3[i] = ROTL8( FT2[i] ); |
#endif /* !MBEDTLS_AES_FEWER_TABLES */ |
x = RSb[i]; |
RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ |
( (uint32_t) MUL( 0x09, x ) << 8 ) ^ |
( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ |
( (uint32_t) MUL( 0x0B, x ) << 24 ); |
#if !defined(MBEDTLS_AES_FEWER_TABLES) |
RT1[i] = ROTL8( RT0[i] ); |
RT2[i] = ROTL8( RT1[i] ); |
RT3[i] = ROTL8( RT2[i] ); |
#endif /* !MBEDTLS_AES_FEWER_TABLES */ |
} |
} |
#undef ROTL8 |
#endif /* MBEDTLS_AES_ROM_TABLES */ |
#if defined(MBEDTLS_AES_FEWER_TABLES) |
#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) ) |
#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) ) |
#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) ) |
#define AES_RT0(idx) RT0[idx] |
#define AES_RT1(idx) ROTL8( RT0[idx] ) |
#define AES_RT2(idx) ROTL16( RT0[idx] ) |
#define AES_RT3(idx) ROTL24( RT0[idx] ) |
#define AES_FT0(idx) FT0[idx] |
#define AES_FT1(idx) ROTL8( FT0[idx] ) |
#define AES_FT2(idx) ROTL16( FT0[idx] ) |
#define AES_FT3(idx) ROTL24( FT0[idx] ) |
#else /* MBEDTLS_AES_FEWER_TABLES */ |
#define AES_RT0(idx) RT0[idx] |
#define AES_RT1(idx) RT1[idx] |
#define AES_RT2(idx) RT2[idx] |
#define AES_RT3(idx) RT3[idx] |
#define AES_FT0(idx) FT0[idx] |
#define AES_FT1(idx) FT1[idx] |
#define AES_FT2(idx) FT2[idx] |
#define AES_FT3(idx) FT3[idx] |
#endif /* MBEDTLS_AES_FEWER_TABLES */ |
void mbedtls_aes_init( mbedtls_aes_context *ctx ) |
{ |
AES_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_aes_context ) ); |
} |
void mbedtls_aes_free( mbedtls_aes_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) |
{ |
AES_VALIDATE( ctx != NULL ); |
mbedtls_aes_init( &ctx->crypt ); |
mbedtls_aes_init( &ctx->tweak ); |
} |
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_aes_free( &ctx->crypt ); |
mbedtls_aes_free( &ctx->tweak ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
/* |
* AES key schedule (encryption) |
*/ |
#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) |
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, |
unsigned int keybits ) |
{ |
unsigned int i; |
uint32_t *RK; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( key != NULL ); |
switch( keybits ) |
{ |
case 128: ctx->nr = 10; break; |
case 192: ctx->nr = 12; break; |
case 256: ctx->nr = 14; break; |
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); |
} |
#if !defined(MBEDTLS_AES_ROM_TABLES) |
if( aes_init_done == 0 ) |
{ |
aes_gen_tables(); |
aes_init_done = 1; |
} |
#endif |
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) |
if( aes_padlock_ace == -1 ) |
aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); |
if( aes_padlock_ace ) |
ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); |
else |
#endif |
ctx->rk = RK = ctx->buf; |
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) |
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) |
return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); |
#endif |
for( i = 0; i < ( keybits >> 5 ); i++ ) |
{ |
GET_UINT32_LE( RK[i], key, i << 2 ); |
} |
switch( ctx->nr ) |
{ |
case 10: |
for( i = 0; i < 10; i++, RK += 4 ) |
{ |
RK[4] = RK[0] ^ RCON[i] ^ |
( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); |
RK[5] = RK[1] ^ RK[4]; |
RK[6] = RK[2] ^ RK[5]; |
RK[7] = RK[3] ^ RK[6]; |
} |
break; |
case 12: |
for( i = 0; i < 8; i++, RK += 6 ) |
{ |
RK[6] = RK[0] ^ RCON[i] ^ |
( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); |
RK[7] = RK[1] ^ RK[6]; |
RK[8] = RK[2] ^ RK[7]; |
RK[9] = RK[3] ^ RK[8]; |
RK[10] = RK[4] ^ RK[9]; |
RK[11] = RK[5] ^ RK[10]; |
} |
break; |
case 14: |
for( i = 0; i < 7; i++, RK += 8 ) |
{ |
RK[8] = RK[0] ^ RCON[i] ^ |
( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); |
RK[9] = RK[1] ^ RK[8]; |
RK[10] = RK[2] ^ RK[9]; |
RK[11] = RK[3] ^ RK[10]; |
RK[12] = RK[4] ^ |
( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); |
RK[13] = RK[5] ^ RK[12]; |
RK[14] = RK[6] ^ RK[13]; |
RK[15] = RK[7] ^ RK[14]; |
} |
break; |
} |
return( 0 ); |
} |
#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ |
/* |
* AES key schedule (decryption) |
*/ |
#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) |
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, |
unsigned int keybits ) |
{ |
int i, j, ret; |
mbedtls_aes_context cty; |
uint32_t *RK; |
uint32_t *SK; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( key != NULL ); |
mbedtls_aes_init( &cty ); |
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) |
if( aes_padlock_ace == -1 ) |
aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); |
if( aes_padlock_ace ) |
ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); |
else |
#endif |
ctx->rk = RK = ctx->buf; |
/* Also checks keybits */ |
if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) |
goto exit; |
ctx->nr = cty.nr; |
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) |
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) |
{ |
mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, |
(const unsigned char *) cty.rk, ctx->nr ); |
goto exit; |
} |
#endif |
SK = cty.rk + cty.nr * 4; |
*RK++ = *SK++; |
*RK++ = *SK++; |
*RK++ = *SK++; |
*RK++ = *SK++; |
for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) |
{ |
for( j = 0; j < 4; j++, SK++ ) |
{ |
*RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^ |
AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^ |
AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^ |
AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] ); |
} |
} |
*RK++ = *SK++; |
*RK++ = *SK++; |
*RK++ = *SK++; |
*RK++ = *SK++; |
exit: |
mbedtls_aes_free( &cty ); |
return( ret ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
static int mbedtls_aes_xts_decode_keys( const unsigned char *key, |
unsigned int keybits, |
const unsigned char **key1, |
unsigned int *key1bits, |
const unsigned char **key2, |
unsigned int *key2bits ) |
{ |
const unsigned int half_keybits = keybits / 2; |
const unsigned int half_keybytes = half_keybits / 8; |
switch( keybits ) |
{ |
case 256: break; |
case 512: break; |
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); |
} |
*key1bits = half_keybits; |
*key2bits = half_keybits; |
*key1 = &key[0]; |
*key2 = &key[half_keybytes]; |
return 0; |
} |
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, |
const unsigned char *key, |
unsigned int keybits) |
{ |
int ret; |
const unsigned char *key1, *key2; |
unsigned int key1bits, key2bits; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( key != NULL ); |
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, |
&key2, &key2bits ); |
if( ret != 0 ) |
return( ret ); |
/* Set the tweak key. Always set tweak key for the encryption mode. */ |
ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); |
if( ret != 0 ) |
return( ret ); |
/* Set crypt key for encryption. */ |
return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); |
} |
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, |
const unsigned char *key, |
unsigned int keybits) |
{ |
int ret; |
const unsigned char *key1, *key2; |
unsigned int key1bits, key2bits; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( key != NULL ); |
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, |
&key2, &key2bits ); |
if( ret != 0 ) |
return( ret ); |
/* Set the tweak key. Always set tweak key for encryption. */ |
ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); |
if( ret != 0 ) |
return( ret ); |
/* Set crypt key for decryption. */ |
return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ |
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ |
do \ |
{ \ |
(X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ |
AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ |
AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ |
AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ |
\ |
(X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ |
AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ |
AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ |
AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ |
\ |
(X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ |
AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ |
AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ |
AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ |
\ |
(X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ |
AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ |
AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ |
AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ |
} while( 0 ) |
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ |
do \ |
{ \ |
(X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ |
AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ |
AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ |
AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ |
\ |
(X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ |
AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ |
AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ |
AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ |
\ |
(X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ |
AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ |
AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ |
AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ |
\ |
(X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ |
AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ |
AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ |
AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ |
} while( 0 ) |
/* |
* AES-ECB block encryption |
*/ |
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) |
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
int i; |
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; |
RK = ctx->rk; |
GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; |
GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; |
GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; |
GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; |
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) |
{ |
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); |
} |
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
X0 = *RK++ ^ \ |
( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); |
X1 = *RK++ ^ \ |
( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); |
X2 = *RK++ ^ \ |
( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); |
X3 = *RK++ ^ \ |
( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ |
( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); |
PUT_UINT32_LE( X0, output, 0 ); |
PUT_UINT32_LE( X1, output, 4 ); |
PUT_UINT32_LE( X2, output, 8 ); |
PUT_UINT32_LE( X3, output, 12 ); |
mbedtls_platform_zeroize( &X0, sizeof( X0 ) ); |
mbedtls_platform_zeroize( &X1, sizeof( X1 ) ); |
mbedtls_platform_zeroize( &X2, sizeof( X2 ) ); |
mbedtls_platform_zeroize( &X3, sizeof( X3 ) ); |
mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) ); |
mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) ); |
mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) ); |
mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) ); |
mbedtls_platform_zeroize( &RK, sizeof( RK ) ); |
return( 0 ); |
} |
#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
mbedtls_internal_aes_encrypt( ctx, input, output ); |
} |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/* |
* AES-ECB block decryption |
*/ |
#if !defined(MBEDTLS_AES_DECRYPT_ALT) |
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
int i; |
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; |
RK = ctx->rk; |
GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; |
GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; |
GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; |
GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; |
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) |
{ |
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); |
} |
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); |
X0 = *RK++ ^ \ |
( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ |
( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); |
X1 = *RK++ ^ \ |
( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ |
( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); |
X2 = *RK++ ^ \ |
( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ |
( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); |
X3 = *RK++ ^ \ |
( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ |
( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ |
( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ |
( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); |
PUT_UINT32_LE( X0, output, 0 ); |
PUT_UINT32_LE( X1, output, 4 ); |
PUT_UINT32_LE( X2, output, 8 ); |
PUT_UINT32_LE( X3, output, 12 ); |
mbedtls_platform_zeroize( &X0, sizeof( X0 ) ); |
mbedtls_platform_zeroize( &X1, sizeof( X1 ) ); |
mbedtls_platform_zeroize( &X2, sizeof( X2 ) ); |
mbedtls_platform_zeroize( &X3, sizeof( X3 ) ); |
mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) ); |
mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) ); |
mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) ); |
mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) ); |
mbedtls_platform_zeroize( &RK, sizeof( RK ) ); |
return( 0 ); |
} |
#endif /* !MBEDTLS_AES_DECRYPT_ALT */ |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
mbedtls_internal_aes_decrypt( ctx, input, output ); |
} |
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ |
/* |
* AES-ECB block encryption/decryption |
*/ |
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || |
mode == MBEDTLS_AES_DECRYPT ); |
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) |
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) |
return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); |
#endif |
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) |
if( aes_padlock_ace ) |
{ |
if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) |
return( 0 ); |
// If padlock data misaligned, we just fall back to |
// unaccelerated mode |
// |
} |
#endif |
if( mode == MBEDTLS_AES_ENCRYPT ) |
return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); |
else |
return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* AES-CBC buffer encryption/decryption |
*/ |
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int i; |
unsigned char temp[16]; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || |
mode == MBEDTLS_AES_DECRYPT ); |
AES_VALIDATE_RET( iv != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
if( length % 16 ) |
return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); |
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) |
if( aes_padlock_ace ) |
{ |
if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) |
return( 0 ); |
// If padlock data misaligned, we just fall back to |
// unaccelerated mode |
// |
} |
#endif |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, 16 ); |
mbedtls_aes_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] ); |
mbedtls_aes_crypt_ecb( ctx, mode, output, output ); |
memcpy( iv, output, 16 ); |
input += 16; |
output += 16; |
length -= 16; |
} |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/* Endianess with 64 bits values */ |
#ifndef GET_UINT64_LE |
#define GET_UINT64_LE(n,b,i) \ |
{ \ |
(n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ |
| ( (uint64_t) (b)[(i) + 6] << 48 ) \ |
| ( (uint64_t) (b)[(i) + 5] << 40 ) \ |
| ( (uint64_t) (b)[(i) + 4] << 32 ) \ |
| ( (uint64_t) (b)[(i) + 3] << 24 ) \ |
| ( (uint64_t) (b)[(i) + 2] << 16 ) \ |
| ( (uint64_t) (b)[(i) + 1] << 8 ) \ |
| ( (uint64_t) (b)[(i) ] ); \ |
} |
#endif |
#ifndef PUT_UINT64_LE |
#define PUT_UINT64_LE(n,b,i) \ |
{ \ |
(b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ |
(b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ |
(b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ |
(b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ |
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ |
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ |
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ |
(b)[(i) ] = (unsigned char) ( (n) ); \ |
} |
#endif |
typedef unsigned char mbedtls_be128[16]; |
/* |
* GF(2^128) multiplication function |
* |
* This function multiplies a field element by x in the polynomial field |
* representation. It uses 64-bit word operations to gain speed but compensates |
* for machine endianess and hence works correctly on both big and little |
* endian machines. |
*/ |
static void mbedtls_gf128mul_x_ble( unsigned char r[16], |
const unsigned char x[16] ) |
{ |
uint64_t a, b, ra, rb; |
GET_UINT64_LE( a, x, 0 ); |
GET_UINT64_LE( b, x, 8 ); |
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); |
rb = ( a >> 63 ) | ( b << 1 ); |
PUT_UINT64_LE( ra, r, 0 ); |
PUT_UINT64_LE( rb, r, 8 ); |
} |
/* |
* AES-XTS buffer encryption/decryption |
*/ |
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, |
int mode, |
size_t length, |
const unsigned char data_unit[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
size_t blocks = length / 16; |
size_t leftover = length % 16; |
unsigned char tweak[16]; |
unsigned char prev_tweak[16]; |
unsigned char tmp[16]; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || |
mode == MBEDTLS_AES_DECRYPT ); |
AES_VALIDATE_RET( data_unit != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
/* Data units must be at least 16 bytes long. */ |
if( length < 16 ) |
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; |
/* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ |
if( length > ( 1 << 20 ) * 16 ) |
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; |
/* Compute the tweak. */ |
ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, |
data_unit, tweak ); |
if( ret != 0 ) |
return( ret ); |
while( blocks-- ) |
{ |
size_t i; |
if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) |
{ |
/* We are on the last block in a decrypt operation that has |
* leftover bytes, so we need to use the next tweak for this block, |
* and this tweak for the lefover bytes. Save the current tweak for |
* the leftovers and then update the current tweak for use on this, |
* the last full block. */ |
memcpy( prev_tweak, tweak, sizeof( tweak ) ); |
mbedtls_gf128mul_x_ble( tweak, tweak ); |
} |
for( i = 0; i < 16; i++ ) |
tmp[i] = input[i] ^ tweak[i]; |
ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); |
if( ret != 0 ) |
return( ret ); |
for( i = 0; i < 16; i++ ) |
output[i] = tmp[i] ^ tweak[i]; |
/* Update the tweak for the next block. */ |
mbedtls_gf128mul_x_ble( tweak, tweak ); |
output += 16; |
input += 16; |
} |
if( leftover ) |
{ |
/* If we are on the leftover bytes in a decrypt operation, we need to |
* use the previous tweak for these bytes (as saved in prev_tweak). */ |
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; |
/* We are now on the final part of the data unit, which doesn't divide |
* evenly by 16. It's time for ciphertext stealing. */ |
size_t i; |
unsigned char *prev_output = output - 16; |
/* Copy ciphertext bytes from the previous block to our output for each |
* byte of cyphertext we won't steal. At the same time, copy the |
* remainder of the input for this final round (since the loop bounds |
* are the same). */ |
for( i = 0; i < leftover; i++ ) |
{ |
output[i] = prev_output[i]; |
tmp[i] = input[i] ^ t[i]; |
} |
/* Copy ciphertext bytes from the previous block for input in this |
* round. */ |
for( ; i < 16; i++ ) |
tmp[i] = prev_output[i] ^ t[i]; |
ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); |
if( ret != 0 ) |
return ret; |
/* Write the result back to the previous block, overriding the previous |
* output we copied. */ |
for( i = 0; i < 16; i++ ) |
prev_output[i] = tmp[i] ^ t[i]; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/* |
* AES-CFB128 buffer encryption/decryption |
*/ |
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c; |
size_t n; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || |
mode == MBEDTLS_AES_DECRYPT ); |
AES_VALIDATE_RET( iv_off != NULL ); |
AES_VALIDATE_RET( iv != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
n = *iv_off; |
if( n > 15 ) |
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
while( length-- ) |
{ |
if( n == 0 ) |
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_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 ) |
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); |
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); |
n = ( n + 1 ) & 0x0F; |
} |
} |
*iv_off = n; |
return( 0 ); |
} |
/* |
* AES-CFB8 buffer encryption/decryption |
*/ |
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
unsigned char c; |
unsigned char ov[17]; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || |
mode == MBEDTLS_AES_DECRYPT ); |
AES_VALIDATE_RET( iv != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
while( length-- ) |
{ |
memcpy( ov, iv, 16 ); |
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); |
if( mode == MBEDTLS_AES_DECRYPT ) |
ov[16] = *input; |
c = *output++ = (unsigned char)( iv[0] ^ *input++ ); |
if( mode == MBEDTLS_AES_ENCRYPT ) |
ov[16] = c; |
memcpy( iv, ov + 1, 16 ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
/* |
* AES-OFB (Output Feedback Mode) buffer encryption/decryption |
*/ |
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, |
size_t length, |
size_t *iv_off, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret = 0; |
size_t n; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( iv_off != NULL ); |
AES_VALIDATE_RET( iv != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
n = *iv_off; |
if( n > 15 ) |
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); |
while( length-- ) |
{ |
if( n == 0 ) |
{ |
ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); |
if( ret != 0 ) |
goto exit; |
} |
*output++ = *input++ ^ iv[n]; |
n = ( n + 1 ) & 0x0F; |
} |
*iv_off = n; |
exit: |
return( ret ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* AES-CTR buffer encryption/decryption |
*/ |
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[16], |
unsigned char stream_block[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c, i; |
size_t n; |
AES_VALIDATE_RET( ctx != NULL ); |
AES_VALIDATE_RET( nc_off != NULL ); |
AES_VALIDATE_RET( nonce_counter != NULL ); |
AES_VALIDATE_RET( stream_block != NULL ); |
AES_VALIDATE_RET( input != NULL ); |
AES_VALIDATE_RET( output != NULL ); |
n = *nc_off; |
if ( n > 0x0F ) |
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA ); |
while( length-- ) |
{ |
if( n == 0 ) { |
mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); |
for( i = 16; i > 0; i-- ) |
if( ++nonce_counter[i - 1] != 0 ) |
break; |
} |
c = *input++; |
*output++ = (unsigned char)( c ^ stream_block[n] ); |
n = ( n + 1 ) & 0x0F; |
} |
*nc_off = n; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#endif /* !MBEDTLS_AES_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* AES test vectors from: |
* |
* http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip |
*/ |
static const unsigned char aes_test_ecb_dec[3][16] = |
{ |
{ 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, |
0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, |
{ 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, |
0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, |
{ 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, |
0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } |
}; |
static const unsigned char aes_test_ecb_enc[3][16] = |
{ |
{ 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, |
0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, |
{ 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, |
0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, |
{ 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, |
0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const unsigned char aes_test_cbc_dec[3][16] = |
{ |
{ 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, |
0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, |
{ 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, |
0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, |
{ 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, |
0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } |
}; |
static const unsigned char aes_test_cbc_enc[3][16] = |
{ |
{ 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, |
0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, |
{ 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, |
0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, |
{ 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, |
0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/* |
* AES-CFB128 test vectors from: |
* |
* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf |
*/ |
static const unsigned char aes_test_cfb128_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 aes_test_cfb128_iv[16] = |
{ |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F |
}; |
static const unsigned char aes_test_cfb128_pt[64] = |
{ |
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, |
0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, |
0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 |
}; |
static const unsigned char aes_test_cfb128_ct[3][64] = |
{ |
{ 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, |
0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, |
0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, |
0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, |
0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, |
0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, |
0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, |
0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, |
{ 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, |
0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, |
0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, |
0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, |
0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, |
0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, |
0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, |
0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, |
{ 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, |
0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, |
0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, |
0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, |
0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, |
0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, |
0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, |
0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
/* |
* AES-OFB test vectors from: |
* |
* https://csrc.nist.gov/publications/detail/sp/800-38a/final |
*/ |
static const unsigned char aes_test_ofb_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 aes_test_ofb_iv[16] = |
{ |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F |
}; |
static const unsigned char aes_test_ofb_pt[64] = |
{ |
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, |
0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, |
0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 |
}; |
static const unsigned char aes_test_ofb_ct[3][64] = |
{ |
{ 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, |
0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, |
0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, |
0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, |
0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, |
0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, |
0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, |
0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, |
{ 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, |
0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, |
0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, |
0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, |
0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, |
0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, |
0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, |
0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, |
{ 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, |
0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, |
0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, |
0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, |
0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, |
0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, |
0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, |
0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* AES-CTR test vectors from: |
* |
* http://www.faqs.org/rfcs/rfc3686.html |
*/ |
static const unsigned char aes_test_ctr_key[3][16] = |
{ |
{ 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, |
0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, |
{ 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, |
0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, |
{ 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, |
0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } |
}; |
static const unsigned char aes_test_ctr_nonce_counter[3][16] = |
{ |
{ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, |
{ 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, |
0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, |
{ 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, |
0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } |
}; |
static const unsigned char aes_test_ctr_pt[3][48] = |
{ |
{ 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, |
0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, |
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, |
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, |
0x20, 0x21, 0x22, 0x23 } |
}; |
static const unsigned char aes_test_ctr_ct[3][48] = |
{ |
{ 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, |
0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, |
{ 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, |
0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, |
0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, |
0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, |
{ 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, |
0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, |
0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, |
0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, |
0x25, 0xB2, 0x07, 0x2F } |
}; |
static const int aes_test_ctr_len[3] = |
{ 16, 32, 36 }; |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
/* |
* AES-XTS test vectors from: |
* |
* IEEE P1619/D16 Annex B |
* https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf |
* (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) |
*/ |
static const unsigned char aes_test_xts_key[][32] = |
{ |
{ 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 }, |
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, |
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, |
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, |
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, |
{ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, |
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, |
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, |
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, |
}; |
static const unsigned char aes_test_xts_pt32[][32] = |
{ |
{ 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 }, |
{ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, |
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, |
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, |
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, |
{ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, |
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, |
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, |
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, |
}; |
static const unsigned char aes_test_xts_ct32[][32] = |
{ |
{ 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, |
0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, |
0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, |
0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, |
{ 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, |
0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, |
0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, |
0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, |
{ 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, |
0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, |
0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, |
0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, |
}; |
static const unsigned char aes_test_xts_data_unit[][16] = |
{ |
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
}; |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
/* |
* Checkup routine |
*/ |
int mbedtls_aes_self_test( int verbose ) |
{ |
int ret = 0, i, j, u, mode; |
unsigned int keybits; |
unsigned char key[32]; |
unsigned char buf[64]; |
const unsigned char *aes_tests; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) |
unsigned char iv[16]; |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
unsigned char prv[16]; |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ |
defined(MBEDTLS_CIPHER_MODE_OFB) |
size_t offset; |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) |
int len; |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
unsigned char nonce_counter[16]; |
unsigned char stream_block[16]; |
#endif |
mbedtls_aes_context ctx; |
memset( key, 0, 32 ); |
mbedtls_aes_init( &ctx ); |
/* |
* ECB mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
keybits = 128 + u * 64; |
mode = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " AES-ECB-%3d (%s): ", keybits, |
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); |
memset( buf, 0, 16 ); |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); |
aes_tests = aes_test_ecb_dec[u]; |
} |
else |
{ |
ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); |
aes_tests = aes_test_ecb_enc[u]; |
} |
/* |
* AES-192 is an optional feature that may be unavailable when |
* there is an alternative underlying implementation i.e. when |
* MBEDTLS_AES_ALT is defined. |
*/ |
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) |
{ |
mbedtls_printf( "skipped\n" ); |
continue; |
} |
else if( ret != 0 ) |
{ |
goto exit; |
} |
for( j = 0; j < 10000; j++ ) |
{ |
ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf ); |
if( ret != 0 ) |
goto exit; |
} |
if( memcmp( buf, aes_tests, 16 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* CBC mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
keybits = 128 + u * 64; |
mode = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " AES-CBC-%3d (%s): ", keybits, |
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); |
memset( iv , 0, 16 ); |
memset( prv, 0, 16 ); |
memset( buf, 0, 16 ); |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
ret = mbedtls_aes_setkey_dec( &ctx, key, keybits ); |
aes_tests = aes_test_cbc_dec[u]; |
} |
else |
{ |
ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); |
aes_tests = aes_test_cbc_enc[u]; |
} |
/* |
* AES-192 is an optional feature that may be unavailable when |
* there is an alternative underlying implementation i.e. when |
* MBEDTLS_AES_ALT is defined. |
*/ |
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) |
{ |
mbedtls_printf( "skipped\n" ); |
continue; |
} |
else if( ret != 0 ) |
{ |
goto exit; |
} |
for( j = 0; j < 10000; j++ ) |
{ |
if( mode == MBEDTLS_AES_ENCRYPT ) |
{ |
unsigned char tmp[16]; |
memcpy( tmp, prv, 16 ); |
memcpy( prv, buf, 16 ); |
memcpy( buf, tmp, 16 ); |
} |
ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf ); |
if( ret != 0 ) |
goto exit; |
} |
if( memcmp( buf, aes_tests, 16 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/* |
* CFB128 mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
keybits = 128 + u * 64; |
mode = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits, |
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); |
memcpy( iv, aes_test_cfb128_iv, 16 ); |
memcpy( key, aes_test_cfb128_key[u], keybits / 8 ); |
offset = 0; |
ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); |
/* |
* AES-192 is an optional feature that may be unavailable when |
* there is an alternative underlying implementation i.e. when |
* MBEDTLS_AES_ALT is defined. |
*/ |
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) |
{ |
mbedtls_printf( "skipped\n" ); |
continue; |
} |
else if( ret != 0 ) |
{ |
goto exit; |
} |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
memcpy( buf, aes_test_cfb128_ct[u], 64 ); |
aes_tests = aes_test_cfb128_pt; |
} |
else |
{ |
memcpy( buf, aes_test_cfb128_pt, 64 ); |
aes_tests = aes_test_cfb128_ct[u]; |
} |
ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, aes_tests, 64 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
/* |
* OFB mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
keybits = 128 + u * 64; |
mode = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, |
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); |
memcpy( iv, aes_test_ofb_iv, 16 ); |
memcpy( key, aes_test_ofb_key[u], keybits / 8 ); |
offset = 0; |
ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); |
/* |
* AES-192 is an optional feature that may be unavailable when |
* there is an alternative underlying implementation i.e. when |
* MBEDTLS_AES_ALT is defined. |
*/ |
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 ) |
{ |
mbedtls_printf( "skipped\n" ); |
continue; |
} |
else if( ret != 0 ) |
{ |
goto exit; |
} |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
memcpy( buf, aes_test_ofb_ct[u], 64 ); |
aes_tests = aes_test_ofb_pt; |
} |
else |
{ |
memcpy( buf, aes_test_ofb_pt, 64 ); |
aes_tests = aes_test_ofb_ct[u]; |
} |
ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, aes_tests, 64 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* CTR mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
mode = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " AES-CTR-128 (%s): ", |
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); |
memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); |
memcpy( key, aes_test_ctr_key[u], 16 ); |
offset = 0; |
if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 ) |
goto exit; |
len = aes_test_ctr_len[u]; |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
memcpy( buf, aes_test_ctr_ct[u], len ); |
aes_tests = aes_test_ctr_pt[u]; |
} |
else |
{ |
memcpy( buf, aes_test_ctr_pt[u], len ); |
aes_tests = aes_test_ctr_ct[u]; |
} |
ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, |
stream_block, buf, buf ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, aes_tests, len ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
{ |
static const int num_tests = |
sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); |
mbedtls_aes_xts_context ctx_xts; |
/* |
* XTS mode |
*/ |
mbedtls_aes_xts_init( &ctx_xts ); |
for( i = 0; i < num_tests << 1; i++ ) |
{ |
const unsigned char *data_unit; |
u = i >> 1; |
mode = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " AES-XTS-128 (%s): ", |
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); |
memset( key, 0, sizeof( key ) ); |
memcpy( key, aes_test_xts_key[u], 32 ); |
data_unit = aes_test_xts_data_unit[u]; |
len = sizeof( *aes_test_xts_ct32 ); |
if( mode == MBEDTLS_AES_DECRYPT ) |
{ |
ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); |
if( ret != 0) |
goto exit; |
memcpy( buf, aes_test_xts_ct32[u], len ); |
aes_tests = aes_test_xts_pt32[u]; |
} |
else |
{ |
ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); |
if( ret != 0) |
goto exit; |
memcpy( buf, aes_test_xts_pt32[u], len ); |
aes_tests = aes_test_xts_ct32[u]; |
} |
ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, |
buf, buf ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, aes_tests, len ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
mbedtls_aes_xts_free( &ctx_xts ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
ret = 0; |
exit: |
if( ret != 0 && verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
mbedtls_aes_free( &ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_AES_C */ |
/programs/develop/libraries/kos_mbedtls/library/aesni.c |
---|
0,0 → 1,472 |
/* |
* AES-NI support functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set |
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_AESNI_C) |
#if defined(__has_feature) |
#if __has_feature(memory_sanitizer) |
#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code." |
#endif |
#endif |
#include "mbedtls/aesni.h" |
#include <string.h> |
#ifndef asm |
#define asm __asm |
#endif |
#if defined(MBEDTLS_HAVE_X86_64) |
/* |
* AES-NI support detection routine |
*/ |
int mbedtls_aesni_has_support( unsigned int what ) |
{ |
static int done = 0; |
static unsigned int c = 0; |
if( ! done ) |
{ |
asm( "movl $1, %%eax \n\t" |
"cpuid \n\t" |
: "=c" (c) |
: |
: "eax", "ebx", "edx" ); |
done = 1; |
} |
return( ( c & what ) != 0 ); |
} |
/* |
* Binutils needs to be at least 2.19 to support AES-NI instructions. |
* Unfortunately, a lot of users have a lower version now (2014-04). |
* Emit bytecode directly in order to support "old" version of gas. |
* |
* Opcodes from the Intel architecture reference manual, vol. 3. |
* We always use registers, so we don't need prefixes for memory operands. |
* Operand macros are in gas order (src, dst) as opposed to Intel order |
* (dst, src) in order to blend better into the surrounding assembly code. |
*/ |
#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," |
#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," |
#define AESENC ".byte 0x66,0x0F,0x38,0xDC," |
#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," |
#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," |
#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," |
#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," |
#define xmm0_xmm0 "0xC0" |
#define xmm0_xmm1 "0xC8" |
#define xmm0_xmm2 "0xD0" |
#define xmm0_xmm3 "0xD8" |
#define xmm0_xmm4 "0xE0" |
#define xmm1_xmm0 "0xC1" |
#define xmm1_xmm2 "0xD1" |
/* |
* AES-NI AES-ECB block en(de)cryption |
*/ |
int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
asm( "movdqu (%3), %%xmm0 \n\t" // load input |
"movdqu (%1), %%xmm1 \n\t" // load round key 0 |
"pxor %%xmm1, %%xmm0 \n\t" // round 0 |
"add $16, %1 \n\t" // point to next round key |
"subl $1, %0 \n\t" // normal rounds = nr - 1 |
"test %2, %2 \n\t" // mode? |
"jz 2f \n\t" // 0 = decrypt |
"1: \n\t" // encryption loop |
"movdqu (%1), %%xmm1 \n\t" // load round key |
AESENC xmm1_xmm0 "\n\t" // do round |
"add $16, %1 \n\t" // point to next round key |
"subl $1, %0 \n\t" // loop |
"jnz 1b \n\t" |
"movdqu (%1), %%xmm1 \n\t" // load round key |
AESENCLAST xmm1_xmm0 "\n\t" // last round |
"jmp 3f \n\t" |
"2: \n\t" // decryption loop |
"movdqu (%1), %%xmm1 \n\t" |
AESDEC xmm1_xmm0 "\n\t" // do round |
"add $16, %1 \n\t" |
"subl $1, %0 \n\t" |
"jnz 2b \n\t" |
"movdqu (%1), %%xmm1 \n\t" // load round key |
AESDECLAST xmm1_xmm0 "\n\t" // last round |
"3: \n\t" |
"movdqu %%xmm0, (%4) \n\t" // export output |
: |
: "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) |
: "memory", "cc", "xmm0", "xmm1" ); |
return( 0 ); |
} |
/* |
* GCM multiplication: c = a times b in GF(2^128) |
* Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. |
*/ |
void mbedtls_aesni_gcm_mult( unsigned char c[16], |
const unsigned char a[16], |
const unsigned char b[16] ) |
{ |
unsigned char aa[16], bb[16], cc[16]; |
size_t i; |
/* The inputs are in big-endian order, so byte-reverse them */ |
for( i = 0; i < 16; i++ ) |
{ |
aa[i] = a[15 - i]; |
bb[i] = b[15 - i]; |
} |
asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 |
"movdqu (%1), %%xmm1 \n\t" // b1:b0 |
/* |
* Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 |
* using [CLMUL-WP] algorithm 1 (p. 13). |
*/ |
"movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 |
"movdqa %%xmm1, %%xmm3 \n\t" // same |
"movdqa %%xmm1, %%xmm4 \n\t" // same |
PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 |
PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 |
PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 |
PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 |
"pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 |
"movdqa %%xmm4, %%xmm3 \n\t" // same |
"psrldq $8, %%xmm4 \n\t" // 0:e1+f1 |
"pslldq $8, %%xmm3 \n\t" // e0+f0:0 |
"pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 |
"pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 |
/* |
* Now shift the result one bit to the left, |
* taking advantage of [CLMUL-WP] eq 27 (p. 20) |
*/ |
"movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 |
"movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 |
"psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 |
"psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 |
"psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 |
"psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 |
"movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 |
"pslldq $8, %%xmm3 \n\t" // r0>>63:0 |
"pslldq $8, %%xmm4 \n\t" // r2>>63:0 |
"psrldq $8, %%xmm5 \n\t" // 0:r1>>63 |
"por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 |
"por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 |
"por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 |
/* |
* Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 |
* using [CLMUL-WP] algorithm 5 (p. 20). |
* Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). |
*/ |
/* Step 2 (1) */ |
"movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 |
"movdqa %%xmm1, %%xmm4 \n\t" // same |
"movdqa %%xmm1, %%xmm5 \n\t" // same |
"psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a |
"psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b |
"psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c |
/* Step 2 (2) */ |
"pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b |
"pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c |
"pslldq $8, %%xmm3 \n\t" // a+b+c:0 |
"pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 |
/* Steps 3 and 4 */ |
"movdqa %%xmm1,%%xmm0 \n\t" // d:x0 |
"movdqa %%xmm1,%%xmm4 \n\t" // same |
"movdqa %%xmm1,%%xmm5 \n\t" // same |
"psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' |
"psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' |
"psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' |
"pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' |
"pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' |
// e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing |
// bits carried from d. Now get those\t bits back in. |
"movdqa %%xmm1,%%xmm3 \n\t" // d:x0 |
"movdqa %%xmm1,%%xmm4 \n\t" // same |
"movdqa %%xmm1,%%xmm5 \n\t" // same |
"psllq $63, %%xmm3 \n\t" // d<<63:stuff |
"psllq $62, %%xmm4 \n\t" // d<<62:stuff |
"psllq $57, %%xmm5 \n\t" // d<<57:stuff |
"pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff |
"pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff |
"psrldq $8, %%xmm3 \n\t" // 0:missing bits of d |
"pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 |
"pxor %%xmm1, %%xmm0 \n\t" // h1:h0 |
"pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 |
"movdqu %%xmm0, (%2) \n\t" // done |
: |
: "r" (aa), "r" (bb), "r" (cc) |
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); |
/* Now byte-reverse the outputs */ |
for( i = 0; i < 16; i++ ) |
c[i] = cc[15 - i]; |
return; |
} |
/* |
* Compute decryption round keys from encryption round keys |
*/ |
void mbedtls_aesni_inverse_key( unsigned char *invkey, |
const unsigned char *fwdkey, int nr ) |
{ |
unsigned char *ik = invkey; |
const unsigned char *fk = fwdkey + 16 * nr; |
memcpy( ik, fk, 16 ); |
for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) |
asm( "movdqu (%0), %%xmm0 \n\t" |
AESIMC xmm0_xmm0 "\n\t" |
"movdqu %%xmm0, (%1) \n\t" |
: |
: "r" (fk), "r" (ik) |
: "memory", "xmm0" ); |
memcpy( ik, fk, 16 ); |
} |
/* |
* Key expansion, 128-bit case |
*/ |
static void aesni_setkey_enc_128( unsigned char *rk, |
const unsigned char *key ) |
{ |
asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key |
"movdqu %%xmm0, (%0) \n\t" // as round key 0 |
"jmp 2f \n\t" // skip auxiliary routine |
/* |
* Finish generating the next round key. |
* |
* On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff |
* with X = rot( sub( r3 ) ) ^ RCON. |
* |
* On exit, xmm0 is r7:r6:r5:r4 |
* with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 |
* and those are written to the round key buffer. |
*/ |
"1: \n\t" |
"pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X |
"pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 |
"pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 |
"pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 |
"pslldq $4, %%xmm0 \n\t" // etc |
"pxor %%xmm0, %%xmm1 \n\t" |
"pslldq $4, %%xmm0 \n\t" |
"pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! |
"add $16, %0 \n\t" // point to next round key |
"movdqu %%xmm0, (%0) \n\t" // write it |
"ret \n\t" |
/* Main "loop" */ |
"2: \n\t" |
AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" |
AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" |
: |
: "r" (rk), "r" (key) |
: "memory", "cc", "0" ); |
} |
/* |
* Key expansion, 192-bit case |
*/ |
static void aesni_setkey_enc_192( unsigned char *rk, |
const unsigned char *key ) |
{ |
asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key |
"movdqu %%xmm0, (%0) \n\t" |
"add $16, %0 \n\t" |
"movq 16(%1), %%xmm1 \n\t" |
"movq %%xmm1, (%0) \n\t" |
"add $8, %0 \n\t" |
"jmp 2f \n\t" // skip auxiliary routine |
/* |
* Finish generating the next 6 quarter-keys. |
* |
* On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 |
* and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. |
* |
* On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 |
* and those are written to the round key buffer. |
*/ |
"1: \n\t" |
"pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X |
"pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 |
"pslldq $4, %%xmm0 \n\t" // etc |
"pxor %%xmm0, %%xmm2 \n\t" |
"pslldq $4, %%xmm0 \n\t" |
"pxor %%xmm0, %%xmm2 \n\t" |
"pslldq $4, %%xmm0 \n\t" |
"pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 |
"movdqu %%xmm0, (%0) \n\t" |
"add $16, %0 \n\t" |
"pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 |
"pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 |
"pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 |
"pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 |
"movq %%xmm1, (%0) \n\t" |
"add $8, %0 \n\t" |
"ret \n\t" |
"2: \n\t" |
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" |
: |
: "r" (rk), "r" (key) |
: "memory", "cc", "0" ); |
} |
/* |
* Key expansion, 256-bit case |
*/ |
static void aesni_setkey_enc_256( unsigned char *rk, |
const unsigned char *key ) |
{ |
asm( "movdqu (%1), %%xmm0 \n\t" |
"movdqu %%xmm0, (%0) \n\t" |
"add $16, %0 \n\t" |
"movdqu 16(%1), %%xmm1 \n\t" |
"movdqu %%xmm1, (%0) \n\t" |
"jmp 2f \n\t" // skip auxiliary routine |
/* |
* Finish generating the next two round keys. |
* |
* On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and |
* xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON |
* |
* On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 |
* and those have been written to the output buffer. |
*/ |
"1: \n\t" |
"pshufd $0xff, %%xmm2, %%xmm2 \n\t" |
"pxor %%xmm0, %%xmm2 \n\t" |
"pslldq $4, %%xmm0 \n\t" |
"pxor %%xmm0, %%xmm2 \n\t" |
"pslldq $4, %%xmm0 \n\t" |
"pxor %%xmm0, %%xmm2 \n\t" |
"pslldq $4, %%xmm0 \n\t" |
"pxor %%xmm2, %%xmm0 \n\t" |
"add $16, %0 \n\t" |
"movdqu %%xmm0, (%0) \n\t" |
/* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) |
* and proceed to generate next round key from there */ |
AESKEYGENA xmm0_xmm2 ",0x00 \n\t" |
"pshufd $0xaa, %%xmm2, %%xmm2 \n\t" |
"pxor %%xmm1, %%xmm2 \n\t" |
"pslldq $4, %%xmm1 \n\t" |
"pxor %%xmm1, %%xmm2 \n\t" |
"pslldq $4, %%xmm1 \n\t" |
"pxor %%xmm1, %%xmm2 \n\t" |
"pslldq $4, %%xmm1 \n\t" |
"pxor %%xmm2, %%xmm1 \n\t" |
"add $16, %0 \n\t" |
"movdqu %%xmm1, (%0) \n\t" |
"ret \n\t" |
/* |
* Main "loop" - Generating one more key than necessary, |
* see definition of mbedtls_aes_context.buf |
*/ |
"2: \n\t" |
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" |
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" |
: |
: "r" (rk), "r" (key) |
: "memory", "cc", "0" ); |
} |
/* |
* Key expansion, wrapper |
*/ |
int mbedtls_aesni_setkey_enc( unsigned char *rk, |
const unsigned char *key, |
size_t bits ) |
{ |
switch( bits ) |
{ |
case 128: aesni_setkey_enc_128( rk, key ); break; |
case 192: aesni_setkey_enc_192( rk, key ); break; |
case 256: aesni_setkey_enc_256( rk, key ); break; |
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_HAVE_X86_64 */ |
#endif /* MBEDTLS_AESNI_C */ |
/programs/develop/libraries/kos_mbedtls/library/arc4.c |
---|
0,0 → 1,203 |
/* |
* An implementation of the ARCFOUR algorithm |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The ARCFOUR algorithm was publicly disclosed on 94/09. |
* |
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ARC4_C) |
#include "mbedtls/arc4.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_ARC4_ALT) |
void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_arc4_context ) ); |
} |
void mbedtls_arc4_free( mbedtls_arc4_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) ); |
} |
/* |
* ARC4 key schedule |
*/ |
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, |
unsigned int keylen ) |
{ |
int i, j, a; |
unsigned int k; |
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 mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, |
unsigned char *output ) |
{ |
int x, y, a, b; |
size_t i; |
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 ); |
} |
#endif /* !MBEDTLS_ARC4_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* 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 mbedtls_arc4_self_test( int verbose ) |
{ |
int i, ret = 0; |
unsigned char ibuf[8]; |
unsigned char obuf[8]; |
mbedtls_arc4_context ctx; |
mbedtls_arc4_init( &ctx ); |
for( i = 0; i < 3; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " ARC4 test #%d: ", i + 1 ); |
memcpy( ibuf, arc4_test_pt[i], 8 ); |
mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 ); |
mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf ); |
if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
exit: |
mbedtls_arc4_free( &ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_ARC4_C */ |
/programs/develop/libraries/kos_mbedtls/library/aria.c |
---|
0,0 → 1,1081 |
/* |
* ARIA implementation |
* |
* Copyright (C) 2006-2017, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* This implementation is based on the following standards: |
* [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf |
* [2] https://tools.ietf.org/html/rfc5794 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ARIA_C) |
#include "mbedtls/aria.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_ARIA_ALT) |
#include "mbedtls/platform_util.h" |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
/* Parameter validation macros */ |
#define ARIA_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ) |
#define ARIA_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* 32-bit integer manipulation macros (little endian) |
*/ |
#ifndef GET_UINT32_LE |
#define GET_UINT32_LE( n, b, i ) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] ) \ |
| ( (uint32_t) (b)[(i) + 1] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 3] << 24 ); \ |
} |
#endif |
#ifndef PUT_UINT32_LE |
#define PUT_UINT32_LE( n, b, i ) \ |
{ \ |
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ |
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ |
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ |
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ |
} |
#endif |
/* |
* modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes |
* |
* This is submatrix P1 in [1] Appendix B.1 |
* |
* Common compilers fail to translate this to minimal number of instructions, |
* so let's provide asm versions for common platforms with C fallback. |
*/ |
#if defined(MBEDTLS_HAVE_ASM) |
#if defined(__arm__) /* rev16 available from v6 up */ |
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ |
#if defined(__GNUC__) && \ |
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ |
__ARM_ARCH >= 6 |
static inline uint32_t aria_p1( uint32_t x ) |
{ |
uint32_t r; |
__asm( "rev16 %0, %1" : "=l" (r) : "l" (x) ); |
return( r ); |
} |
#define ARIA_P1 aria_p1 |
#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ |
( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) |
static inline uint32_t aria_p1( uint32_t x ) |
{ |
uint32_t r; |
__asm( "rev16 r, x" ); |
return( r ); |
} |
#define ARIA_P1 aria_p1 |
#endif |
#endif /* arm */ |
#if defined(__GNUC__) && \ |
defined(__i386__) || defined(__amd64__) || defined( __x86_64__) |
/* I couldn't find an Intel equivalent of rev16, so two instructions */ |
#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) ) |
#endif /* x86 gnuc */ |
#endif /* MBEDTLS_HAVE_ASM && GNUC */ |
#if !defined(ARIA_P1) |
#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8)) |
#endif |
/* |
* modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits |
* |
* This is submatrix P2 in [1] Appendix B.1 |
* |
* Common compilers will translate this to a single instruction. |
*/ |
#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16)) |
/* |
* modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness |
* |
* This is submatrix P3 in [1] Appendix B.1 |
* |
* Some compilers fail to translate this to a single instruction, |
* so let's provide asm versions for common platforms with C fallback. |
*/ |
#if defined(MBEDTLS_HAVE_ASM) |
#if defined(__arm__) /* rev available from v6 up */ |
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ |
#if defined(__GNUC__) && \ |
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \ |
__ARM_ARCH >= 6 |
static inline uint32_t aria_p3( uint32_t x ) |
{ |
uint32_t r; |
__asm( "rev %0, %1" : "=l" (r) : "l" (x) ); |
return( r ); |
} |
#define ARIA_P3 aria_p3 |
#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ |
( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 ) |
static inline uint32_t aria_p3( uint32_t x ) |
{ |
uint32_t r; |
__asm( "rev r, x" ); |
return( r ); |
} |
#define ARIA_P3 aria_p3 |
#endif |
#endif /* arm */ |
#if defined(__GNUC__) && \ |
defined(__i386__) || defined(__amd64__) || defined( __x86_64__) |
static inline uint32_t aria_p3( uint32_t x ) |
{ |
__asm( "bswap %0" : "=r" (x) : "0" (x) ); |
return( x ); |
} |
#define ARIA_P3 aria_p3 |
#endif /* x86 gnuc */ |
#endif /* MBEDTLS_HAVE_ASM && GNUC */ |
#if !defined(ARIA_P3) |
#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) ) |
#endif |
/* |
* ARIA Affine Transform |
* (a, b, c, d) = state in/out |
* |
* If we denote the first byte of input by 0, ..., the last byte by f, |
* then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef. |
* |
* Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple |
* rearrangements on adjacent pairs, output is: |
* |
* a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe |
* = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd |
* b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd |
* = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc |
* c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe |
* = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc |
* d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef |
* = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef |
* |
* Note: another presentation of the A transform can be found as the first |
* half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4. |
* The implementation below uses only P1 and P2 as they are sufficient. |
*/ |
static inline void aria_a( uint32_t *a, uint32_t *b, |
uint32_t *c, uint32_t *d ) |
{ |
uint32_t ta, tb, tc; |
ta = *b; // 4567 |
*b = *a; // 0123 |
*a = ARIA_P2( ta ); // 6745 |
tb = ARIA_P2( *d ); // efcd |
*d = ARIA_P1( *c ); // 98ba |
*c = ARIA_P1( tb ); // fedc |
ta ^= *d; // 4567+98ba |
tc = ARIA_P2( *b ); // 2301 |
ta = ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc |
tb ^= ARIA_P2( *d ); // ba98+efcd |
tc ^= ARIA_P1( *a ); // 2301+7654 |
*b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT |
tb = ARIA_P2( tb ) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc |
*a ^= ARIA_P1( tb ); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT |
ta = ARIA_P2( ta ); // 0123+7654+ab89+dcfe |
*d ^= ARIA_P1( ta ) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT |
tc = ARIA_P2( tc ); // 0123+5476 |
*c ^= ARIA_P1( tc ) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT |
} |
/* |
* ARIA Substitution Layer SL1 / SL2 |
* (a, b, c, d) = state in/out |
* (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below) |
* |
* By passing sb1, sb2, is1, is2 as S-Boxes you get SL1 |
* By passing is1, is2, sb1, sb2 as S-Boxes you get SL2 |
*/ |
static inline void aria_sl( uint32_t *a, uint32_t *b, |
uint32_t *c, uint32_t *d, |
const uint8_t sa[256], const uint8_t sb[256], |
const uint8_t sc[256], const uint8_t sd[256] ) |
{ |
*a = ( (uint32_t) sa[ *a & 0xFF] ) ^ |
(((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^ |
(((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^ |
(((uint32_t) sd[ *a >> 24 ]) << 24); |
*b = ( (uint32_t) sa[ *b & 0xFF] ) ^ |
(((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^ |
(((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^ |
(((uint32_t) sd[ *b >> 24 ]) << 24); |
*c = ( (uint32_t) sa[ *c & 0xFF] ) ^ |
(((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^ |
(((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^ |
(((uint32_t) sd[ *c >> 24 ]) << 24); |
*d = ( (uint32_t) sa[ *d & 0xFF] ) ^ |
(((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^ |
(((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^ |
(((uint32_t) sd[ *d >> 24 ]) << 24); |
} |
/* |
* S-Boxes |
*/ |
static const uint8_t aria_sb1[256] = |
{ |
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, |
0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, |
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, |
0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, |
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, |
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, |
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, |
0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, |
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, |
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, |
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, |
0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, |
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, |
0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, |
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, |
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, |
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, |
0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, |
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, |
0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, |
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, |
0xB0, 0x54, 0xBB, 0x16 |
}; |
static const uint8_t aria_sb2[256] = |
{ |
0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, |
0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, |
0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B, |
0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB, |
0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, |
0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, |
0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, |
0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, |
0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, |
0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, |
0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD, |
0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC, |
0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, |
0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, |
0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5, |
0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8, |
0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, |
0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, |
0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, |
0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, |
0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, |
0xAF, 0xBA, 0xB5, 0x81 |
}; |
static const uint8_t aria_is1[256] = |
{ |
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, |
0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, |
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, |
0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, |
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, |
0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, |
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, |
0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, |
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, |
0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, |
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, |
0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, |
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, |
0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, |
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, |
0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, |
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, |
0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, |
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, |
0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, |
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, |
0x55, 0x21, 0x0C, 0x7D |
}; |
static const uint8_t aria_is2[256] = |
{ |
0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, |
0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, |
0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89, |
0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D, |
0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, |
0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, |
0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, |
0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, |
0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, |
0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, |
0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55, |
0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A, |
0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, |
0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, |
0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6, |
0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5, |
0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, |
0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, |
0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, |
0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, |
0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, |
0x03, 0xA2, 0xAC, 0x60 |
}; |
/* |
* Helper for key schedule: r = FO( p, k ) ^ x |
*/ |
static void aria_fo_xor( uint32_t r[4], const uint32_t p[4], |
const uint32_t k[4], const uint32_t x[4] ) |
{ |
uint32_t a, b, c, d; |
a = p[0] ^ k[0]; |
b = p[1] ^ k[1]; |
c = p[2] ^ k[2]; |
d = p[3] ^ k[3]; |
aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); |
aria_a( &a, &b, &c, &d ); |
r[0] = a ^ x[0]; |
r[1] = b ^ x[1]; |
r[2] = c ^ x[2]; |
r[3] = d ^ x[3]; |
} |
/* |
* Helper for key schedule: r = FE( p, k ) ^ x |
*/ |
static void aria_fe_xor( uint32_t r[4], const uint32_t p[4], |
const uint32_t k[4], const uint32_t x[4] ) |
{ |
uint32_t a, b, c, d; |
a = p[0] ^ k[0]; |
b = p[1] ^ k[1]; |
c = p[2] ^ k[2]; |
d = p[3] ^ k[3]; |
aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); |
aria_a( &a, &b, &c, &d ); |
r[0] = a ^ x[0]; |
r[1] = b ^ x[1]; |
r[2] = c ^ x[2]; |
r[3] = d ^ x[3]; |
} |
/* |
* Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup. |
* |
* We chose to store bytes into 32-bit words in little-endian format (see |
* GET/PUT_UINT32_LE) so we need to reverse bytes here. |
*/ |
static void aria_rot128( uint32_t r[4], const uint32_t a[4], |
const uint32_t b[4], uint8_t n ) |
{ |
uint8_t i, j; |
uint32_t t, u; |
const uint8_t n1 = n % 32; // bit offset |
const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset |
j = ( n / 32 ) % 4; // initial word offset |
t = ARIA_P3( b[j] ); // big endian |
for( i = 0; i < 4; i++ ) |
{ |
j = ( j + 1 ) % 4; // get next word, big endian |
u = ARIA_P3( b[j] ); |
t <<= n1; // rotate |
t |= u >> n2; |
t = ARIA_P3( t ); // back to little endian |
r[i] = a[i] ^ t; // store |
t = u; // move to next word |
} |
} |
/* |
* Set encryption key |
*/ |
int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx, |
const unsigned char *key, unsigned int keybits ) |
{ |
/* round constant masks */ |
const uint32_t rc[3][4] = |
{ |
{ 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA }, |
{ 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF }, |
{ 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 } |
}; |
int i; |
uint32_t w[4][4], *w2; |
ARIA_VALIDATE_RET( ctx != NULL ); |
ARIA_VALIDATE_RET( key != NULL ); |
if( keybits != 128 && keybits != 192 && keybits != 256 ) |
return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); |
/* Copy key to W0 (and potential remainder to W1) */ |
GET_UINT32_LE( w[0][0], key, 0 ); |
GET_UINT32_LE( w[0][1], key, 4 ); |
GET_UINT32_LE( w[0][2], key, 8 ); |
GET_UINT32_LE( w[0][3], key, 12 ); |
memset( w[1], 0, 16 ); |
if( keybits >= 192 ) |
{ |
GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key |
GET_UINT32_LE( w[1][1], key, 20 ); |
} |
if( keybits == 256 ) |
{ |
GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key |
GET_UINT32_LE( w[1][3], key, 28 ); |
} |
i = ( keybits - 128 ) >> 6; // index: 0, 1, 2 |
ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16 |
aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR |
i = i < 2 ? i + 1 : 0; |
aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0 |
i = i < 2 ? i + 1 : 0; |
aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1 |
for( i = 0; i < 4; i++ ) // create round keys |
{ |
w2 = w[(i + 1) & 3]; |
aria_rot128( ctx->rk[i ], w[i], w2, 128 - 19 ); |
aria_rot128( ctx->rk[i + 4], w[i], w2, 128 - 31 ); |
aria_rot128( ctx->rk[i + 8], w[i], w2, 61 ); |
aria_rot128( ctx->rk[i + 12], w[i], w2, 31 ); |
} |
aria_rot128( ctx->rk[16], w[0], w[1], 19 ); |
/* w holds enough info to reconstruct the round keys */ |
mbedtls_platform_zeroize( w, sizeof( w ) ); |
return( 0 ); |
} |
/* |
* Set decryption key |
*/ |
int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx, |
const unsigned char *key, unsigned int keybits ) |
{ |
int i, j, k, ret; |
ARIA_VALIDATE_RET( ctx != NULL ); |
ARIA_VALIDATE_RET( key != NULL ); |
ret = mbedtls_aria_setkey_enc( ctx, key, keybits ); |
if( ret != 0 ) |
return( ret ); |
/* flip the order of round keys */ |
for( i = 0, j = ctx->nr; i < j; i++, j-- ) |
{ |
for( k = 0; k < 4; k++ ) |
{ |
uint32_t t = ctx->rk[i][k]; |
ctx->rk[i][k] = ctx->rk[j][k]; |
ctx->rk[j][k] = t; |
} |
} |
/* apply affine transform to middle keys */ |
for( i = 1; i < ctx->nr; i++ ) |
{ |
aria_a( &ctx->rk[i][0], &ctx->rk[i][1], |
&ctx->rk[i][2], &ctx->rk[i][3] ); |
} |
return( 0 ); |
} |
/* |
* Encrypt a block |
*/ |
int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx, |
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], |
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] ) |
{ |
int i; |
uint32_t a, b, c, d; |
ARIA_VALIDATE_RET( ctx != NULL ); |
ARIA_VALIDATE_RET( input != NULL ); |
ARIA_VALIDATE_RET( output != NULL ); |
GET_UINT32_LE( a, input, 0 ); |
GET_UINT32_LE( b, input, 4 ); |
GET_UINT32_LE( c, input, 8 ); |
GET_UINT32_LE( d, input, 12 ); |
i = 0; |
while( 1 ) |
{ |
a ^= ctx->rk[i][0]; |
b ^= ctx->rk[i][1]; |
c ^= ctx->rk[i][2]; |
d ^= ctx->rk[i][3]; |
i++; |
aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 ); |
aria_a( &a, &b, &c, &d ); |
a ^= ctx->rk[i][0]; |
b ^= ctx->rk[i][1]; |
c ^= ctx->rk[i][2]; |
d ^= ctx->rk[i][3]; |
i++; |
aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 ); |
if( i >= ctx->nr ) |
break; |
aria_a( &a, &b, &c, &d ); |
} |
/* final key mixing */ |
a ^= ctx->rk[i][0]; |
b ^= ctx->rk[i][1]; |
c ^= ctx->rk[i][2]; |
d ^= ctx->rk[i][3]; |
PUT_UINT32_LE( a, output, 0 ); |
PUT_UINT32_LE( b, output, 4 ); |
PUT_UINT32_LE( c, output, 8 ); |
PUT_UINT32_LE( d, output, 12 ); |
return( 0 ); |
} |
/* Initialize context */ |
void mbedtls_aria_init( mbedtls_aria_context *ctx ) |
{ |
ARIA_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_aria_context ) ); |
} |
/* Clear context */ |
void mbedtls_aria_free( mbedtls_aria_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* ARIA-CBC buffer encryption/decryption |
*/ |
int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int i; |
unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; |
ARIA_VALIDATE_RET( ctx != NULL ); |
ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || |
mode == MBEDTLS_ARIA_DECRYPT ); |
ARIA_VALIDATE_RET( length == 0 || input != NULL ); |
ARIA_VALIDATE_RET( length == 0 || output != NULL ); |
ARIA_VALIDATE_RET( iv != NULL ); |
if( length % MBEDTLS_ARIA_BLOCKSIZE ) |
return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH ); |
if( mode == MBEDTLS_ARIA_DECRYPT ) |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE ); |
mbedtls_aria_crypt_ecb( ctx, input, output ); |
for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) |
output[i] = (unsigned char)( output[i] ^ iv[i] ); |
memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE ); |
input += MBEDTLS_ARIA_BLOCKSIZE; |
output += MBEDTLS_ARIA_BLOCKSIZE; |
length -= MBEDTLS_ARIA_BLOCKSIZE; |
} |
} |
else |
{ |
while( length > 0 ) |
{ |
for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ ) |
output[i] = (unsigned char)( input[i] ^ iv[i] ); |
mbedtls_aria_crypt_ecb( ctx, output, output ); |
memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE ); |
input += MBEDTLS_ARIA_BLOCKSIZE; |
output += MBEDTLS_ARIA_BLOCKSIZE; |
length -= MBEDTLS_ARIA_BLOCKSIZE; |
} |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/* |
* ARIA-CFB128 buffer encryption/decryption |
*/ |
int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ) |
{ |
unsigned char c; |
size_t n; |
ARIA_VALIDATE_RET( ctx != NULL ); |
ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT || |
mode == MBEDTLS_ARIA_DECRYPT ); |
ARIA_VALIDATE_RET( length == 0 || input != NULL ); |
ARIA_VALIDATE_RET( length == 0 || output != NULL ); |
ARIA_VALIDATE_RET( iv != NULL ); |
ARIA_VALIDATE_RET( iv_off != NULL ); |
n = *iv_off; |
/* An overly large value of n can lead to an unlimited |
* buffer overflow. Therefore, guard against this |
* outside of parameter validation. */ |
if( n >= MBEDTLS_ARIA_BLOCKSIZE ) |
return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); |
if( mode == MBEDTLS_ARIA_DECRYPT ) |
{ |
while( length-- ) |
{ |
if( n == 0 ) |
mbedtls_aria_crypt_ecb( ctx, iv, iv ); |
c = *input++; |
*output++ = c ^ iv[n]; |
iv[n] = c; |
n = ( n + 1 ) & 0x0F; |
} |
} |
else |
{ |
while( length-- ) |
{ |
if( n == 0 ) |
mbedtls_aria_crypt_ecb( ctx, iv, iv ); |
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); |
n = ( n + 1 ) & 0x0F; |
} |
} |
*iv_off = n; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* ARIA-CTR buffer encryption/decryption |
*/ |
int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], |
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c, i; |
size_t n; |
ARIA_VALIDATE_RET( ctx != NULL ); |
ARIA_VALIDATE_RET( length == 0 || input != NULL ); |
ARIA_VALIDATE_RET( length == 0 || output != NULL ); |
ARIA_VALIDATE_RET( nonce_counter != NULL ); |
ARIA_VALIDATE_RET( stream_block != NULL ); |
ARIA_VALIDATE_RET( nc_off != NULL ); |
n = *nc_off; |
/* An overly large value of n can lead to an unlimited |
* buffer overflow. Therefore, guard against this |
* outside of parameter validation. */ |
if( n >= MBEDTLS_ARIA_BLOCKSIZE ) |
return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA ); |
while( length-- ) |
{ |
if( n == 0 ) { |
mbedtls_aria_crypt_ecb( ctx, nonce_counter, |
stream_block ); |
for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- ) |
if( ++nonce_counter[i - 1] != 0 ) |
break; |
} |
c = *input++; |
*output++ = (unsigned char)( c ^ stream_block[n] ); |
n = ( n + 1 ) & 0x0F; |
} |
*nc_off = n; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#endif /* !MBEDTLS_ARIA_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* Basic ARIA ECB test vectors from RFC 5794 |
*/ |
static const uint8_t aria_test1_ecb_key[32] = // test key |
{ |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit |
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit |
}; |
static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext |
{ |
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all |
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes |
}; |
static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext |
{ |
{ 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit |
0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 }, |
{ 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit |
0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 }, |
{ 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit |
0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC } |
}; |
/* |
* Mode tests from "Test Vectors for ARIA" Version 1.0 |
* http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf |
*/ |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ |
defined(MBEDTLS_CIPHER_MODE_CTR)) |
static const uint8_t aria_test2_key[32] = |
{ |
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit |
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, |
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit |
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit |
}; |
static const uint8_t aria_test2_pt[48] = |
{ |
0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all |
0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb, |
0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, |
0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, |
0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa, |
0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb, |
}; |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)) |
static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] = |
{ |
0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB |
0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV |
}; |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext |
{ |
{ 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key |
0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34, |
0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64, |
0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38, |
0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c, |
0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 }, |
{ 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key |
0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f, |
0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1, |
0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5, |
0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92, |
0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e }, |
{ 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key |
0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab, |
0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef, |
0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52, |
0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5, |
0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext |
{ |
{ 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key |
0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00, |
0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a, |
0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01, |
0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96, |
0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b }, |
{ 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key |
0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c, |
0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94, |
0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59, |
0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86, |
0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b }, |
{ 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key |
0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35, |
0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70, |
0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa, |
0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c, |
0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext |
{ |
{ 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key |
0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1, |
0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1, |
0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f, |
0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71, |
0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 }, |
{ 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key |
0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce, |
0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde, |
0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79, |
0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce, |
0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf }, |
{ 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key |
0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2, |
0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89, |
0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f, |
0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7, |
0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#define ARIA_SELF_TEST_IF_FAIL \ |
{ \ |
if( verbose ) \ |
mbedtls_printf( "failed\n" ); \ |
return( 1 ); \ |
} else { \ |
if( verbose ) \ |
mbedtls_printf( "passed\n" ); \ |
} |
/* |
* Checkup routine |
*/ |
int mbedtls_aria_self_test( int verbose ) |
{ |
int i; |
uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; |
mbedtls_aria_context ctx; |
#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) |
size_t j; |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \ |
defined(MBEDTLS_CIPHER_MODE_CFB) || \ |
defined(MBEDTLS_CIPHER_MODE_CTR)) |
uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; |
#endif |
/* |
* Test set 1 |
*/ |
for( i = 0; i < 3; i++ ) |
{ |
/* test ECB encryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-ECB-%d (enc): ", 128 + 64 * i ); |
mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i ); |
mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk ); |
if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
/* test ECB decryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-ECB-%d (dec): ", 128 + 64 * i ); |
mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i ); |
mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk ); |
if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
} |
if( verbose ) |
mbedtls_printf( "\n" ); |
/* |
* Test set 2 |
*/ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
for( i = 0; i < 3; i++ ) |
{ |
/* Test CBC encryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-CBC-%d (enc): ", 128 + 64 * i ); |
mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); |
memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); |
memset( buf, 0x55, sizeof( buf ) ); |
mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, |
aria_test2_pt, buf ); |
if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
/* Test CBC decryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-CBC-%d (dec): ", 128 + 64 * i ); |
mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i ); |
memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); |
memset( buf, 0xAA, sizeof( buf ) ); |
mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, |
aria_test2_cbc_ct[i], buf ); |
if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
} |
if( verbose ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
for( i = 0; i < 3; i++ ) |
{ |
/* Test CFB encryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-CFB-%d (enc): ", 128 + 64 * i ); |
mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); |
memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); |
memset( buf, 0x55, sizeof( buf ) ); |
j = 0; |
mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, |
aria_test2_pt, buf ); |
if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
/* Test CFB decryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-CFB-%d (dec): ", 128 + 64 * i ); |
mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); |
memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE ); |
memset( buf, 0xAA, sizeof( buf ) ); |
j = 0; |
mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, |
iv, aria_test2_cfb_ct[i], buf ); |
if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
} |
if( verbose ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
for( i = 0; i < 3; i++ ) |
{ |
/* Test CTR encryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-CTR-%d (enc): ", 128 + 64 * i ); |
mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); |
memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 |
memset( buf, 0x55, sizeof( buf ) ); |
j = 0; |
mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, |
aria_test2_pt, buf ); |
if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
/* Test CTR decryption */ |
if( verbose ) |
mbedtls_printf( " ARIA-CTR-%d (dec): ", 128 + 64 * i ); |
mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i ); |
memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE ); // IV = 0 |
memset( buf, 0xAA, sizeof( buf ) ); |
j = 0; |
mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk, |
aria_test2_ctr_ct[i], buf ); |
if( memcmp( buf, aria_test2_pt, 48 ) != 0 ) |
ARIA_SELF_TEST_IF_FAIL; |
} |
if( verbose ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_ARIA_C */ |
/programs/develop/libraries/kos_mbedtls/library/asn1parse.c |
---|
0,0 → 1,391 |
/* |
* Generic ASN.1 parsing |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ASN1_PARSE_C) |
#include "mbedtls/asn1.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_BIGNUM_C) |
#include "mbedtls/bignum.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
/* |
* ASN.1 DER decoding routines |
*/ |
int mbedtls_asn1_get_len( unsigned char **p, |
const unsigned char *end, |
size_t *len ) |
{ |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
if( ( **p & 0x80 ) == 0 ) |
*len = *(*p)++; |
else |
{ |
switch( **p & 0x7F ) |
{ |
case 1: |
if( ( end - *p ) < 2 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
*len = (*p)[1]; |
(*p) += 2; |
break; |
case 2: |
if( ( end - *p ) < 3 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
*len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; |
(*p) += 3; |
break; |
case 3: |
if( ( end - *p ) < 4 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
*len = ( (size_t)(*p)[1] << 16 ) | |
( (size_t)(*p)[2] << 8 ) | (*p)[3]; |
(*p) += 4; |
break; |
case 4: |
if( ( end - *p ) < 5 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
*len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | |
( (size_t)(*p)[3] << 8 ) | (*p)[4]; |
(*p) += 5; |
break; |
default: |
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
} |
} |
if( *len > (size_t) ( end - *p ) ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
return( 0 ); |
} |
int mbedtls_asn1_get_tag( unsigned char **p, |
const unsigned char *end, |
size_t *len, int tag ) |
{ |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
if( **p != tag ) |
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
(*p)++; |
return( mbedtls_asn1_get_len( p, end, len ) ); |
} |
int mbedtls_asn1_get_bool( unsigned char **p, |
const unsigned char *end, |
int *val ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) |
return( ret ); |
if( len != 1 ) |
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
*val = ( **p != 0 ) ? 1 : 0; |
(*p)++; |
return( 0 ); |
} |
int mbedtls_asn1_get_int( unsigned char **p, |
const unsigned char *end, |
int *val ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) |
return( ret ); |
if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) |
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
*val = 0; |
while( len-- > 0 ) |
{ |
*val = ( *val << 8 ) | **p; |
(*p)++; |
} |
return( 0 ); |
} |
#if defined(MBEDTLS_BIGNUM_C) |
int mbedtls_asn1_get_mpi( unsigned char **p, |
const unsigned char *end, |
mbedtls_mpi *X ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) |
return( ret ); |
ret = mbedtls_mpi_read_binary( X, *p, len ); |
*p += len; |
return( ret ); |
} |
#endif /* MBEDTLS_BIGNUM_C */ |
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, |
mbedtls_asn1_bitstring *bs) |
{ |
int ret; |
/* Certificate type is a single byte bitstring */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) |
return( ret ); |
/* Check length, subtract one for actual bit string length */ |
if( bs->len < 1 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
bs->len -= 1; |
/* Get number of unused bits, ensure unused bits <= 7 */ |
bs->unused_bits = **p; |
if( bs->unused_bits > 7 ) |
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
(*p)++; |
/* Get actual bitstring */ |
bs->p = *p; |
*p += bs->len; |
if( *p != end ) |
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* Get a bit string without unused bits |
*/ |
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, |
size_t *len ) |
{ |
int ret; |
if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) |
return( ret ); |
if( (*len)-- < 2 || *(*p)++ != 0 ) |
return( MBEDTLS_ERR_ASN1_INVALID_DATA ); |
return( 0 ); |
} |
/* |
* Parses and splits an ASN.1 "SEQUENCE OF <tag>" |
*/ |
int mbedtls_asn1_get_sequence_of( unsigned char **p, |
const unsigned char *end, |
mbedtls_asn1_sequence *cur, |
int tag) |
{ |
int ret; |
size_t len; |
mbedtls_asn1_buf *buf; |
/* Get main sequence tag */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( ret ); |
if( *p + len != end ) |
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
while( *p < end ) |
{ |
buf = &(cur->buf); |
buf->tag = **p; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) |
return( ret ); |
buf->p = *p; |
*p += buf->len; |
/* Allocate and assign next pointer */ |
if( *p < end ) |
{ |
cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, |
sizeof( mbedtls_asn1_sequence ) ); |
if( cur->next == NULL ) |
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); |
cur = cur->next; |
} |
} |
/* Set final sequence entry's next pointer to NULL */ |
cur->next = NULL; |
if( *p != end ) |
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
int mbedtls_asn1_get_alg( unsigned char **p, |
const unsigned char *end, |
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( ret ); |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
alg->tag = **p; |
end = *p + len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) |
return( ret ); |
alg->p = *p; |
*p += alg->len; |
if( *p == end ) |
{ |
mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); |
return( 0 ); |
} |
params->tag = **p; |
(*p)++; |
if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) |
return( ret ); |
params->p = *p; |
*p += params->len; |
if( *p != end ) |
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
int mbedtls_asn1_get_alg_null( unsigned char **p, |
const unsigned char *end, |
mbedtls_asn1_buf *alg ) |
{ |
int ret; |
mbedtls_asn1_buf params; |
memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); |
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) |
return( ret ); |
if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) |
return( MBEDTLS_ERR_ASN1_INVALID_DATA ); |
return( 0 ); |
} |
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) |
{ |
if( cur == NULL ) |
return; |
mbedtls_free( cur->oid.p ); |
mbedtls_free( cur->val.p ); |
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); |
} |
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) |
{ |
mbedtls_asn1_named_data *cur; |
while( ( cur = *head ) != NULL ) |
{ |
*head = cur->next; |
mbedtls_asn1_free_named_data( cur ); |
mbedtls_free( cur ); |
} |
} |
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, |
const char *oid, size_t len ) |
{ |
while( list != NULL ) |
{ |
if( list->oid.len == len && |
memcmp( list->oid.p, oid, len ) == 0 ) |
{ |
break; |
} |
list = list->next; |
} |
return( list ); |
} |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
/programs/develop/libraries/kos_mbedtls/library/asn1write.c |
---|
0,0 → 1,423 |
/* |
* ASN.1 buffer writing functionality |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ASN1_WRITE_C) |
#include "mbedtls/asn1write.h" |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) |
{ |
if( len < 0x80 ) |
{ |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = (unsigned char) len; |
return( 1 ); |
} |
if( len <= 0xFF ) |
{ |
if( *p - start < 2 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = (unsigned char) len; |
*--(*p) = 0x81; |
return( 2 ); |
} |
if( len <= 0xFFFF ) |
{ |
if( *p - start < 3 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = ( len ) & 0xFF; |
*--(*p) = ( len >> 8 ) & 0xFF; |
*--(*p) = 0x82; |
return( 3 ); |
} |
if( len <= 0xFFFFFF ) |
{ |
if( *p - start < 4 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = ( len ) & 0xFF; |
*--(*p) = ( len >> 8 ) & 0xFF; |
*--(*p) = ( len >> 16 ) & 0xFF; |
*--(*p) = 0x83; |
return( 4 ); |
} |
#if SIZE_MAX > 0xFFFFFFFF |
if( len <= 0xFFFFFFFF ) |
#endif |
{ |
if( *p - start < 5 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = ( len ) & 0xFF; |
*--(*p) = ( len >> 8 ) & 0xFF; |
*--(*p) = ( len >> 16 ) & 0xFF; |
*--(*p) = ( len >> 24 ) & 0xFF; |
*--(*p) = 0x84; |
return( 5 ); |
} |
#if SIZE_MAX > 0xFFFFFFFF |
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
#endif |
} |
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) |
{ |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = tag; |
return( 1 ); |
} |
int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, |
const unsigned char *buf, size_t size ) |
{ |
size_t len = 0; |
if( *p < start || (size_t)( *p - start ) < size ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
len = size; |
(*p) -= len; |
memcpy( *p, buf, len ); |
return( (int) len ); |
} |
#if defined(MBEDTLS_BIGNUM_C) |
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) |
{ |
int ret; |
size_t len = 0; |
// Write the MPI |
// |
len = mbedtls_mpi_size( X ); |
if( *p < start || (size_t)( *p - start ) < len ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
(*p) -= len; |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); |
// DER format assumes 2s complement for numbers, so the leftmost bit |
// should be 0 for positive numbers and 1 for negative numbers. |
// |
if( X->s ==1 && **p & 0x80 ) |
{ |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = 0x00; |
len += 1; |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); |
ret = (int) len; |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_BIGNUM_C */ |
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) |
{ |
int ret; |
size_t len = 0; |
// Write NULL |
// |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, |
const char *oid, size_t oid_len ) |
{ |
int ret; |
size_t len = 0; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, |
(const unsigned char *) oid, oid_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, |
const char *oid, size_t oid_len, |
size_t par_len ) |
{ |
int ret; |
size_t len = 0; |
if( par_len == 0 ) |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); |
else |
len += par_len; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) |
{ |
int ret; |
size_t len = 0; |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = (boolean) ? 255 : 0; |
len++; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) |
{ |
int ret; |
size_t len = 0; |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
len += 1; |
*--(*p) = val; |
if( val > 0 && **p & 0x80 ) |
{ |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = 0x00; |
len += 1; |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag, |
const char *text, size_t text_len ) |
{ |
int ret; |
size_t len = 0; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, |
(const unsigned char *) text, text_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, |
const char *text, size_t text_len ) |
{ |
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) ); |
} |
int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, |
const char *text, size_t text_len ) |
{ |
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) ); |
} |
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, |
const char *text, size_t text_len ) |
{ |
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) ); |
} |
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, |
const unsigned char *buf, size_t bits ) |
{ |
int ret; |
size_t len = 0; |
size_t unused_bits, byte_len; |
byte_len = ( bits + 7 ) / 8; |
unused_bits = ( byte_len * 8 ) - bits; |
if( *p < start || (size_t)( *p - start ) < byte_len + 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
len = byte_len + 1; |
/* Write the bitstring. Ensure the unused bits are zeroed */ |
if( byte_len > 0 ) |
{ |
byte_len--; |
*--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 ); |
( *p ) -= byte_len; |
memcpy( *p, buf, byte_len ); |
} |
/* Write unused bits */ |
*--( *p ) = (unsigned char)unused_bits; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); |
return( (int) len ); |
} |
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, |
const unsigned char *buf, size_t size ) |
{ |
int ret; |
size_t len = 0; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); |
return( (int) len ); |
} |
/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), |
* which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ |
static mbedtls_asn1_named_data *asn1_find_named_data( |
mbedtls_asn1_named_data *list, |
const char *oid, size_t len ) |
{ |
while( list != NULL ) |
{ |
if( list->oid.len == len && |
memcmp( list->oid.p, oid, len ) == 0 ) |
{ |
break; |
} |
list = list->next; |
} |
return( list ); |
} |
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( |
mbedtls_asn1_named_data **head, |
const char *oid, size_t oid_len, |
const unsigned char *val, |
size_t val_len ) |
{ |
mbedtls_asn1_named_data *cur; |
if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) |
{ |
// Add new entry if not present yet based on OID |
// |
cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, |
sizeof(mbedtls_asn1_named_data) ); |
if( cur == NULL ) |
return( NULL ); |
cur->oid.len = oid_len; |
cur->oid.p = mbedtls_calloc( 1, oid_len ); |
if( cur->oid.p == NULL ) |
{ |
mbedtls_free( cur ); |
return( NULL ); |
} |
memcpy( cur->oid.p, oid, oid_len ); |
cur->val.len = val_len; |
cur->val.p = mbedtls_calloc( 1, val_len ); |
if( cur->val.p == NULL ) |
{ |
mbedtls_free( cur->oid.p ); |
mbedtls_free( cur ); |
return( NULL ); |
} |
cur->next = *head; |
*head = cur; |
} |
else if( cur->val.len < val_len ) |
{ |
/* |
* Enlarge existing value buffer if needed |
* Preserve old data until the allocation succeeded, to leave list in |
* a consistent state in case allocation fails. |
*/ |
void *p = mbedtls_calloc( 1, val_len ); |
if( p == NULL ) |
return( NULL ); |
mbedtls_free( cur->val.p ); |
cur->val.p = p; |
cur->val.len = val_len; |
} |
if( val != NULL ) |
memcpy( cur->val.p, val, val_len ); |
return( cur ); |
} |
#endif /* MBEDTLS_ASN1_WRITE_C */ |
/programs/develop/libraries/kos_mbedtls/library/base64.c |
---|
0,0 → 1,295 |
/* |
* RFC 1521 base64 encoding/decoding |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_BASE64_C) |
#include "mbedtls/base64.h" |
#include <stdint.h> |
#if defined(MBEDTLS_SELF_TEST) |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
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 |
}; |
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ |
/* |
* Encode a buffer into base64 format |
*/ |
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, |
const unsigned char *src, size_t slen ) |
{ |
size_t i, n; |
int C1, C2, C3; |
unsigned char *p; |
if( slen == 0 ) |
{ |
*olen = 0; |
return( 0 ); |
} |
n = slen / 3 + ( slen % 3 != 0 ); |
if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) |
{ |
*olen = BASE64_SIZE_T_MAX; |
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); |
} |
n *= 4; |
if( ( dlen < n + 1 ) || ( NULL == dst ) ) |
{ |
*olen = n + 1; |
return( MBEDTLS_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++ = '='; |
} |
*olen = p - dst; |
*p = 0; |
return( 0 ); |
} |
/* |
* Decode a base64-formatted buffer |
*/ |
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, |
const unsigned char *src, size_t slen ) |
{ |
size_t i, n; |
uint32_t j, x; |
unsigned char *p; |
/* First pass: check for validity and get output length */ |
for( i = n = j = 0; i < slen; i++ ) |
{ |
/* Skip spaces before checking for EOL */ |
x = 0; |
while( i < slen && src[i] == ' ' ) |
{ |
++i; |
++x; |
} |
/* Spaces at end of buffer are OK */ |
if( i == slen ) |
break; |
if( ( slen - i ) >= 2 && |
src[i] == '\r' && src[i + 1] == '\n' ) |
continue; |
if( src[i] == '\n' ) |
continue; |
/* Space inside a line is an error */ |
if( x != 0 ) |
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); |
if( src[i] == '=' && ++j > 2 ) |
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); |
if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) |
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); |
if( base64_dec_map[src[i]] < 64 && j != 0 ) |
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); |
n++; |
} |
if( n == 0 ) |
{ |
*olen = 0; |
return( 0 ); |
} |
/* The following expression is to calculate the following formula without |
* risk of integer overflow in n: |
* n = ( ( n * 6 ) + 7 ) >> 3; |
*/ |
n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 ); |
n -= j; |
if( dst == NULL || dlen < n ) |
{ |
*olen = n; |
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); |
} |
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) |
{ |
if( *src == '\r' || *src == '\n' || *src == ' ' ) |
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 ); |
} |
} |
*olen = p - dst; |
return( 0 ); |
} |
#if defined(MBEDTLS_SELF_TEST) |
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 mbedtls_base64_self_test( int verbose ) |
{ |
size_t len; |
const unsigned char *src; |
unsigned char buffer[128]; |
if( verbose != 0 ) |
mbedtls_printf( " Base64 encoding test: " ); |
src = base64_test_dec; |
if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || |
memcmp( base64_test_enc, buffer, 88 ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n Base64 decoding test: " ); |
src = base64_test_enc; |
if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || |
memcmp( base64_test_dec, buffer, 64 ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_BASE64_C */ |
/programs/develop/libraries/kos_mbedtls/library/bignum.c |
---|
0,0 → 1,2868 |
/* |
* Multi-precision integer library |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The following sources were referenced in the design of this Multi-precision |
* Integer library: |
* |
* [1] Handbook of Applied Cryptography - 1997 |
* Menezes, van Oorschot and Vanstone |
* |
* [2] Multi-Precision Math |
* Tom St Denis |
* https://github.com/libtom/libtommath/blob/develop/tommath.pdf |
* |
* [3] GNU Multi-Precision Arithmetic Library |
* https://gmplib.org/manual/index.html |
* |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_BIGNUM_C) |
#include "mbedtls/bignum.h" |
#include "mbedtls/bn_mul.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_printf printf |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#define MPI_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA ) |
#define MPI_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ |
#define biL (ciL << 3) /* bits in limb */ |
#define biH (ciL << 2) /* half limb size */ |
#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ |
/* |
* Convert between bits/chars and number of limbs |
* Divide first in order to avoid potential overflows |
*/ |
#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) |
#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) |
/* Implementation that should never be optimized out by the compiler */ |
static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) |
{ |
mbedtls_platform_zeroize( v, ciL * n ); |
} |
/* |
* Initialize one MPI |
*/ |
void mbedtls_mpi_init( mbedtls_mpi *X ) |
{ |
MPI_VALIDATE( X != NULL ); |
X->s = 1; |
X->n = 0; |
X->p = NULL; |
} |
/* |
* Unallocate one MPI |
*/ |
void mbedtls_mpi_free( mbedtls_mpi *X ) |
{ |
if( X == NULL ) |
return; |
if( X->p != NULL ) |
{ |
mbedtls_mpi_zeroize( X->p, X->n ); |
mbedtls_free( X->p ); |
} |
X->s = 1; |
X->n = 0; |
X->p = NULL; |
} |
/* |
* Enlarge to the specified number of limbs |
*/ |
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) |
{ |
mbedtls_mpi_uint *p; |
MPI_VALIDATE_RET( X != NULL ); |
if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) |
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); |
if( X->n < nblimbs ) |
{ |
if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) |
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); |
if( X->p != NULL ) |
{ |
memcpy( p, X->p, X->n * ciL ); |
mbedtls_mpi_zeroize( X->p, X->n ); |
mbedtls_free( X->p ); |
} |
X->n = nblimbs; |
X->p = p; |
} |
return( 0 ); |
} |
/* |
* Resize down as much as possible, |
* while keeping at least the specified number of limbs |
*/ |
int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) |
{ |
mbedtls_mpi_uint *p; |
size_t i; |
MPI_VALIDATE_RET( X != NULL ); |
if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) |
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); |
/* Actually resize up if there are currently fewer than nblimbs limbs. */ |
if( X->n <= nblimbs ) |
return( mbedtls_mpi_grow( X, nblimbs ) ); |
/* After this point, then X->n > nblimbs and in particular X->n > 0. */ |
for( i = X->n - 1; i > 0; i-- ) |
if( X->p[i] != 0 ) |
break; |
i++; |
if( i < nblimbs ) |
i = nblimbs; |
if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) |
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); |
if( X->p != NULL ) |
{ |
memcpy( p, X->p, i * ciL ); |
mbedtls_mpi_zeroize( X->p, X->n ); |
mbedtls_free( X->p ); |
} |
X->n = i; |
X->p = p; |
return( 0 ); |
} |
/* |
* Copy the contents of Y into X |
*/ |
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) |
{ |
int ret = 0; |
size_t i; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( Y != NULL ); |
if( X == Y ) |
return( 0 ); |
if( Y->n == 0 ) |
{ |
mbedtls_mpi_free( X ); |
return( 0 ); |
} |
for( i = Y->n - 1; i > 0; i-- ) |
if( Y->p[i] != 0 ) |
break; |
i++; |
X->s = Y->s; |
if( X->n < i ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) ); |
} |
else |
{ |
memset( X->p + i, 0, ( X->n - i ) * ciL ); |
} |
memcpy( X->p, Y->p, i * ciL ); |
cleanup: |
return( ret ); |
} |
/* |
* Swap the contents of X and Y |
*/ |
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) |
{ |
mbedtls_mpi T; |
MPI_VALIDATE( X != NULL ); |
MPI_VALIDATE( Y != NULL ); |
memcpy( &T, X, sizeof( mbedtls_mpi ) ); |
memcpy( X, Y, sizeof( mbedtls_mpi ) ); |
memcpy( Y, &T, sizeof( mbedtls_mpi ) ); |
} |
/* |
* Conditionally assign X = Y, without leaking information |
* about whether the assignment was made or not. |
* (Leaking information about the respective sizes of X and Y is ok however.) |
*/ |
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ) |
{ |
int ret = 0; |
size_t i; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( Y != NULL ); |
/* make sure assign is 0 or 1 in a time-constant manner */ |
assign = (assign | (unsigned char)-assign) >> 7; |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); |
X->s = X->s * ( 1 - assign ) + Y->s * assign; |
for( i = 0; i < Y->n; i++ ) |
X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign; |
for( ; i < X->n; i++ ) |
X->p[i] *= ( 1 - assign ); |
cleanup: |
return( ret ); |
} |
/* |
* Conditionally swap X and Y, without leaking information |
* about whether the swap was made or not. |
* Here it is not ok to simply swap the pointers, which whould lead to |
* different memory access patterns when X and Y are used afterwards. |
*/ |
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap ) |
{ |
int ret, s; |
size_t i; |
mbedtls_mpi_uint tmp; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( Y != NULL ); |
if( X == Y ) |
return( 0 ); |
/* make sure swap is 0 or 1 in a time-constant manner */ |
swap = (swap | (unsigned char)-swap) >> 7; |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) ); |
s = X->s; |
X->s = X->s * ( 1 - swap ) + Y->s * swap; |
Y->s = Y->s * ( 1 - swap ) + s * swap; |
for( i = 0; i < X->n; i++ ) |
{ |
tmp = X->p[i]; |
X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; |
Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; |
} |
cleanup: |
return( ret ); |
} |
/* |
* Set value from integer |
*/ |
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) |
{ |
int ret; |
MPI_VALIDATE_RET( X != NULL ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) ); |
memset( X->p, 0, X->n * ciL ); |
X->p[0] = ( z < 0 ) ? -z : z; |
X->s = ( z < 0 ) ? -1 : 1; |
cleanup: |
return( ret ); |
} |
/* |
* Get a specific bit |
*/ |
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) |
{ |
MPI_VALIDATE_RET( X != NULL ); |
if( X->n * biL <= pos ) |
return( 0 ); |
return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); |
} |
/* Get a specific byte, without range checks. */ |
#define GET_BYTE( X, i ) \ |
( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff ) |
/* |
* Set a bit to a specific value of 0 or 1 |
*/ |
int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ) |
{ |
int ret = 0; |
size_t off = pos / biL; |
size_t idx = pos % biL; |
MPI_VALIDATE_RET( X != NULL ); |
if( val != 0 && val != 1 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
if( X->n * biL <= pos ) |
{ |
if( val == 0 ) |
return( 0 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) ); |
} |
X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx ); |
X->p[off] |= (mbedtls_mpi_uint) val << idx; |
cleanup: |
return( ret ); |
} |
/* |
* Return the number of less significant zero-bits |
*/ |
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ) |
{ |
size_t i, j, count = 0; |
MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 ); |
for( i = 0; i < X->n; i++ ) |
for( j = 0; j < biL; j++, count++ ) |
if( ( ( X->p[i] >> j ) & 1 ) != 0 ) |
return( count ); |
return( 0 ); |
} |
/* |
* Count leading zero bits in a given integer |
*/ |
static size_t mbedtls_clz( const mbedtls_mpi_uint x ) |
{ |
size_t j; |
mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); |
for( j = 0; j < biL; j++ ) |
{ |
if( x & mask ) break; |
mask >>= 1; |
} |
return j; |
} |
/* |
* Return the number of bits |
*/ |
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ) |
{ |
size_t i, j; |
if( X->n == 0 ) |
return( 0 ); |
for( i = X->n - 1; i > 0; i-- ) |
if( X->p[i] != 0 ) |
break; |
j = biL - mbedtls_clz( X->p[i] ); |
return( ( i * biL ) + j ); |
} |
/* |
* Return the total size in bytes |
*/ |
size_t mbedtls_mpi_size( const mbedtls_mpi *X ) |
{ |
return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 ); |
} |
/* |
* Convert an ASCII character to digit value |
*/ |
static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c ) |
{ |
*d = 255; |
if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; |
if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; |
if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; |
if( *d >= (mbedtls_mpi_uint) radix ) |
return( MBEDTLS_ERR_MPI_INVALID_CHARACTER ); |
return( 0 ); |
} |
/* |
* Import from an ASCII string |
*/ |
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) |
{ |
int ret; |
size_t i, j, slen, n; |
mbedtls_mpi_uint d; |
mbedtls_mpi T; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( s != NULL ); |
if( radix < 2 || radix > 16 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
mbedtls_mpi_init( &T ); |
slen = strlen( s ); |
if( radix == 16 ) |
{ |
if( slen > MPI_SIZE_T_MAX >> 2 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
n = BITS_TO_LIMBS( slen << 2 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); |
for( i = slen, j = 0; i > 0; i--, j++ ) |
{ |
if( i == 1 && s[i - 1] == '-' ) |
{ |
X->s = -1; |
break; |
} |
MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); |
X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); |
} |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); |
for( i = 0; i < slen; i++ ) |
{ |
if( i == 0 && s[i] == '-' ) |
{ |
X->s = -1; |
continue; |
} |
MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) ); |
if( X->s == 1 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) ); |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) ); |
} |
} |
} |
cleanup: |
mbedtls_mpi_free( &T ); |
return( ret ); |
} |
/* |
* Helper to write the digits high-order first. |
*/ |
static int mpi_write_hlp( mbedtls_mpi *X, int radix, |
char **p, const size_t buflen ) |
{ |
int ret; |
mbedtls_mpi_uint r; |
size_t length = 0; |
char *p_end = *p + buflen; |
do |
{ |
if( length >= buflen ) |
{ |
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); |
/* |
* Write the residue in the current position, as an ASCII character. |
*/ |
if( r < 0xA ) |
*(--p_end) = (char)( '0' + r ); |
else |
*(--p_end) = (char)( 'A' + ( r - 0xA ) ); |
length++; |
} while( mbedtls_mpi_cmp_int( X, 0 ) != 0 ); |
memmove( *p, p_end, length ); |
*p += length; |
cleanup: |
return( ret ); |
} |
/* |
* Export into an ASCII string |
*/ |
int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, |
char *buf, size_t buflen, size_t *olen ) |
{ |
int ret = 0; |
size_t n; |
char *p; |
mbedtls_mpi T; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( olen != NULL ); |
MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); |
if( radix < 2 || radix > 16 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */ |
if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present |
* `n`. If radix > 4, this might be a strict |
* overapproximation of the number of |
* radix-adic digits needed to present `n`. */ |
if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to |
* present `n`. */ |
n += 1; /* Terminating null byte */ |
n += 1; /* Compensate for the divisions above, which round down `n` |
* in case it's not even. */ |
n += 1; /* Potential '-'-sign. */ |
n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing, |
* which always uses an even number of hex-digits. */ |
if( buflen < n ) |
{ |
*olen = n; |
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); |
} |
p = buf; |
mbedtls_mpi_init( &T ); |
if( X->s == -1 ) |
{ |
*p++ = '-'; |
buflen--; |
} |
if( radix == 16 ) |
{ |
int c; |
size_t i, j, k; |
for( i = X->n, k = 0; i > 0; i-- ) |
{ |
for( j = ciL; j > 0; j-- ) |
{ |
c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; |
if( c == 0 && k == 0 && ( i + j ) != 2 ) |
continue; |
*(p++) = "0123456789ABCDEF" [c / 16]; |
*(p++) = "0123456789ABCDEF" [c % 16]; |
k = 1; |
} |
} |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) ); |
if( T.s == -1 ) |
T.s = 1; |
MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) ); |
} |
*p++ = '\0'; |
*olen = p - buf; |
cleanup: |
mbedtls_mpi_free( &T ); |
return( ret ); |
} |
#if defined(MBEDTLS_FS_IO) |
/* |
* Read X from an opened file |
*/ |
int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ) |
{ |
mbedtls_mpi_uint d; |
size_t slen; |
char *p; |
/* |
* Buffer should have space for (short) label and decimal formatted MPI, |
* newline characters and '\0' |
*/ |
char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( fin != NULL ); |
if( radix < 2 || radix > 16 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
memset( s, 0, sizeof( s ) ); |
if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) |
return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); |
slen = strlen( s ); |
if( slen == sizeof( s ) - 2 ) |
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); |
if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } |
if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } |
p = s + slen; |
while( p-- > s ) |
if( mpi_get_digit( &d, radix, *p ) != 0 ) |
break; |
return( mbedtls_mpi_read_string( X, radix, p + 1 ) ); |
} |
/* |
* Write X into an opened file (or stdout if fout == NULL) |
*/ |
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout ) |
{ |
int ret; |
size_t n, slen, plen; |
/* |
* Buffer should have space for (short) label and decimal formatted MPI, |
* newline characters and '\0' |
*/ |
char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; |
MPI_VALIDATE_RET( X != NULL ); |
if( radix < 2 || radix > 16 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
memset( s, 0, sizeof( s ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) ); |
if( p == NULL ) p = ""; |
plen = strlen( p ); |
slen = strlen( s ); |
s[slen++] = '\r'; |
s[slen++] = '\n'; |
if( fout != NULL ) |
{ |
if( fwrite( p, 1, plen, fout ) != plen || |
fwrite( s, 1, slen, fout ) != slen ) |
return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); |
} |
else |
mbedtls_printf( "%s%s", p, s ); |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint |
* into the storage form used by mbedtls_mpi. */ |
static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x ) |
{ |
uint8_t i; |
unsigned char *x_ptr; |
mbedtls_mpi_uint tmp = 0; |
for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ ) |
{ |
tmp <<= CHAR_BIT; |
tmp |= (mbedtls_mpi_uint) *x_ptr; |
} |
return( tmp ); |
} |
static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x ) |
{ |
#if defined(__BYTE_ORDER__) |
/* Nothing to do on bigendian systems. */ |
#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) |
return( x ); |
#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */ |
#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) |
/* For GCC and Clang, have builtins for byte swapping. */ |
#if defined(__GNUC__) && defined(__GNUC_PREREQ) |
#if __GNUC_PREREQ(4,3) |
#define have_bswap |
#endif |
#endif |
#if defined(__clang__) && defined(__has_builtin) |
#if __has_builtin(__builtin_bswap32) && \ |
__has_builtin(__builtin_bswap64) |
#define have_bswap |
#endif |
#endif |
#if defined(have_bswap) |
/* The compiler is hopefully able to statically evaluate this! */ |
switch( sizeof(mbedtls_mpi_uint) ) |
{ |
case 4: |
return( __builtin_bswap32(x) ); |
case 8: |
return( __builtin_bswap64(x) ); |
} |
#endif |
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ |
#endif /* __BYTE_ORDER__ */ |
/* Fall back to C-based reordering if we don't know the byte order |
* or we couldn't use a compiler-specific builtin. */ |
return( mpi_uint_bigendian_to_host_c( x ) ); |
} |
static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs ) |
{ |
mbedtls_mpi_uint *cur_limb_left; |
mbedtls_mpi_uint *cur_limb_right; |
if( limbs == 0 ) |
return; |
/* |
* Traverse limbs and |
* - adapt byte-order in each limb |
* - swap the limbs themselves. |
* For that, simultaneously traverse the limbs from left to right |
* and from right to left, as long as the left index is not bigger |
* than the right index (it's not a problem if limbs is odd and the |
* indices coincide in the last iteration). |
*/ |
for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 ); |
cur_limb_left <= cur_limb_right; |
cur_limb_left++, cur_limb_right-- ) |
{ |
mbedtls_mpi_uint tmp; |
/* Note that if cur_limb_left == cur_limb_right, |
* this code effectively swaps the bytes only once. */ |
tmp = mpi_uint_bigendian_to_host( *cur_limb_left ); |
*cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right ); |
*cur_limb_right = tmp; |
} |
} |
/* |
* Import X from unsigned binary data, big endian |
*/ |
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) |
{ |
int ret; |
size_t const limbs = CHARS_TO_LIMBS( buflen ); |
size_t const overhead = ( limbs * ciL ) - buflen; |
unsigned char *Xp; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); |
/* Ensure that target MPI has exactly the necessary number of limbs */ |
if( X->n != limbs ) |
{ |
mbedtls_mpi_free( X ); |
mbedtls_mpi_init( X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); |
/* Avoid calling `memcpy` with NULL source argument, |
* even if buflen is 0. */ |
if( buf != NULL ) |
{ |
Xp = (unsigned char*) X->p; |
memcpy( Xp + overhead, buf, buflen ); |
mpi_bigendian_to_host( X->p, limbs ); |
} |
cleanup: |
return( ret ); |
} |
/* |
* Export X into unsigned binary data, big endian |
*/ |
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, |
unsigned char *buf, size_t buflen ) |
{ |
size_t stored_bytes; |
size_t bytes_to_copy; |
unsigned char *p; |
size_t i; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); |
stored_bytes = X->n * ciL; |
if( stored_bytes < buflen ) |
{ |
/* There is enough space in the output buffer. Write initial |
* null bytes and record the position at which to start |
* writing the significant bytes. In this case, the execution |
* trace of this function does not depend on the value of the |
* number. */ |
bytes_to_copy = stored_bytes; |
p = buf + buflen - stored_bytes; |
memset( buf, 0, buflen - stored_bytes ); |
} |
else |
{ |
/* The output buffer is smaller than the allocated size of X. |
* However X may fit if its leading bytes are zero. */ |
bytes_to_copy = buflen; |
p = buf; |
for( i = bytes_to_copy; i < stored_bytes; i++ ) |
{ |
if( GET_BYTE( X, i ) != 0 ) |
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); |
} |
} |
for( i = 0; i < bytes_to_copy; i++ ) |
p[bytes_to_copy - i - 1] = GET_BYTE( X, i ); |
return( 0 ); |
} |
/* |
* Left-shift: X <<= count |
*/ |
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ) |
{ |
int ret; |
size_t i, v0, t1; |
mbedtls_mpi_uint r0 = 0, r1; |
MPI_VALIDATE_RET( X != NULL ); |
v0 = count / (biL ); |
t1 = count & (biL - 1); |
i = mbedtls_mpi_bitlen( X ) + count; |
if( X->n * biL < i ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) ); |
ret = 0; |
/* |
* shift by count / limb_size |
*/ |
if( v0 > 0 ) |
{ |
for( i = X->n; i > v0; i-- ) |
X->p[i - 1] = X->p[i - v0 - 1]; |
for( ; i > 0; i-- ) |
X->p[i - 1] = 0; |
} |
/* |
* shift by count % limb_size |
*/ |
if( t1 > 0 ) |
{ |
for( i = v0; i < X->n; i++ ) |
{ |
r1 = X->p[i] >> (biL - t1); |
X->p[i] <<= t1; |
X->p[i] |= r0; |
r0 = r1; |
} |
} |
cleanup: |
return( ret ); |
} |
/* |
* Right-shift: X >>= count |
*/ |
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) |
{ |
size_t i, v0, v1; |
mbedtls_mpi_uint r0 = 0, r1; |
MPI_VALIDATE_RET( X != NULL ); |
v0 = count / biL; |
v1 = count & (biL - 1); |
if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) |
return mbedtls_mpi_lset( X, 0 ); |
/* |
* shift by count / limb_size |
*/ |
if( v0 > 0 ) |
{ |
for( i = 0; i < X->n - v0; i++ ) |
X->p[i] = X->p[i + v0]; |
for( ; i < X->n; i++ ) |
X->p[i] = 0; |
} |
/* |
* shift by count % limb_size |
*/ |
if( v1 > 0 ) |
{ |
for( i = X->n; i > 0; i-- ) |
{ |
r1 = X->p[i - 1] << (biL - v1); |
X->p[i - 1] >>= v1; |
X->p[i - 1] |= r0; |
r0 = r1; |
} |
} |
return( 0 ); |
} |
/* |
* Compare unsigned values |
*/ |
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ) |
{ |
size_t i, j; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( Y != NULL ); |
for( i = X->n; i > 0; i-- ) |
if( X->p[i - 1] != 0 ) |
break; |
for( j = Y->n; j > 0; j-- ) |
if( Y->p[j - 1] != 0 ) |
break; |
if( i == 0 && j == 0 ) |
return( 0 ); |
if( i > j ) return( 1 ); |
if( j > i ) return( -1 ); |
for( ; i > 0; i-- ) |
{ |
if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); |
if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); |
} |
return( 0 ); |
} |
/* |
* Compare signed values |
*/ |
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ) |
{ |
size_t i, j; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( Y != NULL ); |
for( i = X->n; i > 0; i-- ) |
if( X->p[i - 1] != 0 ) |
break; |
for( j = Y->n; j > 0; j-- ) |
if( Y->p[j - 1] != 0 ) |
break; |
if( i == 0 && j == 0 ) |
return( 0 ); |
if( i > j ) return( X->s ); |
if( j > i ) return( -Y->s ); |
if( X->s > 0 && Y->s < 0 ) return( 1 ); |
if( Y->s > 0 && X->s < 0 ) return( -1 ); |
for( ; i > 0; i-- ) |
{ |
if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); |
if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); |
} |
return( 0 ); |
} |
/** Decide if an integer is less than the other, without branches. |
* |
* \param x First integer. |
* \param y Second integer. |
* |
* \return 1 if \p x is less than \p y, 0 otherwise |
*/ |
static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x, |
const mbedtls_mpi_uint y ) |
{ |
mbedtls_mpi_uint ret; |
mbedtls_mpi_uint cond; |
/* |
* Check if the most significant bits (MSB) of the operands are different. |
*/ |
cond = ( x ^ y ); |
/* |
* If the MSB are the same then the difference x-y will be negative (and |
* have its MSB set to 1 during conversion to unsigned) if and only if x<y. |
*/ |
ret = ( x - y ) & ~cond; |
/* |
* If the MSB are different, then the operand with the MSB of 1 is the |
* bigger. (That is if y has MSB of 1, then x<y is true and it is false if |
* the MSB of y is 0.) |
*/ |
ret |= y & cond; |
ret = ret >> ( biL - 1 ); |
return (unsigned) ret; |
} |
/* |
* Compare signed values in constant time |
*/ |
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, |
unsigned *ret ) |
{ |
size_t i; |
/* The value of any of these variables is either 0 or 1 at all times. */ |
unsigned cond, done, X_is_negative, Y_is_negative; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( Y != NULL ); |
MPI_VALIDATE_RET( ret != NULL ); |
if( X->n != Y->n ) |
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
/* |
* Set sign_N to 1 if N >= 0, 0 if N < 0. |
* We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0. |
*/ |
X_is_negative = ( X->s & 2 ) >> 1; |
Y_is_negative = ( Y->s & 2 ) >> 1; |
/* |
* If the signs are different, then the positive operand is the bigger. |
* That is if X is negative (X_is_negative == 1), then X < Y is true and it |
* is false if X is positive (X_is_negative == 0). |
*/ |
cond = ( X_is_negative ^ Y_is_negative ); |
*ret = cond & X_is_negative; |
/* |
* This is a constant-time function. We might have the result, but we still |
* need to go through the loop. Record if we have the result already. |
*/ |
done = cond; |
for( i = X->n; i > 0; i-- ) |
{ |
/* |
* If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both |
* X and Y are negative. |
* |
* Again even if we can make a decision, we just mark the result and |
* the fact that we are done and continue looping. |
*/ |
cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] ); |
*ret |= cond & ( 1 - done ) & X_is_negative; |
done |= cond; |
/* |
* If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both |
* X and Y are positive. |
* |
* Again even if we can make a decision, we just mark the result and |
* the fact that we are done and continue looping. |
*/ |
cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] ); |
*ret |= cond & ( 1 - done ) & ( 1 - X_is_negative ); |
done |= cond; |
} |
return( 0 ); |
} |
/* |
* Compare signed values |
*/ |
int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) |
{ |
mbedtls_mpi Y; |
mbedtls_mpi_uint p[1]; |
MPI_VALIDATE_RET( X != NULL ); |
*p = ( z < 0 ) ? -z : z; |
Y.s = ( z < 0 ) ? -1 : 1; |
Y.n = 1; |
Y.p = p; |
return( mbedtls_mpi_cmp_mpi( X, &Y ) ); |
} |
/* |
* Unsigned addition: X = |A| + |B| (HAC 14.7) |
*/ |
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
int ret; |
size_t i, j; |
mbedtls_mpi_uint *o, *p, c, tmp; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
if( X == B ) |
{ |
const mbedtls_mpi *T = A; A = X; B = T; |
} |
if( X != A ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); |
/* |
* X should always be positive as a result of unsigned additions. |
*/ |
X->s = 1; |
for( j = B->n; j > 0; j-- ) |
if( B->p[j - 1] != 0 ) |
break; |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); |
o = B->p; p = X->p; c = 0; |
/* |
* tmp is used because it might happen that p == o |
*/ |
for( i = 0; i < j; i++, o++, p++ ) |
{ |
tmp= *o; |
*p += c; c = ( *p < c ); |
*p += tmp; c += ( *p < tmp ); |
} |
while( c != 0 ) |
{ |
if( i >= X->n ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) ); |
p = X->p + i; |
} |
*p += c; c = ( *p < c ); i++; p++; |
} |
cleanup: |
return( ret ); |
} |
/* |
* Helper for mbedtls_mpi subtraction |
*/ |
static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d ) |
{ |
size_t i; |
mbedtls_mpi_uint c, z; |
for( i = c = 0; i < n; i++, s++, d++ ) |
{ |
z = ( *d < c ); *d -= c; |
c = ( *d < *s ) + z; *d -= *s; |
} |
while( c != 0 ) |
{ |
z = ( *d < c ); *d -= c; |
c = z; d++; |
} |
} |
/* |
* Unsigned subtraction: X = |A| - |B| (HAC 14.9) |
*/ |
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
mbedtls_mpi TB; |
int ret; |
size_t n; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) |
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); |
mbedtls_mpi_init( &TB ); |
if( X == B ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); |
B = &TB; |
} |
if( X != A ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); |
/* |
* X should always be positive as a result of unsigned subtractions. |
*/ |
X->s = 1; |
ret = 0; |
for( n = B->n; n > 0; n-- ) |
if( B->p[n - 1] != 0 ) |
break; |
mpi_sub_hlp( n, B->p, X->p ); |
cleanup: |
mbedtls_mpi_free( &TB ); |
return( ret ); |
} |
/* |
* Signed addition: X = A + B |
*/ |
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
int ret, s; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
s = A->s; |
if( A->s * B->s < 0 ) |
{ |
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); |
X->s = s; |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); |
X->s = -s; |
} |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); |
X->s = s; |
} |
cleanup: |
return( ret ); |
} |
/* |
* Signed subtraction: X = A - B |
*/ |
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
int ret, s; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
s = A->s; |
if( A->s * B->s > 0 ) |
{ |
if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); |
X->s = s; |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); |
X->s = -s; |
} |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); |
X->s = s; |
} |
cleanup: |
return( ret ); |
} |
/* |
* Signed addition: X = A + b |
*/ |
int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) |
{ |
mbedtls_mpi _B; |
mbedtls_mpi_uint p[1]; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
p[0] = ( b < 0 ) ? -b : b; |
_B.s = ( b < 0 ) ? -1 : 1; |
_B.n = 1; |
_B.p = p; |
return( mbedtls_mpi_add_mpi( X, A, &_B ) ); |
} |
/* |
* Signed subtraction: X = A - b |
*/ |
int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) |
{ |
mbedtls_mpi _B; |
mbedtls_mpi_uint p[1]; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
p[0] = ( b < 0 ) ? -b : b; |
_B.s = ( b < 0 ) ? -1 : 1; |
_B.n = 1; |
_B.p = p; |
return( mbedtls_mpi_sub_mpi( X, A, &_B ) ); |
} |
/* |
* Helper for mbedtls_mpi multiplication |
*/ |
static |
#if defined(__APPLE__) && defined(__arm__) |
/* |
* Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) |
* appears to need this to prevent bad ARM code generation at -O3. |
*/ |
__attribute__ ((noinline)) |
#endif |
void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b ) |
{ |
mbedtls_mpi_uint c = 0, t = 0; |
#if defined(MULADDC_HUIT) |
for( ; i >= 8; i -= 8 ) |
{ |
MULADDC_INIT |
MULADDC_HUIT |
MULADDC_STOP |
} |
for( ; i > 0; i-- ) |
{ |
MULADDC_INIT |
MULADDC_CORE |
MULADDC_STOP |
} |
#else /* MULADDC_HUIT */ |
for( ; i >= 16; i -= 16 ) |
{ |
MULADDC_INIT |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_STOP |
} |
for( ; i >= 8; i -= 8 ) |
{ |
MULADDC_INIT |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_CORE MULADDC_CORE |
MULADDC_STOP |
} |
for( ; i > 0; i-- ) |
{ |
MULADDC_INIT |
MULADDC_CORE |
MULADDC_STOP |
} |
#endif /* MULADDC_HUIT */ |
t++; |
do { |
*d += c; c = ( *d < c ); d++; |
} |
while( c != 0 ); |
} |
/* |
* Baseline multiplication: X = A * B (HAC 14.12) |
*/ |
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
int ret; |
size_t i, j; |
mbedtls_mpi TA, TB; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); |
if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; } |
if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; } |
for( i = A->n; i > 0; i-- ) |
if( A->p[i - 1] != 0 ) |
break; |
for( j = B->n; j > 0; j-- ) |
if( B->p[j - 1] != 0 ) |
break; |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); |
for( ; j > 0; j-- ) |
mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] ); |
X->s = A->s * B->s; |
cleanup: |
mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA ); |
return( ret ); |
} |
/* |
* Baseline multiplication: X = A * b |
*/ |
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ) |
{ |
mbedtls_mpi _B; |
mbedtls_mpi_uint p[1]; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
_B.s = 1; |
_B.n = 1; |
_B.p = p; |
p[0] = b; |
return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); |
} |
/* |
* Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and |
* mbedtls_mpi_uint divisor, d |
*/ |
static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1, |
mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r ) |
{ |
#if defined(MBEDTLS_HAVE_UDBL) |
mbedtls_t_udbl dividend, quotient; |
#else |
const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH; |
const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1; |
mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient; |
mbedtls_mpi_uint u0_msw, u0_lsw; |
size_t s; |
#endif |
/* |
* Check for overflow |
*/ |
if( 0 == d || u1 >= d ) |
{ |
if (r != NULL) *r = ~0; |
return ( ~0 ); |
} |
#if defined(MBEDTLS_HAVE_UDBL) |
dividend = (mbedtls_t_udbl) u1 << biL; |
dividend |= (mbedtls_t_udbl) u0; |
quotient = dividend / d; |
if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 ) |
quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1; |
if( r != NULL ) |
*r = (mbedtls_mpi_uint)( dividend - (quotient * d ) ); |
return (mbedtls_mpi_uint) quotient; |
#else |
/* |
* Algorithm D, Section 4.3.1 - The Art of Computer Programming |
* Vol. 2 - Seminumerical Algorithms, Knuth |
*/ |
/* |
* Normalize the divisor, d, and dividend, u0, u1 |
*/ |
s = mbedtls_clz( d ); |
d = d << s; |
u1 = u1 << s; |
u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) ); |
u0 = u0 << s; |
d1 = d >> biH; |
d0 = d & uint_halfword_mask; |
u0_msw = u0 >> biH; |
u0_lsw = u0 & uint_halfword_mask; |
/* |
* Find the first quotient and remainder |
*/ |
q1 = u1 / d1; |
r0 = u1 - d1 * q1; |
while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) ) |
{ |
q1 -= 1; |
r0 += d1; |
if ( r0 >= radix ) break; |
} |
rAX = ( u1 * radix ) + ( u0_msw - q1 * d ); |
q0 = rAX / d1; |
r0 = rAX - q0 * d1; |
while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) ) |
{ |
q0 -= 1; |
r0 += d1; |
if ( r0 >= radix ) break; |
} |
if (r != NULL) |
*r = ( rAX * radix + u0_lsw - q0 * d ) >> s; |
quotient = q1 * radix + q0; |
return quotient; |
#endif |
} |
/* |
* Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) |
*/ |
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, |
const mbedtls_mpi *B ) |
{ |
int ret; |
size_t i, n, t, k; |
mbedtls_mpi X, Y, Z, T1, T2; |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
if( mbedtls_mpi_cmp_int( B, 0 ) == 0 ) |
return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); |
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); |
mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); |
if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) |
{ |
if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) ); |
if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) ); |
return( 0 ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) ); |
X.s = Y.s = 1; |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) ); |
k = mbedtls_mpi_bitlen( &Y ) % biL; |
if( k < biL - 1 ) |
{ |
k = biL - 1 - k; |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) ); |
} |
else k = 0; |
n = X.n - 1; |
t = Y.n - 1; |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) ); |
while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 ) |
{ |
Z.p[n - t]++; |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) ); |
for( i = n; i > t ; i-- ) |
{ |
if( X.p[i] >= Y.p[t] ) |
Z.p[i - t - 1] = ~0; |
else |
{ |
Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1], |
Y.p[t], NULL); |
} |
Z.p[i - t - 1]++; |
do |
{ |
Z.p[i - t - 1]--; |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) ); |
T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; |
T1.p[1] = Y.p[t]; |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) ); |
T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; |
T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; |
T2.p[2] = X.p[i]; |
} |
while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); |
if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) ); |
Z.p[i - t - 1]--; |
} |
} |
if( Q != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) ); |
Q->s = A->s * B->s; |
} |
if( R != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) ); |
X.s = A->s; |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) ); |
if( mbedtls_mpi_cmp_int( R, 0 ) == 0 ) |
R->s = 1; |
} |
cleanup: |
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); |
mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); |
return( ret ); |
} |
/* |
* Division by int: A = Q * b + R |
*/ |
int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, |
const mbedtls_mpi *A, |
mbedtls_mpi_sint b ) |
{ |
mbedtls_mpi _B; |
mbedtls_mpi_uint p[1]; |
MPI_VALIDATE_RET( A != NULL ); |
p[0] = ( b < 0 ) ? -b : b; |
_B.s = ( b < 0 ) ? -1 : 1; |
_B.n = 1; |
_B.p = p; |
return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) ); |
} |
/* |
* Modulo: R = A mod B |
*/ |
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
int ret; |
MPI_VALIDATE_RET( R != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
if( mbedtls_mpi_cmp_int( B, 0 ) < 0 ) |
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) ); |
while( mbedtls_mpi_cmp_int( R, 0 ) < 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); |
while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Modulo: r = A mod b |
*/ |
int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ) |
{ |
size_t i; |
mbedtls_mpi_uint x, y, z; |
MPI_VALIDATE_RET( r != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
if( b == 0 ) |
return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); |
if( b < 0 ) |
return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); |
/* |
* handle trivial cases |
*/ |
if( b == 1 ) |
{ |
*r = 0; |
return( 0 ); |
} |
if( b == 2 ) |
{ |
*r = A->p[0] & 1; |
return( 0 ); |
} |
/* |
* general case |
*/ |
for( i = A->n, y = 0; i > 0; i-- ) |
{ |
x = A->p[i - 1]; |
y = ( y << biH ) | ( x >> biH ); |
z = y / b; |
y -= z * b; |
x <<= biH; |
y = ( y << biH ) | ( x >> biH ); |
z = y / b; |
y -= z * b; |
} |
/* |
* If A is negative, then the current y represents a negative value. |
* Flipping it to the positive side. |
*/ |
if( A->s < 0 && y != 0 ) |
y = b - y; |
*r = y; |
return( 0 ); |
} |
/* |
* Fast Montgomery initialization (thanks to Tom St Denis) |
*/ |
static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N ) |
{ |
mbedtls_mpi_uint x, m0 = N->p[0]; |
unsigned int i; |
x = m0; |
x += ( ( m0 + 2 ) & 4 ) << 1; |
for( i = biL; i >= 8; i /= 2 ) |
x *= ( 2 - ( m0 * x ) ); |
*mm = ~x + 1; |
} |
/* |
* Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) |
*/ |
static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, |
const mbedtls_mpi *T ) |
{ |
size_t i, n, m; |
mbedtls_mpi_uint u0, u1, *d; |
if( T->n < N->n + 1 || T->p == NULL ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
memset( T->p, 0, T->n * ciL ); |
d = T->p; |
n = N->n; |
m = ( B->n < n ) ? B->n : n; |
for( i = 0; i < n; i++ ) |
{ |
/* |
* T = (T + u0*B + u1*N) / 2^biL |
*/ |
u0 = A->p[i]; |
u1 = ( d[0] + u0 * B->p[0] ) * mm; |
mpi_mul_hlp( m, B->p, d, u0 ); |
mpi_mul_hlp( n, N->p, d, u1 ); |
*d++ = u0; d[n + 1] = 0; |
} |
memcpy( A->p, d, ( n + 1 ) * ciL ); |
if( mbedtls_mpi_cmp_abs( A, N ) >= 0 ) |
mpi_sub_hlp( n, N->p, A->p ); |
else |
/* prevent timing attacks */ |
mpi_sub_hlp( n, A->p, T->p ); |
return( 0 ); |
} |
/* |
* Montgomery reduction: A = A * R^-1 mod N |
*/ |
static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, |
mbedtls_mpi_uint mm, const mbedtls_mpi *T ) |
{ |
mbedtls_mpi_uint z = 1; |
mbedtls_mpi U; |
U.n = U.s = (int) z; |
U.p = &z; |
return( mpi_montmul( A, &U, N, mm, T ) ); |
} |
/* |
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85) |
*/ |
int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, |
const mbedtls_mpi *E, const mbedtls_mpi *N, |
mbedtls_mpi *_RR ) |
{ |
int ret; |
size_t wbits, wsize, one = 1; |
size_t i, j, nblimbs; |
size_t bufsize, nbits; |
mbedtls_mpi_uint ei, mm, state; |
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; |
int neg; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( E != NULL ); |
MPI_VALIDATE_RET( N != NULL ); |
if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
/* |
* Init temps and window size |
*/ |
mpi_montg_init( &mm, N ); |
mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T ); |
mbedtls_mpi_init( &Apos ); |
memset( W, 0, sizeof( W ) ); |
i = mbedtls_mpi_bitlen( E ); |
wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : |
( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; |
#if( MBEDTLS_MPI_WINDOW_SIZE < 6 ) |
if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) |
wsize = MBEDTLS_MPI_WINDOW_SIZE; |
#endif |
j = N->n + 1; |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) ); |
/* |
* Compensate for negative A (and correct at the end) |
*/ |
neg = ( A->s == -1 ); |
if( neg ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) ); |
Apos.s = 1; |
A = &Apos; |
} |
/* |
* If 1st call, pre-compute R^2 mod N |
*/ |
if( _RR == NULL || _RR->p == NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) ); |
if( _RR != NULL ) |
memcpy( _RR, &RR, sizeof( mbedtls_mpi ) ); |
} |
else |
memcpy( &RR, _RR, sizeof( mbedtls_mpi ) ); |
/* |
* W[1] = A * R^2 * R^-1 mod N = A * R mod N |
*/ |
if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) ); |
else |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); |
MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) ); |
/* |
* X = R^2 * R^-1 mod N = R mod N |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); |
MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); |
if( wsize > 1 ) |
{ |
/* |
* W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) |
*/ |
j = one << ( wsize - 1 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) ); |
for( i = 0; i < wsize - 1; i++ ) |
MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) ); |
/* |
* W[i] = W[i - 1] * W[1] |
*/ |
for( i = j + 1; i < ( one << wsize ); i++ ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) ); |
MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) ); |
} |
} |
nblimbs = E->n; |
bufsize = 0; |
nbits = 0; |
wbits = 0; |
state = 0; |
while( 1 ) |
{ |
if( bufsize == 0 ) |
{ |
if( nblimbs == 0 ) |
break; |
nblimbs--; |
bufsize = sizeof( mbedtls_mpi_uint ) << 3; |
} |
bufsize--; |
ei = (E->p[nblimbs] >> bufsize) & 1; |
/* |
* skip leading 0s |
*/ |
if( ei == 0 && state == 0 ) |
continue; |
if( ei == 0 && state == 1 ) |
{ |
/* |
* out of window, square X |
*/ |
MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); |
continue; |
} |
/* |
* add ei to current window |
*/ |
state = 2; |
nbits++; |
wbits |= ( ei << ( wsize - nbits ) ); |
if( nbits == wsize ) |
{ |
/* |
* X = X^wsize R^-1 mod N |
*/ |
for( i = 0; i < wsize; i++ ) |
MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); |
/* |
* X = X * W[wbits] R^-1 mod N |
*/ |
MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) ); |
state--; |
nbits = 0; |
wbits = 0; |
} |
} |
/* |
* process the remaining bits |
*/ |
for( i = 0; i < nbits; i++ ) |
{ |
MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); |
wbits <<= 1; |
if( ( wbits & ( one << wsize ) ) != 0 ) |
MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) ); |
} |
/* |
* X = A^E * R * R^-1 mod N = A^E mod N |
*/ |
MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); |
if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 ) |
{ |
X->s = -1; |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); |
} |
cleanup: |
for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) |
mbedtls_mpi_free( &W[i] ); |
mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos ); |
if( _RR == NULL || _RR->p == NULL ) |
mbedtls_mpi_free( &RR ); |
return( ret ); |
} |
/* |
* Greatest common divisor: G = gcd(A, B) (HAC 14.54) |
*/ |
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ) |
{ |
int ret; |
size_t lz, lzt; |
mbedtls_mpi TG, TA, TB; |
MPI_VALIDATE_RET( G != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( B != NULL ); |
mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); |
lz = mbedtls_mpi_lsb( &TA ); |
lzt = mbedtls_mpi_lsb( &TB ); |
if( lzt < lz ) |
lz = lzt; |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) ); |
TA.s = TB.s = 1; |
while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) ); |
if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) ); |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) ); |
} |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) ); |
cleanup: |
mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB ); |
return( ret ); |
} |
/* |
* Fill X with size bytes of random. |
* |
* Use a temporary bytes representation to make sure the result is the same |
* regardless of the platform endianness (useful when f_rng is actually |
* deterministic, eg for tests). |
*/ |
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
size_t const limbs = CHARS_TO_LIMBS( size ); |
size_t const overhead = ( limbs * ciL ) - size; |
unsigned char *Xp; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( f_rng != NULL ); |
/* Ensure that target MPI has exactly the necessary number of limbs */ |
if( X->n != limbs ) |
{ |
mbedtls_mpi_free( X ); |
mbedtls_mpi_init( X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); |
Xp = (unsigned char*) X->p; |
f_rng( p_rng, Xp + overhead, size ); |
mpi_bigendian_to_host( X->p, limbs ); |
cleanup: |
return( ret ); |
} |
/* |
* Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) |
*/ |
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ) |
{ |
int ret; |
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( A != NULL ); |
MPI_VALIDATE_RET( N != NULL ); |
if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 ); |
mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV ); |
mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) ); |
if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) |
{ |
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) ); |
do |
{ |
while( ( TU.p[0] & 1 ) == 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) ); |
if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) ); |
} |
while( ( TV.p[0] & 1 ) == 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) ); |
if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) ); |
} |
if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) ); |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) ); |
} |
} |
while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 ); |
while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) ); |
while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) ); |
cleanup: |
mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 ); |
mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV ); |
mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 ); |
return( ret ); |
} |
#if defined(MBEDTLS_GENPRIME) |
static const int small_prime[] = |
{ |
3, 5, 7, 11, 13, 17, 19, 23, |
29, 31, 37, 41, 43, 47, 53, 59, |
61, 67, 71, 73, 79, 83, 89, 97, |
101, 103, 107, 109, 113, 127, 131, 137, |
139, 149, 151, 157, 163, 167, 173, 179, |
181, 191, 193, 197, 199, 211, 223, 227, |
229, 233, 239, 241, 251, 257, 263, 269, |
271, 277, 281, 283, 293, 307, 311, 313, |
317, 331, 337, 347, 349, 353, 359, 367, |
373, 379, 383, 389, 397, 401, 409, 419, |
421, 431, 433, 439, 443, 449, 457, 461, |
463, 467, 479, 487, 491, 499, 503, 509, |
521, 523, 541, 547, 557, 563, 569, 571, |
577, 587, 593, 599, 601, 607, 613, 617, |
619, 631, 641, 643, 647, 653, 659, 661, |
673, 677, 683, 691, 701, 709, 719, 727, |
733, 739, 743, 751, 757, 761, 769, 773, |
787, 797, 809, 811, 821, 823, 827, 829, |
839, 853, 857, 859, 863, 877, 881, 883, |
887, 907, 911, 919, 929, 937, 941, 947, |
953, 967, 971, 977, 983, 991, 997, -103 |
}; |
/* |
* Small divisors test (X must be positive) |
* |
* Return values: |
* 0: no small factor (possible prime, more tests needed) |
* 1: certain prime |
* MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime |
* other negative: error |
*/ |
static int mpi_check_small_factors( const mbedtls_mpi *X ) |
{ |
int ret = 0; |
size_t i; |
mbedtls_mpi_uint r; |
if( ( X->p[0] & 1 ) == 0 ) |
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); |
for( i = 0; small_prime[i] > 0; i++ ) |
{ |
if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 ) |
return( 1 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) ); |
if( r == 0 ) |
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); |
} |
cleanup: |
return( ret ); |
} |
/* |
* Miller-Rabin pseudo-primality test (HAC 4.24) |
*/ |
static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret, count; |
size_t i, j, k, s; |
mbedtls_mpi W, R, T, A, RR; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( f_rng != NULL ); |
mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); |
mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); |
mbedtls_mpi_init( &RR ); |
/* |
* W = |X| - 1 |
* R = W >> lsb( W ) |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) ); |
s = mbedtls_mpi_lsb( &W ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) ); |
for( i = 0; i < rounds; i++ ) |
{ |
/* |
* pick a random A, 1 < A < |X| - 1 |
*/ |
count = 0; |
do { |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); |
j = mbedtls_mpi_bitlen( &A ); |
k = mbedtls_mpi_bitlen( &W ); |
if (j > k) { |
A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1; |
} |
if (count++ > 30) { |
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; |
goto cleanup; |
} |
} while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 || |
mbedtls_mpi_cmp_int( &A, 1 ) <= 0 ); |
/* |
* A = A^R mod |X| |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) ); |
if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 || |
mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) |
continue; |
j = 1; |
while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ) |
{ |
/* |
* A = A * A mod |X| |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) ); |
if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) |
break; |
j++; |
} |
/* |
* not prime if A != |X| - 1 or A == 1 |
*/ |
if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 || |
mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) |
{ |
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; |
break; |
} |
} |
cleanup: |
mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); |
mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A ); |
mbedtls_mpi_free( &RR ); |
return( ret ); |
} |
/* |
* Pseudo-primality test: small factors, then Miller-Rabin |
*/ |
int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
mbedtls_mpi XX; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( f_rng != NULL ); |
XX.s = 1; |
XX.n = X->n; |
XX.p = X->p; |
if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 || |
mbedtls_mpi_cmp_int( &XX, 1 ) == 0 ) |
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); |
if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 ) |
return( 0 ); |
if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) |
{ |
if( ret == 1 ) |
return( 0 ); |
return( ret ); |
} |
return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
/* |
* Pseudo-primality test, error probability 2^-80 |
*/ |
int mbedtls_mpi_is_prime( const mbedtls_mpi *X, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( f_rng != NULL ); |
/* |
* In the past our key generation aimed for an error rate of at most |
* 2^-80. Since this function is deprecated, aim for the same certainty |
* here as well. |
*/ |
return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) ); |
} |
#endif |
/* |
* Prime number generation |
* |
* To generate an RSA key in a way recommended by FIPS 186-4, both primes must |
* be either 1024 bits or 1536 bits long, and flags must contain |
* MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR. |
*/ |
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
#ifdef MBEDTLS_HAVE_INT64 |
// ceil(2^63.5) |
#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL |
#else |
// ceil(2^31.5) |
#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U |
#endif |
int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; |
size_t k, n; |
int rounds; |
mbedtls_mpi_uint r; |
mbedtls_mpi Y; |
MPI_VALIDATE_RET( X != NULL ); |
MPI_VALIDATE_RET( f_rng != NULL ); |
if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
mbedtls_mpi_init( &Y ); |
n = BITS_TO_LIMBS( nbits ); |
if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 ) |
{ |
/* |
* 2^-80 error probability, number of rounds chosen per HAC, table 4.4 |
*/ |
rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 : |
( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 : |
( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 ); |
} |
else |
{ |
/* |
* 2^-100 error probability, number of rounds computed based on HAC, |
* fact 4.48 |
*/ |
rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 : |
( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 : |
( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 : |
( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 ); |
} |
while( 1 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); |
/* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */ |
if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue; |
k = n * biL; |
if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) ); |
X->p[0] |= 1; |
if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 ) |
{ |
ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng ); |
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) |
goto cleanup; |
} |
else |
{ |
/* |
* An necessary condition for Y and X = 2Y + 1 to be prime |
* is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). |
* Make sure it is satisfied, while keeping X = 3 mod 4 |
*/ |
X->p[0] |= 2; |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) ); |
if( r == 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) ); |
else if( r == 1 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) ); |
/* Set Y = (X-1) / 2, which is X / 2 because X is odd */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) ); |
while( 1 ) |
{ |
/* |
* First, check small factors for X and Y |
* before doing Miller-Rabin on any of them |
*/ |
if( ( ret = mpi_check_small_factors( X ) ) == 0 && |
( ret = mpi_check_small_factors( &Y ) ) == 0 && |
( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) ) |
== 0 && |
( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) ) |
== 0 ) |
goto cleanup; |
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) |
goto cleanup; |
/* |
* Next candidates. We want to preserve Y = (X-1) / 2 and |
* Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) |
* so up Y by 6 and X by 12. |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); |
} |
} |
} |
cleanup: |
mbedtls_mpi_free( &Y ); |
return( ret ); |
} |
#endif /* MBEDTLS_GENPRIME */ |
#if defined(MBEDTLS_SELF_TEST) |
#define GCD_PAIR_COUNT 3 |
static const int gcd_pairs[GCD_PAIR_COUNT][3] = |
{ |
{ 693, 609, 21 }, |
{ 1764, 868, 28 }, |
{ 768454923, 542167814, 1 } |
}; |
/* |
* Checkup routine |
*/ |
int mbedtls_mpi_self_test( int verbose ) |
{ |
int ret, i; |
mbedtls_mpi A, E, N, X, Y, U, V; |
mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X ); |
mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16, |
"EFE021C2645FD1DC586E69184AF4A31E" \ |
"D5F53E93B5F123FA41680867BA110131" \ |
"944FE7952E2517337780CB0DB80E61AA" \ |
"E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16, |
"B2E7EFD37075B9F03FF989C7C5051C20" \ |
"34D2A323810251127E7BF8625A4F49A5" \ |
"F3E27F4DA8BD59C47D6DAABA4C8127BD" \ |
"5B5C25763222FEFCCFC38B832366C29E" ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16, |
"0066A198186C18C10B2F5ED9B522752A" \ |
"9830B69916E535C8F047518A889A43A5" \ |
"94B6BED27A168D31D4A52F88925AA8F5" ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, |
"602AB7ECA597A3D6B56FF9829A5E8B85" \ |
"9E857EA95A03512E2BAE7391688D264A" \ |
"A5663B0341DB9CCFD2C4C5F421FEC814" \ |
"8001B72E848A38CAE1C65F78E56ABDEF" \ |
"E12D3C039B8A02D6BE593F0BBBDA56F1" \ |
"ECF677152EF804370C1A305CAF3B5BF1" \ |
"30879B56C61DE584A0F53A2447A51E" ) ); |
if( verbose != 0 ) |
mbedtls_printf( " MPI test #1 (mul_mpi): " ); |
if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, |
"256567336059E52CAE22925474705F39A94" ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16, |
"6613F26162223DF488E9CD48CC132C7A" \ |
"0AC93C701B001B092E4E5B9F73BCD27B" \ |
"9EE50D0657C77F374E903CDFA4C642" ) ); |
if( verbose != 0 ) |
mbedtls_printf( " MPI test #2 (div_mpi): " ); |
if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 || |
mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, |
"36E139AEA55215609D2816998ED020BB" \ |
"BD96C37890F65171D948E9BC7CBAA4D9" \ |
"325D24D6A3C12710F10A09FA08AB87" ) ); |
if( verbose != 0 ) |
mbedtls_printf( " MPI test #3 (exp_mod): " ); |
if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, |
"003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ |
"C3DBA76456363A10869622EAC2DD84EC" \ |
"C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); |
if( verbose != 0 ) |
mbedtls_printf( " MPI test #4 (inv_mod): " ); |
if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " MPI test #5 (simple gcd): " ); |
for( i = 0; i < GCD_PAIR_COUNT; i++ ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) ); |
if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed at %d\n", i ); |
ret = 1; |
goto cleanup; |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
cleanup: |
if( ret != 0 && verbose != 0 ) |
mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); |
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X ); |
mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V ); |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_BIGNUM_C */ |
/programs/develop/libraries/kos_mbedtls/library/blowfish.c |
---|
0,0 → 1,698 |
/* |
* Blowfish implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The Blowfish block cipher was designed by Bruce Schneier in 1993. |
* http://www.schneier.com/blowfish.html |
* http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 |
* |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_BLOWFISH_C) |
#include "mbedtls/blowfish.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if !defined(MBEDTLS_BLOWFISH_ALT) |
/* Parameter validation macros */ |
#define BLOWFISH_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ) |
#define BLOWFISH_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_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 uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = { |
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, |
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, |
0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, |
0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, |
0x9216D5D9L, 0x8979FB1BL |
}; |
/* declarations of data at the end of this file */ |
static const uint32_t S[4][256]; |
static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x ) |
{ |
unsigned short a, b, c, d; |
uint32_t y; |
d = (unsigned short)(x & 0xFF); |
x >>= 8; |
c = (unsigned short)(x & 0xFF); |
x >>= 8; |
b = (unsigned short)(x & 0xFF); |
x >>= 8; |
a = (unsigned short)(x & 0xFF); |
y = ctx->S[0][a] + ctx->S[1][b]; |
y = y ^ ctx->S[2][c]; |
y = y + ctx->S[3][d]; |
return( y ); |
} |
static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) |
{ |
uint32_t Xl, Xr, temp; |
short i; |
Xl = *xl; |
Xr = *xr; |
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i ) |
{ |
Xl = Xl ^ ctx->P[i]; |
Xr = F( ctx, Xl ) ^ Xr; |
temp = Xl; |
Xl = Xr; |
Xr = temp; |
} |
temp = Xl; |
Xl = Xr; |
Xr = temp; |
Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS]; |
Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1]; |
*xl = Xl; |
*xr = Xr; |
} |
static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) |
{ |
uint32_t Xl, Xr, temp; |
short i; |
Xl = *xl; |
Xr = *xr; |
for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i ) |
{ |
Xl = Xl ^ ctx->P[i]; |
Xr = F( ctx, Xl ) ^ Xr; |
temp = Xl; |
Xl = Xr; |
Xr = temp; |
} |
temp = Xl; |
Xl = Xr; |
Xr = temp; |
Xr = Xr ^ ctx->P[1]; |
Xl = Xl ^ ctx->P[0]; |
*xl = Xl; |
*xr = Xr; |
} |
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ) |
{ |
BLOWFISH_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_blowfish_context ) ); |
} |
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) ); |
} |
/* |
* Blowfish key schedule |
*/ |
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, |
const unsigned char *key, |
unsigned int keybits ) |
{ |
unsigned int i, j, k; |
uint32_t data, datal, datar; |
BLOWFISH_VALIDATE_RET( ctx != NULL ); |
BLOWFISH_VALIDATE_RET( key != NULL ); |
if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || |
keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS || |
keybits % 8 != 0 ) |
{ |
return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); |
} |
keybits >>= 3; |
for( i = 0; i < 4; i++ ) |
{ |
for( j = 0; j < 256; j++ ) |
ctx->S[i][j] = S[i][j]; |
} |
j = 0; |
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i ) |
{ |
data = 0x00000000; |
for( k = 0; k < 4; ++k ) |
{ |
data = ( data << 8 ) | key[j++]; |
if( j >= keybits ) |
j = 0; |
} |
ctx->P[i] = P[i] ^ data; |
} |
datal = 0x00000000; |
datar = 0x00000000; |
for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 ) |
{ |
blowfish_enc( ctx, &datal, &datar ); |
ctx->P[i] = datal; |
ctx->P[i + 1] = datar; |
} |
for( i = 0; i < 4; i++ ) |
{ |
for( j = 0; j < 256; j += 2 ) |
{ |
blowfish_enc( ctx, &datal, &datar ); |
ctx->S[i][j] = datal; |
ctx->S[i][j + 1] = datar; |
} |
} |
return( 0 ); |
} |
/* |
* Blowfish-ECB block encryption/decryption |
*/ |
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, |
int mode, |
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], |
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ) |
{ |
uint32_t X0, X1; |
BLOWFISH_VALIDATE_RET( ctx != NULL ); |
BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || |
mode == MBEDTLS_BLOWFISH_DECRYPT ); |
BLOWFISH_VALIDATE_RET( input != NULL ); |
BLOWFISH_VALIDATE_RET( output != NULL ); |
GET_UINT32_BE( X0, input, 0 ); |
GET_UINT32_BE( X1, input, 4 ); |
if( mode == MBEDTLS_BLOWFISH_DECRYPT ) |
{ |
blowfish_dec( ctx, &X0, &X1 ); |
} |
else /* MBEDTLS_BLOWFISH_ENCRYPT */ |
{ |
blowfish_enc( ctx, &X0, &X1 ); |
} |
PUT_UINT32_BE( X0, output, 0 ); |
PUT_UINT32_BE( X1, output, 4 ); |
return( 0 ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* Blowfish-CBC buffer encryption/decryption |
*/ |
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int i; |
unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE]; |
BLOWFISH_VALIDATE_RET( ctx != NULL ); |
BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || |
mode == MBEDTLS_BLOWFISH_DECRYPT ); |
BLOWFISH_VALIDATE_RET( iv != NULL ); |
BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); |
BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); |
if( length % MBEDTLS_BLOWFISH_BLOCKSIZE ) |
return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); |
if( mode == MBEDTLS_BLOWFISH_DECRYPT ) |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE ); |
mbedtls_blowfish_crypt_ecb( ctx, mode, input, output ); |
for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ ) |
output[i] = (unsigned char)( output[i] ^ iv[i] ); |
memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE ); |
input += MBEDTLS_BLOWFISH_BLOCKSIZE; |
output += MBEDTLS_BLOWFISH_BLOCKSIZE; |
length -= MBEDTLS_BLOWFISH_BLOCKSIZE; |
} |
} |
else |
{ |
while( length > 0 ) |
{ |
for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ ) |
output[i] = (unsigned char)( input[i] ^ iv[i] ); |
mbedtls_blowfish_crypt_ecb( ctx, mode, output, output ); |
memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE ); |
input += MBEDTLS_BLOWFISH_BLOCKSIZE; |
output += MBEDTLS_BLOWFISH_BLOCKSIZE; |
length -= MBEDTLS_BLOWFISH_BLOCKSIZE; |
} |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/* |
* Blowfish CFB buffer encryption/decryption |
*/ |
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c; |
size_t n; |
BLOWFISH_VALIDATE_RET( ctx != NULL ); |
BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT || |
mode == MBEDTLS_BLOWFISH_DECRYPT ); |
BLOWFISH_VALIDATE_RET( iv != NULL ); |
BLOWFISH_VALIDATE_RET( iv_off != NULL ); |
BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); |
BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); |
n = *iv_off; |
if( n >= 8 ) |
return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); |
if( mode == MBEDTLS_BLOWFISH_DECRYPT ) |
{ |
while( length-- ) |
{ |
if( n == 0 ) |
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); |
c = *input++; |
*output++ = (unsigned char)( c ^ iv[n] ); |
iv[n] = (unsigned char) c; |
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; |
} |
} |
else |
{ |
while( length-- ) |
{ |
if( n == 0 ) |
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); |
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); |
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; |
} |
} |
*iv_off = n; |
return( 0 ); |
} |
#endif /*MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* Blowfish CTR buffer encryption/decryption |
*/ |
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], |
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c, i; |
size_t n; |
BLOWFISH_VALIDATE_RET( ctx != NULL ); |
BLOWFISH_VALIDATE_RET( nonce_counter != NULL ); |
BLOWFISH_VALIDATE_RET( stream_block != NULL ); |
BLOWFISH_VALIDATE_RET( nc_off != NULL ); |
BLOWFISH_VALIDATE_RET( length == 0 || input != NULL ); |
BLOWFISH_VALIDATE_RET( length == 0 || output != NULL ); |
n = *nc_off; |
if( n >= 8 ) |
return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA ); |
while( length-- ) |
{ |
if( n == 0 ) { |
mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter, |
stream_block ); |
for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- ) |
if( ++nonce_counter[i - 1] != 0 ) |
break; |
} |
c = *input++; |
*output++ = (unsigned char)( c ^ stream_block[n] ); |
n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; |
} |
*nc_off = n; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
static const uint32_t S[4][256] = { |
{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, |
0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, |
0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, |
0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, |
0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, |
0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, |
0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, |
0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, |
0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, |
0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, |
0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, |
0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, |
0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, |
0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, |
0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, |
0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, |
0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, |
0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, |
0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, |
0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, |
0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, |
0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, |
0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, |
0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, |
0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, |
0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, |
0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, |
0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, |
0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, |
0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, |
0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, |
0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, |
0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, |
0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, |
0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, |
0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, |
0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, |
0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, |
0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, |
0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, |
0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, |
0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, |
0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, |
0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, |
0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, |
0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, |
0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, |
0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, |
0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, |
0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, |
0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, |
0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, |
0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, |
0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, |
0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, |
0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, |
0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, |
0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, |
0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, |
0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, |
0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, |
0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, |
0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, |
0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, |
{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, |
0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, |
0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, |
0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, |
0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, |
0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, |
0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, |
0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, |
0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, |
0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, |
0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, |
0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, |
0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, |
0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, |
0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, |
0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, |
0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, |
0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, |
0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, |
0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, |
0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, |
0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, |
0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, |
0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, |
0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, |
0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, |
0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, |
0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, |
0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, |
0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, |
0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, |
0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, |
0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, |
0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, |
0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, |
0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, |
0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, |
0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, |
0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, |
0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, |
0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, |
0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, |
0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, |
0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, |
0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, |
0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, |
0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, |
0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, |
0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, |
0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, |
0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, |
0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, |
0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, |
0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, |
0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, |
0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, |
0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, |
0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, |
0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, |
0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, |
0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, |
0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, |
0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, |
0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, |
{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, |
0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, |
0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, |
0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, |
0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, |
0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, |
0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, |
0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, |
0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, |
0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, |
0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, |
0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, |
0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, |
0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, |
0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, |
0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, |
0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, |
0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, |
0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, |
0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, |
0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, |
0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, |
0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, |
0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, |
0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, |
0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, |
0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, |
0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, |
0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, |
0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, |
0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, |
0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, |
0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, |
0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, |
0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, |
0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, |
0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, |
0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, |
0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, |
0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, |
0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, |
0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, |
0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, |
0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, |
0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, |
0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, |
0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, |
0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, |
0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, |
0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, |
0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, |
0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, |
0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, |
0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, |
0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, |
0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, |
0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, |
0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, |
0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, |
0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, |
0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, |
0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, |
0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, |
0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, |
{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, |
0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, |
0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, |
0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, |
0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, |
0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, |
0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, |
0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, |
0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, |
0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, |
0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, |
0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, |
0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, |
0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, |
0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, |
0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, |
0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, |
0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, |
0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, |
0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, |
0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, |
0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, |
0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, |
0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, |
0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, |
0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, |
0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, |
0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, |
0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, |
0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, |
0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, |
0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, |
0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, |
0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, |
0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, |
0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, |
0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, |
0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, |
0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, |
0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, |
0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, |
0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, |
0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, |
0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, |
0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, |
0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, |
0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, |
0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, |
0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, |
0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, |
0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, |
0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, |
0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, |
0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, |
0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, |
0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, |
0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, |
0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, |
0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, |
0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, |
0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, |
0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, |
0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, |
0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } |
}; |
#endif /* !MBEDTLS_BLOWFISH_ALT */ |
#endif /* MBEDTLS_BLOWFISH_C */ |
/programs/develop/libraries/kos_mbedtls/library/camellia.c |
---|
0,0 → 1,1116 |
/* |
* Camellia implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The Camellia block cipher was designed by NTT and Mitsubishi Electric |
* Corporation. |
* |
* http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CAMELLIA_C) |
#include "mbedtls/camellia.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_CAMELLIA_ALT) |
/* Parameter validation macros */ |
#define CAMELLIA_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ) |
#define CAMELLIA_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_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 } |
}; |
#if defined(MBEDTLS_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 /* MBEDTLS_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 |
}; |
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 /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ |
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 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) | |
((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) | |
((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) | |
((uint32_t) SBOX4((I0 ) & 0xFF) ); |
I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) | |
((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) | |
((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) | |
((uint32_t) 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; |
} |
void mbedtls_camellia_init( mbedtls_camellia_context *ctx ) |
{ |
CAMELLIA_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_camellia_context ) ); |
} |
void mbedtls_camellia_free( mbedtls_camellia_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) ); |
} |
/* |
* Camellia key schedule (encryption) |
*/ |
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, |
const unsigned char *key, |
unsigned int keybits ) |
{ |
int idx; |
size_t i; |
uint32_t *RK; |
unsigned char t[64]; |
uint32_t SIGMA[6][2]; |
uint32_t KC[16]; |
uint32_t TK[20]; |
CAMELLIA_VALIDATE_RET( ctx != NULL ); |
CAMELLIA_VALIDATE_RET( key != NULL ); |
RK = ctx->rk; |
memset( t, 0, 64 ); |
memset( RK, 0, sizeof(ctx->rk) ); |
switch( keybits ) |
{ |
case 128: ctx->nr = 3; idx = 0; break; |
case 192: |
case 256: ctx->nr = 4; idx = 1; break; |
default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); |
} |
for( i = 0; i < keybits / 8; ++i ) |
t[i] = key[i]; |
if( keybits == 192 ) { |
for( i = 0; i < 8; i++ ) |
t[24 + i] = ~t[16 + i]; |
} |
/* |
* Prepare SIGMA values |
*/ |
for( i = 0; i < 6; i++ ) { |
GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); |
GET_UINT32_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_UINT32_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( keybits > 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( keybits > 128 ) { |
SHIFT_AND_PLACE( idx, 1 ); |
} |
/* Manipulating KA */ |
SHIFT_AND_PLACE( idx, 2 ); |
/* Manipulating KB */ |
if( keybits > 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 mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, |
const unsigned char *key, |
unsigned int keybits ) |
{ |
int idx, ret; |
size_t i; |
mbedtls_camellia_context cty; |
uint32_t *RK; |
uint32_t *SK; |
CAMELLIA_VALIDATE_RET( ctx != NULL ); |
CAMELLIA_VALIDATE_RET( key != NULL ); |
mbedtls_camellia_init( &cty ); |
/* Also checks keybits */ |
if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 ) |
goto exit; |
ctx->nr = cty.nr; |
idx = ( ctx->nr == 4 ); |
RK = ctx->rk; |
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++; |
exit: |
mbedtls_camellia_free( &cty ); |
return( ret ); |
} |
/* |
* Camellia-ECB block encryption/decryption |
*/ |
int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
int NR; |
uint32_t *RK, X[4]; |
CAMELLIA_VALIDATE_RET( ctx != NULL ); |
CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || |
mode == MBEDTLS_CAMELLIA_DECRYPT ); |
CAMELLIA_VALIDATE_RET( input != NULL ); |
CAMELLIA_VALIDATE_RET( output != NULL ); |
( (void) mode ); |
NR = ctx->nr; |
RK = ctx->rk; |
GET_UINT32_BE( X[0], input, 0 ); |
GET_UINT32_BE( X[1], input, 4 ); |
GET_UINT32_BE( X[2], input, 8 ); |
GET_UINT32_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_UINT32_BE( X[2], output, 0 ); |
PUT_UINT32_BE( X[3], output, 4 ); |
PUT_UINT32_BE( X[0], output, 8 ); |
PUT_UINT32_BE( X[1], output, 12 ); |
return( 0 ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* Camellia-CBC buffer encryption/decryption |
*/ |
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int i; |
unsigned char temp[16]; |
CAMELLIA_VALIDATE_RET( ctx != NULL ); |
CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || |
mode == MBEDTLS_CAMELLIA_DECRYPT ); |
CAMELLIA_VALIDATE_RET( iv != NULL ); |
CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); |
CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); |
if( length % 16 ) |
return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH ); |
if( mode == MBEDTLS_CAMELLIA_DECRYPT ) |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, 16 ); |
mbedtls_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] ); |
mbedtls_camellia_crypt_ecb( ctx, mode, output, output ); |
memcpy( iv, output, 16 ); |
input += 16; |
output += 16; |
length -= 16; |
} |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
/* |
* Camellia-CFB128 buffer encryption/decryption |
*/ |
int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, |
int mode, |
size_t length, |
size_t *iv_off, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c; |
size_t n; |
CAMELLIA_VALIDATE_RET( ctx != NULL ); |
CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT || |
mode == MBEDTLS_CAMELLIA_DECRYPT ); |
CAMELLIA_VALIDATE_RET( iv != NULL ); |
CAMELLIA_VALIDATE_RET( iv_off != NULL ); |
CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); |
CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); |
n = *iv_off; |
if( n >= 16 ) |
return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); |
if( mode == MBEDTLS_CAMELLIA_DECRYPT ) |
{ |
while( length-- ) |
{ |
if( n == 0 ) |
mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_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 ) |
mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); |
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); |
n = ( n + 1 ) & 0x0F; |
} |
} |
*iv_off = n; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* Camellia-CTR buffer encryption/decryption |
*/ |
int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, |
size_t length, |
size_t *nc_off, |
unsigned char nonce_counter[16], |
unsigned char stream_block[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int c, i; |
size_t n; |
CAMELLIA_VALIDATE_RET( ctx != NULL ); |
CAMELLIA_VALIDATE_RET( nonce_counter != NULL ); |
CAMELLIA_VALIDATE_RET( stream_block != NULL ); |
CAMELLIA_VALIDATE_RET( nc_off != NULL ); |
CAMELLIA_VALIDATE_RET( length == 0 || input != NULL ); |
CAMELLIA_VALIDATE_RET( length == 0 || output != NULL ); |
n = *nc_off; |
if( n >= 16 ) |
return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA ); |
while( length-- ) |
{ |
if( n == 0 ) { |
mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter, |
stream_block ); |
for( i = 16; i > 0; i-- ) |
if( ++nonce_counter[i - 1] != 0 ) |
break; |
} |
c = *input++; |
*output++ = (unsigned char)( c ^ stream_block[n] ); |
n = ( n + 1 ) & 0x0F; |
} |
*nc_off = n; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#endif /* !MBEDTLS_CAMELLIA_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* 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 } |
} |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#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 } |
} |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* Camellia-CTR test vectors from: |
* |
* http://www.faqs.org/rfcs/rfc5528.html |
*/ |
static const unsigned char camellia_test_ctr_key[3][16] = |
{ |
{ 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, |
0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, |
{ 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, |
0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, |
{ 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, |
0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } |
}; |
static const unsigned char camellia_test_ctr_nonce_counter[3][16] = |
{ |
{ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, |
{ 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, |
0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, |
{ 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, |
0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } |
}; |
static const unsigned char camellia_test_ctr_pt[3][48] = |
{ |
{ 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, |
0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, |
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, |
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, |
0x20, 0x21, 0x22, 0x23 } |
}; |
static const unsigned char camellia_test_ctr_ct[3][48] = |
{ |
{ 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, |
0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, |
{ 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, |
0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, |
0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, |
0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, |
{ 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, |
0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, |
0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, |
0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, |
0xDF, 0x50, 0x86, 0x96 } |
}; |
static const int camellia_test_ctr_len[3] = |
{ 16, 32, 36 }; |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
/* |
* Checkup routine |
*/ |
int mbedtls_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]; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
unsigned char iv[16]; |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
size_t offset, len; |
unsigned char nonce_counter[16]; |
unsigned char stream_block[16]; |
#endif |
mbedtls_camellia_context ctx; |
memset( key, 0, 32 ); |
for( j = 0; j < 6; j++ ) { |
u = j >> 1; |
v = j & 1; |
if( verbose != 0 ) |
mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, |
(v == MBEDTLS_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 == MBEDTLS_CAMELLIA_DECRYPT ) { |
mbedtls_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 { /* MBEDTLS_CAMELLIA_ENCRYPT */ |
mbedtls_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 ); |
} |
mbedtls_camellia_crypt_ecb( &ctx, v, src, buf ); |
if( memcmp( buf, dst, 16 ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* CBC mode |
*/ |
for( j = 0; j < 6; j++ ) |
{ |
u = j >> 1; |
v = j & 1; |
if( verbose != 0 ) |
mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, |
( v == MBEDTLS_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 == MBEDTLS_CAMELLIA_DECRYPT ) { |
mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); |
} else { |
mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); |
} |
for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { |
if( v == MBEDTLS_CAMELLIA_DECRYPT ) { |
memcpy( iv , src, 16 ); |
memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); |
memcpy( dst, camellia_test_cbc_plain[i], 16 ); |
} else { /* MBEDTLS_CAMELLIA_ENCRYPT */ |
memcpy( iv , dst, 16 ); |
memcpy( src, camellia_test_cbc_plain[i], 16 ); |
memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); |
} |
mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); |
if( memcmp( buf, dst, 16 ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
/* |
* CTR mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
v = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " CAMELLIA-CTR-128 (%s): ", |
( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); |
memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); |
memcpy( key, camellia_test_ctr_key[u], 16 ); |
offset = 0; |
mbedtls_camellia_setkey_enc( &ctx, key, 128 ); |
if( v == MBEDTLS_CAMELLIA_DECRYPT ) |
{ |
len = camellia_test_ctr_len[u]; |
memcpy( buf, camellia_test_ctr_ct[u], len ); |
mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, |
buf, buf ); |
if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
} |
else |
{ |
len = camellia_test_ctr_len[u]; |
memcpy( buf, camellia_test_ctr_pt[u], len ); |
mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, |
buf, buf ); |
if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
/programs/develop/libraries/kos_mbedtls/library/ccm.c |
---|
0,0 → 1,547 |
/* |
* NIST SP800-38C compliant CCM implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* Definition of CCM: |
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf |
* RFC 3610 "Counter with CBC-MAC (CCM)" |
* |
* Related: |
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption" |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CCM_C) |
#include "mbedtls/ccm.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#if !defined(MBEDTLS_CCM_ALT) |
#define CCM_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT ) |
#define CCM_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#define CCM_ENCRYPT 0 |
#define CCM_DECRYPT 1 |
/* |
* Initialize context |
*/ |
void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) |
{ |
CCM_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); |
} |
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, |
mbedtls_cipher_id_t cipher, |
const unsigned char *key, |
unsigned int keybits ) |
{ |
int ret; |
const mbedtls_cipher_info_t *cipher_info; |
CCM_VALIDATE_RET( ctx != NULL ); |
CCM_VALIDATE_RET( key != NULL ); |
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
if( cipher_info->block_size != 16 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
mbedtls_cipher_free( &ctx->cipher_ctx ); |
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, |
MBEDTLS_ENCRYPT ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
/* |
* Free context |
*/ |
void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_cipher_free( &ctx->cipher_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); |
} |
/* |
* Macros for common operations. |
* Results in smaller compiled code than static inline functions. |
*/ |
/* |
* Update the CBC-MAC state in y using a block in b |
* (Always using b as the source helps the compiler optimise a bit better.) |
*/ |
#define UPDATE_CBC_MAC \ |
for( i = 0; i < 16; i++ ) \ |
y[i] ^= b[i]; \ |
\ |
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ |
return( ret ); |
/* |
* Encrypt or decrypt a partial block with CTR |
* Warning: using b for temporary storage! src and dst must not be b! |
* This avoids allocating one more 16 bytes buffer while allowing src == dst. |
*/ |
#define CTR_CRYPT( dst, src, len ) \ |
do \ |
{ \ |
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \ |
16, b, &olen ) ) != 0 ) \ |
{ \ |
return( ret ); \ |
} \ |
\ |
for( i = 0; i < (len); i++ ) \ |
(dst)[i] = (src)[i] ^ b[i]; \ |
} while( 0 ) |
/* |
* Authenticated encryption or decryption |
*/ |
static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
unsigned char *tag, size_t tag_len ) |
{ |
int ret; |
unsigned char i; |
unsigned char q; |
size_t len_left, olen; |
unsigned char b[16]; |
unsigned char y[16]; |
unsigned char ctr[16]; |
const unsigned char *src; |
unsigned char *dst; |
/* |
* Check length requirements: SP800-38C A.1 |
* Additional requirement: a < 2^16 - 2^8 to simplify the code. |
* 'length' checked later (when writing it to the first block) |
* |
* Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). |
*/ |
if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
/* Also implies q is within bounds */ |
if( iv_len < 7 || iv_len > 13 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
if( add_len > 0xFF00 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
q = 16 - 1 - (unsigned char) iv_len; |
/* |
* First block B_0: |
* 0 .. 0 flags |
* 1 .. iv_len nonce (aka iv) |
* iv_len+1 .. 15 length |
* |
* With flags as (bits): |
* 7 0 |
* 6 add present? |
* 5 .. 3 (t - 2) / 2 |
* 2 .. 0 q - 1 |
*/ |
b[0] = 0; |
b[0] |= ( add_len > 0 ) << 6; |
b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; |
b[0] |= q - 1; |
memcpy( b + 1, iv, iv_len ); |
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) |
b[15-i] = (unsigned char)( len_left & 0xFF ); |
if( len_left > 0 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
/* Start CBC-MAC with first block */ |
memset( y, 0, 16 ); |
UPDATE_CBC_MAC; |
/* |
* If there is additional data, update CBC-MAC with |
* add_len, add, 0 (padding to a block boundary) |
*/ |
if( add_len > 0 ) |
{ |
size_t use_len; |
len_left = add_len; |
src = add; |
memset( b, 0, 16 ); |
b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); |
b[1] = (unsigned char)( ( add_len ) & 0xFF ); |
use_len = len_left < 16 - 2 ? len_left : 16 - 2; |
memcpy( b + 2, src, use_len ); |
len_left -= use_len; |
src += use_len; |
UPDATE_CBC_MAC; |
while( len_left > 0 ) |
{ |
use_len = len_left > 16 ? 16 : len_left; |
memset( b, 0, 16 ); |
memcpy( b, src, use_len ); |
UPDATE_CBC_MAC; |
len_left -= use_len; |
src += use_len; |
} |
} |
/* |
* Prepare counter block for encryption: |
* 0 .. 0 flags |
* 1 .. iv_len nonce (aka iv) |
* iv_len+1 .. 15 counter (initially 1) |
* |
* With flags as (bits): |
* 7 .. 3 0 |
* 2 .. 0 q - 1 |
*/ |
ctr[0] = q - 1; |
memcpy( ctr + 1, iv, iv_len ); |
memset( ctr + 1 + iv_len, 0, q ); |
ctr[15] = 1; |
/* |
* Authenticate and {en,de}crypt the message. |
* |
* The only difference between encryption and decryption is |
* the respective order of authentication and {en,de}cryption. |
*/ |
len_left = length; |
src = input; |
dst = output; |
while( len_left > 0 ) |
{ |
size_t use_len = len_left > 16 ? 16 : len_left; |
if( mode == CCM_ENCRYPT ) |
{ |
memset( b, 0, 16 ); |
memcpy( b, src, use_len ); |
UPDATE_CBC_MAC; |
} |
CTR_CRYPT( dst, src, use_len ); |
if( mode == CCM_DECRYPT ) |
{ |
memset( b, 0, 16 ); |
memcpy( b, dst, use_len ); |
UPDATE_CBC_MAC; |
} |
dst += use_len; |
src += use_len; |
len_left -= use_len; |
/* |
* Increment counter. |
* No need to check for overflow thanks to the length check above. |
*/ |
for( i = 0; i < q; i++ ) |
if( ++ctr[15-i] != 0 ) |
break; |
} |
/* |
* Authentication: reset counter and crypt/mask internal tag |
*/ |
for( i = 0; i < q; i++ ) |
ctr[15-i] = 0; |
CTR_CRYPT( y, y, 16 ); |
memcpy( tag, y, tag_len ); |
return( 0 ); |
} |
/* |
* Authenticated encryption |
*/ |
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
unsigned char *tag, size_t tag_len ) |
{ |
CCM_VALIDATE_RET( ctx != NULL ); |
CCM_VALIDATE_RET( iv != NULL ); |
CCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
CCM_VALIDATE_RET( length == 0 || input != NULL ); |
CCM_VALIDATE_RET( length == 0 || output != NULL ); |
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, |
add, add_len, input, output, tag, tag_len ) ); |
} |
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
unsigned char *tag, size_t tag_len ) |
{ |
CCM_VALIDATE_RET( ctx != NULL ); |
CCM_VALIDATE_RET( iv != NULL ); |
CCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
CCM_VALIDATE_RET( length == 0 || input != NULL ); |
CCM_VALIDATE_RET( length == 0 || output != NULL ); |
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
if( tag_len == 0 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add, |
add_len, input, output, tag, tag_len ) ); |
} |
/* |
* Authenticated decryption |
*/ |
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
const unsigned char *tag, size_t tag_len ) |
{ |
int ret; |
unsigned char check_tag[16]; |
unsigned char i; |
int diff; |
CCM_VALIDATE_RET( ctx != NULL ); |
CCM_VALIDATE_RET( iv != NULL ); |
CCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
CCM_VALIDATE_RET( length == 0 || input != NULL ); |
CCM_VALIDATE_RET( length == 0 || output != NULL ); |
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, |
iv, iv_len, add, add_len, |
input, output, check_tag, tag_len ) ) != 0 ) |
{ |
return( ret ); |
} |
/* Check tag in "constant-time" */ |
for( diff = 0, i = 0; i < tag_len; i++ ) |
diff |= tag[i] ^ check_tag[i]; |
if( diff != 0 ) |
{ |
mbedtls_platform_zeroize( output, length ); |
return( MBEDTLS_ERR_CCM_AUTH_FAILED ); |
} |
return( 0 ); |
} |
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *add, size_t add_len, |
const unsigned char *input, unsigned char *output, |
const unsigned char *tag, size_t tag_len ) |
{ |
CCM_VALIDATE_RET( ctx != NULL ); |
CCM_VALIDATE_RET( iv != NULL ); |
CCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
CCM_VALIDATE_RET( length == 0 || input != NULL ); |
CCM_VALIDATE_RET( length == 0 || output != NULL ); |
CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
if( tag_len == 0 ) |
return( MBEDTLS_ERR_CCM_BAD_INPUT ); |
return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add, |
add_len, input, output, tag, tag_len ) ); |
} |
#endif /* !MBEDTLS_CCM_ALT */ |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
/* |
* Examples 1 to 3 from SP800-38C Appendix C |
*/ |
#define NB_TESTS 3 |
#define CCM_SELFTEST_PT_MAX_LEN 24 |
#define CCM_SELFTEST_CT_MAX_LEN 32 |
/* |
* The data is the same for all tests, only the used length changes |
*/ |
static const unsigned char key[] = { |
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, |
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f |
}; |
static const unsigned char iv[] = { |
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
0x18, 0x19, 0x1a, 0x1b |
}; |
static const unsigned char ad[] = { |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
0x10, 0x11, 0x12, 0x13 |
}; |
static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = { |
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, |
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, |
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
}; |
static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; |
static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; |
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; |
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; |
static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = { |
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, |
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, |
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, |
0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, |
{ 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, |
0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, |
0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, |
0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } |
}; |
int mbedtls_ccm_self_test( int verbose ) |
{ |
mbedtls_ccm_context ctx; |
/* |
* Some hardware accelerators require the input and output buffers |
* would be in RAM, because the flash is not accessible. |
* Use buffers on the stack to hold the test vectors data. |
*/ |
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN]; |
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN]; |
size_t i; |
int ret; |
mbedtls_ccm_init( &ctx ); |
if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " CCM: setup failed" ); |
return( 1 ); |
} |
for( i = 0; i < NB_TESTS; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); |
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); |
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN ); |
memcpy( plaintext, msg, msg_len[i] ); |
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], |
iv, iv_len[i], ad, add_len[i], |
plaintext, ciphertext, |
ciphertext + msg_len[i], tag_len[i] ); |
if( ret != 0 || |
memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN ); |
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], |
iv, iv_len[i], ad, add_len[i], |
ciphertext, plaintext, |
ciphertext + msg_len[i], tag_len[i] ); |
if( ret != 0 || |
memcmp( plaintext, msg, msg_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
mbedtls_ccm_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#endif /* MBEDTLS_CCM_C */ |
/programs/develop/libraries/kos_mbedtls/library/certs.c |
---|
0,0 → 1,1755 |
/* |
* X.509 test certificates |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "mbedtls/certs.h" |
#if defined(MBEDTLS_CERTS_C) |
/* |
* Test CA Certificates |
* |
* We define test CA certificates for each choice of the following parameters: |
* - PEM or DER encoding |
* - SHA-1 or SHA-256 hash |
* - RSA or EC key |
* |
* Things to add: |
* - multiple EC curve types |
* |
*/ |
/* This is taken from tests/data_files/test-ca2.crt */ |
/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca2.crt */ |
#define TEST_CA_CRT_EC_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIICBDCCAYigAwIBAgIJAMFD4n5iQ8zoMAwGCCqGSM49BAMCBQAwPjELMAkGA1UE\r\n" \ |
"BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ |
"IEVDIENBMB4XDTE5MDIxMDE0NDQwMFoXDTI5MDIxMDE0NDQwMFowPjELMAkGA1UE\r\n" \ |
"BhMCTkwxETAPBgNVBAoMCFBvbGFyU1NMMRwwGgYDVQQDDBNQb2xhcnNzbCBUZXN0\r\n" \ |
"IEVDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEw9orNEE3WC+HVv78ibopQ0tO\r\n" \ |
"4G7DDldTMzlY1FK0kZU5CyPfXxckYkj8GpUpziwth8KIUoCv1mqrId240xxuWLjK\r\n" \ |
"6LJpjvNBrSnDtF91p0dv1RkpVWmaUzsgtGYWYDMeo1AwTjAMBgNVHRMEBTADAQH/\r\n" \ |
"MB0GA1UdDgQWBBSdbSAkSQE/K8t4tRm8fiTJ2/s2fDAfBgNVHSMEGDAWgBSdbSAk\r\n" \ |
"SQE/K8t4tRm8fiTJ2/s2fDAMBggqhkjOPQQDAgUAA2gAMGUCMFHKrjAPpHB0BN1a\r\n" \ |
"LH8TwcJ3vh0AxeKZj30mRdOKBmg/jLS3rU3g8VQBHpn8sOTTBwIxANxPO5AerimZ\r\n" \ |
"hCjMe0d4CTHf1gFZMF70+IqEP+o5VHsIp2Cqvflb0VGWFC5l9a4cQg==\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is generated from tests/data_files/test-ca2.crt.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CA_CRT_EC_DER tests/data_files/test-ca2.crt.der */ |
#define TEST_CA_CRT_EC_DER { \ |
0x30, 0x82, 0x02, 0x04, 0x30, 0x82, 0x01, 0x88, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, \ |
0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, \ |
0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, \ |
0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, \ |
0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x50, \ |
0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, \ |
0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, \ |
0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, \ |
0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, \ |
0x30, 0x5a, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, \ |
0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, \ |
0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x50, \ |
0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, \ |
0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, \ |
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, \ |
0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xc3, 0xda, 0x2b, 0x34, 0x41, 0x37, \ |
0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, 0xba, 0x29, 0x43, 0x4b, 0x4e, \ |
0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, 0x39, 0x58, 0xd4, 0x52, 0xb4, \ |
0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, 0x17, 0x24, 0x62, 0x48, 0xfc, \ |
0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, 0xc2, 0x88, 0x52, 0x80, 0xaf, \ |
0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, 0x1c, 0x6e, 0x58, 0xb8, 0xca, \ |
0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, 0x29, 0xc3, 0xb4, 0x5f, 0x75, \ |
0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, 0x69, 0x9a, 0x53, 0x3b, 0x20, \ |
0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x0c, \ |
0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, \ |
0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, \ |
0x6d, 0x20, 0x24, 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, \ |
0x7e, 0x24, 0xc9, 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x1f, 0x06, 0x03, 0x55, \ |
0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, \ |
0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, \ |
0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ |
0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, \ |
0x30, 0x51, 0xca, 0xae, 0x30, 0x0f, 0xa4, 0x70, 0x74, 0x04, 0xdd, 0x5a, \ |
0x2c, 0x7f, 0x13, 0xc1, 0xc2, 0x77, 0xbe, 0x1d, 0x00, 0xc5, 0xe2, 0x99, \ |
0x8f, 0x7d, 0x26, 0x45, 0xd3, 0x8a, 0x06, 0x68, 0x3f, 0x8c, 0xb4, 0xb7, \ |
0xad, 0x4d, 0xe0, 0xf1, 0x54, 0x01, 0x1e, 0x99, 0xfc, 0xb0, 0xe4, 0xd3, \ |
0x07, 0x02, 0x31, 0x00, 0xdc, 0x4f, 0x3b, 0x90, 0x1e, 0xae, 0x29, 0x99, \ |
0x84, 0x28, 0xcc, 0x7b, 0x47, 0x78, 0x09, 0x31, 0xdf, 0xd6, 0x01, 0x59, \ |
0x30, 0x5e, 0xf4, 0xf8, 0x8a, 0x84, 0x3f, 0xea, 0x39, 0x54, 0x7b, 0x08, \ |
0xa7, 0x60, 0xaa, 0xbd, 0xf9, 0x5b, 0xd1, 0x51, 0x96, 0x14, 0x2e, 0x65, \ |
0xf5, 0xae, 0x1c, 0x42 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/test-ca2.key.enc */ |
/* BEGIN FILE string macro TEST_CA_KEY_EC_PEM tests/data_files/test-ca2.key.enc */ |
#define TEST_CA_KEY_EC_PEM \ |
"-----BEGIN EC PRIVATE KEY-----\r\n" \ |
"Proc-Type: 4,ENCRYPTED\r\n" \ |
"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" \ |
"\r\n" \ |
"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" \ |
"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" \ |
"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" \ |
"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" \ |
"-----END EC PRIVATE KEY-----\r\n" |
/* END FILE */ |
#define TEST_CA_PWD_EC_PEM "PolarSSLTest" |
/* This is generated from tests/data_files/test-ca2.key.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CA_KEY_EC_DER tests/data_files/test-ca2.key.der */ |
#define TEST_CA_KEY_EC_DER { \ |
0x30, 0x81, 0xa4, 0x02, 0x01, 0x01, 0x04, 0x30, 0x83, 0xd9, 0x15, 0x0e, \ |
0xa0, 0x71, 0xf0, 0x57, 0x10, 0x33, 0xa3, 0x38, 0xb8, 0x86, 0xc1, 0xa6, \ |
0x11, 0x5d, 0x6d, 0xb4, 0x03, 0xe1, 0x29, 0x76, 0x45, 0xd7, 0x87, 0x6f, \ |
0x23, 0xab, 0x44, 0x20, 0xea, 0x64, 0x7b, 0x85, 0xb1, 0x76, 0xe7, 0x85, \ |
0x95, 0xaa, 0x74, 0xd6, 0xd1, 0xa4, 0x5e, 0xea, 0xa0, 0x07, 0x06, 0x05, \ |
0x2b, 0x81, 0x04, 0x00, 0x22, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0xc3, \ |
0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, \ |
0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, \ |
0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, \ |
0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, \ |
0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, \ |
0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, \ |
0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, \ |
0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/test-ca-sha256.crt. */ |
/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA256_PEM tests/data_files/test-ca-sha256.crt */ |
#define TEST_CA_CRT_RSA_SHA256_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ |
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ |
"MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ |
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ |
"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ |
"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ |
"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ |
"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ |
"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ |
"UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ |
"MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBCwUA\r\n" \ |
"A4IBAQA4qFSCth2q22uJIdE4KGHJsJjVEfw2/xn+MkTvCMfxVrvmRvqCtjE4tKDl\r\n" \ |
"oK4MxFOek07oDZwvtAT9ijn1hHftTNS7RH9zd/fxNpfcHnMZXVC4w4DNA1fSANtW\r\n" \ |
"5sY1JB5Je9jScrsLSS+mAjyv0Ow3Hb2Bix8wu7xNNrV5fIf7Ubm+wt6SqEBxu3Kb\r\n" \ |
"+EfObAT4huf3czznhH3C17ed6NSbXwoXfby7stWUDeRJv08RaFOykf/Aae7bY5PL\r\n" \ |
"yTVrkAnikMntJ9YI+hNNYt3inqq11A5cN0+rVTst8UKCxzQ4GpvroSwPKTFkbMw4\r\n" \ |
"/anT1dVxr/BtwJfiESoK3/4CeXR1\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is generated from tests/data_files/test-ca-sha256.crt.der |
* using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA256_DER tests/data_files/test-ca-sha256.crt.der */ |
#define TEST_CA_CRT_RSA_SHA256_DER { \ |
0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ |
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ |
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ |
0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ |
0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ |
0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ |
0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ |
0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ |
0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ |
0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ |
0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ |
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ |
0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ |
0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ |
0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ |
0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ |
0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ |
0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ |
0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ |
0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ |
0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ |
0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ |
0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ |
0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ |
0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ |
0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ |
0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ |
0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ |
0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ |
0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ |
0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ |
0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ |
0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ |
0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ |
0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ |
0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ |
0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ |
0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ |
0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ |
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ |
0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ |
0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ |
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, \ |
0x03, 0x82, 0x01, 0x01, 0x00, 0x38, 0xa8, 0x54, 0x82, 0xb6, 0x1d, 0xaa, \ |
0xdb, 0x6b, 0x89, 0x21, 0xd1, 0x38, 0x28, 0x61, 0xc9, 0xb0, 0x98, 0xd5, \ |
0x11, 0xfc, 0x36, 0xff, 0x19, 0xfe, 0x32, 0x44, 0xef, 0x08, 0xc7, 0xf1, \ |
0x56, 0xbb, 0xe6, 0x46, 0xfa, 0x82, 0xb6, 0x31, 0x38, 0xb4, 0xa0, 0xe5, \ |
0xa0, 0xae, 0x0c, 0xc4, 0x53, 0x9e, 0x93, 0x4e, 0xe8, 0x0d, 0x9c, 0x2f, \ |
0xb4, 0x04, 0xfd, 0x8a, 0x39, 0xf5, 0x84, 0x77, 0xed, 0x4c, 0xd4, 0xbb, \ |
0x44, 0x7f, 0x73, 0x77, 0xf7, 0xf1, 0x36, 0x97, 0xdc, 0x1e, 0x73, 0x19, \ |
0x5d, 0x50, 0xb8, 0xc3, 0x80, 0xcd, 0x03, 0x57, 0xd2, 0x00, 0xdb, 0x56, \ |
0xe6, 0xc6, 0x35, 0x24, 0x1e, 0x49, 0x7b, 0xd8, 0xd2, 0x72, 0xbb, 0x0b, \ |
0x49, 0x2f, 0xa6, 0x02, 0x3c, 0xaf, 0xd0, 0xec, 0x37, 0x1d, 0xbd, 0x81, \ |
0x8b, 0x1f, 0x30, 0xbb, 0xbc, 0x4d, 0x36, 0xb5, 0x79, 0x7c, 0x87, 0xfb, \ |
0x51, 0xb9, 0xbe, 0xc2, 0xde, 0x92, 0xa8, 0x40, 0x71, 0xbb, 0x72, 0x9b, \ |
0xf8, 0x47, 0xce, 0x6c, 0x04, 0xf8, 0x86, 0xe7, 0xf7, 0x73, 0x3c, 0xe7, \ |
0x84, 0x7d, 0xc2, 0xd7, 0xb7, 0x9d, 0xe8, 0xd4, 0x9b, 0x5f, 0x0a, 0x17, \ |
0x7d, 0xbc, 0xbb, 0xb2, 0xd5, 0x94, 0x0d, 0xe4, 0x49, 0xbf, 0x4f, 0x11, \ |
0x68, 0x53, 0xb2, 0x91, 0xff, 0xc0, 0x69, 0xee, 0xdb, 0x63, 0x93, 0xcb, \ |
0xc9, 0x35, 0x6b, 0x90, 0x09, 0xe2, 0x90, 0xc9, 0xed, 0x27, 0xd6, 0x08, \ |
0xfa, 0x13, 0x4d, 0x62, 0xdd, 0xe2, 0x9e, 0xaa, 0xb5, 0xd4, 0x0e, 0x5c, \ |
0x37, 0x4f, 0xab, 0x55, 0x3b, 0x2d, 0xf1, 0x42, 0x82, 0xc7, 0x34, 0x38, \ |
0x1a, 0x9b, 0xeb, 0xa1, 0x2c, 0x0f, 0x29, 0x31, 0x64, 0x6c, 0xcc, 0x38, \ |
0xfd, 0xa9, 0xd3, 0xd5, 0xd5, 0x71, 0xaf, 0xf0, 0x6d, 0xc0, 0x97, 0xe2, \ |
0x11, 0x2a, 0x0a, 0xdf, 0xfe, 0x02, 0x79, 0x74, 0x75 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/test-ca-sha1.crt. */ |
/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA1_PEM tests/data_files/test-ca-sha1.crt */ |
#define TEST_CA_CRT_RSA_SHA1_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ |
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ |
"MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ |
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ |
"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ |
"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ |
"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ |
"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ |
"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ |
"UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ |
"MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \ |
"A4IBAQB0ZiNRFdia6kskaPnhrqejIRq8YMEGAf2oIPnyZ78xoyERgc35lHGyMtsL\r\n" \ |
"hWicNjP4d/hS9As4j5KA2gdNGi5ETA1X7SowWOGsryivSpMSHVy1+HdfWlsYQOzm\r\n" \ |
"8o+faQNUm8XzPVmttfAVspxeHSxJZ36Oo+QWZ5wZlCIEyjEdLUId+Tm4Bz3B5jRD\r\n" \ |
"zZa/SaqDokq66N2zpbgKKAl3GU2O++fBqP2dSkdQykmTxhLLWRN8FJqhYATyQntZ\r\n" \ |
"0QSi3W9HfSZPnFTcPIXeoiPd2pLlxt1hZu8dws2LTXE63uP6MM4LHvWxiuJaWkP/\r\n" \ |
"mtxyUALj2pQxRitopORFQdn7AOY5\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is taken from tests/data_files/test-ca-sha1.crt.der. */ |
/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA1_DER tests/data_files/test-ca-sha1.crt.der */ |
#define TEST_CA_CRT_RSA_SHA1_DER { \ |
0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ |
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ |
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ |
0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ |
0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ |
0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ |
0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ |
0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ |
0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ |
0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ |
0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ |
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ |
0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ |
0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ |
0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ |
0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ |
0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ |
0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ |
0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ |
0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ |
0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ |
0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ |
0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ |
0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ |
0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ |
0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ |
0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ |
0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ |
0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ |
0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ |
0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ |
0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ |
0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ |
0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ |
0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ |
0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ |
0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ |
0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ |
0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ |
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ |
0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ |
0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ |
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \ |
0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0x66, 0x23, 0x51, 0x15, 0xd8, 0x9a, \ |
0xea, 0x4b, 0x24, 0x68, 0xf9, 0xe1, 0xae, 0xa7, 0xa3, 0x21, 0x1a, 0xbc, \ |
0x60, 0xc1, 0x06, 0x01, 0xfd, 0xa8, 0x20, 0xf9, 0xf2, 0x67, 0xbf, 0x31, \ |
0xa3, 0x21, 0x11, 0x81, 0xcd, 0xf9, 0x94, 0x71, 0xb2, 0x32, 0xdb, 0x0b, \ |
0x85, 0x68, 0x9c, 0x36, 0x33, 0xf8, 0x77, 0xf8, 0x52, 0xf4, 0x0b, 0x38, \ |
0x8f, 0x92, 0x80, 0xda, 0x07, 0x4d, 0x1a, 0x2e, 0x44, 0x4c, 0x0d, 0x57, \ |
0xed, 0x2a, 0x30, 0x58, 0xe1, 0xac, 0xaf, 0x28, 0xaf, 0x4a, 0x93, 0x12, \ |
0x1d, 0x5c, 0xb5, 0xf8, 0x77, 0x5f, 0x5a, 0x5b, 0x18, 0x40, 0xec, 0xe6, \ |
0xf2, 0x8f, 0x9f, 0x69, 0x03, 0x54, 0x9b, 0xc5, 0xf3, 0x3d, 0x59, 0xad, \ |
0xb5, 0xf0, 0x15, 0xb2, 0x9c, 0x5e, 0x1d, 0x2c, 0x49, 0x67, 0x7e, 0x8e, \ |
0xa3, 0xe4, 0x16, 0x67, 0x9c, 0x19, 0x94, 0x22, 0x04, 0xca, 0x31, 0x1d, \ |
0x2d, 0x42, 0x1d, 0xf9, 0x39, 0xb8, 0x07, 0x3d, 0xc1, 0xe6, 0x34, 0x43, \ |
0xcd, 0x96, 0xbf, 0x49, 0xaa, 0x83, 0xa2, 0x4a, 0xba, 0xe8, 0xdd, 0xb3, \ |
0xa5, 0xb8, 0x0a, 0x28, 0x09, 0x77, 0x19, 0x4d, 0x8e, 0xfb, 0xe7, 0xc1, \ |
0xa8, 0xfd, 0x9d, 0x4a, 0x47, 0x50, 0xca, 0x49, 0x93, 0xc6, 0x12, 0xcb, \ |
0x59, 0x13, 0x7c, 0x14, 0x9a, 0xa1, 0x60, 0x04, 0xf2, 0x42, 0x7b, 0x59, \ |
0xd1, 0x04, 0xa2, 0xdd, 0x6f, 0x47, 0x7d, 0x26, 0x4f, 0x9c, 0x54, 0xdc, \ |
0x3c, 0x85, 0xde, 0xa2, 0x23, 0xdd, 0xda, 0x92, 0xe5, 0xc6, 0xdd, 0x61, \ |
0x66, 0xef, 0x1d, 0xc2, 0xcd, 0x8b, 0x4d, 0x71, 0x3a, 0xde, 0xe3, 0xfa, \ |
0x30, 0xce, 0x0b, 0x1e, 0xf5, 0xb1, 0x8a, 0xe2, 0x5a, 0x5a, 0x43, 0xff, \ |
0x9a, 0xdc, 0x72, 0x50, 0x02, 0xe3, 0xda, 0x94, 0x31, 0x46, 0x2b, 0x68, \ |
0xa4, 0xe4, 0x45, 0x41, 0xd9, 0xfb, 0x00, 0xe6, 0x39 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/test-ca.key */ |
/* BEGIN FILE string macro TEST_CA_KEY_RSA_PEM tests/data_files/test-ca.key */ |
#define TEST_CA_KEY_RSA_PEM \ |
"-----BEGIN RSA PRIVATE KEY-----\r\n" \ |
"Proc-Type: 4,ENCRYPTED\r\n" \ |
"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" \ |
"\r\n" \ |
"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" \ |
"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" \ |
"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" \ |
"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" \ |
"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" \ |
"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" \ |
"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" \ |
"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" \ |
"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" \ |
"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" \ |
"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" \ |
"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" \ |
"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" \ |
"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" \ |
"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" \ |
"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" \ |
"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" \ |
"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" \ |
"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" \ |
"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" \ |
"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" \ |
"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" \ |
"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" \ |
"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" \ |
"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" \ |
"-----END RSA PRIVATE KEY-----\r\n" |
/* END FILE */ |
#define TEST_CA_PWD_RSA_PEM "PolarSSLTest" |
/* This was generated from test-ca.key.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CA_KEY_RSA_DER tests/data_files/test-ca.key.der */ |
#define TEST_CA_KEY_RSA_DER { \ |
0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ |
0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, 0x86, 0xde, \ |
0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, 0x99, 0xd4, \ |
0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, 0x9b, 0xc5, \ |
0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, 0xc0, 0x8d, \ |
0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, 0x93, 0xe8, \ |
0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, 0xe7, 0x40, \ |
0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, 0xf9, 0x3e, \ |
0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, 0x29, 0x00, \ |
0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, 0xbd, 0x83, \ |
0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, 0x60, 0xc3, \ |
0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, 0x32, 0xbe, \ |
0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, 0xfb, 0xf5, \ |
0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, 0xee, 0xe2, \ |
0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, 0x47, 0xb1, \ |
0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, 0xf1, 0x79, \ |
0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, 0x6f, 0x27, \ |
0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, 0xa1, 0x30, \ |
0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, 0x28, 0xd1, \ |
0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, 0x09, 0xea, \ |
0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, 0xc9, 0xab, \ |
0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, 0x9e, 0x99, \ |
0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ |
0x00, 0x3f, 0xf7, 0x07, 0xd3, 0x34, 0x6f, 0xdb, 0xc9, 0x37, 0xb7, 0x84, \ |
0xdc, 0x37, 0x45, 0xe1, 0x63, 0xad, 0xb8, 0xb6, 0x75, 0xb1, 0xc7, 0x35, \ |
0xb4, 0x77, 0x2a, 0x5b, 0x77, 0xf9, 0x7e, 0xe0, 0xc1, 0xa3, 0xd1, 0xb7, \ |
0xcb, 0xa9, 0x5a, 0xc1, 0x87, 0xda, 0x5a, 0xfa, 0x17, 0xe4, 0xd5, 0x38, \ |
0x03, 0xde, 0x68, 0x98, 0x81, 0xec, 0xb5, 0xf2, 0x2a, 0x8d, 0xe9, 0x2c, \ |
0xf3, 0xa6, 0xe5, 0x32, 0x17, 0x7f, 0x33, 0x81, 0xe8, 0x38, 0x72, 0xd5, \ |
0x9c, 0xfa, 0x4e, 0xfb, 0x26, 0xf5, 0x15, 0x0b, 0xaf, 0x84, 0x66, 0xab, \ |
0x02, 0xe0, 0x18, 0xd5, 0x91, 0x7c, 0xd6, 0x8f, 0xc9, 0x4b, 0x76, 0x08, \ |
0x2b, 0x1d, 0x81, 0x68, 0x30, 0xe1, 0xfa, 0x70, 0x6c, 0x13, 0x4e, 0x10, \ |
0x03, 0x35, 0x3e, 0xc5, 0xca, 0x58, 0x20, 0x8a, 0x21, 0x18, 0x38, 0xa0, \ |
0x0f, 0xed, 0xc4, 0xbb, 0x45, 0x6f, 0xf5, 0x84, 0x5b, 0xb0, 0xcf, 0x4e, \ |
0x9d, 0x58, 0x13, 0x6b, 0x35, 0x35, 0x69, 0xa1, 0xd2, 0xc4, 0xf2, 0xc1, \ |
0x48, 0x04, 0x20, 0x51, 0xb9, 0x6b, 0xa4, 0x5d, 0xa5, 0x4b, 0x84, 0x88, \ |
0x43, 0x48, 0x99, 0x2c, 0xbb, 0xa4, 0x97, 0xd6, 0xd6, 0x18, 0xf6, 0xec, \ |
0x5c, 0xd1, 0x31, 0x49, 0xc9, 0xf2, 0x8f, 0x0b, 0x4d, 0xef, 0x09, 0x02, \ |
0xfe, 0x7d, 0xfd, 0xbb, 0xaf, 0x2b, 0x83, 0x94, 0x22, 0xc4, 0xa7, 0x3e, \ |
0x66, 0xf5, 0xe0, 0x57, 0xdc, 0xf2, 0xed, 0x2c, 0x3e, 0x81, 0x74, 0x76, \ |
0x1e, 0x96, 0x6f, 0x74, 0x1e, 0x32, 0x0e, 0x14, 0x31, 0xd0, 0x74, 0xf0, \ |
0xf4, 0x07, 0xbd, 0xc3, 0xd1, 0x22, 0xc2, 0xa8, 0x95, 0x92, 0x06, 0x7f, \ |
0x43, 0x02, 0x91, 0xbc, 0xdd, 0x23, 0x01, 0x89, 0x94, 0x20, 0x44, 0x64, \ |
0xf5, 0x1d, 0x67, 0xd2, 0x8f, 0xe8, 0x69, 0xa5, 0x29, 0x25, 0xe6, 0x50, \ |
0x9c, 0xe3, 0xe9, 0xcb, 0x75, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x29, 0x3e, \ |
0xaa, 0x6b, 0xd5, 0x59, 0x1e, 0x9c, 0xe6, 0x47, 0xd5, 0xb6, 0xd7, 0xe3, \ |
0xf1, 0x8e, 0x9e, 0xe9, 0x83, 0x5f, 0x10, 0x9f, 0x63, 0xec, 0x04, 0x44, \ |
0xcc, 0x3f, 0xf8, 0xd9, 0x3a, 0x17, 0xe0, 0x4f, 0xfe, 0xd8, 0x4d, 0xcd, \ |
0x46, 0x54, 0x74, 0xbf, 0x0a, 0xc4, 0x67, 0x9c, 0xa7, 0xd8, 0x89, 0x65, \ |
0x4c, 0xfd, 0x58, 0x2a, 0x47, 0x0f, 0xf4, 0x37, 0xb6, 0x55, 0xb0, 0x1d, \ |
0xed, 0xa7, 0x39, 0xfc, 0x4f, 0xa3, 0xc4, 0x75, 0x3a, 0xa3, 0x98, 0xa7, \ |
0x45, 0xf5, 0x66, 0xcb, 0x7c, 0x65, 0xfb, 0x80, 0x23, 0xe6, 0xff, 0xfd, \ |
0x99, 0x1f, 0x8e, 0x6b, 0xff, 0x5e, 0x93, 0x66, 0xdf, 0x6c, 0x6f, 0xc3, \ |
0xf6, 0x38, 0x2e, 0xff, 0x69, 0xb5, 0xac, 0xae, 0xbb, 0xc6, 0x71, 0x16, \ |
0x6b, 0xd0, 0xf8, 0x22, 0xd9, 0xf8, 0xa2, 0x72, 0x20, 0xd2, 0xe2, 0x3a, \ |
0x70, 0x4b, 0xde, 0xab, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xda, 0x51, 0x9b, \ |
0xb8, 0xb2, 0x2a, 0x14, 0x75, 0x58, 0x40, 0x8d, 0x27, 0x70, 0xfa, 0x31, \ |
0x48, 0xb0, 0x20, 0x21, 0x34, 0xfa, 0x4c, 0x57, 0xa8, 0x11, 0x88, 0xf3, \ |
0xa7, 0xae, 0x21, 0xe9, 0xb6, 0x2b, 0xd1, 0xcd, 0xa7, 0xf8, 0xd8, 0x0c, \ |
0x8a, 0x76, 0x22, 0x35, 0x44, 0xce, 0x3f, 0x25, 0x29, 0x83, 0x7d, 0x79, \ |
0xa7, 0x31, 0xd6, 0xec, 0xb2, 0xbf, 0xda, 0x34, 0xb6, 0xf6, 0xb2, 0x3b, \ |
0xf3, 0x78, 0x5a, 0x04, 0x83, 0x33, 0x3e, 0xa2, 0xe2, 0x81, 0x82, 0x13, \ |
0xd4, 0x35, 0x17, 0x63, 0x9b, 0x9e, 0xc4, 0x8d, 0x91, 0x4c, 0x03, 0x77, \ |
0xc7, 0x71, 0x5b, 0xee, 0x83, 0x6d, 0xd5, 0x78, 0x88, 0xf6, 0x2c, 0x79, \ |
0xc2, 0x4a, 0xb4, 0x79, 0x90, 0x70, 0xbf, 0xdf, 0x34, 0x56, 0x96, 0x71, \ |
0xe3, 0x0e, 0x68, 0x91, 0xbc, 0xea, 0xcb, 0x33, 0xc0, 0xbe, 0x45, 0xd7, \ |
0xfc, 0x30, 0xfd, 0x01, 0x3b, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x9f, 0x2a, \ |
0xb7, 0x38, 0x19, 0xc7, 0x17, 0x95, 0x73, 0x78, 0xae, 0xf5, 0xcb, 0x75, \ |
0x83, 0x7f, 0x19, 0x4b, 0xcb, 0x86, 0xfb, 0x4a, 0x15, 0x9a, 0xb6, 0x17, \ |
0x04, 0x49, 0x07, 0x8d, 0xf6, 0x66, 0x4a, 0x06, 0xf6, 0x05, 0xa7, 0xdf, \ |
0x66, 0x82, 0x3c, 0xff, 0xb6, 0x1d, 0x57, 0x89, 0x33, 0x5f, 0x9c, 0x05, \ |
0x75, 0x7f, 0xf3, 0x5d, 0xdc, 0x34, 0x65, 0x72, 0x85, 0x22, 0xa4, 0x14, \ |
0x1b, 0x41, 0xc3, 0xe4, 0xd0, 0x9e, 0x69, 0xd5, 0xeb, 0x38, 0x74, 0x70, \ |
0x43, 0xdc, 0xd9, 0x50, 0xe4, 0x97, 0x6d, 0x73, 0xd6, 0xfb, 0xc8, 0xa7, \ |
0xfa, 0xb4, 0xc2, 0xc4, 0x9d, 0x5d, 0x0c, 0xd5, 0x9f, 0x79, 0xb3, 0x54, \ |
0xc2, 0xb7, 0x6c, 0x3d, 0x7d, 0xcb, 0x2d, 0xf8, 0xc4, 0xf3, 0x78, 0x5a, \ |
0x33, 0x2a, 0xb8, 0x0c, 0x6d, 0x06, 0xfa, 0xf2, 0x62, 0xd3, 0x42, 0xd0, \ |
0xbd, 0xc8, 0x4a, 0xa5, 0x0d, 0x02, 0x81, 0x81, 0x00, 0xd4, 0xa9, 0x90, \ |
0x15, 0xde, 0xbf, 0x2c, 0xc4, 0x8d, 0x9d, 0xfb, 0xa1, 0xc2, 0xe4, 0x83, \ |
0xe3, 0x79, 0x65, 0x22, 0xd3, 0xb7, 0x49, 0x6c, 0x4d, 0x94, 0x1f, 0x22, \ |
0xb1, 0x60, 0xe7, 0x3a, 0x00, 0xb1, 0x38, 0xa2, 0xab, 0x0f, 0xb4, 0x6c, \ |
0xaa, 0xe7, 0x9e, 0x34, 0xe3, 0x7c, 0x40, 0x78, 0x53, 0xb2, 0xf9, 0x23, \ |
0xea, 0xa0, 0x9a, 0xea, 0x60, 0xc8, 0x8f, 0xa6, 0xaf, 0xdf, 0x29, 0x09, \ |
0x4b, 0x06, 0x1e, 0x31, 0xad, 0x17, 0xda, 0xd8, 0xd1, 0xe9, 0x33, 0xab, \ |
0x5b, 0x18, 0x08, 0x5b, 0x87, 0xf8, 0xa5, 0x1f, 0xfd, 0xbb, 0xdc, 0xd8, \ |
0xed, 0x97, 0x57, 0xe4, 0xc3, 0x73, 0xd6, 0xf0, 0x9e, 0x01, 0xa6, 0x9b, \ |
0x48, 0x8e, 0x7a, 0xb4, 0xbb, 0xe5, 0x88, 0x91, 0xc5, 0x2a, 0xdf, 0x4b, \ |
0xba, 0xd0, 0x8b, 0x3e, 0x03, 0x97, 0x77, 0x2f, 0x47, 0x7e, 0x51, 0x0c, \ |
0xae, 0x65, 0x8d, 0xde, 0x87, 0x02, 0x81, 0x80, 0x20, 0x24, 0x0f, 0xd2, \ |
0xaf, 0xc2, 0x28, 0x3b, 0x97, 0x20, 0xb2, 0x92, 0x49, 0xeb, 0x09, 0x68, \ |
0x40, 0xb2, 0xbe, 0xd1, 0xc3, 0x83, 0x94, 0x34, 0x38, 0xd6, 0xc9, 0xec, \ |
0x34, 0x09, 0xf9, 0x41, 0x6d, 0x5c, 0x42, 0x94, 0xf7, 0x04, 0xfc, 0x32, \ |
0x39, 0x69, 0xbc, 0x1c, 0xfb, 0x3e, 0x61, 0x98, 0xc0, 0x80, 0xd8, 0x36, \ |
0x47, 0xc3, 0x6d, 0xc2, 0x2e, 0xe7, 0x81, 0x2a, 0x17, 0x34, 0x64, 0x30, \ |
0x4e, 0x96, 0xbb, 0x26, 0x16, 0xb9, 0x41, 0x36, 0xfe, 0x8a, 0xd6, 0x53, \ |
0x7c, 0xaa, 0xec, 0x39, 0x42, 0x50, 0xef, 0xe3, 0xb3, 0x01, 0x28, 0x32, \ |
0xca, 0x6d, 0xf5, 0x9a, 0x1e, 0x9f, 0x37, 0xbe, 0xfe, 0x38, 0x20, 0x22, \ |
0x91, 0x8c, 0xcd, 0x95, 0x02, 0xf2, 0x4d, 0x6f, 0x1a, 0xb4, 0x43, 0xf0, \ |
0x19, 0xdf, 0x65, 0xc0, 0x92, 0xe7, 0x9d, 0x2f, 0x09, 0xe7, 0xec, 0x69, \ |
0xa8, 0xc2, 0x8f, 0x0d \ |
} |
/* END FILE */ |
/* |
* Test server Certificates |
* |
* Test server certificates are defined for each choice |
* of the following parameters: |
* - PEM or DER encoding |
* - SHA-1 or SHA-256 hash |
* - RSA or EC key |
* |
* Things to add: |
* - multiple EC curve types |
*/ |
/* This is taken from tests/data_files/server5.crt. */ |
/* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server5.crt */ |
#define TEST_SRV_CRT_EC_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" \ |
"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" \ |
"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" \ |
"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" \ |
"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" \ |
"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" \ |
"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" \ |
"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" \ |
"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" \ |
"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is generated from tests/data_files/server5.crt.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_SRV_CRT_EC_DER tests/data_files/server5.crt.der */ |
#define TEST_SRV_CRT_EC_DER { \ |
0x30, 0x82, 0x02, 0x1f, 0x30, 0x82, 0x01, 0xa5, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x09, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ |
0x3d, 0x04, 0x03, 0x02, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ |
0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, \ |
0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ |
0x31, 0x33, 0x30, 0x39, 0x32, 0x34, 0x31, 0x35, 0x35, 0x32, 0x30, 0x34, \ |
0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x35, \ |
0x32, 0x30, 0x34, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ |
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, \ |
0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, \ |
0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, \ |
0x04, 0x37, 0xcc, 0x56, 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, \ |
0x59, 0x2d, 0xff, 0x20, 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, \ |
0xad, 0x14, 0xb5, 0xf7, 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, \ |
0xd8, 0x23, 0x11, 0xff, 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, \ |
0x8a, 0x88, 0xc2, 0x6b, 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, \ |
0x01, 0xc8, 0xb4, 0xed, 0xff, 0xa3, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x30, \ |
0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, \ |
0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x50, 0x61, 0xa5, \ |
0x8f, 0xd4, 0x07, 0xd9, 0xd7, 0x82, 0x01, 0x0c, 0xe5, 0x65, 0x7f, 0x8c, \ |
0x63, 0x46, 0xa7, 0x13, 0xbe, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23, \ |
0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01, \ |
0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb, \ |
0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ |
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ |
0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ |
0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ |
0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, \ |
0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09, \ |
0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0a, 0x06, \ |
0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x68, 0x00, \ |
0x30, 0x65, 0x02, 0x31, 0x00, 0x9a, 0x2c, 0x5c, 0xd7, 0xa6, 0xdb, 0xa2, \ |
0xe5, 0x64, 0x0d, 0xf0, 0xb9, 0x4e, 0xdd, 0xd7, 0x61, 0xd6, 0x13, 0x31, \ |
0xc7, 0xab, 0x73, 0x80, 0xbb, 0xd3, 0xd3, 0x73, 0x13, 0x54, 0xad, 0x92, \ |
0x0b, 0x5d, 0xab, 0xd0, 0xbc, 0xf7, 0xae, 0x2f, 0xe6, 0xa1, 0x21, 0x29, \ |
0x35, 0x95, 0xaa, 0x3e, 0x39, 0x02, 0x30, 0x21, 0x36, 0x7f, 0x9d, 0xc6, \ |
0x5d, 0xc6, 0x0b, 0xab, 0x27, 0xf2, 0x25, 0x1d, 0x3b, 0xf1, 0xcf, 0xf1, \ |
0x35, 0x25, 0x14, 0xe7, 0xe5, 0xf1, 0x97, 0xb5, 0x59, 0xe3, 0x5e, 0x15, \ |
0x7c, 0x66, 0xb9, 0x90, 0x7b, 0xc7, 0x01, 0x10, 0x4f, 0x73, 0xc6, 0x00, \ |
0x21, 0x52, 0x2a, 0x0e, 0xf1, 0xc7, 0xd5 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/server5.key. */ |
/* BEGIN FILE string macro TEST_SRV_KEY_EC_PEM tests/data_files/server5.key */ |
#define TEST_SRV_KEY_EC_PEM \ |
"-----BEGIN EC PRIVATE KEY-----\r\n" \ |
"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" \ |
"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" \ |
"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" \ |
"-----END EC PRIVATE KEY-----\r\n" |
/* END FILE */ |
/* This is generated from tests/data_files/server5.key.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_SRV_KEY_EC_DER tests/data_files/server5.key.der */ |
#define TEST_SRV_KEY_EC_DER { \ |
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf1, 0x2a, 0x13, 0x20, 0x76, \ |
0x02, 0x70, 0xa8, 0x3c, 0xbf, 0xfd, 0x53, 0xf6, 0x03, 0x1e, 0xf7, 0x6a, \ |
0x5d, 0x86, 0xc8, 0xa2, 0x04, 0xf2, 0xc3, 0x0c, 0xa9, 0xeb, 0xf5, 0x1f, \ |
0x0f, 0x0e, 0xa7, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ |
0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x37, 0xcc, 0x56, \ |
0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, 0x59, 0x2d, 0xff, 0x20, \ |
0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, 0xad, 0x14, 0xb5, 0xf7, \ |
0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, 0xd8, 0x23, 0x11, 0xff, \ |
0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, 0x8a, 0x88, 0xc2, 0x6b, \ |
0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, 0x01, 0xc8, 0xb4, 0xed, \ |
0xff \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/server2-sha256.crt. */ |
/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA256_PEM tests/data_files/server2-sha256.crt */ |
#define TEST_SRV_CRT_RSA_SHA256_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ |
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ |
"MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ |
"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ |
"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ |
"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ |
"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ |
"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ |
"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ |
"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ |
"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAC465FJh\r\n" \ |
"Pqel7zJngHIHJrqj/wVAxGAFOTF396XKATGAp+HRCqJ81Ry60CNK1jDzk8dv6M6U\r\n" \ |
"HoS7RIFiM/9rXQCbJfiPD5xMTejZp5n5UYHAmxsxDaazfA5FuBhkfokKK6jD4Eq9\r\n" \ |
"1C94xGKb6X4/VkaPF7cqoBBw/bHxawXc0UEPjqayiBpCYU/rJoVZgLqFVP7Px3sv\r\n" \ |
"a1nOrNx8rPPI1hJ+ZOg8maiPTxHZnBVLakSSLQy/sWeWyazO1RnrbxjrbgQtYKz0\r\n" \ |
"e3nwGpu1w13vfckFmUSBhHXH7AAS/HpKC4IH7G2GAk3+n8iSSN71sZzpxonQwVbo\r\n" \ |
"pMZqLmbBm/7WPLc=\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is taken from tests/data_files/server2-sha256.crt.der. */ |
/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA256_DER tests/data_files/server2-sha256.crt.der */ |
#define TEST_SRV_CRT_RSA_SHA256_DER { \ |
0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ |
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ |
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ |
0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ |
0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ |
0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ |
0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ |
0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ |
0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ |
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ |
0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ |
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ |
0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ |
0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ |
0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ |
0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ |
0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ |
0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ |
0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ |
0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ |
0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ |
0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ |
0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ |
0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ |
0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ |
0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ |
0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ |
0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ |
0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ |
0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ |
0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ |
0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ |
0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ |
0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ |
0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ |
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ |
0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ |
0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ |
0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ |
0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ |
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, \ |
0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2e, 0x3a, 0xe4, 0x52, 0x61, \ |
0x3e, 0xa7, 0xa5, 0xef, 0x32, 0x67, 0x80, 0x72, 0x07, 0x26, 0xba, 0xa3, \ |
0xff, 0x05, 0x40, 0xc4, 0x60, 0x05, 0x39, 0x31, 0x77, 0xf7, 0xa5, 0xca, \ |
0x01, 0x31, 0x80, 0xa7, 0xe1, 0xd1, 0x0a, 0xa2, 0x7c, 0xd5, 0x1c, 0xba, \ |
0xd0, 0x23, 0x4a, 0xd6, 0x30, 0xf3, 0x93, 0xc7, 0x6f, 0xe8, 0xce, 0x94, \ |
0x1e, 0x84, 0xbb, 0x44, 0x81, 0x62, 0x33, 0xff, 0x6b, 0x5d, 0x00, 0x9b, \ |
0x25, 0xf8, 0x8f, 0x0f, 0x9c, 0x4c, 0x4d, 0xe8, 0xd9, 0xa7, 0x99, 0xf9, \ |
0x51, 0x81, 0xc0, 0x9b, 0x1b, 0x31, 0x0d, 0xa6, 0xb3, 0x7c, 0x0e, 0x45, \ |
0xb8, 0x18, 0x64, 0x7e, 0x89, 0x0a, 0x2b, 0xa8, 0xc3, 0xe0, 0x4a, 0xbd, \ |
0xd4, 0x2f, 0x78, 0xc4, 0x62, 0x9b, 0xe9, 0x7e, 0x3f, 0x56, 0x46, 0x8f, \ |
0x17, 0xb7, 0x2a, 0xa0, 0x10, 0x70, 0xfd, 0xb1, 0xf1, 0x6b, 0x05, 0xdc, \ |
0xd1, 0x41, 0x0f, 0x8e, 0xa6, 0xb2, 0x88, 0x1a, 0x42, 0x61, 0x4f, 0xeb, \ |
0x26, 0x85, 0x59, 0x80, 0xba, 0x85, 0x54, 0xfe, 0xcf, 0xc7, 0x7b, 0x2f, \ |
0x6b, 0x59, 0xce, 0xac, 0xdc, 0x7c, 0xac, 0xf3, 0xc8, 0xd6, 0x12, 0x7e, \ |
0x64, 0xe8, 0x3c, 0x99, 0xa8, 0x8f, 0x4f, 0x11, 0xd9, 0x9c, 0x15, 0x4b, \ |
0x6a, 0x44, 0x92, 0x2d, 0x0c, 0xbf, 0xb1, 0x67, 0x96, 0xc9, 0xac, 0xce, \ |
0xd5, 0x19, 0xeb, 0x6f, 0x18, 0xeb, 0x6e, 0x04, 0x2d, 0x60, 0xac, 0xf4, \ |
0x7b, 0x79, 0xf0, 0x1a, 0x9b, 0xb5, 0xc3, 0x5d, 0xef, 0x7d, 0xc9, 0x05, \ |
0x99, 0x44, 0x81, 0x84, 0x75, 0xc7, 0xec, 0x00, 0x12, 0xfc, 0x7a, 0x4a, \ |
0x0b, 0x82, 0x07, 0xec, 0x6d, 0x86, 0x02, 0x4d, 0xfe, 0x9f, 0xc8, 0x92, \ |
0x48, 0xde, 0xf5, 0xb1, 0x9c, 0xe9, 0xc6, 0x89, 0xd0, 0xc1, 0x56, 0xe8, \ |
0xa4, 0xc6, 0x6a, 0x2e, 0x66, 0xc1, 0x9b, 0xfe, 0xd6, 0x3c, 0xb7 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/server2.crt. */ |
/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA1_PEM tests/data_files/server2.crt */ |
#define TEST_SRV_CRT_RSA_SHA1_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ |
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ |
"MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ |
"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ |
"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ |
"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ |
"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ |
"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ |
"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ |
"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ |
"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \ |
"cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \ |
"O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \ |
"KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \ |
"iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \ |
"HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \ |
"Awgk0+4m0T25cNs=\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is taken from tests/data_files/server2.crt.der. */ |
/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA1_DER tests/data_files/server2.crt.der */ |
#define TEST_SRV_CRT_RSA_SHA1_DER { \ |
0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ |
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ |
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ |
0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ |
0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ |
0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ |
0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ |
0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ |
0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ |
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ |
0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ |
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ |
0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ |
0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ |
0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ |
0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ |
0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ |
0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ |
0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ |
0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ |
0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ |
0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ |
0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ |
0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ |
0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ |
0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ |
0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ |
0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ |
0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ |
0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ |
0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ |
0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ |
0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ |
0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ |
0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ |
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ |
0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ |
0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ |
0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ |
0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ |
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \ |
0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x99, 0x25, 0x83, 0x74, 0x38, \ |
0x70, 0x1e, 0xef, 0xec, 0x1c, 0xec, 0xc4, 0xcf, 0xef, 0x2f, 0x22, 0x9c, \ |
0x70, 0xee, 0xa8, 0xa7, 0x4f, 0xe0, 0x67, 0x33, 0x38, 0x82, 0x1b, 0x8b, \ |
0xab, 0x66, 0x37, 0xda, 0x49, 0x74, 0xb0, 0xce, 0xa4, 0x48, 0xd5, 0x14, \ |
0x99, 0xdb, 0xae, 0xab, 0x7b, 0xbf, 0xf8, 0x69, 0x94, 0x64, 0xdd, 0x80, \ |
0x3b, 0xfe, 0xdc, 0xf8, 0x7c, 0x3b, 0x84, 0x31, 0x44, 0x22, 0xf6, 0x64, \ |
0xf7, 0xc6, 0x81, 0x1a, 0x30, 0x8b, 0xaa, 0x7d, 0xc3, 0x9a, 0x01, 0xc8, \ |
0xbf, 0xc4, 0xe8, 0x43, 0xae, 0xe7, 0x7a, 0x59, 0x50, 0xc7, 0x1d, 0x94, \ |
0x8f, 0x7d, 0x3d, 0x3d, 0xd8, 0x23, 0x36, 0x2f, 0xeb, 0xf4, 0x73, 0x9c, \ |
0x28, 0xd0, 0x18, 0x3d, 0xb0, 0x5c, 0x83, 0xa3, 0x09, 0x19, 0x65, 0xa3, \ |
0xd9, 0x32, 0x3a, 0xbc, 0xd6, 0x9c, 0x7a, 0x2a, 0x2c, 0xfc, 0x38, 0x4e, \ |
0x63, 0x1e, 0x55, 0xd2, 0x3e, 0x67, 0x7e, 0xa4, 0x89, 0xfe, 0x99, 0xd4, \ |
0xd2, 0x0f, 0x48, 0x82, 0x7d, 0x8b, 0x02, 0x18, 0x18, 0xa4, 0x62, 0x44, \ |
0x88, 0x43, 0x3d, 0xc1, 0x6e, 0xe1, 0x10, 0xc9, 0x30, 0x9a, 0x4d, 0x21, \ |
0xfe, 0xca, 0x99, 0xb2, 0xb2, 0x6c, 0x18, 0x7e, 0x58, 0xb0, 0x5f, 0xd5, \ |
0x4e, 0x14, 0xaa, 0xfc, 0x95, 0x4e, 0xd5, 0xed, 0xa6, 0x64, 0x7d, 0xaf, \ |
0xae, 0xec, 0x99, 0x28, 0x95, 0x41, 0xab, 0xef, 0x2d, 0x0c, 0xd6, 0x29, \ |
0x1e, 0x42, 0xba, 0xb5, 0x2c, 0x95, 0x61, 0x08, 0x73, 0x22, 0xdd, 0xd2, \ |
0xb4, 0xc2, 0x56, 0x28, 0xc9, 0x7f, 0xa3, 0x99, 0x36, 0x01, 0x8c, 0xfa, \ |
0xb5, 0x20, 0xb5, 0xeb, 0x8f, 0xb5, 0xa0, 0x6f, 0x8c, 0x2f, 0x72, 0xd6, \ |
0x83, 0xc5, 0xeb, 0x18, 0xa6, 0xbd, 0xd4, 0x7e, 0x14, 0x38, 0xa6, 0xa9, \ |
0x03, 0x08, 0x24, 0xd3, 0xee, 0x26, 0xd1, 0x3d, 0xb9, 0x70, 0xdb \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/server2.key. */ |
/* BEGIN FILE string macro TEST_SRV_KEY_RSA_PEM tests/data_files/server2.key */ |
#define TEST_SRV_KEY_RSA_PEM \ |
"-----BEGIN RSA PRIVATE KEY-----\r\n" \ |
"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" \ |
"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" \ |
"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" \ |
"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" \ |
"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" \ |
"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" \ |
"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" \ |
"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" \ |
"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" \ |
"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" \ |
"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" \ |
"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" \ |
"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" \ |
"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" \ |
"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" \ |
"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" \ |
"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" \ |
"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" \ |
"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" \ |
"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" \ |
"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" \ |
"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" \ |
"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" \ |
"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" \ |
"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" \ |
"-----END RSA PRIVATE KEY-----\r\n" |
/* END FILE */ |
/* This was generated from tests/data_files/server2.key.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_SRV_KEY_RSA_DER tests/data_files/server2.key.der */ |
#define TEST_SRV_KEY_RSA_DER { \ |
0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ |
0xc1, 0x4d, 0xa3, 0xdd, 0xe7, 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, \ |
0xb8, 0x99, 0xac, 0x0e, 0x78, 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, \ |
0x16, 0xd0, 0x5a, 0xe4, 0xcd, 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, \ |
0x96, 0xa7, 0x52, 0xb4, 0x90, 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, \ |
0xfc, 0xb6, 0x34, 0xac, 0x24, 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, \ |
0xb0, 0x28, 0x7d, 0xa1, 0xda, 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, \ |
0xfe, 0xc1, 0x04, 0x52, 0xb3, 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, \ |
0xd8, 0x90, 0xc1, 0x61, 0xb4, 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, \ |
0xab, 0x74, 0x5e, 0x07, 0x7d, 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, \ |
0xd9, 0x0d, 0x1c, 0x2d, 0x49, 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, \ |
0x0b, 0x8a, 0x4f, 0x69, 0x0c, 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, \ |
0x66, 0x7d, 0xae, 0x54, 0x2b, 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, \ |
0xc3, 0xcd, 0x40, 0x49, 0x08, 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, \ |
0x46, 0xbf, 0xd0, 0xb8, 0xaa, 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, \ |
0x1e, 0x44, 0x18, 0x0f, 0x0f, 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, \ |
0x18, 0xc6, 0x62, 0x2f, 0xc7, 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, \ |
0x27, 0x89, 0x29, 0x01, 0xc5, 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, \ |
0x4a, 0x0e, 0xef, 0xd6, 0xde, 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, \ |
0x7a, 0xc4, 0x02, 0x3c, 0x9a, 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, \ |
0xcb, 0x73, 0x4b, 0x52, 0x96, 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, \ |
0x39, 0x5a, 0xd3, 0x0f, 0xb0, 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, \ |
0x12, 0x01, 0x30, 0x97, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ |
0x01, 0x00, 0x97, 0x47, 0x44, 0xbc, 0x10, 0x81, 0xc5, 0x18, 0xe4, 0x59, \ |
0xfb, 0xe0, 0x2d, 0x3a, 0x0e, 0x9e, 0x10, 0xdc, 0x43, 0xfb, 0x15, 0x6c, \ |
0xd1, 0xfd, 0x48, 0x78, 0x6c, 0xf9, 0xed, 0x38, 0xe8, 0xdd, 0x09, 0xd7, \ |
0x5f, 0xb5, 0x41, 0x64, 0xd7, 0x63, 0xfa, 0x9d, 0x44, 0x0a, 0xf8, 0x42, \ |
0x13, 0xf1, 0xbb, 0x5e, 0x79, 0x20, 0x53, 0x98, 0x4b, 0x65, 0x7f, 0x86, \ |
0x67, 0x48, 0xe4, 0xcf, 0xfb, 0x6a, 0x24, 0xe2, 0x34, 0xbd, 0x14, 0x9d, \ |
0x2c, 0x16, 0xe2, 0xa4, 0x79, 0xd6, 0xa2, 0xec, 0x81, 0x43, 0x87, 0xbf, \ |
0x03, 0x5c, 0x88, 0x25, 0xd9, 0x41, 0xb6, 0xa5, 0xf1, 0x27, 0x52, 0x84, \ |
0xfe, 0x2b, 0x6e, 0x1d, 0x16, 0xcd, 0x73, 0x88, 0xf8, 0x90, 0xbf, 0x19, \ |
0xfe, 0xbe, 0xa9, 0xbf, 0x09, 0xd3, 0x23, 0x43, 0xd2, 0xc7, 0x61, 0x2a, \ |
0xb3, 0x4e, 0x3c, 0x61, 0xd4, 0xbd, 0xd8, 0xb4, 0xfa, 0xa8, 0x0b, 0xf8, \ |
0x7e, 0x56, 0xcd, 0x0f, 0x13, 0x27, 0xda, 0xe6, 0x3b, 0xb3, 0x8c, 0x9c, \ |
0x4b, 0x84, 0x3c, 0xc3, 0x52, 0x57, 0x9c, 0x27, 0x9a, 0x02, 0x76, 0x26, \ |
0x59, 0x82, 0x39, 0xc3, 0x13, 0xbe, 0x6e, 0xf4, 0x44, 0x2d, 0x1d, 0x8c, \ |
0x73, 0x3e, 0x43, 0x99, 0x59, 0xcb, 0xf2, 0x34, 0x72, 0x9a, 0x5e, 0xa5, \ |
0xeb, 0x9f, 0x36, 0x6d, 0x2b, 0xf9, 0xa2, 0xe7, 0xd1, 0x78, 0x52, 0x1b, \ |
0xc8, 0xf6, 0x5b, 0x41, 0x69, 0x57, 0x81, 0x89, 0xe9, 0xbb, 0xa1, 0xde, \ |
0x19, 0x37, 0x3b, 0x13, 0x5c, 0xca, 0x61, 0x01, 0x86, 0xff, 0xdf, 0x83, \ |
0x41, 0x49, 0x7f, 0xd6, 0xf4, 0x2e, 0x08, 0xfa, 0x90, 0xc2, 0x7c, 0xb4, \ |
0xb5, 0x0a, 0x17, 0xdb, 0x0e, 0x6d, 0x75, 0x8a, 0x5d, 0x31, 0xd5, 0x66, \ |
0xfb, 0x39, 0x0b, 0xb5, 0xb6, 0xa3, 0xcd, 0xd4, 0xef, 0x88, 0x92, 0x5a, \ |
0x4d, 0x6c, 0xcb, 0xea, 0x5b, 0x79, 0x02, 0x81, 0x81, 0x00, 0xdf, 0x3a, \ |
0xf9, 0x25, 0x5e, 0x24, 0x37, 0x26, 0x40, 0x97, 0x2f, 0xe0, 0x4a, 0xba, \ |
0x52, 0x1b, 0x51, 0xaf, 0x84, 0x06, 0x32, 0x24, 0x0c, 0xcf, 0x44, 0xa8, \ |
0x77, 0xa7, 0xad, 0xb5, 0x8c, 0x58, 0xcc, 0xc8, 0x31, 0xb7, 0x0d, 0xbc, \ |
0x08, 0x8a, 0xe0, 0xa6, 0x8c, 0xc2, 0x73, 0xe5, 0x1a, 0x64, 0x92, 0xe8, \ |
0xed, 0x4c, 0x6f, 0x0b, 0xa6, 0xa7, 0xf3, 0x9a, 0xf5, 0x6f, 0x69, 0xca, \ |
0x3c, 0x22, 0xd0, 0x15, 0xa8, 0x20, 0x27, 0x41, 0xf8, 0x43, 0x42, 0x7f, \ |
0xb1, 0x93, 0xa1, 0x04, 0x85, 0xda, 0xa0, 0x1c, 0xd6, 0xc6, 0xf7, 0x8a, \ |
0x9e, 0xea, 0x5c, 0x78, 0xa7, 0x55, 0xc4, 0x6b, 0x05, 0x8b, 0xc0, 0x83, \ |
0xcb, 0xce, 0x83, 0x05, 0xf8, 0xb2, 0x16, 0x2b, 0xdf, 0x06, 0x3f, 0xb8, \ |
0xec, 0x16, 0xda, 0x43, 0x33, 0xc1, 0x8f, 0xb0, 0xb8, 0xac, 0xae, 0xd4, \ |
0x94, 0xb8, 0xda, 0x6f, 0x6a, 0xc3, 0x02, 0x81, 0x81, 0x00, 0xdd, 0xae, \ |
0x00, 0xcd, 0xa0, 0x72, 0x1a, 0x05, 0x8a, 0xee, 0x2f, 0xd4, 0x71, 0x4b, \ |
0xf0, 0x3e, 0xe5, 0xc1, 0xe1, 0x29, 0x8b, 0xa6, 0x67, 0x30, 0x98, 0xe7, \ |
0x12, 0xef, 0xdd, 0x12, 0x01, 0x90, 0x24, 0x58, 0xf0, 0x76, 0x92, 0xe7, \ |
0x3d, 0xbb, 0x23, 0xe1, 0xce, 0xf9, 0xa1, 0xd4, 0x38, 0x1b, 0x3f, 0x20, \ |
0xb3, 0x0f, 0x65, 0x6a, 0x8f, 0x55, 0x57, 0x36, 0xee, 0xb2, 0x84, 0x44, \ |
0xfc, 0x91, 0x88, 0xe1, 0xa4, 0xdd, 0x3b, 0x4a, 0x40, 0x4d, 0x7c, 0x86, \ |
0xed, 0xe1, 0xb5, 0x42, 0xef, 0xb9, 0x61, 0xcd, 0x58, 0x19, 0x77, 0x02, \ |
0xae, 0x58, 0x80, 0xdb, 0x13, 0x3d, 0xc7, 0x1f, 0x9d, 0xed, 0xff, 0xac, \ |
0x98, 0xfc, 0xcd, 0xf9, 0x62, 0x04, 0x83, 0x91, 0x89, 0x0d, 0x86, 0x43, \ |
0x8c, 0x0c, 0xc7, 0x1b, 0x90, 0x4d, 0xbe, 0x2f, 0xc5, 0x7c, 0xcd, 0x42, \ |
0xf5, 0xd3, 0xad, 0x8e, 0xfd, 0x9d, 0x02, 0x81, 0x80, 0x17, 0x4b, 0x79, \ |
0x2a, 0x6c, 0x1b, 0x8d, 0x61, 0xc1, 0x85, 0xc5, 0x6a, 0x3b, 0x82, 0x1c, \ |
0x05, 0x5b, 0xcd, 0xdc, 0x12, 0x25, 0x73, 0x5b, 0x9e, 0xd9, 0x84, 0x57, \ |
0x10, 0x39, 0x71, 0x63, 0x96, 0xf4, 0xaf, 0xc3, 0x78, 0x5d, 0xc7, 0x8c, \ |
0x80, 0xa9, 0x96, 0xd7, 0xc3, 0x87, 0x02, 0x96, 0x71, 0x7e, 0x5f, 0x2e, \ |
0x3c, 0x36, 0xae, 0x59, 0x92, 0xd7, 0x3a, 0x09, 0x78, 0xb9, 0xea, 0x6f, \ |
0xc2, 0x16, 0x42, 0xdc, 0x4b, 0x96, 0xad, 0x2c, 0xb2, 0x20, 0x23, 0x61, \ |
0x2d, 0x8d, 0xb5, 0x02, 0x1e, 0xe1, 0x6c, 0x81, 0x01, 0x3c, 0x5d, 0xcb, \ |
0xdd, 0x9b, 0x0e, 0xc0, 0x2f, 0x94, 0x12, 0xb2, 0xfe, 0x75, 0x75, 0x8b, \ |
0x74, 0x1e, 0x7a, 0x26, 0x0c, 0xb7, 0x81, 0x96, 0x81, 0x79, 0x6e, 0xdb, \ |
0xbc, 0x3a, 0xc4, 0x9e, 0x87, 0x09, 0x6e, 0xa0, 0xa6, 0xec, 0x8b, 0xa4, \ |
0x85, 0x71, 0xce, 0x04, 0xaf, 0x02, 0x81, 0x81, 0x00, 0xc2, 0xa7, 0x47, \ |
0x07, 0x48, 0x6a, 0xc8, 0xd4, 0xb3, 0x20, 0xe1, 0x98, 0xee, 0xff, 0x5a, \ |
0x6f, 0x30, 0x7a, 0xa5, 0x47, 0x40, 0xdc, 0x16, 0x62, 0x42, 0xf1, 0x2c, \ |
0xdc, 0xb8, 0xc7, 0x55, 0xde, 0x07, 0x3c, 0x9d, 0xb1, 0xd0, 0xdf, 0x02, \ |
0x82, 0xb0, 0x48, 0x58, 0xe1, 0x34, 0xab, 0xcf, 0xb4, 0x85, 0x23, 0x26, \ |
0x78, 0x4f, 0x7a, 0x59, 0x6f, 0xfb, 0x8c, 0x3d, 0xdf, 0x3d, 0x6c, 0x02, \ |
0x47, 0x9c, 0xe5, 0x5e, 0x49, 0xf1, 0x05, 0x0b, 0x1f, 0xbf, 0x48, 0x0f, \ |
0xdc, 0x10, 0xb9, 0x3d, 0x1d, 0x10, 0x77, 0x2a, 0x73, 0xf9, 0xdf, 0xbd, \ |
0xcd, 0xf3, 0x1f, 0xeb, 0x6e, 0x64, 0xca, 0x2b, 0x78, 0x4f, 0xf8, 0x73, \ |
0xc2, 0x10, 0xef, 0x79, 0x95, 0x33, 0x1e, 0x79, 0x35, 0x09, 0xff, 0x88, \ |
0x1b, 0xb4, 0x3e, 0x4c, 0xe1, 0x27, 0x2e, 0x75, 0x80, 0x58, 0x11, 0x03, \ |
0x21, 0x23, 0x96, 0x9a, 0xb5, 0x02, 0x81, 0x80, 0x05, 0x12, 0x64, 0x71, \ |
0x83, 0x00, 0x1c, 0xfe, 0xef, 0x83, 0xea, 0xdd, 0x2c, 0xc8, 0x2c, 0x00, \ |
0x62, 0x1e, 0x8f, 0x3a, 0xdb, 0x1c, 0xab, 0xd6, 0x34, 0x8b, 0xd1, 0xb2, \ |
0x5a, 0x4f, 0x3d, 0x37, 0x38, 0x02, 0xe0, 0xd7, 0x70, 0xc1, 0xb0, 0x47, \ |
0xe0, 0x08, 0x1a, 0x84, 0xec, 0x48, 0xc5, 0x7c, 0x76, 0x83, 0x12, 0x67, \ |
0xab, 0x7c, 0x9f, 0x90, 0x97, 0xc8, 0x8f, 0x07, 0xf4, 0xb3, 0x60, 0xf2, \ |
0x3f, 0x49, 0x18, 0xdb, 0x2e, 0x94, 0x6b, 0x53, 0x9e, 0xa2, 0x63, 0xde, \ |
0x63, 0xd9, 0xab, 0x21, 0x2e, 0x2d, 0x0a, 0xe0, 0xd0, 0xe8, 0xba, 0xc4, \ |
0x4c, 0x1e, 0xa5, 0xf5, 0x51, 0xa8, 0xc4, 0x92, 0xf8, 0x7f, 0x21, 0xe7, \ |
0x65, 0xbf, 0x0b, 0xe6, 0x01, 0xaf, 0x9c, 0x1d, 0x5b, 0x6c, 0x3f, 0x1c, \ |
0x2f, 0xa6, 0x0f, 0x68, 0x38, 0x8e, 0x85, 0xc4, 0x6c, 0x78, 0x2f, 0x6f, \ |
0x06, 0x21, 0x2e, 0x56 \ |
} |
/* END FILE */ |
/* |
* Test client Certificates |
* |
* Test client certificates are defined for each choice |
* of the following parameters: |
* - PEM or DER encoding |
* - RSA or EC key |
* |
* Things to add: |
* - hash type |
* - multiple EC curve types |
*/ |
/* This is taken from tests/data_files/cli2.crt. */ |
/* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli2.crt */ |
#define TEST_CLI_CRT_EC_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIIB3zCCAWOgAwIBAgIBDTAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw\r\n" \ |
"DwYDVQQKDAhQb2xhclNTTDEcMBoGA1UEAwwTUG9sYXJTU0wgVGVzdCBFQyBDQTAe\r\n" \ |
"Fw0xOTAyMTAxNDQ0MDBaFw0yOTAyMTAxNDQ0MDBaMEExCzAJBgNVBAYTAk5MMREw\r\n" \ |
"DwYDVQQKDAhQb2xhclNTTDEfMB0GA1UEAwwWUG9sYXJTU0wgVGVzdCBDbGllbnQg\r\n" \ |
"MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFflrrFz39Osu5O4gf8Sru7mU6zO\r\n" \ |
"VVP2NA7MLuNjJQvfmOLzXGA2lsDVGBRw5X+f1UtFGOWwbNVc+JaPh3Cj5MejTTBL\r\n" \ |
"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMB8GA1Ud\r\n" \ |
"IwQYMBaAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8MAwGCCqGSM49BAMCBQADaAAwZQIx\r\n" \ |
"AMqme4DKMldUlplDET9Q6Eptre7uUWKhsLOF+zPkKDlfzpIkJYEFgcloDHGYw80u\r\n" \ |
"IgIwNftyPXsabTqMM7iEHgVpX/GRozKklY9yQI/5eoA6gGW7Y+imuGR/oao5ySOb\r\n" \ |
"a9Vk\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This is generated from tests/data_files/cli2.crt.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli2.crt.der */ |
#define TEST_CLI_CRT_EC_DER { \ |
0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ |
0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ |
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ |
0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ |
0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ |
0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \ |
0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \ |
0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \ |
0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \ |
0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \ |
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ |
0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ |
0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \ |
0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \ |
0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \ |
0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ |
0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \ |
0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \ |
0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \ |
0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \ |
0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \ |
0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \ |
0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \ |
0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \ |
0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \ |
0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \ |
0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \ |
0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \ |
0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \ |
0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ |
0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \ |
0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \ |
0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \ |
0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \ |
0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \ |
0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \ |
0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \ |
0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \ |
0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \ |
0x6b, 0xd5, 0x64 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/cli2.key. */ |
/* BEGIN FILE string macro TEST_CLI_KEY_EC_PEM tests/data_files/cli2.key */ |
#define TEST_CLI_KEY_EC_PEM \ |
"-----BEGIN EC PRIVATE KEY-----\r\n" \ |
"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" \ |
"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" \ |
"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" \ |
"-----END EC PRIVATE KEY-----\r\n" |
/* END FILE */ |
/* This is generated from tests/data_files/cli2.key.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CLI_KEY_EC_DER tests/data_files/cli2.key.der */ |
#define TEST_CLI_KEY_EC_DER { \ |
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf6, 0xf7, 0x86, 0x64, 0xf1, \ |
0x67, 0x7f, 0xe6, 0x64, 0x8d, 0xef, 0xca, 0x4e, 0xe9, 0xdd, 0x4d, 0xf0, \ |
0x05, 0xff, 0x96, 0x22, 0x8a, 0x7a, 0x84, 0x38, 0x64, 0x17, 0x32, 0x61, \ |
0x98, 0xb7, 0x2a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ |
0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, \ |
0xb1, 0x73, 0xdf, 0xd3, 0xac, 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, \ |
0xee, 0xe6, 0x53, 0xac, 0xce, 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, \ |
0xe3, 0x63, 0x25, 0x0b, 0xdf, 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, \ |
0xc0, 0xd5, 0x18, 0x14, 0x70, 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, \ |
0xe5, 0xb0, 0x6c, 0xd5, 0x5c, 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, \ |
0xc7 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/cli-rsa-sha256.crt. */ |
/* BEGIN FILE string macro TEST_CLI_CRT_RSA_PEM tests/data_files/cli-rsa-sha256.crt */ |
#define TEST_CLI_CRT_RSA_PEM \ |
"-----BEGIN CERTIFICATE-----\r\n" \ |
"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ |
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ |
"MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" \ |
"A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" \ |
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" \ |
"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" \ |
"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" \ |
"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" \ |
"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" \ |
"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" \ |
"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" \ |
"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n" \ |
"AQEAXidv1d4pLlBiKWED95rMycBdgDcgyNqJxakFkRfRyA2y1mlyTn7uBXRkNLY5\r\n" \ |
"ZFzK82GCjk2Q2OD4RZSCPAJJqLpHHU34t71ciffvy2KK81YvrxczRhMAE64i+qna\r\n" \ |
"yP3Td2XuWJR05PVPoSemsNELs9gWttdnYy3ce+EY2Y0n7Rsi7982EeLIAA7H6ca4\r\n" \ |
"2Es/NUH//JZJT32OP0doMxeDRA+vplkKqTLLWf7dX26LIriBkBaRCgR5Yv9LBPFc\r\n" \ |
"NOtpzu/LbrY7QFXKJMI+JXDudCsOn8KCmiA4d6Emisqfh3V3485l7HEQNcvLTxlD\r\n" \ |
"6zDQyi0/ykYUYZkwQTK1N2Nvlw==\r\n" \ |
"-----END CERTIFICATE-----\r\n" |
/* END FILE */ |
/* This was generated from tests/data_files/cli-rsa-sha256.crt.der |
using `xxd -i.` */ |
/* BEGIN FILE binary macro TEST_CLI_CRT_RSA_DER tests/data_files/cli-rsa-sha256.crt.der */ |
#define TEST_CLI_CRT_RSA_DER { \ |
0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \ |
0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ |
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ |
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ |
0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ |
0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ |
0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ |
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ |
0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ |
0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \ |
0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ |
0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ |
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ |
0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ |
0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \ |
0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \ |
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \ |
0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \ |
0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \ |
0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \ |
0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \ |
0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \ |
0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \ |
0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \ |
0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \ |
0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \ |
0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \ |
0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \ |
0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \ |
0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \ |
0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \ |
0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \ |
0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \ |
0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \ |
0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \ |
0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \ |
0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \ |
0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \ |
0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \ |
0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \ |
0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \ |
0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \ |
0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \ |
0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \ |
0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \ |
0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \ |
0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \ |
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \ |
0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \ |
0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \ |
0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \ |
0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \ |
0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \ |
0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \ |
0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \ |
0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \ |
0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \ |
0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \ |
0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \ |
0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \ |
0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \ |
0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \ |
0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \ |
0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \ |
0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \ |
0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \ |
0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \ |
0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \ |
0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \ |
0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \ |
} |
/* END FILE */ |
/* This is taken from tests/data_files/cli-rsa.key. */ |
/* BEGIN FILE string macro TEST_CLI_KEY_RSA_PEM tests/data_files/cli-rsa.key */ |
#define TEST_CLI_KEY_RSA_PEM \ |
"-----BEGIN RSA PRIVATE KEY-----\r\n" \ |
"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" \ |
"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" \ |
"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" \ |
"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" \ |
"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" \ |
"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" \ |
"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" \ |
"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" \ |
"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" \ |
"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" \ |
"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" \ |
"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" \ |
"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" \ |
"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" \ |
"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" \ |
"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" \ |
"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" \ |
"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" \ |
"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" \ |
"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" \ |
"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" \ |
"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" \ |
"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" \ |
"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" \ |
"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" \ |
"-----END RSA PRIVATE KEY-----\r\n"/* END FILE */ |
/* This was generated from tests/data_files/cli-rsa.key.der using `xxd -i`. */ |
/* BEGIN FILE binary macro TEST_CLI_KEY_RSA_DER tests/data_files/cli-rsa.key.der */ |
#define TEST_CLI_KEY_RSA_DER { \ |
0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ |
0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, 0x45, 0xd9, 0x14, \ |
0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, 0x33, 0xad, 0x0d, \ |
0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, 0xcc, 0x66, 0x85, \ |
0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, 0x9e, 0x0a, 0x6e, \ |
0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, 0x93, 0x86, 0x49, \ |
0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, 0xd4, 0x2f, 0x77, \ |
0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, 0x48, 0x70, 0xf5, \ |
0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, 0xe6, 0x43, 0xea, \ |
0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, 0x57, 0x4e, 0xa9, \ |
0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, 0x32, 0x30, 0xd5, \ |
0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, 0x5f, 0xf9, 0x3d, \ |
0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, 0xfb, 0xe5, 0x0c, \ |
0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, 0x7f, 0xca, 0xad, \ |
0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, 0xe0, 0x9b, 0xf8, \ |
0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, 0x04, 0x66, 0xc7, \ |
0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, 0x06, 0x67, 0xf4, \ |
0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, 0x3c, 0x8b, 0x35, \ |
0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, 0xfc, 0x36, 0x6b, \ |
0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, 0x00, 0xcf, 0xaf, \ |
0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, 0xe7, 0x50, 0x71, \ |
0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, 0xe4, 0xc4, 0xfd, \ |
0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ |
0x00, 0x67, 0x4d, 0xb5, 0xf6, 0x03, 0x89, 0xaa, 0x7a, 0x6f, 0x3b, 0x2d, \ |
0xca, 0x10, 0xa2, 0x23, 0xc9, 0xbd, 0x4e, 0xda, 0xe1, 0x67, 0x0e, 0x0c, \ |
0x8a, 0xc6, 0x84, 0x68, 0xdf, 0xe5, 0x97, 0x75, 0xd2, 0x8d, 0xa3, 0x86, \ |
0xd9, 0xdb, 0xd5, 0xeb, 0x13, 0x19, 0x08, 0xc5, 0x7e, 0xe5, 0x37, 0x97, \ |
0x0c, 0x73, 0x80, 0x66, 0x76, 0x35, 0xf1, 0x88, 0xb5, 0xf2, 0xfc, 0xf3, \ |
0xe1, 0x4b, 0x76, 0x4e, 0x73, 0x45, 0xce, 0x2c, 0xc2, 0x10, 0x26, 0x0d, \ |
0x68, 0x0d, 0x9f, 0x49, 0x3d, 0xd6, 0x80, 0x89, 0xe7, 0xc5, 0x49, 0x15, \ |
0xdd, 0x85, 0xc0, 0xc8, 0xfe, 0x82, 0x37, 0x12, 0x5a, 0x0a, 0x6b, 0xf6, \ |
0x68, 0x0d, 0x32, 0x16, 0xbd, 0xa4, 0x15, 0x54, 0x9e, 0x68, 0xa1, 0xad, \ |
0xca, 0x6b, 0xe5, 0x8c, 0xda, 0x76, 0x35, 0x59, 0x2f, 0x9b, 0xb4, 0xe1, \ |
0xf1, 0xf0, 0x50, 0x04, 0xee, 0xc8, 0xec, 0x05, 0xe1, 0xcf, 0x8d, 0xe4, \ |
0xd2, 0x64, 0x7b, 0x5e, 0x63, 0xe0, 0x7b, 0x07, 0xbc, 0x02, 0x96, 0x4e, \ |
0x1b, 0x78, 0x6c, 0xb6, 0x43, 0x9a, 0x32, 0xf6, 0xd6, 0x02, 0xf5, 0x80, \ |
0xcc, 0x26, 0x6e, 0xa5, 0xd0, 0xe3, 0x65, 0x88, 0xce, 0x26, 0xa9, 0x40, \ |
0xe1, 0xe1, 0x00, 0xe0, 0x7f, 0x3f, 0xc3, 0xb1, 0x7c, 0xde, 0xbe, 0x42, \ |
0xba, 0x07, 0x81, 0x13, 0xc2, 0xe0, 0x11, 0x11, 0x23, 0x2c, 0xf8, 0xb2, \ |
0x7a, 0x3a, 0xd4, 0xe4, 0x7d, 0x5f, 0xb9, 0xb1, 0x18, 0xfa, 0x1d, 0x1d, \ |
0x97, 0x91, 0xd9, 0x04, 0x9e, 0xbc, 0xc9, 0xb4, 0xd7, 0x7d, 0x0e, 0x54, \ |
0xf6, 0x8f, 0xd0, 0x28, 0x0d, 0xdd, 0x77, 0x4b, 0x68, 0x04, 0x48, 0x61, \ |
0x75, 0x15, 0x03, 0x1b, 0x35, 0xad, 0x8e, 0xfc, 0x24, 0x11, 0x07, 0xea, \ |
0x17, 0x5a, 0xde, 0x19, 0x68, 0xff, 0xb6, 0x87, 0x7f, 0x80, 0x2a, 0x5f, \ |
0x0c, 0x58, 0xba, 0x5f, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe3, 0x03, 0xaf, \ |
0xfe, 0x98, 0xd2, 0x0b, 0x7b, 0x72, 0xe9, 0x3b, 0x8e, 0xbc, 0xa5, 0xf6, \ |
0xac, 0xe5, 0x22, 0x06, 0xb2, 0xd7, 0x5e, 0xfd, 0x89, 0x4b, 0x16, 0x67, \ |
0x32, 0x83, 0x22, 0x58, 0x8e, 0x62, 0xa4, 0xb4, 0x2d, 0xf9, 0x16, 0x13, \ |
0x54, 0xf6, 0x9f, 0x2f, 0xf9, 0xbb, 0x0e, 0x7e, 0x8c, 0x6f, 0x08, 0xda, \ |
0xc8, 0xe9, 0x1c, 0x66, 0x10, 0x70, 0x93, 0x90, 0x8d, 0xcf, 0x90, 0x3a, \ |
0x43, 0x89, 0x49, 0xeb, 0x83, 0x2a, 0xfe, 0x5a, 0x87, 0xce, 0x74, 0x42, \ |
0x41, 0x0d, 0x8c, 0x73, 0x51, 0xbc, 0x7b, 0x20, 0xc5, 0xfd, 0xf6, 0x0b, \ |
0x65, 0xed, 0xa9, 0x2e, 0xfc, 0x0f, 0xf5, 0x50, 0xf9, 0x8d, 0x37, 0x36, \ |
0x9a, 0x20, 0xdf, 0xc3, 0xe3, 0x27, 0xbc, 0x98, 0x72, 0xc1, 0x14, 0x4b, \ |
0x71, 0xe9, 0x83, 0x14, 0xff, 0x24, 0xe2, 0x14, 0x15, 0xb6, 0x6f, 0x0f, \ |
0x32, 0x9d, 0xd9, 0x98, 0xd1, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x0c, 0xfb, \ |
0xc3, 0x33, 0x9b, 0x47, 0x88, 0x27, 0xf2, 0x26, 0xde, 0xeb, 0x5e, 0xee, \ |
0x40, 0xf6, 0x63, 0x5b, 0x35, 0x23, 0xf5, 0xd5, 0x07, 0x61, 0xdf, 0xa2, \ |
0x9f, 0x58, 0x30, 0x04, 0x22, 0x2b, 0xb4, 0xd9, 0xda, 0x46, 0x7f, 0x48, \ |
0xf5, 0x4f, 0xd0, 0xea, 0xd7, 0xa0, 0x45, 0x8a, 0x62, 0x8b, 0x8c, 0xac, \ |
0x73, 0x5e, 0xfa, 0x36, 0x65, 0x3e, 0xba, 0x6c, 0xba, 0x5e, 0x6b, 0x92, \ |
0x29, 0x5e, 0x6a, 0x0f, 0xd6, 0xd2, 0xa5, 0x95, 0x86, 0xda, 0x72, 0xc5, \ |
0x9e, 0xc9, 0x6b, 0x37, 0x5e, 0x4b, 0x9b, 0x77, 0xe1, 0x67, 0x1a, 0x1e, \ |
0x30, 0xd8, 0x41, 0x68, 0x40, 0xd3, 0x9c, 0xb4, 0xf6, 0xeb, 0x2a, 0x22, \ |
0xdf, 0x78, 0x29, 0xd2, 0x64, 0x92, 0x5b, 0x2f, 0x78, 0x64, 0x4a, 0xa2, \ |
0xa6, 0x6b, 0x3e, 0x50, 0xb1, 0x7a, 0xb1, 0x8d, 0x59, 0xb4, 0x55, 0xba, \ |
0xb6, 0x91, 0x85, 0xa3, 0x2f, 0x02, 0x81, 0x80, 0x10, 0x1e, 0x19, 0xe7, \ |
0xbc, 0x97, 0xe5, 0x22, 0xcd, 0xa4, 0xcb, 0x8a, 0xb5, 0xd0, 0x1e, 0xb4, \ |
0x65, 0xcc, 0x45, 0xa7, 0x7a, 0xed, 0x0e, 0x99, 0x29, 0xd0, 0x9c, 0x61, \ |
0x14, 0xb8, 0x62, 0x8b, 0x31, 0x6b, 0xba, 0x33, 0x2d, 0x65, 0x28, 0xd8, \ |
0x36, 0x6e, 0x54, 0xec, 0xa9, 0x20, 0x3d, 0x51, 0xe1, 0x2c, 0x42, 0xc4, \ |
0x52, 0xf0, 0xa6, 0x3a, 0x72, 0x93, 0xb7, 0x86, 0xa9, 0xfe, 0xf6, 0x74, \ |
0x07, 0x12, 0x4d, 0x7b, 0x51, 0x99, 0x1f, 0x7a, 0x56, 0xe9, 0x20, 0x2f, \ |
0x18, 0x34, 0x29, 0x97, 0xdb, 0x06, 0xee, 0xeb, 0xbf, 0xbd, 0x31, 0x4f, \ |
0xfa, 0x50, 0xb1, 0xba, 0x49, 0xb3, 0xc4, 0x1d, 0x03, 0xae, 0xb0, 0xdc, \ |
0xbe, 0x8a, 0xc4, 0x90, 0xa3, 0x28, 0x9b, 0xb6, 0x42, 0x09, 0x1b, 0xd6, \ |
0x29, 0x9b, 0x19, 0xe9, 0x87, 0x87, 0xd9, 0x9f, 0x35, 0x05, 0xab, 0x91, \ |
0x8f, 0x6d, 0x7c, 0x91, 0x02, 0x81, 0x81, 0x00, 0x94, 0x57, 0xf0, 0xe0, \ |
0x28, 0xfd, 0xbd, 0xf3, 0x9c, 0x43, 0x4d, 0x3e, 0xfd, 0x37, 0x4f, 0x23, \ |
0x52, 0x8d, 0xe1, 0x4c, 0xfe, 0x4c, 0x55, 0x80, 0x82, 0xba, 0x3f, 0xfe, \ |
0x51, 0xe1, 0x30, 0xd5, 0x3b, 0xd9, 0x73, 0x1d, 0xcb, 0x25, 0xbc, 0xbb, \ |
0x3f, 0xa5, 0xda, 0x77, 0xa6, 0xb5, 0xfc, 0x1a, 0xaf, 0x79, 0xa1, 0xb2, \ |
0x14, 0xa2, 0x1f, 0x10, 0x52, 0x1a, 0x05, 0x40, 0x48, 0xb6, 0x4f, 0x34, \ |
0xd6, 0xc0, 0xc3, 0xa4, 0x36, 0x98, 0x73, 0x88, 0x0b, 0xd3, 0x45, 0xdc, \ |
0xee, 0x51, 0x6e, 0x04, 0x73, 0x99, 0x93, 0x12, 0x58, 0x96, 0xcb, 0x39, \ |
0x42, 0xb1, 0xa9, 0xb8, 0xe1, 0x25, 0xf5, 0x9c, 0x14, 0xb7, 0x92, 0x2b, \ |
0x14, 0xb0, 0x5d, 0x61, 0xa2, 0xaa, 0x34, 0x7c, 0xcd, 0x54, 0x2d, 0x69, \ |
0x08, 0xf7, 0xdb, 0xfc, 0x9c, 0x87, 0xe8, 0x3a, 0xf6, 0x1d, 0x4c, 0x6a, \ |
0x83, 0x15, 0x30, 0x01, 0x02, 0x81, 0x81, 0x00, 0x9c, 0x53, 0xa1, 0xb6, \ |
0x2f, 0xc0, 0x06, 0xf5, 0xdf, 0x5c, 0xd1, 0x4a, 0x4e, 0xc8, 0xbd, 0x6d, \ |
0x32, 0xf1, 0x5e, 0xe5, 0x3b, 0x70, 0xd0, 0xa8, 0xe5, 0x41, 0x57, 0x6c, \ |
0x87, 0x53, 0x0f, 0xeb, 0x28, 0xa0, 0x62, 0x8f, 0x43, 0x62, 0xec, 0x2e, \ |
0x6c, 0x71, 0x55, 0x5b, 0x6a, 0xf4, 0x74, 0x14, 0xea, 0x7a, 0x03, 0xf6, \ |
0xfc, 0xa4, 0xce, 0xc4, 0xac, 0xda, 0x1d, 0xf0, 0xb5, 0xa9, 0xfd, 0x11, \ |
0x18, 0x3b, 0x14, 0xa0, 0x90, 0x8d, 0x26, 0xb7, 0x75, 0x73, 0x0a, 0x02, \ |
0x2c, 0x6f, 0x0f, 0xd8, 0x41, 0x78, 0xc3, 0x73, 0x81, 0xac, 0xaa, 0xaf, \ |
0xf2, 0xee, 0x32, 0xb5, 0x8d, 0x05, 0xf9, 0x59, 0x5a, 0x9e, 0x3e, 0x65, \ |
0x9b, 0x74, 0xda, 0xa0, 0x74, 0x95, 0x17, 0x5f, 0x8d, 0x58, 0xfc, 0x8e, \ |
0x4e, 0x2c, 0x1e, 0xbc, 0x81, 0x02, 0x18, 0xac, 0x12, 0xc6, 0xf9, 0x64, \ |
0x8b, 0x87, 0xc3, 0x00 \ |
} |
/* END FILE */ |
/* |
* |
* Test certificates and keys as C variables |
* |
*/ |
/* |
* CA |
*/ |
const char mbedtls_test_ca_crt_ec_pem[] = TEST_CA_CRT_EC_PEM; |
const char mbedtls_test_ca_key_ec_pem[] = TEST_CA_KEY_EC_PEM; |
const char mbedtls_test_ca_pwd_ec_pem[] = TEST_CA_PWD_EC_PEM; |
const char mbedtls_test_ca_key_rsa_pem[] = TEST_CA_KEY_RSA_PEM; |
const char mbedtls_test_ca_pwd_rsa_pem[] = TEST_CA_PWD_RSA_PEM; |
const char mbedtls_test_ca_crt_rsa_sha1_pem[] = TEST_CA_CRT_RSA_SHA1_PEM; |
const char mbedtls_test_ca_crt_rsa_sha256_pem[] = TEST_CA_CRT_RSA_SHA256_PEM; |
const unsigned char mbedtls_test_ca_crt_ec_der[] = TEST_CA_CRT_EC_DER; |
const unsigned char mbedtls_test_ca_key_ec_der[] = TEST_CA_KEY_EC_DER; |
const unsigned char mbedtls_test_ca_key_rsa_der[] = TEST_CA_KEY_RSA_DER; |
const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[] = |
TEST_CA_CRT_RSA_SHA1_DER; |
const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[] = |
TEST_CA_CRT_RSA_SHA256_DER; |
const size_t mbedtls_test_ca_crt_ec_pem_len = |
sizeof( mbedtls_test_ca_crt_ec_pem ); |
const size_t mbedtls_test_ca_key_ec_pem_len = |
sizeof( mbedtls_test_ca_key_ec_pem ); |
const size_t mbedtls_test_ca_pwd_ec_pem_len = |
sizeof( mbedtls_test_ca_pwd_ec_pem ) - 1; |
const size_t mbedtls_test_ca_key_rsa_pem_len = |
sizeof( mbedtls_test_ca_key_rsa_pem ); |
const size_t mbedtls_test_ca_pwd_rsa_pem_len = |
sizeof( mbedtls_test_ca_pwd_rsa_pem ) - 1; |
const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len = |
sizeof( mbedtls_test_ca_crt_rsa_sha1_pem ); |
const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len = |
sizeof( mbedtls_test_ca_crt_rsa_sha256_pem ); |
const size_t mbedtls_test_ca_crt_ec_der_len = |
sizeof( mbedtls_test_ca_crt_ec_der ); |
const size_t mbedtls_test_ca_key_ec_der_len = |
sizeof( mbedtls_test_ca_key_ec_der ); |
const size_t mbedtls_test_ca_pwd_ec_der_len = 0; |
const size_t mbedtls_test_ca_key_rsa_der_len = |
sizeof( mbedtls_test_ca_key_rsa_der ); |
const size_t mbedtls_test_ca_pwd_rsa_der_len = 0; |
const size_t mbedtls_test_ca_crt_rsa_sha1_der_len = |
sizeof( mbedtls_test_ca_crt_rsa_sha1_der ); |
const size_t mbedtls_test_ca_crt_rsa_sha256_der_len = |
sizeof( mbedtls_test_ca_crt_rsa_sha256_der ); |
/* |
* Server |
*/ |
const char mbedtls_test_srv_crt_ec_pem[] = TEST_SRV_CRT_EC_PEM; |
const char mbedtls_test_srv_key_ec_pem[] = TEST_SRV_KEY_EC_PEM; |
const char mbedtls_test_srv_pwd_ec_pem[] = ""; |
const char mbedtls_test_srv_key_rsa_pem[] = TEST_SRV_KEY_RSA_PEM; |
const char mbedtls_test_srv_pwd_rsa_pem[] = ""; |
const char mbedtls_test_srv_crt_rsa_sha1_pem[] = TEST_SRV_CRT_RSA_SHA1_PEM; |
const char mbedtls_test_srv_crt_rsa_sha256_pem[] = TEST_SRV_CRT_RSA_SHA256_PEM; |
const unsigned char mbedtls_test_srv_crt_ec_der[] = TEST_SRV_CRT_EC_DER; |
const unsigned char mbedtls_test_srv_key_ec_der[] = TEST_SRV_KEY_EC_DER; |
const unsigned char mbedtls_test_srv_key_rsa_der[] = TEST_SRV_KEY_RSA_DER; |
const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[] = |
TEST_SRV_CRT_RSA_SHA1_DER; |
const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[] = |
TEST_SRV_CRT_RSA_SHA256_DER; |
const size_t mbedtls_test_srv_crt_ec_pem_len = |
sizeof( mbedtls_test_srv_crt_ec_pem ); |
const size_t mbedtls_test_srv_key_ec_pem_len = |
sizeof( mbedtls_test_srv_key_ec_pem ); |
const size_t mbedtls_test_srv_pwd_ec_pem_len = |
sizeof( mbedtls_test_srv_pwd_ec_pem ) - 1; |
const size_t mbedtls_test_srv_key_rsa_pem_len = |
sizeof( mbedtls_test_srv_key_rsa_pem ); |
const size_t mbedtls_test_srv_pwd_rsa_pem_len = |
sizeof( mbedtls_test_srv_pwd_rsa_pem ) - 1; |
const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len = |
sizeof( mbedtls_test_srv_crt_rsa_sha1_pem ); |
const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len = |
sizeof( mbedtls_test_srv_crt_rsa_sha256_pem ); |
const size_t mbedtls_test_srv_crt_ec_der_len = |
sizeof( mbedtls_test_srv_crt_ec_der ); |
const size_t mbedtls_test_srv_key_ec_der_len = |
sizeof( mbedtls_test_srv_key_ec_der ); |
const size_t mbedtls_test_srv_pwd_ec_der_len = 0; |
const size_t mbedtls_test_srv_key_rsa_der_len = |
sizeof( mbedtls_test_srv_key_rsa_der ); |
const size_t mbedtls_test_srv_pwd_rsa_der_len = 0; |
const size_t mbedtls_test_srv_crt_rsa_sha1_der_len = |
sizeof( mbedtls_test_srv_crt_rsa_sha1_der ); |
const size_t mbedtls_test_srv_crt_rsa_sha256_der_len = |
sizeof( mbedtls_test_srv_crt_rsa_sha256_der ); |
/* |
* Client |
*/ |
const char mbedtls_test_cli_crt_ec_pem[] = TEST_CLI_CRT_EC_PEM; |
const char mbedtls_test_cli_key_ec_pem[] = TEST_CLI_KEY_EC_PEM; |
const char mbedtls_test_cli_pwd_ec_pem[] = ""; |
const char mbedtls_test_cli_key_rsa_pem[] = TEST_CLI_KEY_RSA_PEM; |
const char mbedtls_test_cli_pwd_rsa_pem[] = ""; |
const char mbedtls_test_cli_crt_rsa_pem[] = TEST_CLI_CRT_RSA_PEM; |
const unsigned char mbedtls_test_cli_crt_ec_der[] = TEST_CLI_CRT_EC_DER; |
const unsigned char mbedtls_test_cli_key_ec_der[] = TEST_CLI_KEY_EC_DER; |
const unsigned char mbedtls_test_cli_key_rsa_der[] = TEST_CLI_KEY_RSA_DER; |
const unsigned char mbedtls_test_cli_crt_rsa_der[] = TEST_CLI_CRT_RSA_DER; |
const size_t mbedtls_test_cli_crt_ec_pem_len = |
sizeof( mbedtls_test_cli_crt_ec_pem ); |
const size_t mbedtls_test_cli_key_ec_pem_len = |
sizeof( mbedtls_test_cli_key_ec_pem ); |
const size_t mbedtls_test_cli_pwd_ec_pem_len = |
sizeof( mbedtls_test_cli_pwd_ec_pem ) - 1; |
const size_t mbedtls_test_cli_key_rsa_pem_len = |
sizeof( mbedtls_test_cli_key_rsa_pem ); |
const size_t mbedtls_test_cli_pwd_rsa_pem_len = |
sizeof( mbedtls_test_cli_pwd_rsa_pem ) - 1; |
const size_t mbedtls_test_cli_crt_rsa_pem_len = |
sizeof( mbedtls_test_cli_crt_rsa_pem ); |
const size_t mbedtls_test_cli_crt_ec_der_len = |
sizeof( mbedtls_test_cli_crt_ec_der ); |
const size_t mbedtls_test_cli_key_ec_der_len = |
sizeof( mbedtls_test_cli_key_ec_der ); |
const size_t mbedtls_test_cli_key_rsa_der_len = |
sizeof( mbedtls_test_cli_key_rsa_der ); |
const size_t mbedtls_test_cli_crt_rsa_der_len = |
sizeof( mbedtls_test_cli_crt_rsa_der ); |
/* |
* |
* Definitions of test CRTs without specification of all parameters, choosing |
* them automatically according to the config. For example, mbedtls_test_ca_crt |
* is one of mbedtls_test_ca_crt_{rsa|ec}_{sha1|sha256}_{pem|der}. |
* |
*/ |
/* |
* Dispatch between PEM and DER according to config |
*/ |
#if defined(MBEDTLS_PEM_PARSE_C) |
/* PEM encoded test CA certificates and keys */ |
#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_PEM |
#define TEST_CA_PWD_RSA TEST_CA_PWD_RSA_PEM |
#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_PEM |
#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_PEM |
#define TEST_CA_KEY_EC TEST_CA_KEY_EC_PEM |
#define TEST_CA_PWD_EC TEST_CA_PWD_EC_PEM |
#define TEST_CA_CRT_EC TEST_CA_CRT_EC_PEM |
/* PEM encoded test server certificates and keys */ |
#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_PEM |
#define TEST_SRV_PWD_RSA "" |
#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_PEM |
#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_PEM |
#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_PEM |
#define TEST_SRV_PWD_EC "" |
#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_PEM |
/* PEM encoded test client certificates and keys */ |
#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_PEM |
#define TEST_CLI_PWD_RSA "" |
#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_PEM |
#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_PEM |
#define TEST_CLI_PWD_EC "" |
#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_PEM |
#else /* MBEDTLS_PEM_PARSE_C */ |
/* DER encoded test CA certificates and keys */ |
#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_DER |
#define TEST_CA_PWD_RSA "" |
#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_DER |
#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_DER |
#define TEST_CA_KEY_EC TEST_CA_KEY_EC_DER |
#define TEST_CA_PWD_EC "" |
#define TEST_CA_CRT_EC TEST_CA_CRT_EC_DER |
/* DER encoded test server certificates and keys */ |
#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_DER |
#define TEST_SRV_PWD_RSA "" |
#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_DER |
#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_DER |
#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_DER |
#define TEST_SRV_PWD_EC "" |
#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_DER |
/* DER encoded test client certificates and keys */ |
#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_DER |
#define TEST_CLI_PWD_RSA "" |
#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_DER |
#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_DER |
#define TEST_CLI_PWD_EC "" |
#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_DER |
#endif /* MBEDTLS_PEM_PARSE_C */ |
const char mbedtls_test_ca_key_rsa[] = TEST_CA_KEY_RSA; |
const char mbedtls_test_ca_pwd_rsa[] = TEST_CA_PWD_RSA; |
const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; |
const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; |
const char mbedtls_test_ca_key_ec[] = TEST_CA_KEY_EC; |
const char mbedtls_test_ca_pwd_ec[] = TEST_CA_PWD_EC; |
const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; |
const char mbedtls_test_srv_key_rsa[] = TEST_SRV_KEY_RSA; |
const char mbedtls_test_srv_pwd_rsa[] = TEST_SRV_PWD_RSA; |
const char mbedtls_test_srv_crt_rsa_sha256[] = TEST_SRV_CRT_RSA_SHA256; |
const char mbedtls_test_srv_crt_rsa_sha1[] = TEST_SRV_CRT_RSA_SHA1; |
const char mbedtls_test_srv_key_ec[] = TEST_SRV_KEY_EC; |
const char mbedtls_test_srv_pwd_ec[] = TEST_SRV_PWD_EC; |
const char mbedtls_test_srv_crt_ec[] = TEST_SRV_CRT_EC; |
const char mbedtls_test_cli_key_rsa[] = TEST_CLI_KEY_RSA; |
const char mbedtls_test_cli_pwd_rsa[] = TEST_CLI_PWD_RSA; |
const char mbedtls_test_cli_crt_rsa[] = TEST_CLI_CRT_RSA; |
const char mbedtls_test_cli_key_ec[] = TEST_CLI_KEY_EC; |
const char mbedtls_test_cli_pwd_ec[] = TEST_CLI_PWD_EC; |
const char mbedtls_test_cli_crt_ec[] = TEST_CLI_CRT_EC; |
const size_t mbedtls_test_ca_key_rsa_len = |
sizeof( mbedtls_test_ca_key_rsa ); |
const size_t mbedtls_test_ca_pwd_rsa_len = |
sizeof( mbedtls_test_ca_pwd_rsa ) - 1; |
const size_t mbedtls_test_ca_crt_rsa_sha256_len = |
sizeof( mbedtls_test_ca_crt_rsa_sha256 ); |
const size_t mbedtls_test_ca_crt_rsa_sha1_len = |
sizeof( mbedtls_test_ca_crt_rsa_sha1 ); |
const size_t mbedtls_test_ca_key_ec_len = |
sizeof( mbedtls_test_ca_key_ec ); |
const size_t mbedtls_test_ca_pwd_ec_len = |
sizeof( mbedtls_test_ca_pwd_ec ) - 1; |
const size_t mbedtls_test_ca_crt_ec_len = |
sizeof( mbedtls_test_ca_crt_ec ); |
const size_t mbedtls_test_srv_key_rsa_len = |
sizeof( mbedtls_test_srv_key_rsa ); |
const size_t mbedtls_test_srv_pwd_rsa_len = |
sizeof( mbedtls_test_srv_pwd_rsa ) -1; |
const size_t mbedtls_test_srv_crt_rsa_sha256_len = |
sizeof( mbedtls_test_srv_crt_rsa_sha256 ); |
const size_t mbedtls_test_srv_crt_rsa_sha1_len = |
sizeof( mbedtls_test_srv_crt_rsa_sha1 ); |
const size_t mbedtls_test_srv_key_ec_len = |
sizeof( mbedtls_test_srv_key_ec ); |
const size_t mbedtls_test_srv_pwd_ec_len = |
sizeof( mbedtls_test_srv_pwd_ec ) - 1; |
const size_t mbedtls_test_srv_crt_ec_len = |
sizeof( mbedtls_test_srv_crt_ec ); |
const size_t mbedtls_test_cli_key_rsa_len = |
sizeof( mbedtls_test_cli_key_rsa ); |
const size_t mbedtls_test_cli_pwd_rsa_len = |
sizeof( mbedtls_test_cli_pwd_rsa ) - 1; |
const size_t mbedtls_test_cli_crt_rsa_len = |
sizeof( mbedtls_test_cli_crt_rsa ); |
const size_t mbedtls_test_cli_key_ec_len = |
sizeof( mbedtls_test_cli_key_ec ); |
const size_t mbedtls_test_cli_pwd_ec_len = |
sizeof( mbedtls_test_cli_pwd_ec ) - 1; |
const size_t mbedtls_test_cli_crt_ec_len = |
sizeof( mbedtls_test_cli_crt_ec ); |
/* |
* Dispatch between SHA-1 and SHA-256 |
*/ |
#if defined(MBEDTLS_SHA256_C) |
#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA256 |
#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA256 |
#else |
#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA1 |
#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA1 |
#endif /* MBEDTLS_SHA256_C */ |
const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA; |
const char mbedtls_test_srv_crt_rsa[] = TEST_SRV_CRT_RSA; |
const size_t mbedtls_test_ca_crt_rsa_len = |
sizeof( mbedtls_test_ca_crt_rsa ); |
const size_t mbedtls_test_srv_crt_rsa_len = |
sizeof( mbedtls_test_srv_crt_rsa ); |
/* |
* Dispatch between RSA and EC |
*/ |
#if defined(MBEDTLS_RSA_C) |
#define TEST_CA_KEY TEST_CA_KEY_RSA |
#define TEST_CA_PWD TEST_CA_PWD_RSA |
#define TEST_CA_CRT TEST_CA_CRT_RSA |
#define TEST_SRV_KEY TEST_SRV_KEY_RSA |
#define TEST_SRV_PWD TEST_SRV_PWD_RSA |
#define TEST_SRV_CRT TEST_SRV_CRT_RSA |
#define TEST_CLI_KEY TEST_CLI_KEY_RSA |
#define TEST_CLI_PWD TEST_CLI_PWD_RSA |
#define TEST_CLI_CRT TEST_CLI_CRT_RSA |
#else /* no RSA, so assume ECDSA */ |
#define TEST_CA_KEY TEST_CA_KEY_EC |
#define TEST_CA_PWD TEST_CA_PWD_EC |
#define TEST_CA_CRT TEST_CA_CRT_EC |
#define TEST_SRV_KEY TEST_SRV_KEY_EC |
#define TEST_SRV_PWD TEST_SRV_PWD_EC |
#define TEST_SRV_CRT TEST_SRV_CRT_EC |
#define TEST_CLI_KEY TEST_CLI_KEY_EC |
#define TEST_CLI_PWD TEST_CLI_PWD_EC |
#define TEST_CLI_CRT TEST_CLI_CRT_EC |
#endif /* MBEDTLS_RSA_C */ |
/* API stability forces us to declare |
* mbedtls_test_{ca|srv|cli}_{key|pwd|crt} |
* as pointers. */ |
static const char test_ca_key[] = TEST_CA_KEY; |
static const char test_ca_pwd[] = TEST_CA_PWD; |
static const char test_ca_crt[] = TEST_CA_CRT; |
static const char test_srv_key[] = TEST_SRV_KEY; |
static const char test_srv_pwd[] = TEST_SRV_PWD; |
static const char test_srv_crt[] = TEST_SRV_CRT; |
static const char test_cli_key[] = TEST_CLI_KEY; |
static const char test_cli_pwd[] = TEST_CLI_PWD; |
static const char test_cli_crt[] = TEST_CLI_CRT; |
const char *mbedtls_test_ca_key = test_ca_key; |
const char *mbedtls_test_ca_pwd = test_ca_pwd; |
const char *mbedtls_test_ca_crt = test_ca_crt; |
const char *mbedtls_test_srv_key = test_srv_key; |
const char *mbedtls_test_srv_pwd = test_srv_pwd; |
const char *mbedtls_test_srv_crt = test_srv_crt; |
const char *mbedtls_test_cli_key = test_cli_key; |
const char *mbedtls_test_cli_pwd = test_cli_pwd; |
const char *mbedtls_test_cli_crt = test_cli_crt; |
const size_t mbedtls_test_ca_key_len = |
sizeof( test_ca_key ); |
const size_t mbedtls_test_ca_pwd_len = |
sizeof( test_ca_pwd ) - 1; |
const size_t mbedtls_test_ca_crt_len = |
sizeof( test_ca_crt ); |
const size_t mbedtls_test_srv_key_len = |
sizeof( test_srv_key ); |
const size_t mbedtls_test_srv_pwd_len = |
sizeof( test_srv_pwd ) - 1; |
const size_t mbedtls_test_srv_crt_len = |
sizeof( test_srv_crt ); |
const size_t mbedtls_test_cli_key_len = |
sizeof( test_cli_key ); |
const size_t mbedtls_test_cli_pwd_len = |
sizeof( test_cli_pwd ) - 1; |
const size_t mbedtls_test_cli_crt_len = |
sizeof( test_cli_crt ); |
/* |
* |
* Lists of certificates |
* |
*/ |
/* List of CAs in PEM or DER, depending on config */ |
const char * mbedtls_test_cas[] = { |
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) |
mbedtls_test_ca_crt_rsa_sha1, |
#endif |
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) |
mbedtls_test_ca_crt_rsa_sha256, |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
mbedtls_test_ca_crt_ec, |
#endif |
NULL |
}; |
const size_t mbedtls_test_cas_len[] = { |
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) |
sizeof( mbedtls_test_ca_crt_rsa_sha1 ), |
#endif |
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) |
sizeof( mbedtls_test_ca_crt_rsa_sha256 ), |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
sizeof( mbedtls_test_ca_crt_ec ), |
#endif |
0 |
}; |
/* List of all available CA certificates in DER format */ |
const unsigned char * mbedtls_test_cas_der[] = { |
#if defined(MBEDTLS_RSA_C) |
#if defined(MBEDTLS_SHA256_C) |
mbedtls_test_ca_crt_rsa_sha256_der, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
mbedtls_test_ca_crt_rsa_sha1_der, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECDSA_C) |
mbedtls_test_ca_crt_ec_der, |
#endif /* MBEDTLS_ECDSA_C */ |
NULL |
}; |
const size_t mbedtls_test_cas_der_len[] = { |
#if defined(MBEDTLS_RSA_C) |
#if defined(MBEDTLS_SHA256_C) |
sizeof( mbedtls_test_ca_crt_rsa_sha256_der ), |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
sizeof( mbedtls_test_ca_crt_rsa_sha1_der ), |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECDSA_C) |
sizeof( mbedtls_test_ca_crt_ec_der ), |
#endif /* MBEDTLS_ECDSA_C */ |
0 |
}; |
/* Concatenation of all available CA certificates in PEM format */ |
#if defined(MBEDTLS_PEM_PARSE_C) |
const char mbedtls_test_cas_pem[] = |
#if defined(MBEDTLS_RSA_C) |
#if defined(MBEDTLS_SHA256_C) |
TEST_CA_CRT_RSA_SHA256_PEM |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
TEST_CA_CRT_RSA_SHA1_PEM |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECDSA_C) |
TEST_CA_CRT_EC_PEM |
#endif /* MBEDTLS_ECDSA_C */ |
""; |
const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); |
#endif /* MBEDTLS_PEM_PARSE_C */ |
#endif /* MBEDTLS_CERTS_C */ |
/programs/develop/libraries/kos_mbedtls/library/chacha20.c |
---|
0,0 → 1,572 |
/** |
* \file chacha20.c |
* |
* \brief ChaCha20 cipher. |
* |
* \author Daniel King <damaki.gh@gmail.com> |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CHACHA20_C) |
#include "mbedtls/chacha20.h" |
#include "mbedtls/platform_util.h" |
#include <stddef.h> |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_CHACHA20_ALT) |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
/* Parameter validation macros */ |
#define CHACHA20_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) |
#define CHACHA20_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#define BYTES_TO_U32_LE( data, offset ) \ |
( (uint32_t) (data)[offset] \ |
| (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ |
| (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ |
| (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ |
) |
#define ROTL32( value, amount ) \ |
( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) ) |
#define CHACHA20_CTR_INDEX ( 12U ) |
#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U ) |
/** |
* \brief ChaCha20 quarter round operation. |
* |
* The quarter round is defined as follows (from RFC 7539): |
* 1. a += b; d ^= a; d <<<= 16; |
* 2. c += d; b ^= c; b <<<= 12; |
* 3. a += b; d ^= a; d <<<= 8; |
* 4. c += d; b ^= c; b <<<= 7; |
* |
* \param state ChaCha20 state to modify. |
* \param a The index of 'a' in the state. |
* \param b The index of 'b' in the state. |
* \param c The index of 'c' in the state. |
* \param d The index of 'd' in the state. |
*/ |
static inline void chacha20_quarter_round( uint32_t state[16], |
size_t a, |
size_t b, |
size_t c, |
size_t d ) |
{ |
/* a += b; d ^= a; d <<<= 16; */ |
state[a] += state[b]; |
state[d] ^= state[a]; |
state[d] = ROTL32( state[d], 16 ); |
/* c += d; b ^= c; b <<<= 12 */ |
state[c] += state[d]; |
state[b] ^= state[c]; |
state[b] = ROTL32( state[b], 12 ); |
/* a += b; d ^= a; d <<<= 8; */ |
state[a] += state[b]; |
state[d] ^= state[a]; |
state[d] = ROTL32( state[d], 8 ); |
/* c += d; b ^= c; b <<<= 7; */ |
state[c] += state[d]; |
state[b] ^= state[c]; |
state[b] = ROTL32( state[b], 7 ); |
} |
/** |
* \brief Perform the ChaCha20 inner block operation. |
* |
* This function performs two rounds: the column round and the |
* diagonal round. |
* |
* \param state The ChaCha20 state to update. |
*/ |
static void chacha20_inner_block( uint32_t state[16] ) |
{ |
chacha20_quarter_round( state, 0, 4, 8, 12 ); |
chacha20_quarter_round( state, 1, 5, 9, 13 ); |
chacha20_quarter_round( state, 2, 6, 10, 14 ); |
chacha20_quarter_round( state, 3, 7, 11, 15 ); |
chacha20_quarter_round( state, 0, 5, 10, 15 ); |
chacha20_quarter_round( state, 1, 6, 11, 12 ); |
chacha20_quarter_round( state, 2, 7, 8, 13 ); |
chacha20_quarter_round( state, 3, 4, 9, 14 ); |
} |
/** |
* \brief Generates a keystream block. |
* |
* \param initial_state The initial ChaCha20 state (key, nonce, counter). |
* \param keystream Generated keystream bytes are written to this buffer. |
*/ |
static void chacha20_block( const uint32_t initial_state[16], |
unsigned char keystream[64] ) |
{ |
uint32_t working_state[16]; |
size_t i; |
memcpy( working_state, |
initial_state, |
CHACHA20_BLOCK_SIZE_BYTES ); |
for( i = 0U; i < 10U; i++ ) |
chacha20_inner_block( working_state ); |
working_state[ 0] += initial_state[ 0]; |
working_state[ 1] += initial_state[ 1]; |
working_state[ 2] += initial_state[ 2]; |
working_state[ 3] += initial_state[ 3]; |
working_state[ 4] += initial_state[ 4]; |
working_state[ 5] += initial_state[ 5]; |
working_state[ 6] += initial_state[ 6]; |
working_state[ 7] += initial_state[ 7]; |
working_state[ 8] += initial_state[ 8]; |
working_state[ 9] += initial_state[ 9]; |
working_state[10] += initial_state[10]; |
working_state[11] += initial_state[11]; |
working_state[12] += initial_state[12]; |
working_state[13] += initial_state[13]; |
working_state[14] += initial_state[14]; |
working_state[15] += initial_state[15]; |
for( i = 0U; i < 16; i++ ) |
{ |
size_t offset = i * 4U; |
keystream[offset ] = (unsigned char)( working_state[i] ); |
keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 ); |
keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 ); |
keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 ); |
} |
mbedtls_platform_zeroize( working_state, sizeof( working_state ) ); |
} |
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) |
{ |
CHACHA20_VALIDATE( ctx != NULL ); |
mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) ); |
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); |
/* Initially, there's no keystream bytes available */ |
ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; |
} |
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) |
{ |
if( ctx != NULL ) |
{ |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); |
} |
} |
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, |
const unsigned char key[32] ) |
{ |
CHACHA20_VALIDATE_RET( ctx != NULL ); |
CHACHA20_VALIDATE_RET( key != NULL ); |
/* ChaCha20 constants - the string "expand 32-byte k" */ |
ctx->state[0] = 0x61707865; |
ctx->state[1] = 0x3320646e; |
ctx->state[2] = 0x79622d32; |
ctx->state[3] = 0x6b206574; |
/* Set key */ |
ctx->state[4] = BYTES_TO_U32_LE( key, 0 ); |
ctx->state[5] = BYTES_TO_U32_LE( key, 4 ); |
ctx->state[6] = BYTES_TO_U32_LE( key, 8 ); |
ctx->state[7] = BYTES_TO_U32_LE( key, 12 ); |
ctx->state[8] = BYTES_TO_U32_LE( key, 16 ); |
ctx->state[9] = BYTES_TO_U32_LE( key, 20 ); |
ctx->state[10] = BYTES_TO_U32_LE( key, 24 ); |
ctx->state[11] = BYTES_TO_U32_LE( key, 28 ); |
return( 0 ); |
} |
int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, |
const unsigned char nonce[12], |
uint32_t counter ) |
{ |
CHACHA20_VALIDATE_RET( ctx != NULL ); |
CHACHA20_VALIDATE_RET( nonce != NULL ); |
/* Counter */ |
ctx->state[12] = counter; |
/* Nonce */ |
ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 ); |
ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 ); |
ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 ); |
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); |
/* Initially, there's no keystream bytes available */ |
ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; |
return( 0 ); |
} |
int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, |
size_t size, |
const unsigned char *input, |
unsigned char *output ) |
{ |
size_t offset = 0U; |
size_t i; |
CHACHA20_VALIDATE_RET( ctx != NULL ); |
CHACHA20_VALIDATE_RET( size == 0 || input != NULL ); |
CHACHA20_VALIDATE_RET( size == 0 || output != NULL ); |
/* Use leftover keystream bytes, if available */ |
while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) |
{ |
output[offset] = input[offset] |
^ ctx->keystream8[ctx->keystream_bytes_used]; |
ctx->keystream_bytes_used++; |
offset++; |
size--; |
} |
/* Process full blocks */ |
while( size >= CHACHA20_BLOCK_SIZE_BYTES ) |
{ |
/* Generate new keystream block and increment counter */ |
chacha20_block( ctx->state, ctx->keystream8 ); |
ctx->state[CHACHA20_CTR_INDEX]++; |
for( i = 0U; i < 64U; i += 8U ) |
{ |
output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ]; |
output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1]; |
output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2]; |
output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3]; |
output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4]; |
output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5]; |
output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6]; |
output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7]; |
} |
offset += CHACHA20_BLOCK_SIZE_BYTES; |
size -= CHACHA20_BLOCK_SIZE_BYTES; |
} |
/* Last (partial) block */ |
if( size > 0U ) |
{ |
/* Generate new keystream block and increment counter */ |
chacha20_block( ctx->state, ctx->keystream8 ); |
ctx->state[CHACHA20_CTR_INDEX]++; |
for( i = 0U; i < size; i++) |
{ |
output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; |
} |
ctx->keystream_bytes_used = size; |
} |
return( 0 ); |
} |
int mbedtls_chacha20_crypt( const unsigned char key[32], |
const unsigned char nonce[12], |
uint32_t counter, |
size_t data_len, |
const unsigned char* input, |
unsigned char* output ) |
{ |
mbedtls_chacha20_context ctx; |
int ret; |
CHACHA20_VALIDATE_RET( key != NULL ); |
CHACHA20_VALIDATE_RET( nonce != NULL ); |
CHACHA20_VALIDATE_RET( data_len == 0 || input != NULL ); |
CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL ); |
mbedtls_chacha20_init( &ctx ); |
ret = mbedtls_chacha20_setkey( &ctx, key ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_chacha20_starts( &ctx, nonce, counter ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_chacha20_update( &ctx, data_len, input, output ); |
cleanup: |
mbedtls_chacha20_free( &ctx ); |
return( ret ); |
} |
#endif /* !MBEDTLS_CHACHA20_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
static const unsigned char test_keys[2][32] = |
{ |
{ |
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, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 |
} |
}; |
static const unsigned char test_nonces[2][12] = |
{ |
{ |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00 |
}, |
{ |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x02 |
} |
}; |
static const uint32_t test_counters[2] = |
{ |
0U, |
1U |
}; |
static const unsigned char test_input[2][375] = |
{ |
{ |
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, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
}, |
{ |
0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, |
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, |
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, |
0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, |
0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, |
0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, |
0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, |
0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, |
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, |
0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, |
0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, |
0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, |
0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, |
0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, |
0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, |
0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, |
0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, |
0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, |
0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, |
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, |
0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, |
0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, |
0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, |
0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, |
0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, |
0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, |
0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, |
0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, |
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, |
0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, |
0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, |
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, |
0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, |
0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, |
0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, |
0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, |
0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, |
0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, |
0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, |
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, |
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, |
0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, |
0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, |
0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, |
0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, |
0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, |
0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f |
} |
}; |
static const unsigned char test_output[2][375] = |
{ |
{ |
0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, |
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, |
0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, |
0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, |
0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, |
0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, |
0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, |
0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86 |
}, |
{ |
0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde, |
0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, |
0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd, |
0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec, |
0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15, |
0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, |
0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f, |
0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d, |
0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa, |
0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, |
0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7, |
0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, |
0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05, |
0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c, |
0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05, |
0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, |
0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0, |
0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66, |
0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4, |
0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, |
0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91, |
0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, |
0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87, |
0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b, |
0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2, |
0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, |
0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76, |
0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c, |
0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b, |
0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, |
0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd, |
0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, |
0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe, |
0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0, |
0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80, |
0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, |
0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3, |
0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62, |
0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91, |
0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, |
0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64, |
0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, |
0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41, |
0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab, |
0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba, |
0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, |
0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21 |
} |
}; |
static const size_t test_lengths[2] = |
{ |
64U, |
375U |
}; |
#define ASSERT( cond, args ) \ |
do \ |
{ \ |
if( ! ( cond ) ) \ |
{ \ |
if( verbose != 0 ) \ |
mbedtls_printf args; \ |
\ |
return( -1 ); \ |
} \ |
} \ |
while( 0 ) |
int mbedtls_chacha20_self_test( int verbose ) |
{ |
unsigned char output[381]; |
unsigned i; |
int ret; |
for( i = 0U; i < 2U; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " ChaCha20 test %u ", i ); |
ret = mbedtls_chacha20_crypt( test_keys[i], |
test_nonces[i], |
test_counters[i], |
test_lengths[i], |
test_input[i], |
output ); |
ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); |
ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ), |
( "failed (output)\n" ) ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* !MBEDTLS_CHACHA20_C */ |
/programs/develop/libraries/kos_mbedtls/library/chachapoly.c |
---|
0,0 → 1,542 |
/** |
* \file chachapoly.c |
* |
* \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CHACHAPOLY_C) |
#include "mbedtls/chachapoly.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_CHACHAPOLY_ALT) |
/* Parameter validation macros */ |
#define CHACHAPOLY_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) |
#define CHACHAPOLY_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#define CHACHAPOLY_STATE_INIT ( 0 ) |
#define CHACHAPOLY_STATE_AAD ( 1 ) |
#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ |
#define CHACHAPOLY_STATE_FINISHED ( 3 ) |
/** |
* \brief Adds nul bytes to pad the AAD for Poly1305. |
* |
* \param ctx The ChaCha20-Poly1305 context. |
*/ |
static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) |
{ |
uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); |
unsigned char zeroes[15]; |
if( partial_block_len == 0U ) |
return( 0 ); |
memset( zeroes, 0, sizeof( zeroes ) ); |
return( mbedtls_poly1305_update( &ctx->poly1305_ctx, |
zeroes, |
16U - partial_block_len ) ); |
} |
/** |
* \brief Adds nul bytes to pad the ciphertext for Poly1305. |
* |
* \param ctx The ChaCha20-Poly1305 context. |
*/ |
static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) |
{ |
uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); |
unsigned char zeroes[15]; |
if( partial_block_len == 0U ) |
return( 0 ); |
memset( zeroes, 0, sizeof( zeroes ) ); |
return( mbedtls_poly1305_update( &ctx->poly1305_ctx, |
zeroes, |
16U - partial_block_len ) ); |
} |
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) |
{ |
CHACHAPOLY_VALIDATE( ctx != NULL ); |
mbedtls_chacha20_init( &ctx->chacha20_ctx ); |
mbedtls_poly1305_init( &ctx->poly1305_ctx ); |
ctx->aad_len = 0U; |
ctx->ciphertext_len = 0U; |
ctx->state = CHACHAPOLY_STATE_INIT; |
ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; |
} |
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_chacha20_free( &ctx->chacha20_ctx ); |
mbedtls_poly1305_free( &ctx->poly1305_ctx ); |
ctx->aad_len = 0U; |
ctx->ciphertext_len = 0U; |
ctx->state = CHACHAPOLY_STATE_INIT; |
ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; |
} |
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, |
const unsigned char key[32] ) |
{ |
int ret; |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( key != NULL ); |
ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); |
return( ret ); |
} |
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, |
const unsigned char nonce[12], |
mbedtls_chachapoly_mode_t mode ) |
{ |
int ret; |
unsigned char poly1305_key[64]; |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( nonce != NULL ); |
/* Set counter = 0, will be update to 1 when generating Poly1305 key */ |
ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U ); |
if( ret != 0 ) |
goto cleanup; |
/* Generate the Poly1305 key by getting the ChaCha20 keystream output with |
* counter = 0. This is the same as encrypting a buffer of zeroes. |
* Only the first 256-bits (32 bytes) of the key is used for Poly1305. |
* The other 256 bits are discarded. |
*/ |
memset( poly1305_key, 0, sizeof( poly1305_key ) ); |
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), |
poly1305_key, poly1305_key ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); |
if( ret == 0 ) |
{ |
ctx->aad_len = 0U; |
ctx->ciphertext_len = 0U; |
ctx->state = CHACHAPOLY_STATE_AAD; |
ctx->mode = mode; |
} |
cleanup: |
mbedtls_platform_zeroize( poly1305_key, 64U ); |
return( ret ); |
} |
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, |
const unsigned char *aad, |
size_t aad_len ) |
{ |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); |
if( ctx->state != CHACHAPOLY_STATE_AAD ) |
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); |
ctx->aad_len += aad_len; |
return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) ); |
} |
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, |
size_t len, |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL ); |
CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL ); |
if( ( ctx->state != CHACHAPOLY_STATE_AAD ) && |
( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) |
{ |
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); |
} |
if( ctx->state == CHACHAPOLY_STATE_AAD ) |
{ |
ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; |
ret = chachapoly_pad_aad( ctx ); |
if( ret != 0 ) |
return( ret ); |
} |
ctx->ciphertext_len += len; |
if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT ) |
{ |
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); |
if( ret != 0 ) |
return( ret ); |
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len ); |
if( ret != 0 ) |
return( ret ); |
} |
else /* DECRYPT */ |
{ |
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len ); |
if( ret != 0 ) |
return( ret ); |
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); |
if( ret != 0 ) |
return( ret ); |
} |
return( 0 ); |
} |
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, |
unsigned char mac[16] ) |
{ |
int ret; |
unsigned char len_block[16]; |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( mac != NULL ); |
if( ctx->state == CHACHAPOLY_STATE_INIT ) |
{ |
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); |
} |
if( ctx->state == CHACHAPOLY_STATE_AAD ) |
{ |
ret = chachapoly_pad_aad( ctx ); |
if( ret != 0 ) |
return( ret ); |
} |
else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) |
{ |
ret = chachapoly_pad_ciphertext( ctx ); |
if( ret != 0 ) |
return( ret ); |
} |
ctx->state = CHACHAPOLY_STATE_FINISHED; |
/* The lengths of the AAD and ciphertext are processed by |
* Poly1305 as the final 128-bit block, encoded as little-endian integers. |
*/ |
len_block[ 0] = (unsigned char)( ctx->aad_len ); |
len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 ); |
len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 ); |
len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 ); |
len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 ); |
len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 ); |
len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 ); |
len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 ); |
len_block[ 8] = (unsigned char)( ctx->ciphertext_len ); |
len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 ); |
len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 ); |
len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 ); |
len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 ); |
len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 ); |
len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 ); |
len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 ); |
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U ); |
if( ret != 0 ) |
return( ret ); |
ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); |
return( ret ); |
} |
static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, |
mbedtls_chachapoly_mode_t mode, |
size_t length, |
const unsigned char nonce[12], |
const unsigned char *aad, |
size_t aad_len, |
const unsigned char *input, |
unsigned char *output, |
unsigned char tag[16] ) |
{ |
int ret; |
ret = mbedtls_chachapoly_starts( ctx, nonce, mode ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_chachapoly_update( ctx, length, input, output ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_chachapoly_finish( ctx, tag ); |
cleanup: |
return( ret ); |
} |
int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, |
size_t length, |
const unsigned char nonce[12], |
const unsigned char *aad, |
size_t aad_len, |
const unsigned char *input, |
unsigned char *output, |
unsigned char tag[16] ) |
{ |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( nonce != NULL ); |
CHACHAPOLY_VALIDATE_RET( tag != NULL ); |
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); |
CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL ); |
CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL ); |
return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, |
length, nonce, aad, aad_len, |
input, output, tag ) ); |
} |
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, |
size_t length, |
const unsigned char nonce[12], |
const unsigned char *aad, |
size_t aad_len, |
const unsigned char tag[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
unsigned char check_tag[16]; |
size_t i; |
int diff; |
CHACHAPOLY_VALIDATE_RET( ctx != NULL ); |
CHACHAPOLY_VALIDATE_RET( nonce != NULL ); |
CHACHAPOLY_VALIDATE_RET( tag != NULL ); |
CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL ); |
CHACHAPOLY_VALIDATE_RET( length == 0 || input != NULL ); |
CHACHAPOLY_VALIDATE_RET( length == 0 || output != NULL ); |
if( ( ret = chachapoly_crypt_and_tag( ctx, |
MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, |
aad, aad_len, input, output, check_tag ) ) != 0 ) |
{ |
return( ret ); |
} |
/* Check tag in "constant-time" */ |
for( diff = 0, i = 0; i < sizeof( check_tag ); i++ ) |
diff |= tag[i] ^ check_tag[i]; |
if( diff != 0 ) |
{ |
mbedtls_platform_zeroize( output, length ); |
return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CHACHAPOLY_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
static const unsigned char test_key[1][32] = |
{ |
{ |
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, |
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, |
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, |
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f |
} |
}; |
static const unsigned char test_nonce[1][12] = |
{ |
{ |
0x07, 0x00, 0x00, 0x00, /* 32-bit common part */ |
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */ |
} |
}; |
static const unsigned char test_aad[1][12] = |
{ |
{ |
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, |
0xc4, 0xc5, 0xc6, 0xc7 |
} |
}; |
static const size_t test_aad_len[1] = |
{ |
12U |
}; |
static const unsigned char test_input[1][114] = |
{ |
{ |
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, |
0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, |
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, |
0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, |
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, |
0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, |
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, |
0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, |
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, |
0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, |
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, |
0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, |
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, |
0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, |
0x74, 0x2e |
} |
}; |
static const unsigned char test_output[1][114] = |
{ |
{ |
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, |
0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, |
0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, |
0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, |
0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, |
0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, |
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, |
0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, |
0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, |
0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, |
0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, |
0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, |
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, |
0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, |
0x61, 0x16 |
} |
}; |
static const size_t test_input_len[1] = |
{ |
114U |
}; |
static const unsigned char test_mac[1][16] = |
{ |
{ |
0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, |
0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 |
} |
}; |
#define ASSERT( cond, args ) \ |
do \ |
{ \ |
if( ! ( cond ) ) \ |
{ \ |
if( verbose != 0 ) \ |
mbedtls_printf args; \ |
\ |
return( -1 ); \ |
} \ |
} \ |
while( 0 ) |
int mbedtls_chachapoly_self_test( int verbose ) |
{ |
mbedtls_chachapoly_context ctx; |
unsigned i; |
int ret; |
unsigned char output[200]; |
unsigned char mac[16]; |
for( i = 0U; i < 1U; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); |
mbedtls_chachapoly_init( &ctx ); |
ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); |
ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) ); |
ret = mbedtls_chachapoly_encrypt_and_tag( &ctx, |
test_input_len[i], |
test_nonce[i], |
test_aad[i], |
test_aad_len[i], |
test_input[i], |
output, |
mac ); |
ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) ); |
ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ), |
( "failure (wrong output)\n" ) ); |
ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), |
( "failure (wrong MAC)\n" ) ); |
mbedtls_chachapoly_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
/programs/develop/libraries/kos_mbedtls/library/cipher.c |
---|
0,0 → 1,1160 |
/** |
* \file cipher.c |
* |
* \brief Generic cipher wrapper for mbed TLS |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CIPHER_C) |
#include "mbedtls/cipher.h" |
#include "mbedtls/cipher_internal.h" |
#include "mbedtls/platform_util.h" |
#include <stdlib.h> |
#include <string.h> |
#if defined(MBEDTLS_CHACHAPOLY_C) |
#include "mbedtls/chachapoly.h" |
#endif |
#if defined(MBEDTLS_GCM_C) |
#include "mbedtls/gcm.h" |
#endif |
#if defined(MBEDTLS_CCM_C) |
#include "mbedtls/ccm.h" |
#endif |
#if defined(MBEDTLS_CHACHA20_C) |
#include "mbedtls/chacha20.h" |
#endif |
#if defined(MBEDTLS_CMAC_C) |
#include "mbedtls/cmac.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#define CIPHER_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ) |
#define CIPHER_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) |
/* Compare the contents of two buffers in constant time. |
* Returns 0 if the contents are bitwise identical, otherwise returns |
* a non-zero value. |
* This is currently only used by GCM and ChaCha20+Poly1305. |
*/ |
static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) |
{ |
const unsigned char *p1 = (const unsigned char*) v1; |
const unsigned char *p2 = (const unsigned char*) v2; |
size_t i; |
unsigned char diff; |
for( diff = 0, i = 0; i < len; i++ ) |
diff |= p1[i] ^ p2[i]; |
return( (int)diff ); |
} |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ |
static int supported_init = 0; |
const int *mbedtls_cipher_list( void ) |
{ |
const mbedtls_cipher_definition_t *def; |
int *type; |
if( ! supported_init ) |
{ |
def = mbedtls_cipher_definitions; |
type = mbedtls_cipher_supported; |
while( def->type != 0 ) |
*type++ = (*def++).type; |
*type = 0; |
supported_init = 1; |
} |
return( mbedtls_cipher_supported ); |
} |
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) |
{ |
const mbedtls_cipher_definition_t *def; |
for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) |
if( def->type == cipher_type ) |
return( def->info ); |
return( NULL ); |
} |
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) |
{ |
const mbedtls_cipher_definition_t *def; |
if( NULL == cipher_name ) |
return( NULL ); |
for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) |
if( ! strcmp( def->info->name, cipher_name ) ) |
return( def->info ); |
return( NULL ); |
} |
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, |
int key_bitlen, |
const mbedtls_cipher_mode_t mode ) |
{ |
const mbedtls_cipher_definition_t *def; |
for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) |
if( def->info->base->cipher == cipher_id && |
def->info->key_bitlen == (unsigned) key_bitlen && |
def->info->mode == mode ) |
return( def->info ); |
return( NULL ); |
} |
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) |
{ |
CIPHER_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); |
} |
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) |
{ |
if( ctx == NULL ) |
return; |
#if defined(MBEDTLS_CMAC_C) |
if( ctx->cmac_ctx ) |
{ |
mbedtls_platform_zeroize( ctx->cmac_ctx, |
sizeof( mbedtls_cmac_context_t ) ); |
mbedtls_free( ctx->cmac_ctx ); |
} |
#endif |
if( ctx->cipher_ctx ) |
ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); |
} |
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); |
if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) |
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); |
ctx->cipher_info = cipher_info; |
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) |
/* |
* Ignore possible errors caused by a cipher mode that doesn't use padding |
*/ |
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) |
(void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); |
#else |
(void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); |
#endif |
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ |
return( 0 ); |
} |
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, |
const unsigned char *key, |
int key_bitlen, |
const mbedtls_operation_t operation ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( key != NULL ); |
CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT || |
operation == MBEDTLS_DECRYPT ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && |
(int) ctx->cipher_info->key_bitlen != key_bitlen ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
ctx->key_bitlen = key_bitlen; |
ctx->operation = operation; |
/* |
* For OFB, CFB and CTR mode always use the encryption key schedule |
*/ |
if( MBEDTLS_ENCRYPT == operation || |
MBEDTLS_MODE_CFB == ctx->cipher_info->mode || |
MBEDTLS_MODE_OFB == ctx->cipher_info->mode || |
MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) |
{ |
return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, |
ctx->key_bitlen ) ); |
} |
if( MBEDTLS_DECRYPT == operation ) |
return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, |
ctx->key_bitlen ) ); |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, |
size_t iv_len ) |
{ |
size_t actual_iv_size; |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
/* avoid buffer overflow in ctx->iv */ |
if( iv_len > MBEDTLS_MAX_IV_LENGTH ) |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) |
actual_iv_size = iv_len; |
else |
{ |
actual_iv_size = ctx->cipher_info->iv_size; |
/* avoid reading past the end of input buffer */ |
if( actual_iv_size > iv_len ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
#if defined(MBEDTLS_CHACHA20_C) |
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) |
{ |
if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, |
iv, |
0U ) ) /* Initial counter value */ |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
} |
#endif |
if ( actual_iv_size != 0 ) |
{ |
memcpy( ctx->iv, iv, actual_iv_size ); |
ctx->iv_size = actual_iv_size; |
} |
return( 0 ); |
} |
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
ctx->unprocessed_len = 0; |
return( 0 ); |
} |
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) |
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, |
const unsigned char *ad, size_t ad_len ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_GCM_C) |
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) |
{ |
return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, |
ctx->iv, ctx->iv_size, ad, ad_len ) ); |
} |
#endif |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) |
{ |
int result; |
mbedtls_chachapoly_mode_t mode; |
mode = ( ctx->operation == MBEDTLS_ENCRYPT ) |
? MBEDTLS_CHACHAPOLY_ENCRYPT |
: MBEDTLS_CHACHAPOLY_DECRYPT; |
result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, |
ctx->iv, |
mode ); |
if ( result != 0 ) |
return( result ); |
return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, |
ad, ad_len ) ); |
} |
#endif |
return( 0 ); |
} |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ |
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, |
size_t ilen, unsigned char *output, size_t *olen ) |
{ |
int ret; |
size_t block_size; |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); |
CIPHER_VALIDATE_RET( output != NULL ); |
CIPHER_VALIDATE_RET( olen != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
*olen = 0; |
block_size = mbedtls_cipher_get_block_size( ctx ); |
if ( 0 == block_size ) |
{ |
return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ); |
} |
if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) |
{ |
if( ilen != block_size ) |
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); |
*olen = ilen; |
if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, |
ctx->operation, input, output ) ) ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
#if defined(MBEDTLS_GCM_C) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) |
{ |
*olen = ilen; |
return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, |
output ) ); |
} |
#endif |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) |
{ |
*olen = ilen; |
return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, |
ilen, input, output ) ); |
} |
#endif |
if( input == output && |
( ctx->unprocessed_len != 0 || ilen % block_size ) ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) |
{ |
size_t copy_len = 0; |
/* |
* If there is not enough data for a full block, cache it. |
*/ |
if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && |
ilen <= block_size - ctx->unprocessed_len ) || |
( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && |
ilen < block_size - ctx->unprocessed_len ) || |
( ctx->operation == MBEDTLS_ENCRYPT && |
ilen < block_size - ctx->unprocessed_len ) ) |
{ |
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, |
ilen ); |
ctx->unprocessed_len += ilen; |
return( 0 ); |
} |
/* |
* Process cached data first |
*/ |
if( 0 != ctx->unprocessed_len ) |
{ |
copy_len = block_size - ctx->unprocessed_len; |
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, |
copy_len ); |
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, |
ctx->operation, block_size, ctx->iv, |
ctx->unprocessed_data, output ) ) ) |
{ |
return( ret ); |
} |
*olen += block_size; |
output += block_size; |
ctx->unprocessed_len = 0; |
input += copy_len; |
ilen -= copy_len; |
} |
/* |
* Cache final, incomplete block |
*/ |
if( 0 != ilen ) |
{ |
/* Encryption: only cache partial blocks |
* Decryption w/ padding: always keep at least one whole block |
* Decryption w/o padding: only cache partial blocks |
*/ |
copy_len = ilen % block_size; |
if( copy_len == 0 && |
ctx->operation == MBEDTLS_DECRYPT && |
NULL != ctx->add_padding) |
{ |
copy_len = block_size; |
} |
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), |
copy_len ); |
ctx->unprocessed_len += copy_len; |
ilen -= copy_len; |
} |
/* |
* Process remaining full blocks |
*/ |
if( ilen ) |
{ |
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, |
ctx->operation, ilen, ctx->iv, input, output ) ) ) |
{ |
return( ret ); |
} |
*olen += ilen; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) |
{ |
if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, |
ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, |
input, output ) ) ) |
{ |
return( ret ); |
} |
*olen = ilen; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) |
{ |
if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, |
ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) |
{ |
return( ret ); |
} |
*olen = ilen; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) |
{ |
if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, |
ilen, &ctx->unprocessed_len, ctx->iv, |
ctx->unprocessed_data, input, output ) ) ) |
{ |
return( ret ); |
} |
*olen = ilen; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) |
{ |
if( ctx->unprocessed_len > 0 ) { |
/* We can only process an entire data unit at a time. */ |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, |
ctx->operation, ilen, ctx->iv, input, output ); |
if( ret != 0 ) |
{ |
return( ret ); |
} |
*olen = ilen; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) |
{ |
if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, |
ilen, input, output ) ) ) |
{ |
return( ret ); |
} |
*olen = ilen; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_STREAM */ |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) |
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) |
/* |
* PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len |
*/ |
static void add_pkcs_padding( unsigned char *output, size_t output_len, |
size_t data_len ) |
{ |
size_t padding_len = output_len - data_len; |
unsigned char i; |
for( i = 0; i < padding_len; i++ ) |
output[data_len + i] = (unsigned char) padding_len; |
} |
static int get_pkcs_padding( unsigned char *input, size_t input_len, |
size_t *data_len ) |
{ |
size_t i, pad_idx; |
unsigned char padding_len, bad = 0; |
if( NULL == input || NULL == data_len ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
padding_len = input[input_len - 1]; |
*data_len = input_len - padding_len; |
/* Avoid logical || since it results in a branch */ |
bad |= padding_len > input_len; |
bad |= padding_len == 0; |
/* The number of bytes checked must be independent of padding_len, |
* so pick input_len, which is usually 8 or 16 (one block) */ |
pad_idx = input_len - padding_len; |
for( i = 0; i < input_len; i++ ) |
bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); |
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); |
} |
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ |
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) |
/* |
* One and zeros padding: fill with 80 00 ... 00 |
*/ |
static void add_one_and_zeros_padding( unsigned char *output, |
size_t output_len, size_t data_len ) |
{ |
size_t padding_len = output_len - data_len; |
unsigned char i = 0; |
output[data_len] = 0x80; |
for( i = 1; i < padding_len; i++ ) |
output[data_len + i] = 0x00; |
} |
static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, |
size_t *data_len ) |
{ |
size_t i; |
unsigned char done = 0, prev_done, bad; |
if( NULL == input || NULL == data_len ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
bad = 0x80; |
*data_len = 0; |
for( i = input_len; i > 0; i-- ) |
{ |
prev_done = done; |
done |= ( input[i - 1] != 0 ); |
*data_len |= ( i - 1 ) * ( done != prev_done ); |
bad ^= input[i - 1] * ( done != prev_done ); |
} |
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); |
} |
#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ |
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) |
/* |
* Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length |
*/ |
static void add_zeros_and_len_padding( unsigned char *output, |
size_t output_len, size_t data_len ) |
{ |
size_t padding_len = output_len - data_len; |
unsigned char i = 0; |
for( i = 1; i < padding_len; i++ ) |
output[data_len + i - 1] = 0x00; |
output[output_len - 1] = (unsigned char) padding_len; |
} |
static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, |
size_t *data_len ) |
{ |
size_t i, pad_idx; |
unsigned char padding_len, bad = 0; |
if( NULL == input || NULL == data_len ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
padding_len = input[input_len - 1]; |
*data_len = input_len - padding_len; |
/* Avoid logical || since it results in a branch */ |
bad |= padding_len > input_len; |
bad |= padding_len == 0; |
/* The number of bytes checked must be independent of padding_len */ |
pad_idx = input_len - padding_len; |
for( i = 0; i < input_len - 1; i++ ) |
bad |= input[i] * ( i >= pad_idx ); |
return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); |
} |
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ |
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) |
/* |
* Zero padding: fill with 00 ... 00 |
*/ |
static void add_zeros_padding( unsigned char *output, |
size_t output_len, size_t data_len ) |
{ |
size_t i; |
for( i = data_len; i < output_len; i++ ) |
output[i] = 0x00; |
} |
static int get_zeros_padding( unsigned char *input, size_t input_len, |
size_t *data_len ) |
{ |
size_t i; |
unsigned char done = 0, prev_done; |
if( NULL == input || NULL == data_len ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
*data_len = 0; |
for( i = input_len; i > 0; i-- ) |
{ |
prev_done = done; |
done |= ( input[i-1] != 0 ); |
*data_len |= i * ( done != prev_done ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ |
/* |
* No padding: don't pad :) |
* |
* There is no add_padding function (check for NULL in mbedtls_cipher_finish) |
* but a trivial get_padding function |
*/ |
static int get_no_padding( unsigned char *input, size_t input_len, |
size_t *data_len ) |
{ |
if( NULL == input || NULL == data_len ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
*data_len = input_len; |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ |
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, |
unsigned char *output, size_t *olen ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( output != NULL ); |
CIPHER_VALIDATE_RET( olen != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
*olen = 0; |
if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || |
MBEDTLS_MODE_OFB == ctx->cipher_info->mode || |
MBEDTLS_MODE_CTR == ctx->cipher_info->mode || |
MBEDTLS_MODE_GCM == ctx->cipher_info->mode || |
MBEDTLS_MODE_XTS == ctx->cipher_info->mode || |
MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) |
{ |
return( 0 ); |
} |
if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || |
( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) |
{ |
return( 0 ); |
} |
if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) |
{ |
if( ctx->unprocessed_len != 0 ) |
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); |
return( 0 ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) |
{ |
int ret = 0; |
if( MBEDTLS_ENCRYPT == ctx->operation ) |
{ |
/* check for 'no padding' mode */ |
if( NULL == ctx->add_padding ) |
{ |
if( 0 != ctx->unprocessed_len ) |
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); |
return( 0 ); |
} |
ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), |
ctx->unprocessed_len ); |
} |
else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) |
{ |
/* |
* For decrypt operations, expect a full block, |
* or an empty block if no padding |
*/ |
if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) |
return( 0 ); |
return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); |
} |
/* cipher block */ |
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, |
ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, |
ctx->unprocessed_data, output ) ) ) |
{ |
return( ret ); |
} |
/* Set output size for decryption */ |
if( MBEDTLS_DECRYPT == ctx->operation ) |
return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), |
olen ) ); |
/* Set output size for encryption */ |
*olen = mbedtls_cipher_get_block_size( ctx ); |
return( 0 ); |
} |
#else |
((void) output); |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) |
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, |
mbedtls_cipher_padding_t mode ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
switch( mode ) |
{ |
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) |
case MBEDTLS_PADDING_PKCS7: |
ctx->add_padding = add_pkcs_padding; |
ctx->get_padding = get_pkcs_padding; |
break; |
#endif |
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) |
case MBEDTLS_PADDING_ONE_AND_ZEROS: |
ctx->add_padding = add_one_and_zeros_padding; |
ctx->get_padding = get_one_and_zeros_padding; |
break; |
#endif |
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) |
case MBEDTLS_PADDING_ZEROS_AND_LEN: |
ctx->add_padding = add_zeros_and_len_padding; |
ctx->get_padding = get_zeros_and_len_padding; |
break; |
#endif |
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) |
case MBEDTLS_PADDING_ZEROS: |
ctx->add_padding = add_zeros_padding; |
ctx->get_padding = get_zeros_padding; |
break; |
#endif |
case MBEDTLS_PADDING_NONE: |
ctx->add_padding = NULL; |
ctx->get_padding = get_no_padding; |
break; |
default: |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ |
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) |
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, |
unsigned char *tag, size_t tag_len ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if( MBEDTLS_ENCRYPT != ctx->operation ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_GCM_C) |
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) |
return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, |
tag, tag_len ) ); |
#endif |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) |
{ |
/* Don't allow truncated MAC for Poly1305 */ |
if ( tag_len != 16U ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, |
tag ) ); |
} |
#endif |
return( 0 ); |
} |
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, |
const unsigned char *tag, size_t tag_len ) |
{ |
unsigned char check_tag[16]; |
int ret; |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
if( ctx->cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if( MBEDTLS_DECRYPT != ctx->operation ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
#if defined(MBEDTLS_GCM_C) |
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) |
{ |
if( tag_len > sizeof( check_tag ) ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, |
check_tag, tag_len ) ) ) |
{ |
return( ret ); |
} |
/* Check the tag in "constant-time" */ |
if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) |
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); |
return( 0 ); |
} |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) |
{ |
/* Don't allow truncated MAC for Poly1305 */ |
if ( tag_len != sizeof( check_tag ) ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, |
check_tag ); |
if ( ret != 0 ) |
{ |
return( ret ); |
} |
/* Check the tag in "constant-time" */ |
if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) |
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); |
return( 0 ); |
} |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
return( 0 ); |
} |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ |
/* |
* Packet-oriented wrapper for non-AEAD modes |
*/ |
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen ) |
{ |
int ret; |
size_t finish_olen; |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); |
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); |
CIPHER_VALIDATE_RET( output != NULL ); |
CIPHER_VALIDATE_RET( olen != NULL ); |
if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) |
return( ret ); |
*olen += finish_olen; |
return( 0 ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_AEAD) |
/* |
* Packet-oriented encryption for AEAD modes |
*/ |
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *ad, size_t ad_len, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, |
unsigned char *tag, size_t tag_len ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( iv != NULL ); |
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); |
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); |
CIPHER_VALIDATE_RET( output != NULL ); |
CIPHER_VALIDATE_RET( olen != NULL ); |
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
#if defined(MBEDTLS_GCM_C) |
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) |
{ |
*olen = ilen; |
return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, |
iv, iv_len, ad, ad_len, input, output, |
tag_len, tag ) ); |
} |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CCM_C) |
if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) |
{ |
*olen = ilen; |
return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, |
iv, iv_len, ad, ad_len, input, output, |
tag, tag_len ) ); |
} |
#endif /* MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) |
{ |
/* ChachaPoly has fixed length nonce and MAC (tag) */ |
if ( ( iv_len != ctx->cipher_info->iv_size ) || |
( tag_len != 16U ) ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
*olen = ilen; |
return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, |
ilen, iv, ad, ad_len, input, output, tag ) ); |
} |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
/* |
* Packet-oriented decryption for AEAD modes |
*/ |
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, |
const unsigned char *iv, size_t iv_len, |
const unsigned char *ad, size_t ad_len, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, |
const unsigned char *tag, size_t tag_len ) |
{ |
CIPHER_VALIDATE_RET( ctx != NULL ); |
CIPHER_VALIDATE_RET( iv != NULL ); |
CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); |
CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); |
CIPHER_VALIDATE_RET( output != NULL ); |
CIPHER_VALIDATE_RET( olen != NULL ); |
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); |
#if defined(MBEDTLS_GCM_C) |
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) |
{ |
int ret; |
*olen = ilen; |
ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, |
iv, iv_len, ad, ad_len, |
tag, tag_len, input, output ); |
if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
return( ret ); |
} |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CCM_C) |
if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) |
{ |
int ret; |
*olen = ilen; |
ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, |
iv, iv_len, ad, ad_len, |
input, output, tag, tag_len ); |
if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
return( ret ); |
} |
#endif /* MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) |
{ |
int ret; |
/* ChachaPoly has fixed length nonce and MAC (tag) */ |
if ( ( iv_len != ctx->cipher_info->iv_size ) || |
( tag_len != 16U ) ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
*olen = ilen; |
ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, |
iv, ad, ad_len, tag, input, output ); |
if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
return( ret ); |
} |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_AEAD */ |
#endif /* MBEDTLS_CIPHER_C */ |
/programs/develop/libraries/kos_mbedtls/library/cipher_wrap.c |
---|
0,0 → 1,2274 |
/** |
* \file cipher_wrap.c |
* |
* \brief Generic cipher wrapper for mbed TLS |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CIPHER_C) |
#include "mbedtls/cipher_internal.h" |
#if defined(MBEDTLS_CHACHAPOLY_C) |
#include "mbedtls/chachapoly.h" |
#endif |
#if defined(MBEDTLS_AES_C) |
#include "mbedtls/aes.h" |
#endif |
#if defined(MBEDTLS_ARC4_C) |
#include "mbedtls/arc4.h" |
#endif |
#if defined(MBEDTLS_CAMELLIA_C) |
#include "mbedtls/camellia.h" |
#endif |
#if defined(MBEDTLS_ARIA_C) |
#include "mbedtls/aria.h" |
#endif |
#if defined(MBEDTLS_DES_C) |
#include "mbedtls/des.h" |
#endif |
#if defined(MBEDTLS_BLOWFISH_C) |
#include "mbedtls/blowfish.h" |
#endif |
#if defined(MBEDTLS_CHACHA20_C) |
#include "mbedtls/chacha20.h" |
#endif |
#if defined(MBEDTLS_GCM_C) |
#include "mbedtls/gcm.h" |
#endif |
#if defined(MBEDTLS_CCM_C) |
#include "mbedtls/ccm.h" |
#endif |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
#include <string.h> |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#if defined(MBEDTLS_GCM_C) |
/* shared by all GCM ciphers */ |
static void *gcm_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); |
if( ctx != NULL ) |
mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); |
return( ctx ); |
} |
static void gcm_ctx_free( void *ctx ) |
{ |
mbedtls_gcm_free( ctx ); |
mbedtls_free( ctx ); |
} |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CCM_C) |
/* shared by all CCM ciphers */ |
static void *ccm_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); |
if( ctx != NULL ) |
mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); |
return( ctx ); |
} |
static void ccm_ctx_free( void *ctx ) |
{ |
mbedtls_ccm_free( ctx ); |
mbedtls_free( ctx ); |
} |
#endif /* MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_AES_C) |
static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, |
unsigned char *iv, const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, |
output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, size_t *iv_off, unsigned char *iv, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, |
input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off, |
unsigned char *iv, const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off, |
iv, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, |
unsigned char *nonce_counter, unsigned char *stream_block, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, |
stream_block, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, |
const unsigned char data_unit[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
mbedtls_aes_xts_context *xts_ctx = ctx; |
int mode; |
switch( operation ) |
{ |
case MBEDTLS_ENCRYPT: |
mode = MBEDTLS_AES_ENCRYPT; |
break; |
case MBEDTLS_DECRYPT: |
mode = MBEDTLS_AES_DECRYPT; |
break; |
default: |
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
} |
return mbedtls_aes_crypt_xts( xts_ctx, mode, length, |
data_unit, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); |
} |
static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); |
} |
static void * aes_ctx_alloc( void ) |
{ |
mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); |
if( aes == NULL ) |
return( NULL ); |
mbedtls_aes_init( aes ); |
return( aes ); |
} |
static void aes_ctx_free( void *ctx ) |
{ |
mbedtls_aes_free( (mbedtls_aes_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t aes_info = { |
MBEDTLS_CIPHER_ID_AES, |
aes_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
aes_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
aes_crypt_cfb128_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
aes_crypt_ofb_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
aes_crypt_ctr_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
aes_setkey_enc_wrap, |
aes_setkey_dec_wrap, |
aes_ctx_alloc, |
aes_ctx_free |
}; |
static const mbedtls_cipher_info_t aes_128_ecb_info = { |
MBEDTLS_CIPHER_AES_128_ECB, |
MBEDTLS_MODE_ECB, |
128, |
"AES-128-ECB", |
0, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_ecb_info = { |
MBEDTLS_CIPHER_AES_192_ECB, |
MBEDTLS_MODE_ECB, |
192, |
"AES-192-ECB", |
0, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_ecb_info = { |
MBEDTLS_CIPHER_AES_256_ECB, |
MBEDTLS_MODE_ECB, |
256, |
"AES-256-ECB", |
0, |
0, |
16, |
&aes_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t aes_128_cbc_info = { |
MBEDTLS_CIPHER_AES_128_CBC, |
MBEDTLS_MODE_CBC, |
128, |
"AES-128-CBC", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_cbc_info = { |
MBEDTLS_CIPHER_AES_192_CBC, |
MBEDTLS_MODE_CBC, |
192, |
"AES-192-CBC", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_cbc_info = { |
MBEDTLS_CIPHER_AES_256_CBC, |
MBEDTLS_MODE_CBC, |
256, |
"AES-256-CBC", |
16, |
0, |
16, |
&aes_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static const mbedtls_cipher_info_t aes_128_cfb128_info = { |
MBEDTLS_CIPHER_AES_128_CFB128, |
MBEDTLS_MODE_CFB, |
128, |
"AES-128-CFB128", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_cfb128_info = { |
MBEDTLS_CIPHER_AES_192_CFB128, |
MBEDTLS_MODE_CFB, |
192, |
"AES-192-CFB128", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_cfb128_info = { |
MBEDTLS_CIPHER_AES_256_CFB128, |
MBEDTLS_MODE_CFB, |
256, |
"AES-256-CFB128", |
16, |
0, |
16, |
&aes_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
static const mbedtls_cipher_info_t aes_128_ofb_info = { |
MBEDTLS_CIPHER_AES_128_OFB, |
MBEDTLS_MODE_OFB, |
128, |
"AES-128-OFB", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_ofb_info = { |
MBEDTLS_CIPHER_AES_192_OFB, |
MBEDTLS_MODE_OFB, |
192, |
"AES-192-OFB", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_ofb_info = { |
MBEDTLS_CIPHER_AES_256_OFB, |
MBEDTLS_MODE_OFB, |
256, |
"AES-256-OFB", |
16, |
0, |
16, |
&aes_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static const mbedtls_cipher_info_t aes_128_ctr_info = { |
MBEDTLS_CIPHER_AES_128_CTR, |
MBEDTLS_MODE_CTR, |
128, |
"AES-128-CTR", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_ctr_info = { |
MBEDTLS_CIPHER_AES_192_CTR, |
MBEDTLS_MODE_CTR, |
192, |
"AES-192-CTR", |
16, |
0, |
16, |
&aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_ctr_info = { |
MBEDTLS_CIPHER_AES_256_CTR, |
MBEDTLS_MODE_CTR, |
256, |
"AES-256-CTR", |
16, |
0, |
16, |
&aes_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
mbedtls_aes_xts_context *xts_ctx = ctx; |
return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); |
} |
static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
mbedtls_aes_xts_context *xts_ctx = ctx; |
return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); |
} |
static void *xts_aes_ctx_alloc( void ) |
{ |
mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); |
if( xts_ctx != NULL ) |
mbedtls_aes_xts_init( xts_ctx ); |
return( xts_ctx ); |
} |
static void xts_aes_ctx_free( void *ctx ) |
{ |
mbedtls_aes_xts_context *xts_ctx = ctx; |
if( xts_ctx == NULL ) |
return; |
mbedtls_aes_xts_free( xts_ctx ); |
mbedtls_free( xts_ctx ); |
} |
static const mbedtls_cipher_base_t xts_aes_info = { |
MBEDTLS_CIPHER_ID_AES, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
aes_crypt_xts_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
xts_aes_setkey_enc_wrap, |
xts_aes_setkey_dec_wrap, |
xts_aes_ctx_alloc, |
xts_aes_ctx_free |
}; |
static const mbedtls_cipher_info_t aes_128_xts_info = { |
MBEDTLS_CIPHER_AES_128_XTS, |
MBEDTLS_MODE_XTS, |
256, |
"AES-128-XTS", |
16, |
0, |
16, |
&xts_aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_xts_info = { |
MBEDTLS_CIPHER_AES_256_XTS, |
MBEDTLS_MODE_XTS, |
512, |
"AES-256-XTS", |
16, |
0, |
16, |
&xts_aes_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#if defined(MBEDTLS_GCM_C) |
static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, |
key, key_bitlen ); |
} |
static const mbedtls_cipher_base_t gcm_aes_info = { |
MBEDTLS_CIPHER_ID_AES, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
gcm_aes_setkey_wrap, |
gcm_aes_setkey_wrap, |
gcm_ctx_alloc, |
gcm_ctx_free, |
}; |
static const mbedtls_cipher_info_t aes_128_gcm_info = { |
MBEDTLS_CIPHER_AES_128_GCM, |
MBEDTLS_MODE_GCM, |
128, |
"AES-128-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_gcm_info = { |
MBEDTLS_CIPHER_AES_192_GCM, |
MBEDTLS_MODE_GCM, |
192, |
"AES-192-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_gcm_info = { |
MBEDTLS_CIPHER_AES_256_GCM, |
MBEDTLS_MODE_GCM, |
256, |
"AES-256-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_aes_info |
}; |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CCM_C) |
static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, |
key, key_bitlen ); |
} |
static const mbedtls_cipher_base_t ccm_aes_info = { |
MBEDTLS_CIPHER_ID_AES, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
ccm_aes_setkey_wrap, |
ccm_aes_setkey_wrap, |
ccm_ctx_alloc, |
ccm_ctx_free, |
}; |
static const mbedtls_cipher_info_t aes_128_ccm_info = { |
MBEDTLS_CIPHER_AES_128_CCM, |
MBEDTLS_MODE_CCM, |
128, |
"AES-128-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_aes_info |
}; |
static const mbedtls_cipher_info_t aes_192_ccm_info = { |
MBEDTLS_CIPHER_AES_192_CCM, |
MBEDTLS_MODE_CCM, |
192, |
"AES-192-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_aes_info |
}; |
static const mbedtls_cipher_info_t aes_256_ccm_info = { |
MBEDTLS_CIPHER_AES_256_CCM, |
MBEDTLS_MODE_CCM, |
256, |
"AES-256-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_aes_info |
}; |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, |
output ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, unsigned char *iv, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, |
input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, size_t *iv_off, unsigned char *iv, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, |
iv_off, iv, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, |
unsigned char *nonce_counter, unsigned char *stream_block, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, |
nonce_counter, stream_block, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); |
} |
static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); |
} |
static void * camellia_ctx_alloc( void ) |
{ |
mbedtls_camellia_context *ctx; |
ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); |
if( ctx == NULL ) |
return( NULL ); |
mbedtls_camellia_init( ctx ); |
return( ctx ); |
} |
static void camellia_ctx_free( void *ctx ) |
{ |
mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t camellia_info = { |
MBEDTLS_CIPHER_ID_CAMELLIA, |
camellia_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
camellia_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
camellia_crypt_cfb128_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
camellia_crypt_ctr_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
camellia_setkey_enc_wrap, |
camellia_setkey_dec_wrap, |
camellia_ctx_alloc, |
camellia_ctx_free |
}; |
static const mbedtls_cipher_info_t camellia_128_ecb_info = { |
MBEDTLS_CIPHER_CAMELLIA_128_ECB, |
MBEDTLS_MODE_ECB, |
128, |
"CAMELLIA-128-ECB", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_192_ecb_info = { |
MBEDTLS_CIPHER_CAMELLIA_192_ECB, |
MBEDTLS_MODE_ECB, |
192, |
"CAMELLIA-192-ECB", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_256_ecb_info = { |
MBEDTLS_CIPHER_CAMELLIA_256_ECB, |
MBEDTLS_MODE_ECB, |
256, |
"CAMELLIA-256-ECB", |
16, |
0, |
16, |
&camellia_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t camellia_128_cbc_info = { |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, |
MBEDTLS_MODE_CBC, |
128, |
"CAMELLIA-128-CBC", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_192_cbc_info = { |
MBEDTLS_CIPHER_CAMELLIA_192_CBC, |
MBEDTLS_MODE_CBC, |
192, |
"CAMELLIA-192-CBC", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_256_cbc_info = { |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, |
MBEDTLS_MODE_CBC, |
256, |
"CAMELLIA-256-CBC", |
16, |
0, |
16, |
&camellia_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static const mbedtls_cipher_info_t camellia_128_cfb128_info = { |
MBEDTLS_CIPHER_CAMELLIA_128_CFB128, |
MBEDTLS_MODE_CFB, |
128, |
"CAMELLIA-128-CFB128", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_192_cfb128_info = { |
MBEDTLS_CIPHER_CAMELLIA_192_CFB128, |
MBEDTLS_MODE_CFB, |
192, |
"CAMELLIA-192-CFB128", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_256_cfb128_info = { |
MBEDTLS_CIPHER_CAMELLIA_256_CFB128, |
MBEDTLS_MODE_CFB, |
256, |
"CAMELLIA-256-CFB128", |
16, |
0, |
16, |
&camellia_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static const mbedtls_cipher_info_t camellia_128_ctr_info = { |
MBEDTLS_CIPHER_CAMELLIA_128_CTR, |
MBEDTLS_MODE_CTR, |
128, |
"CAMELLIA-128-CTR", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_192_ctr_info = { |
MBEDTLS_CIPHER_CAMELLIA_192_CTR, |
MBEDTLS_MODE_CTR, |
192, |
"CAMELLIA-192-CTR", |
16, |
0, |
16, |
&camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_256_ctr_info = { |
MBEDTLS_CIPHER_CAMELLIA_256_CTR, |
MBEDTLS_MODE_CTR, |
256, |
"CAMELLIA-256-CTR", |
16, |
0, |
16, |
&camellia_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_GCM_C) |
static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, |
key, key_bitlen ); |
} |
static const mbedtls_cipher_base_t gcm_camellia_info = { |
MBEDTLS_CIPHER_ID_CAMELLIA, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
gcm_camellia_setkey_wrap, |
gcm_camellia_setkey_wrap, |
gcm_ctx_alloc, |
gcm_ctx_free, |
}; |
static const mbedtls_cipher_info_t camellia_128_gcm_info = { |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, |
MBEDTLS_MODE_GCM, |
128, |
"CAMELLIA-128-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_192_gcm_info = { |
MBEDTLS_CIPHER_CAMELLIA_192_GCM, |
MBEDTLS_MODE_GCM, |
192, |
"CAMELLIA-192-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_256_gcm_info = { |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, |
MBEDTLS_MODE_GCM, |
256, |
"CAMELLIA-256-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_camellia_info |
}; |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CCM_C) |
static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, |
key, key_bitlen ); |
} |
static const mbedtls_cipher_base_t ccm_camellia_info = { |
MBEDTLS_CIPHER_ID_CAMELLIA, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
ccm_camellia_setkey_wrap, |
ccm_camellia_setkey_wrap, |
ccm_ctx_alloc, |
ccm_ctx_free, |
}; |
static const mbedtls_cipher_info_t camellia_128_ccm_info = { |
MBEDTLS_CIPHER_CAMELLIA_128_CCM, |
MBEDTLS_MODE_CCM, |
128, |
"CAMELLIA-128-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_192_ccm_info = { |
MBEDTLS_CIPHER_CAMELLIA_192_CCM, |
MBEDTLS_MODE_CCM, |
192, |
"CAMELLIA-192-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_camellia_info |
}; |
static const mbedtls_cipher_info_t camellia_256_ccm_info = { |
MBEDTLS_CIPHER_CAMELLIA_256_CCM, |
MBEDTLS_MODE_CCM, |
256, |
"CAMELLIA-256-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_camellia_info |
}; |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_ARIA_C) |
static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, |
const unsigned char *input, unsigned char *output ) |
{ |
(void) operation; |
return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input, |
output ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, unsigned char *iv, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv, |
input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, size_t *iv_off, unsigned char *iv, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length, |
iv_off, iv, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, |
unsigned char *nonce_counter, unsigned char *stream_block, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off, |
nonce_counter, stream_block, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen ); |
} |
static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen ); |
} |
static void * aria_ctx_alloc( void ) |
{ |
mbedtls_aria_context *ctx; |
ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) ); |
if( ctx == NULL ) |
return( NULL ); |
mbedtls_aria_init( ctx ); |
return( ctx ); |
} |
static void aria_ctx_free( void *ctx ) |
{ |
mbedtls_aria_free( (mbedtls_aria_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t aria_info = { |
MBEDTLS_CIPHER_ID_ARIA, |
aria_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
aria_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
aria_crypt_cfb128_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
aria_crypt_ctr_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
aria_setkey_enc_wrap, |
aria_setkey_dec_wrap, |
aria_ctx_alloc, |
aria_ctx_free |
}; |
static const mbedtls_cipher_info_t aria_128_ecb_info = { |
MBEDTLS_CIPHER_ARIA_128_ECB, |
MBEDTLS_MODE_ECB, |
128, |
"ARIA-128-ECB", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_192_ecb_info = { |
MBEDTLS_CIPHER_ARIA_192_ECB, |
MBEDTLS_MODE_ECB, |
192, |
"ARIA-192-ECB", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_256_ecb_info = { |
MBEDTLS_CIPHER_ARIA_256_ECB, |
MBEDTLS_MODE_ECB, |
256, |
"ARIA-256-ECB", |
16, |
0, |
16, |
&aria_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t aria_128_cbc_info = { |
MBEDTLS_CIPHER_ARIA_128_CBC, |
MBEDTLS_MODE_CBC, |
128, |
"ARIA-128-CBC", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_192_cbc_info = { |
MBEDTLS_CIPHER_ARIA_192_CBC, |
MBEDTLS_MODE_CBC, |
192, |
"ARIA-192-CBC", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_256_cbc_info = { |
MBEDTLS_CIPHER_ARIA_256_CBC, |
MBEDTLS_MODE_CBC, |
256, |
"ARIA-256-CBC", |
16, |
0, |
16, |
&aria_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static const mbedtls_cipher_info_t aria_128_cfb128_info = { |
MBEDTLS_CIPHER_ARIA_128_CFB128, |
MBEDTLS_MODE_CFB, |
128, |
"ARIA-128-CFB128", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_192_cfb128_info = { |
MBEDTLS_CIPHER_ARIA_192_CFB128, |
MBEDTLS_MODE_CFB, |
192, |
"ARIA-192-CFB128", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_256_cfb128_info = { |
MBEDTLS_CIPHER_ARIA_256_CFB128, |
MBEDTLS_MODE_CFB, |
256, |
"ARIA-256-CFB128", |
16, |
0, |
16, |
&aria_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static const mbedtls_cipher_info_t aria_128_ctr_info = { |
MBEDTLS_CIPHER_ARIA_128_CTR, |
MBEDTLS_MODE_CTR, |
128, |
"ARIA-128-CTR", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_192_ctr_info = { |
MBEDTLS_CIPHER_ARIA_192_CTR, |
MBEDTLS_MODE_CTR, |
192, |
"ARIA-192-CTR", |
16, |
0, |
16, |
&aria_info |
}; |
static const mbedtls_cipher_info_t aria_256_ctr_info = { |
MBEDTLS_CIPHER_ARIA_256_CTR, |
MBEDTLS_MODE_CTR, |
256, |
"ARIA-256-CTR", |
16, |
0, |
16, |
&aria_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_GCM_C) |
static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, |
key, key_bitlen ); |
} |
static const mbedtls_cipher_base_t gcm_aria_info = { |
MBEDTLS_CIPHER_ID_ARIA, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
gcm_aria_setkey_wrap, |
gcm_aria_setkey_wrap, |
gcm_ctx_alloc, |
gcm_ctx_free, |
}; |
static const mbedtls_cipher_info_t aria_128_gcm_info = { |
MBEDTLS_CIPHER_ARIA_128_GCM, |
MBEDTLS_MODE_GCM, |
128, |
"ARIA-128-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_aria_info |
}; |
static const mbedtls_cipher_info_t aria_192_gcm_info = { |
MBEDTLS_CIPHER_ARIA_192_GCM, |
MBEDTLS_MODE_GCM, |
192, |
"ARIA-192-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_aria_info |
}; |
static const mbedtls_cipher_info_t aria_256_gcm_info = { |
MBEDTLS_CIPHER_ARIA_256_GCM, |
MBEDTLS_MODE_GCM, |
256, |
"ARIA-256-GCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&gcm_aria_info |
}; |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CCM_C) |
static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, |
key, key_bitlen ); |
} |
static const mbedtls_cipher_base_t ccm_aria_info = { |
MBEDTLS_CIPHER_ID_ARIA, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
ccm_aria_setkey_wrap, |
ccm_aria_setkey_wrap, |
ccm_ctx_alloc, |
ccm_ctx_free, |
}; |
static const mbedtls_cipher_info_t aria_128_ccm_info = { |
MBEDTLS_CIPHER_ARIA_128_CCM, |
MBEDTLS_MODE_CCM, |
128, |
"ARIA-128-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_aria_info |
}; |
static const mbedtls_cipher_info_t aria_192_ccm_info = { |
MBEDTLS_CIPHER_ARIA_192_CCM, |
MBEDTLS_MODE_CCM, |
192, |
"ARIA-192-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_aria_info |
}; |
static const mbedtls_cipher_info_t aria_256_ccm_info = { |
MBEDTLS_CIPHER_ARIA_256_CCM, |
MBEDTLS_MODE_CCM, |
256, |
"ARIA-256-CCM", |
12, |
MBEDTLS_CIPHER_VARIABLE_IV_LEN, |
16, |
&ccm_aria_info |
}; |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_ARIA_C */ |
#if defined(MBEDTLS_DES_C) |
static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, |
const unsigned char *input, unsigned char *output ) |
{ |
((void) operation); |
return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); |
} |
static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, |
const unsigned char *input, unsigned char *output ) |
{ |
((void) operation); |
return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, |
unsigned char *iv, const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, |
output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, |
unsigned char *iv, const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, |
output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) key_bitlen); |
return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); |
} |
static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) key_bitlen); |
return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); |
} |
static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) key_bitlen); |
return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); |
} |
static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) key_bitlen); |
return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); |
} |
static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) key_bitlen); |
return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); |
} |
static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) key_bitlen); |
return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); |
} |
static void * des_ctx_alloc( void ) |
{ |
mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); |
if( des == NULL ) |
return( NULL ); |
mbedtls_des_init( des ); |
return( des ); |
} |
static void des_ctx_free( void *ctx ) |
{ |
mbedtls_des_free( (mbedtls_des_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void * des3_ctx_alloc( void ) |
{ |
mbedtls_des3_context *des3; |
des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); |
if( des3 == NULL ) |
return( NULL ); |
mbedtls_des3_init( des3 ); |
return( des3 ); |
} |
static void des3_ctx_free( void *ctx ) |
{ |
mbedtls_des3_free( (mbedtls_des3_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t des_info = { |
MBEDTLS_CIPHER_ID_DES, |
des_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
des_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
des_setkey_enc_wrap, |
des_setkey_dec_wrap, |
des_ctx_alloc, |
des_ctx_free |
}; |
static const mbedtls_cipher_info_t des_ecb_info = { |
MBEDTLS_CIPHER_DES_ECB, |
MBEDTLS_MODE_ECB, |
MBEDTLS_KEY_LENGTH_DES, |
"DES-ECB", |
8, |
0, |
8, |
&des_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t des_cbc_info = { |
MBEDTLS_CIPHER_DES_CBC, |
MBEDTLS_MODE_CBC, |
MBEDTLS_KEY_LENGTH_DES, |
"DES-CBC", |
8, |
0, |
8, |
&des_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
static const mbedtls_cipher_base_t des_ede_info = { |
MBEDTLS_CIPHER_ID_DES, |
des3_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
des3_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
des3_set2key_enc_wrap, |
des3_set2key_dec_wrap, |
des3_ctx_alloc, |
des3_ctx_free |
}; |
static const mbedtls_cipher_info_t des_ede_ecb_info = { |
MBEDTLS_CIPHER_DES_EDE_ECB, |
MBEDTLS_MODE_ECB, |
MBEDTLS_KEY_LENGTH_DES_EDE, |
"DES-EDE-ECB", |
8, |
0, |
8, |
&des_ede_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t des_ede_cbc_info = { |
MBEDTLS_CIPHER_DES_EDE_CBC, |
MBEDTLS_MODE_CBC, |
MBEDTLS_KEY_LENGTH_DES_EDE, |
"DES-EDE-CBC", |
8, |
0, |
8, |
&des_ede_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
static const mbedtls_cipher_base_t des_ede3_info = { |
MBEDTLS_CIPHER_ID_3DES, |
des3_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
des3_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
des3_set3key_enc_wrap, |
des3_set3key_dec_wrap, |
des3_ctx_alloc, |
des3_ctx_free |
}; |
static const mbedtls_cipher_info_t des_ede3_ecb_info = { |
MBEDTLS_CIPHER_DES_EDE3_ECB, |
MBEDTLS_MODE_ECB, |
MBEDTLS_KEY_LENGTH_DES_EDE3, |
"DES-EDE3-ECB", |
8, |
0, |
8, |
&des_ede3_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t des_ede3_cbc_info = { |
MBEDTLS_CIPHER_DES_EDE3_CBC, |
MBEDTLS_MODE_CBC, |
MBEDTLS_KEY_LENGTH_DES_EDE3, |
"DES-EDE3-CBC", |
8, |
0, |
8, |
&des_ede3_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_BLOWFISH_C) |
static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, |
output ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, unsigned char *iv, const unsigned char *input, |
unsigned char *output ) |
{ |
return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, |
input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, |
size_t length, size_t *iv_off, unsigned char *iv, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, |
iv_off, iv, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, |
unsigned char *nonce_counter, unsigned char *stream_block, |
const unsigned char *input, unsigned char *output ) |
{ |
return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, |
nonce_counter, stream_block, input, output ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); |
} |
static void * blowfish_ctx_alloc( void ) |
{ |
mbedtls_blowfish_context *ctx; |
ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); |
if( ctx == NULL ) |
return( NULL ); |
mbedtls_blowfish_init( ctx ); |
return( ctx ); |
} |
static void blowfish_ctx_free( void *ctx ) |
{ |
mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t blowfish_info = { |
MBEDTLS_CIPHER_ID_BLOWFISH, |
blowfish_crypt_ecb_wrap, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
blowfish_crypt_cbc_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
blowfish_crypt_cfb64_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
blowfish_crypt_ctr_wrap, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
blowfish_setkey_wrap, |
blowfish_setkey_wrap, |
blowfish_ctx_alloc, |
blowfish_ctx_free |
}; |
static const mbedtls_cipher_info_t blowfish_ecb_info = { |
MBEDTLS_CIPHER_BLOWFISH_ECB, |
MBEDTLS_MODE_ECB, |
128, |
"BLOWFISH-ECB", |
8, |
MBEDTLS_CIPHER_VARIABLE_KEY_LEN, |
8, |
&blowfish_info |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const mbedtls_cipher_info_t blowfish_cbc_info = { |
MBEDTLS_CIPHER_BLOWFISH_CBC, |
MBEDTLS_MODE_CBC, |
128, |
"BLOWFISH-CBC", |
8, |
MBEDTLS_CIPHER_VARIABLE_KEY_LEN, |
8, |
&blowfish_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
static const mbedtls_cipher_info_t blowfish_cfb64_info = { |
MBEDTLS_CIPHER_BLOWFISH_CFB64, |
MBEDTLS_MODE_CFB, |
128, |
"BLOWFISH-CFB64", |
8, |
MBEDTLS_CIPHER_VARIABLE_KEY_LEN, |
8, |
&blowfish_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
static const mbedtls_cipher_info_t blowfish_ctr_info = { |
MBEDTLS_CIPHER_BLOWFISH_CTR, |
MBEDTLS_MODE_CTR, |
128, |
"BLOWFISH-CTR", |
8, |
MBEDTLS_CIPHER_VARIABLE_KEY_LEN, |
8, |
&blowfish_info |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#endif /* MBEDTLS_BLOWFISH_C */ |
#if defined(MBEDTLS_ARC4_C) |
static int arc4_crypt_stream_wrap( void *ctx, size_t length, |
const unsigned char *input, |
unsigned char *output ) |
{ |
return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); |
} |
static int arc4_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
/* we get key_bitlen in bits, arc4 expects it in bytes */ |
if( key_bitlen % 8 != 0 ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); |
return( 0 ); |
} |
static void * arc4_ctx_alloc( void ) |
{ |
mbedtls_arc4_context *ctx; |
ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); |
if( ctx == NULL ) |
return( NULL ); |
mbedtls_arc4_init( ctx ); |
return( ctx ); |
} |
static void arc4_ctx_free( void *ctx ) |
{ |
mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t arc4_base_info = { |
MBEDTLS_CIPHER_ID_ARC4, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
arc4_crypt_stream_wrap, |
#endif |
arc4_setkey_wrap, |
arc4_setkey_wrap, |
arc4_ctx_alloc, |
arc4_ctx_free |
}; |
static const mbedtls_cipher_info_t arc4_128_info = { |
MBEDTLS_CIPHER_ARC4_128, |
MBEDTLS_MODE_STREAM, |
128, |
"ARC4-128", |
0, |
0, |
1, |
&arc4_base_info |
}; |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_CHACHA20_C) |
static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
if( key_bitlen != 256U ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
return( 0 ); |
} |
static int chacha20_stream_wrap( void *ctx, size_t length, |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
ret = mbedtls_chacha20_update( ctx, length, input, output ); |
if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
return( ret ); |
} |
static void * chacha20_ctx_alloc( void ) |
{ |
mbedtls_chacha20_context *ctx; |
ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) ); |
if( ctx == NULL ) |
return( NULL ); |
mbedtls_chacha20_init( ctx ); |
return( ctx ); |
} |
static void chacha20_ctx_free( void *ctx ) |
{ |
mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t chacha20_base_info = { |
MBEDTLS_CIPHER_ID_CHACHA20, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
chacha20_stream_wrap, |
#endif |
chacha20_setkey_wrap, |
chacha20_setkey_wrap, |
chacha20_ctx_alloc, |
chacha20_ctx_free |
}; |
static const mbedtls_cipher_info_t chacha20_info = { |
MBEDTLS_CIPHER_CHACHA20, |
MBEDTLS_MODE_STREAM, |
256, |
"CHACHA20", |
12, |
0, |
1, |
&chacha20_base_info |
}; |
#endif /* MBEDTLS_CHACHA20_C */ |
#if defined(MBEDTLS_CHACHAPOLY_C) |
static int chachapoly_setkey_wrap( void *ctx, |
const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
if( key_bitlen != 256U ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
return( 0 ); |
} |
static void * chachapoly_ctx_alloc( void ) |
{ |
mbedtls_chachapoly_context *ctx; |
ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); |
if( ctx == NULL ) |
return( NULL ); |
mbedtls_chachapoly_init( ctx ); |
return( ctx ); |
} |
static void chachapoly_ctx_free( void *ctx ) |
{ |
mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static const mbedtls_cipher_base_t chachapoly_base_info = { |
MBEDTLS_CIPHER_ID_CHACHA20, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
NULL, |
#endif |
chachapoly_setkey_wrap, |
chachapoly_setkey_wrap, |
chachapoly_ctx_alloc, |
chachapoly_ctx_free |
}; |
static const mbedtls_cipher_info_t chachapoly_info = { |
MBEDTLS_CIPHER_CHACHA20_POLY1305, |
MBEDTLS_MODE_CHACHAPOLY, |
256, |
"CHACHA20-POLY1305", |
12, |
0, |
1, |
&chachapoly_base_info |
}; |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
static int null_crypt_stream( void *ctx, size_t length, |
const unsigned char *input, |
unsigned char *output ) |
{ |
((void) ctx); |
memmove( output, input, length ); |
return( 0 ); |
} |
static int null_setkey( void *ctx, const unsigned char *key, |
unsigned int key_bitlen ) |
{ |
((void) ctx); |
((void) key); |
((void) key_bitlen); |
return( 0 ); |
} |
static void * null_ctx_alloc( void ) |
{ |
return( (void *) 1 ); |
} |
static void null_ctx_free( void *ctx ) |
{ |
((void) ctx); |
} |
static const mbedtls_cipher_base_t null_base_info = { |
MBEDTLS_CIPHER_ID_NULL, |
NULL, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
NULL, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_STREAM) |
null_crypt_stream, |
#endif |
null_setkey, |
null_setkey, |
null_ctx_alloc, |
null_ctx_free |
}; |
static const mbedtls_cipher_info_t null_cipher_info = { |
MBEDTLS_CIPHER_NULL, |
MBEDTLS_MODE_STREAM, |
0, |
"NULL", |
0, |
0, |
1, |
&null_base_info |
}; |
#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ |
const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = |
{ |
#if defined(MBEDTLS_AES_C) |
{ MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, |
{ MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, |
{ MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, |
{ MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, |
{ MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
{ MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, |
{ MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, |
{ MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
{ MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, |
{ MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, |
{ MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
{ MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, |
{ MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, |
{ MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
{ MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, |
{ MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, |
#endif |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, |
{ MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, |
{ MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, |
#endif |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, |
{ MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, |
{ MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, |
#endif |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_ARC4_C) |
{ MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, |
#endif |
#if defined(MBEDTLS_BLOWFISH_C) |
{ MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
{ MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
{ MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, |
#endif |
#endif /* MBEDTLS_BLOWFISH_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
{ MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
{ MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
{ MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, |
#endif |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, |
#endif |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, |
{ MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, |
#endif |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_ARIA_C) |
{ MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, |
{ MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, |
{ MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, |
{ MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, |
{ MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
{ MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, |
{ MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, |
{ MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
{ MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, |
{ MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, |
{ MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, |
#endif |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, |
{ MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, |
{ MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, |
#endif |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, |
{ MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, |
{ MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, |
#endif |
#endif /* MBEDTLS_ARIA_C */ |
#if defined(MBEDTLS_DES_C) |
{ MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, |
{ MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, |
{ MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, |
{ MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, |
{ MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, |
#endif |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_CHACHA20_C) |
{ MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, |
#endif |
#if defined(MBEDTLS_CHACHAPOLY_C) |
{ MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, |
#endif |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
{ MBEDTLS_CIPHER_NULL, &null_cipher_info }, |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
{ MBEDTLS_CIPHER_NONE, NULL } |
}; |
#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] |
int mbedtls_cipher_supported[NUM_CIPHERS]; |
#endif /* MBEDTLS_CIPHER_C */ |
/programs/develop/libraries/kos_mbedtls/library/cmac.c |
---|
0,0 → 1,1080 |
/** |
* \file cmac.c |
* |
* \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* |
* - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The |
* CMAC Mode for Authentication |
* http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf |
* |
* - RFC 4493 - The AES-CMAC Algorithm |
* https://tools.ietf.org/html/rfc4493 |
* |
* - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message |
* Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) |
* Algorithm for the Internet Key Exchange Protocol (IKE) |
* https://tools.ietf.org/html/rfc4615 |
* |
* Additional test vectors: ISO/IEC 9797-1 |
* |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CMAC_C) |
#include "mbedtls/cmac.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#if defined(MBEDTLS_SELF_TEST) |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_PLATFORM_C */ |
#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) |
/* |
* Multiplication by u in the Galois field of GF(2^n) |
* |
* As explained in NIST SP 800-38B, this can be computed: |
* |
* If MSB(p) = 0, then p = (p << 1) |
* If MSB(p) = 1, then p = (p << 1) ^ R_n |
* with R_64 = 0x1B and R_128 = 0x87 |
* |
* Input and output MUST NOT point to the same buffer |
* Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. |
*/ |
static int cmac_multiply_by_u( unsigned char *output, |
const unsigned char *input, |
size_t blocksize ) |
{ |
const unsigned char R_128 = 0x87; |
const unsigned char R_64 = 0x1B; |
unsigned char R_n, mask; |
unsigned char overflow = 0x00; |
int i; |
if( blocksize == MBEDTLS_AES_BLOCK_SIZE ) |
{ |
R_n = R_128; |
} |
else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE ) |
{ |
R_n = R_64; |
} |
else |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
for( i = (int)blocksize - 1; i >= 0; i-- ) |
{ |
output[i] = input[i] << 1 | overflow; |
overflow = input[i] >> 7; |
} |
/* mask = ( input[0] >> 7 ) ? 0xff : 0x00 |
* using bit operations to avoid branches */ |
/* MSVC has a warning about unary minus on unsigned, but this is |
* well-defined and precisely what we want to do here */ |
#if defined(_MSC_VER) |
#pragma warning( push ) |
#pragma warning( disable : 4146 ) |
#endif |
mask = - ( input[0] >> 7 ); |
#if defined(_MSC_VER) |
#pragma warning( pop ) |
#endif |
output[ blocksize - 1 ] ^= R_n & mask; |
return( 0 ); |
} |
/* |
* Generate subkeys |
* |
* - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm |
*/ |
static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, |
unsigned char* K1, unsigned char* K2 ) |
{ |
int ret; |
unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
size_t olen, block_size; |
mbedtls_platform_zeroize( L, sizeof( L ) ); |
block_size = ctx->cipher_info->block_size; |
/* Calculate Ek(0) */ |
if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 ) |
goto exit; |
/* |
* Generate K1 and K2 |
*/ |
if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 ) |
goto exit; |
if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_platform_zeroize( L, sizeof( L ) ); |
return( ret ); |
} |
#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ |
#if !defined(MBEDTLS_CMAC_ALT) |
static void cmac_xor_block( unsigned char *output, const unsigned char *input1, |
const unsigned char *input2, |
const size_t block_size ) |
{ |
size_t idx; |
for( idx = 0; idx < block_size; idx++ ) |
output[ idx ] = input1[ idx ] ^ input2[ idx ]; |
} |
/* |
* Create padded last block from (partial) last block. |
* |
* We can't use the padding option from the cipher layer, as it only works for |
* CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. |
*/ |
static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX], |
size_t padded_block_len, |
const unsigned char *last_block, |
size_t last_block_len ) |
{ |
size_t j; |
for( j = 0; j < padded_block_len; j++ ) |
{ |
if( j < last_block_len ) |
padded_block[j] = last_block[j]; |
else if( j == last_block_len ) |
padded_block[j] = 0x80; |
else |
padded_block[j] = 0x00; |
} |
} |
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, |
const unsigned char *key, size_t keybits ) |
{ |
mbedtls_cipher_type_t type; |
mbedtls_cmac_context_t *cmac_ctx; |
int retval; |
if( ctx == NULL || ctx->cipher_info == NULL || key == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits, |
MBEDTLS_ENCRYPT ) ) != 0 ) |
return( retval ); |
type = ctx->cipher_info->type; |
switch( type ) |
{ |
case MBEDTLS_CIPHER_AES_128_ECB: |
case MBEDTLS_CIPHER_AES_192_ECB: |
case MBEDTLS_CIPHER_AES_256_ECB: |
case MBEDTLS_CIPHER_DES_EDE3_ECB: |
break; |
default: |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
/* Allocated and initialise in the cipher context memory for the CMAC |
* context */ |
cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) ); |
if( cmac_ctx == NULL ) |
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); |
ctx->cmac_ctx = cmac_ctx; |
mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); |
return 0; |
} |
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, |
const unsigned char *input, size_t ilen ) |
{ |
mbedtls_cmac_context_t* cmac_ctx; |
unsigned char *state; |
int ret = 0; |
size_t n, j, olen, block_size; |
if( ctx == NULL || ctx->cipher_info == NULL || input == NULL || |
ctx->cmac_ctx == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
cmac_ctx = ctx->cmac_ctx; |
block_size = ctx->cipher_info->block_size; |
state = ctx->cmac_ctx->state; |
/* Is there data still to process from the last call, that's greater in |
* size than a block? */ |
if( cmac_ctx->unprocessed_len > 0 && |
ilen > block_size - cmac_ctx->unprocessed_len ) |
{ |
memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], |
input, |
block_size - cmac_ctx->unprocessed_len ); |
cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); |
if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, |
&olen ) ) != 0 ) |
{ |
goto exit; |
} |
input += block_size - cmac_ctx->unprocessed_len; |
ilen -= block_size - cmac_ctx->unprocessed_len; |
cmac_ctx->unprocessed_len = 0; |
} |
/* n is the number of blocks including any final partial block */ |
n = ( ilen + block_size - 1 ) / block_size; |
/* Iterate across the input data in block sized chunks, excluding any |
* final partial or complete block */ |
for( j = 1; j < n; j++ ) |
{ |
cmac_xor_block( state, input, state, block_size ); |
if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, |
&olen ) ) != 0 ) |
goto exit; |
ilen -= block_size; |
input += block_size; |
} |
/* If there is data left over that wasn't aligned to a block */ |
if( ilen > 0 ) |
{ |
memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], |
input, |
ilen ); |
cmac_ctx->unprocessed_len += ilen; |
} |
exit: |
return( ret ); |
} |
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, |
unsigned char *output ) |
{ |
mbedtls_cmac_context_t* cmac_ctx; |
unsigned char *state, *last_block; |
unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
int ret; |
size_t olen, block_size; |
if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || |
output == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
cmac_ctx = ctx->cmac_ctx; |
block_size = ctx->cipher_info->block_size; |
state = cmac_ctx->state; |
mbedtls_platform_zeroize( K1, sizeof( K1 ) ); |
mbedtls_platform_zeroize( K2, sizeof( K2 ) ); |
cmac_generate_subkeys( ctx, K1, K2 ); |
last_block = cmac_ctx->unprocessed_block; |
/* Calculate last block */ |
if( cmac_ctx->unprocessed_len < block_size ) |
{ |
cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); |
cmac_xor_block( M_last, M_last, K2, block_size ); |
} |
else |
{ |
/* Last block is complete block */ |
cmac_xor_block( M_last, last_block, K1, block_size ); |
} |
cmac_xor_block( state, M_last, state, block_size ); |
if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, |
&olen ) ) != 0 ) |
{ |
goto exit; |
} |
memcpy( output, state, block_size ); |
exit: |
/* Wipe the generated keys on the stack, and any other transients to avoid |
* side channel leakage */ |
mbedtls_platform_zeroize( K1, sizeof( K1 ) ); |
mbedtls_platform_zeroize( K2, sizeof( K2 ) ); |
cmac_ctx->unprocessed_len = 0; |
mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, |
sizeof( cmac_ctx->unprocessed_block ) ); |
mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); |
return( ret ); |
} |
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) |
{ |
mbedtls_cmac_context_t* cmac_ctx; |
if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
cmac_ctx = ctx->cmac_ctx; |
/* Reset the internal state */ |
cmac_ctx->unprocessed_len = 0; |
mbedtls_platform_zeroize( cmac_ctx->unprocessed_block, |
sizeof( cmac_ctx->unprocessed_block ) ); |
mbedtls_platform_zeroize( cmac_ctx->state, |
sizeof( cmac_ctx->state ) ); |
return( 0 ); |
} |
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, |
const unsigned char *key, size_t keylen, |
const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
mbedtls_cipher_context_t ctx; |
int ret; |
if( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
mbedtls_cipher_init( &ctx ); |
if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) |
goto exit; |
ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_cipher_cmac_update( &ctx, input, ilen ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_cipher_cmac_finish( &ctx, output ); |
exit: |
mbedtls_cipher_free( &ctx ); |
return( ret ); |
} |
#if defined(MBEDTLS_AES_C) |
/* |
* Implementation of AES-CMAC-PRF-128 defined in RFC 4615 |
*/ |
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, |
const unsigned char *input, size_t in_len, |
unsigned char *output ) |
{ |
int ret; |
const mbedtls_cipher_info_t *cipher_info; |
unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; |
unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; |
if( key == NULL || input == NULL || output == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB ); |
if( cipher_info == NULL ) |
{ |
/* Failing at this point must be due to a build issue */ |
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; |
goto exit; |
} |
if( key_length == MBEDTLS_AES_BLOCK_SIZE ) |
{ |
/* Use key as is */ |
memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); |
} |
else |
{ |
memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); |
ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, |
key_length, int_key ); |
if( ret != 0 ) |
goto exit; |
} |
ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len, |
output ); |
exit: |
mbedtls_platform_zeroize( int_key, sizeof( int_key ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_AES_C */ |
#endif /* !MBEDTLS_CMAC_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* CMAC test data for SP800-38B |
* http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf |
* http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf |
* |
* AES-CMAC-PRF-128 test data from RFC 4615 |
* https://tools.ietf.org/html/rfc4615#page-4 |
*/ |
#define NB_CMAC_TESTS_PER_KEY 4 |
#define NB_PRF_TESTS 3 |
#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) |
/* All CMAC test inputs are truncated from the same 64 byte buffer. */ |
static const unsigned char test_message[] = { |
/* PT */ |
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, |
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, |
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 |
}; |
#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ |
#if defined(MBEDTLS_AES_C) |
/* Truncation point of message for AES CMAC tests */ |
static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { |
/* Mlen */ |
0, |
16, |
20, |
64 |
}; |
/* CMAC-AES128 Test Data */ |
static const unsigned char aes_128_key[16] = { |
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, |
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c |
}; |
static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { |
{ |
/* K1 */ |
0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, |
0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde |
}, |
{ |
/* K2 */ |
0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, |
0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b |
} |
}; |
static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { |
{ |
/* Example #1 */ |
0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, |
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 |
}, |
{ |
/* Example #2 */ |
0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, |
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c |
}, |
{ |
/* Example #3 */ |
0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, |
0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde |
}, |
{ |
/* Example #4 */ |
0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, |
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe |
} |
}; |
/* CMAC-AES192 Test Data */ |
static const unsigned char aes_192_key[24] = { |
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, |
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, |
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b |
}; |
static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { |
{ |
/* K1 */ |
0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, |
0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 |
}, |
{ |
/* K2 */ |
0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, |
0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c |
} |
}; |
static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { |
{ |
/* Example #1 */ |
0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, |
0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 |
}, |
{ |
/* Example #2 */ |
0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, |
0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 |
}, |
{ |
/* Example #3 */ |
0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, |
0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 |
}, |
{ |
/* Example #4 */ |
0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, |
0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 |
} |
}; |
/* CMAC-AES256 Test Data */ |
static const unsigned char aes_256_key[32] = { |
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 aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { |
{ |
/* K1 */ |
0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, |
0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f |
}, |
{ |
/* K2 */ |
0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, |
0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 |
} |
}; |
static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { |
{ |
/* Example #1 */ |
0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, |
0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 |
}, |
{ |
/* Example #2 */ |
0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, |
0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c |
}, |
{ |
/* Example #3 */ |
0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, |
0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 |
}, |
{ |
/* Example #4 */ |
0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, |
0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 |
} |
}; |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_DES_C) |
/* Truncation point of message for 3DES CMAC tests */ |
static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { |
0, |
16, |
20, |
32 |
}; |
/* CMAC-TDES (Generation) - 2 Key Test Data */ |
static const unsigned char des3_2key_key[24] = { |
/* Key1 */ |
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
/* Key2 */ |
0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, |
/* Key3 */ |
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef |
}; |
static const unsigned char des3_2key_subkeys[2][8] = { |
{ |
/* K1 */ |
0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 |
}, |
{ |
/* K2 */ |
0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 |
} |
}; |
static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { |
{ |
/* Sample #1 */ |
0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 |
}, |
{ |
/* Sample #2 */ |
0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b |
}, |
{ |
/* Sample #3 */ |
0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 |
}, |
{ |
/* Sample #4 */ |
0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb |
} |
}; |
/* CMAC-TDES (Generation) - 3 Key Test Data */ |
static const unsigned char des3_3key_key[24] = { |
/* Key1 */ |
0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, |
/* Key2 */ |
0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, |
/* Key3 */ |
0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 |
}; |
static const unsigned char des3_3key_subkeys[2][8] = { |
{ |
/* K1 */ |
0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 |
}, |
{ |
/* K2 */ |
0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b |
} |
}; |
static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { |
{ |
/* Sample #1 */ |
0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 |
}, |
{ |
/* Sample #2 */ |
0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 |
}, |
{ |
/* Sample #3 */ |
0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 |
}, |
{ |
/* Sample #4 */ |
0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 |
} |
}; |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_AES_C) |
/* AES AES-CMAC-PRF-128 Test Data */ |
static const unsigned char PRFK[] = { |
/* Key */ |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
0xed, 0xcb |
}; |
/* Sizes in bytes */ |
static const size_t PRFKlen[NB_PRF_TESTS] = { |
18, |
16, |
10 |
}; |
/* Message */ |
static const unsigned char PRFM[] = { |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
0x10, 0x11, 0x12, 0x13 |
}; |
static const unsigned char PRFT[NB_PRF_TESTS][16] = { |
{ |
0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, |
0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a |
}, |
{ |
0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, |
0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d |
}, |
{ |
0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, |
0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d |
} |
}; |
#endif /* MBEDTLS_AES_C */ |
static int cmac_test_subkeys( int verbose, |
const char* testname, |
const unsigned char* key, |
int keybits, |
const unsigned char* subkeys, |
mbedtls_cipher_type_t cipher_type, |
int block_size, |
int num_tests ) |
{ |
int i, ret = 0; |
mbedtls_cipher_context_t ctx; |
const mbedtls_cipher_info_t *cipher_info; |
unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
cipher_info = mbedtls_cipher_info_from_type( cipher_type ); |
if( cipher_info == NULL ) |
{ |
/* Failing at this point must be due to a build issue */ |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
} |
for( i = 0; i < num_tests; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 ); |
mbedtls_cipher_init( &ctx ); |
if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "test execution failed\n" ); |
goto cleanup; |
} |
if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits, |
MBEDTLS_ENCRYPT ) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "test execution failed\n" ); |
goto cleanup; |
} |
ret = cmac_generate_subkeys( &ctx, K1, K2 ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto cleanup; |
} |
if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 || |
( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
mbedtls_cipher_free( &ctx ); |
} |
ret = 0; |
goto exit; |
cleanup: |
mbedtls_cipher_free( &ctx ); |
exit: |
return( ret ); |
} |
static int cmac_test_wth_cipher( int verbose, |
const char* testname, |
const unsigned char* key, |
int keybits, |
const unsigned char* messages, |
const unsigned int message_lengths[4], |
const unsigned char* expected_result, |
mbedtls_cipher_type_t cipher_type, |
int block_size, |
int num_tests ) |
{ |
const mbedtls_cipher_info_t *cipher_info; |
int i, ret = 0; |
unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; |
cipher_info = mbedtls_cipher_info_from_type( cipher_type ); |
if( cipher_info == NULL ) |
{ |
/* Failing at this point must be due to a build issue */ |
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; |
goto exit; |
} |
for( i = 0; i < num_tests; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 ); |
if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages, |
message_lengths[i], output ) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto exit; |
} |
if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
ret = 0; |
exit: |
return( ret ); |
} |
#if defined(MBEDTLS_AES_C) |
static int test_aes128_cmac_prf( int verbose ) |
{ |
int i; |
int ret; |
unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; |
for( i = 0; i < NB_PRF_TESTS; i++ ) |
{ |
mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); |
ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); |
if( ret != 0 || |
memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( ret ); |
} |
else if( verbose != 0 ) |
{ |
mbedtls_printf( "passed\n" ); |
} |
} |
return( ret ); |
} |
#endif /* MBEDTLS_AES_C */ |
int mbedtls_cmac_self_test( int verbose ) |
{ |
int ret; |
#if defined(MBEDTLS_AES_C) |
/* AES-128 */ |
if( ( ret = cmac_test_subkeys( verbose, |
"AES 128", |
aes_128_key, |
128, |
(const unsigned char*)aes_128_subkeys, |
MBEDTLS_CIPHER_AES_128_ECB, |
MBEDTLS_AES_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = cmac_test_wth_cipher( verbose, |
"AES 128", |
aes_128_key, |
128, |
test_message, |
aes_message_lengths, |
(const unsigned char*)aes_128_expected_result, |
MBEDTLS_CIPHER_AES_128_ECB, |
MBEDTLS_AES_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
/* AES-192 */ |
if( ( ret = cmac_test_subkeys( verbose, |
"AES 192", |
aes_192_key, |
192, |
(const unsigned char*)aes_192_subkeys, |
MBEDTLS_CIPHER_AES_192_ECB, |
MBEDTLS_AES_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = cmac_test_wth_cipher( verbose, |
"AES 192", |
aes_192_key, |
192, |
test_message, |
aes_message_lengths, |
(const unsigned char*)aes_192_expected_result, |
MBEDTLS_CIPHER_AES_192_ECB, |
MBEDTLS_AES_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
/* AES-256 */ |
if( ( ret = cmac_test_subkeys( verbose, |
"AES 256", |
aes_256_key, |
256, |
(const unsigned char*)aes_256_subkeys, |
MBEDTLS_CIPHER_AES_256_ECB, |
MBEDTLS_AES_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = cmac_test_wth_cipher ( verbose, |
"AES 256", |
aes_256_key, |
256, |
test_message, |
aes_message_lengths, |
(const unsigned char*)aes_256_expected_result, |
MBEDTLS_CIPHER_AES_256_ECB, |
MBEDTLS_AES_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_DES_C) |
/* 3DES 2 key */ |
if( ( ret = cmac_test_subkeys( verbose, |
"3DES 2 key", |
des3_2key_key, |
192, |
(const unsigned char*)des3_2key_subkeys, |
MBEDTLS_CIPHER_DES_EDE3_ECB, |
MBEDTLS_DES3_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = cmac_test_wth_cipher( verbose, |
"3DES 2 key", |
des3_2key_key, |
192, |
test_message, |
des3_message_lengths, |
(const unsigned char*)des3_2key_expected_result, |
MBEDTLS_CIPHER_DES_EDE3_ECB, |
MBEDTLS_DES3_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
/* 3DES 3 key */ |
if( ( ret = cmac_test_subkeys( verbose, |
"3DES 3 key", |
des3_3key_key, |
192, |
(const unsigned char*)des3_3key_subkeys, |
MBEDTLS_CIPHER_DES_EDE3_ECB, |
MBEDTLS_DES3_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = cmac_test_wth_cipher( verbose, |
"3DES 3 key", |
des3_3key_key, |
192, |
test_message, |
des3_message_lengths, |
(const unsigned char*)des3_3key_expected_result, |
MBEDTLS_CIPHER_DES_EDE3_ECB, |
MBEDTLS_DES3_BLOCK_SIZE, |
NB_CMAC_TESTS_PER_KEY ) ) != 0 ) |
{ |
return( ret ); |
} |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_AES_C) |
if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 ) |
return( ret ); |
#endif /* MBEDTLS_AES_C */ |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_CMAC_C */ |
/programs/develop/libraries/kos_mbedtls/library/ctr_drbg.c |
---|
0,0 → 1,724 |
/* |
* CTR_DRBG implementation based on AES-256 (NIST SP 800-90) |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The NIST SP 800-90 DRBGs are described in the following publication. |
* |
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_CTR_DRBG_C) |
#include "mbedtls/ctr_drbg.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_FS_IO) |
#include <stdio.h> |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
/* |
* CTR_DRBG context initialization |
*/ |
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &ctx->mutex ); |
#endif |
} |
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &ctx->mutex ); |
#endif |
mbedtls_aes_free( &ctx->aes_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); |
} |
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance ) |
{ |
ctx->prediction_resistance = resistance; |
} |
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ) |
{ |
ctx->entropy_len = len; |
} |
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval ) |
{ |
ctx->reseed_interval = interval; |
} |
static int block_cipher_df( unsigned char *output, |
const unsigned char *data, size_t data_len ) |
{ |
unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; |
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; |
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; |
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; |
unsigned char *p, *iv; |
mbedtls_aes_context aes_ctx; |
int ret = 0; |
int i, j; |
size_t buf_len, use_len; |
if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) |
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); |
memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); |
mbedtls_aes_init( &aes_ctx ); |
/* |
* Construct IV (16 bytes) and S in buffer |
* IV = Counter (in 32-bits) padded to 16 with zeroes |
* S = Length input string (in 32-bits) || Length of output (in 32-bits) || |
* data || 0x80 |
* (Total is padded to a multiple of 16-bytes with zeroes) |
*/ |
p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; |
*p++ = ( data_len >> 24 ) & 0xff; |
*p++ = ( data_len >> 16 ) & 0xff; |
*p++ = ( data_len >> 8 ) & 0xff; |
*p++ = ( data_len ) & 0xff; |
p += 3; |
*p++ = MBEDTLS_CTR_DRBG_SEEDLEN; |
memcpy( p, data, data_len ); |
p[data_len] = 0x80; |
buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; |
for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) |
key[i] = i; |
if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) |
{ |
goto exit; |
} |
/* |
* Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data |
*/ |
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) |
{ |
p = buf; |
memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); |
use_len = buf_len; |
while( use_len > 0 ) |
{ |
for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ ) |
chain[i] ^= p[i]; |
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; |
use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? |
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; |
if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 ) |
{ |
goto exit; |
} |
} |
memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); |
/* |
* Update IV |
*/ |
buf[3]++; |
} |
/* |
* Do final encryption with reduced data |
*/ |
if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) |
{ |
goto exit; |
} |
iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; |
p = output; |
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) |
{ |
if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 ) |
{ |
goto exit; |
} |
memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); |
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; |
} |
exit: |
mbedtls_aes_free( &aes_ctx ); |
/* |
* tidy up the stack |
*/ |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
mbedtls_platform_zeroize( key, sizeof( key ) ); |
mbedtls_platform_zeroize( chain, sizeof( chain ) ); |
if( 0 != ret ) |
{ |
/* |
* wipe partial seed from memory |
*/ |
mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN ); |
} |
return( ret ); |
} |
/* CTR_DRBG_Update (SP 800-90A §10.2.1.2) |
* ctr_drbg_update_internal(ctx, provided_data) |
* implements |
* CTR_DRBG_Update(provided_data, Key, V) |
* with inputs and outputs |
* ctx->aes_ctx = Key |
* ctx->counter = V |
*/ |
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, |
const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] ) |
{ |
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; |
unsigned char *p = tmp; |
int i, j; |
int ret = 0; |
memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); |
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) |
{ |
/* |
* Increase counter |
*/ |
for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) |
if( ++ctx->counter[i - 1] != 0 ) |
break; |
/* |
* Crypt counter block |
*/ |
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 ) |
goto exit; |
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; |
} |
for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ ) |
tmp[i] ^= data[i]; |
/* |
* Update key and counter |
*/ |
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) |
goto exit; |
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); |
exit: |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
return( ret ); |
} |
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) |
* mbedtls_ctr_drbg_update(ctx, additional, add_len) |
* implements |
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, |
* security_strength) -> initial_working_state |
* with inputs |
* ctx->counter = all-bits-0 |
* ctx->aes_ctx = context from all-bits-0 key |
* additional[:add_len] = entropy_input || nonce || personalization_string |
* and with outputs |
* ctx = initial_working_state |
*/ |
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, |
const unsigned char *additional, |
size_t add_len ) |
{ |
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; |
int ret; |
if( add_len == 0 ) |
return( 0 ); |
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) |
goto exit; |
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, |
const unsigned char *additional, |
size_t add_len ) |
{ |
/* MAX_INPUT would be more logical here, but we have to match |
* block_cipher_df()'s limits since we can't propagate errors */ |
if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) |
add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; |
(void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len ); |
} |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) |
* mbedtls_ctr_drbg_reseed(ctx, additional, len) |
* implements |
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input) |
* -> new_working_state |
* with inputs |
* ctx contains working_state |
* additional[:len] = additional_input |
* and entropy_input comes from calling ctx->f_entropy |
* and with output |
* ctx contains new_working_state |
*/ |
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, |
const unsigned char *additional, size_t len ) |
{ |
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; |
size_t seedlen = 0; |
int ret; |
if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || |
len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) |
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); |
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); |
/* |
* Gather entropy_len bytes of entropy to seed state |
*/ |
if( 0 != ctx->f_entropy( ctx->p_entropy, seed, |
ctx->entropy_len ) ) |
{ |
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); |
} |
seedlen += ctx->entropy_len; |
/* |
* Add additional data |
*/ |
if( additional && len ) |
{ |
memcpy( seed + seedlen, additional, len ); |
seedlen += len; |
} |
/* |
* Reduce to 384 bits |
*/ |
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 ) |
goto exit; |
/* |
* Update state |
*/ |
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 ) |
goto exit; |
ctx->reseed_counter = 1; |
exit: |
mbedtls_platform_zeroize( seed, sizeof( seed ) ); |
return( ret ); |
} |
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) |
* mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len) |
* implements |
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, |
* security_strength) -> initial_working_state |
* with inputs |
* custom[:len] = nonce || personalization_string |
* where entropy_input comes from f_entropy for ctx->entropy_len bytes |
* and with outputs |
* ctx = initial_working_state |
*/ |
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, |
int (*f_entropy)(void *, unsigned char *, size_t), |
void *p_entropy, |
const unsigned char *custom, |
size_t len ) |
{ |
int ret; |
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; |
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); |
mbedtls_aes_init( &ctx->aes_ctx ); |
ctx->f_entropy = f_entropy; |
ctx->p_entropy = p_entropy; |
if( ctx->entropy_len == 0 ) |
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN; |
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; |
/* |
* Initialize with an empty key |
*/ |
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
/* Backward compatibility wrapper */ |
int mbedtls_ctr_drbg_seed_entropy_len( |
mbedtls_ctr_drbg_context *ctx, |
int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, |
const unsigned char *custom, size_t len, |
size_t entropy_len ) |
{ |
mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len ); |
return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) ); |
} |
/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2) |
* mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) |
* implements |
* CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len]) |
* -> working_state_after_reseed |
* if required, then |
* CTR_DRBG_Generate(working_state_after_reseed, |
* requested_number_of_bits, additional_input) |
* -> status, returned_bits, new_working_state |
* with inputs |
* ctx contains working_state |
* requested_number_of_bits = 8 * output_len |
* additional[:add_len] = additional_input |
* and entropy_input comes from calling ctx->f_entropy |
* and with outputs |
* status = SUCCESS (this function does the reseed internally) |
* returned_bits = output[:output_len] |
* ctx contains new_working_state |
*/ |
int mbedtls_ctr_drbg_random_with_add( void *p_rng, |
unsigned char *output, size_t output_len, |
const unsigned char *additional, size_t add_len ) |
{ |
int ret = 0; |
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; |
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; |
unsigned char *p = output; |
unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; |
int i; |
size_t use_len; |
if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST ) |
return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); |
if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) |
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); |
memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); |
if( ctx->reseed_counter > ctx->reseed_interval || |
ctx->prediction_resistance ) |
{ |
if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) |
{ |
return( ret ); |
} |
add_len = 0; |
} |
if( add_len > 0 ) |
{ |
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) |
goto exit; |
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) |
goto exit; |
} |
while( output_len > 0 ) |
{ |
/* |
* Increase counter |
*/ |
for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) |
if( ++ctx->counter[i - 1] != 0 ) |
break; |
/* |
* Crypt counter block |
*/ |
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 ) |
goto exit; |
use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : |
output_len; |
/* |
* Copy random block to destination |
*/ |
memcpy( p, tmp, use_len ); |
p += use_len; |
output_len -= use_len; |
} |
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) |
goto exit; |
ctx->reseed_counter++; |
exit: |
mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
return( ret ); |
} |
int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) |
{ |
int ret; |
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
#if defined(MBEDTLS_FS_IO) |
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) |
{ |
int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; |
FILE *f; |
unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; |
if( ( f = fopen( path, "wb" ) ) == NULL ) |
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); |
if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 ) |
goto exit; |
if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT ) |
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; |
else |
ret = 0; |
exit: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
fclose( f ); |
return( ret ); |
} |
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) |
{ |
int ret = 0; |
FILE *f = NULL; |
size_t n; |
unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; |
unsigned char c; |
if( ( f = fopen( path, "rb" ) ) == NULL ) |
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); |
n = fread( buf, 1, sizeof( buf ), f ); |
if( fread( &c, 1, 1, f ) != 0 ) |
{ |
ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; |
goto exit; |
} |
if( n == 0 || ferror( f ) ) |
{ |
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; |
goto exit; |
} |
fclose( f ); |
f = NULL; |
ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n ); |
exit: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
if( f != NULL ) |
fclose( f ); |
if( ret != 0 ) |
return( ret ); |
return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); |
} |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_SELF_TEST) |
static const unsigned char entropy_source_pr[96] = |
{ 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, |
0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, |
0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, |
0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, |
0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, |
0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, |
0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, |
0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, |
0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, |
0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, |
0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, |
0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; |
static const unsigned char entropy_source_nopr[64] = |
{ 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, |
0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, |
0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, |
0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, |
0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, |
0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, |
0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, |
0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; |
static const unsigned char nonce_pers_pr[16] = |
{ 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, |
0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; |
static const unsigned char nonce_pers_nopr[16] = |
{ 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, |
0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; |
static const unsigned char result_pr[16] = |
{ 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, |
0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; |
static const unsigned char result_nopr[16] = |
{ 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, |
0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; |
static size_t test_offset; |
static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, |
size_t len ) |
{ |
const unsigned char *p = data; |
memcpy( buf, p + test_offset, len ); |
test_offset += len; |
return( 0 ); |
} |
#define CHK( c ) if( (c) != 0 ) \ |
{ \ |
if( verbose != 0 ) \ |
mbedtls_printf( "failed\n" ); \ |
return( 1 ); \ |
} |
/* |
* Checkup routine |
*/ |
int mbedtls_ctr_drbg_self_test( int verbose ) |
{ |
mbedtls_ctr_drbg_context ctx; |
unsigned char buf[16]; |
mbedtls_ctr_drbg_init( &ctx ); |
/* |
* Based on a NIST CTR_DRBG test vector (PR = True) |
*/ |
if( verbose != 0 ) |
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); |
test_offset = 0; |
mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); |
CHK( mbedtls_ctr_drbg_seed( &ctx, |
ctr_drbg_self_test_entropy, |
(void *) entropy_source_pr, |
nonce_pers_pr, 16 ) ); |
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); |
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); |
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); |
CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); |
mbedtls_ctr_drbg_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
/* |
* Based on a NIST CTR_DRBG test vector (PR = FALSE) |
*/ |
if( verbose != 0 ) |
mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); |
mbedtls_ctr_drbg_init( &ctx ); |
test_offset = 0; |
mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 ); |
CHK( mbedtls_ctr_drbg_seed( &ctx, |
ctr_drbg_self_test_entropy, |
(void *) entropy_source_nopr, |
nonce_pers_nopr, 16 ) ); |
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); |
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); |
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); |
CHK( memcmp( buf, result_nopr, 16 ) ); |
mbedtls_ctr_drbg_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_CTR_DRBG_C */ |
/programs/develop/libraries/kos_mbedtls/library/debug.c |
---|
0,0 → 1,452 |
/* |
* Debugging routines |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_DEBUG_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#define mbedtls_time_t time_t |
#define mbedtls_snprintf snprintf |
#endif |
#include "mbedtls/debug.h" |
#include <stdarg.h> |
#include <stdio.h> |
#include <string.h> |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
#define DEBUG_BUF_SIZE 512 |
static int debug_threshold = 0; |
void mbedtls_debug_set_threshold( int threshold ) |
{ |
debug_threshold = threshold; |
} |
/* |
* All calls to f_dbg must be made via this function |
*/ |
static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *str ) |
{ |
/* |
* If in a threaded environment, we need a thread identifier. |
* Since there is no portable way to get one, use the address of the ssl |
* context instead, as it shouldn't be shared between threads. |
*/ |
#if defined(MBEDTLS_THREADING_C) |
char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ |
mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str ); |
ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr ); |
#else |
ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str ); |
#endif |
} |
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *format, ... ) |
{ |
va_list argp; |
char str[DEBUG_BUF_SIZE]; |
int ret; |
if( NULL == ssl || |
NULL == ssl->conf || |
NULL == ssl->conf->f_dbg || |
level > debug_threshold ) |
{ |
return; |
} |
va_start( argp, format ); |
#if defined(_WIN32) |
#if defined(_TRUNCATE) && !defined(__MINGW32__) |
ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); |
#else |
ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); |
if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE ) |
{ |
str[DEBUG_BUF_SIZE-1] = '\0'; |
ret = -1; |
} |
#endif |
#else |
ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); |
#endif |
va_end( argp ); |
if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 ) |
{ |
str[ret] = '\n'; |
str[ret + 1] = '\0'; |
} |
debug_send_line( ssl, level, file, line, str ); |
} |
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, int ret ) |
{ |
char str[DEBUG_BUF_SIZE]; |
if( NULL == ssl || |
NULL == ssl->conf || |
NULL == ssl->conf->f_dbg || |
level > debug_threshold ) |
{ |
return; |
} |
/* |
* With non-blocking I/O and examples that just retry immediately, |
* the logs would be quickly flooded with WANT_READ, so ignore that. |
* Don't ignore WANT_WRITE however, since is is usually rare. |
*/ |
if( ret == MBEDTLS_ERR_SSL_WANT_READ ) |
return; |
mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n", |
text, ret, -ret ); |
debug_send_line( ssl, level, file, line, str ); |
} |
void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, const char *text, |
const unsigned char *buf, size_t len ) |
{ |
char str[DEBUG_BUF_SIZE]; |
char txt[17]; |
size_t i, idx = 0; |
if( NULL == ssl || |
NULL == ssl->conf || |
NULL == ssl->conf->f_dbg || |
level > debug_threshold ) |
{ |
return; |
} |
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n", |
text, (unsigned int) len ); |
debug_send_line( ssl, level, file, line, str ); |
idx = 0; |
memset( txt, 0, sizeof( txt ) ); |
for( i = 0; i < len; i++ ) |
{ |
if( i >= 4096 ) |
break; |
if( i % 16 == 0 ) |
{ |
if( i > 0 ) |
{ |
mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); |
debug_send_line( ssl, level, file, line, str ); |
idx = 0; |
memset( txt, 0, sizeof( txt ) ); |
} |
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ", |
(unsigned int) i ); |
} |
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", |
(unsigned int) buf[i] ); |
txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ; |
} |
if( len > 0 ) |
{ |
for( /* i = i */; i % 16 != 0; i++ ) |
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " " ); |
mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); |
debug_send_line( ssl, level, file, line, str ); |
} |
} |
#if defined(MBEDTLS_ECP_C) |
void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_ecp_point *X ) |
{ |
char str[DEBUG_BUF_SIZE]; |
if( NULL == ssl || |
NULL == ssl->conf || |
NULL == ssl->conf->f_dbg || |
level > debug_threshold ) |
{ |
return; |
} |
mbedtls_snprintf( str, sizeof( str ), "%s(X)", text ); |
mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X ); |
mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text ); |
mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y ); |
} |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_BIGNUM_C) |
void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_mpi *X ) |
{ |
char str[DEBUG_BUF_SIZE]; |
int j, k, zeros = 1; |
size_t i, n, idx = 0; |
if( NULL == ssl || |
NULL == ssl->conf || |
NULL == ssl->conf->f_dbg || |
NULL == X || |
level > debug_threshold ) |
{ |
return; |
} |
for( n = X->n - 1; n > 0; n-- ) |
if( X->p[n] != 0 ) |
break; |
for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- ) |
if( ( ( X->p[n] >> j ) & 1 ) != 0 ) |
break; |
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n", |
text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) ); |
debug_send_line( ssl, level, file, line, str ); |
idx = 0; |
for( i = n + 1, j = 0; i > 0; i-- ) |
{ |
if( zeros && X->p[i - 1] == 0 ) |
continue; |
for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- ) |
{ |
if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 ) |
continue; |
else |
zeros = 0; |
if( j % 16 == 0 ) |
{ |
if( j > 0 ) |
{ |
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); |
debug_send_line( ssl, level, file, line, str ); |
idx = 0; |
} |
} |
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int) |
( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ); |
j++; |
} |
} |
if( zeros == 1 ) |
idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" ); |
mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); |
debug_send_line( ssl, level, file, line, str ); |
} |
#endif /* MBEDTLS_BIGNUM_C */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
static void debug_print_pk( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_pk_context *pk ) |
{ |
size_t i; |
mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS]; |
char name[16]; |
memset( items, 0, sizeof( items ) ); |
if( mbedtls_pk_debug( pk, items ) != 0 ) |
{ |
debug_send_line( ssl, level, file, line, |
"invalid PK context\n" ); |
return; |
} |
for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ ) |
{ |
if( items[i].type == MBEDTLS_PK_DEBUG_NONE ) |
return; |
mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name ); |
name[sizeof( name ) - 1] = '\0'; |
if( items[i].type == MBEDTLS_PK_DEBUG_MPI ) |
mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value ); |
else |
#if defined(MBEDTLS_ECP_C) |
if( items[i].type == MBEDTLS_PK_DEBUG_ECP ) |
mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value ); |
else |
#endif |
debug_send_line( ssl, level, file, line, |
"should not happen\n" ); |
} |
} |
static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, const char *text ) |
{ |
char str[DEBUG_BUF_SIZE]; |
const char *start, *cur; |
start = text; |
for( cur = text; *cur != '\0'; cur++ ) |
{ |
if( *cur == '\n' ) |
{ |
size_t len = cur - start + 1; |
if( len > DEBUG_BUF_SIZE - 1 ) |
len = DEBUG_BUF_SIZE - 1; |
memcpy( str, start, len ); |
str[len] = '\0'; |
debug_send_line( ssl, level, file, line, str ); |
start = cur + 1; |
} |
} |
} |
void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const char *text, const mbedtls_x509_crt *crt ) |
{ |
char str[DEBUG_BUF_SIZE]; |
int i = 0; |
if( NULL == ssl || |
NULL == ssl->conf || |
NULL == ssl->conf->f_dbg || |
NULL == crt || |
level > debug_threshold ) |
{ |
return; |
} |
while( crt != NULL ) |
{ |
char buf[1024]; |
mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i ); |
debug_send_line( ssl, level, file, line, str ); |
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt ); |
debug_print_line_by_line( ssl, level, file, line, buf ); |
debug_print_pk( ssl, level, file, line, "crt->", &crt->pk ); |
crt = crt->next; |
} |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_ECDH_C) |
static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl, |
int level, const char *file, |
int line, |
const mbedtls_ecdh_context *ecdh, |
mbedtls_debug_ecdh_attr attr ) |
{ |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
const mbedtls_ecdh_context* ctx = ecdh; |
#else |
const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh; |
#endif |
switch( attr ) |
{ |
case MBEDTLS_DEBUG_ECDH_Q: |
mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q", |
&ctx->Q ); |
break; |
case MBEDTLS_DEBUG_ECDH_QP: |
mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp", |
&ctx->Qp ); |
break; |
case MBEDTLS_DEBUG_ECDH_Z: |
mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z", |
&ctx->z ); |
break; |
default: |
break; |
} |
} |
void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, |
const char *file, int line, |
const mbedtls_ecdh_context *ecdh, |
mbedtls_debug_ecdh_attr attr ) |
{ |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr ); |
#else |
switch( ecdh->var ) |
{ |
default: |
mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, |
attr ); |
} |
#endif |
} |
#endif /* MBEDTLS_ECDH_C */ |
#endif /* MBEDTLS_DEBUG_C */ |
/programs/develop/libraries/kos_mbedtls/library/des.c |
---|
0,0 → 1,1066 |
/* |
* FIPS-46-3 compliant Triple-DES implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* 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 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_DES_C) |
#include "mbedtls/des.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_DES_ALT) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t LHs[16] = |
{ |
0x00000000, 0x00000001, 0x00000100, 0x00000101, |
0x00010000, 0x00010001, 0x00010100, 0x00010101, |
0x01000000, 0x01000001, 0x01000100, 0x01000101, |
0x01010000, 0x01010001, 0x01010100, 0x01010101 |
}; |
static const uint32_t 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) \ |
do \ |
{ \ |
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; \ |
} while( 0 ) |
/* |
* Final Permutation macro |
*/ |
#define DES_FP(X,Y) \ |
do \ |
{ \ |
(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); \ |
} while( 0 ) |
/* |
* DES round macro |
*/ |
#define DES_ROUND(X,Y) \ |
do \ |
{ \ |
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 ]; \ |
} while( 0 ) |
#define SWAP(a,b) \ |
do \ |
{ \ |
uint32_t t = (a); (a) = (b); (b) = t; t = 0; \ |
} while( 0 ) |
void mbedtls_des_init( mbedtls_des_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_des_context ) ); |
} |
void mbedtls_des_free( mbedtls_des_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) ); |
} |
void mbedtls_des3_init( mbedtls_des3_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_des3_context ) ); |
} |
void mbedtls_des3_free( mbedtls_des3_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) ); |
} |
static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, |
11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, |
47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, |
82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, |
115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, |
143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, |
171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, |
199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, |
227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, |
254 }; |
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ) |
{ |
int i; |
for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) |
key[i] = odd_parity_table[key[i] / 2]; |
} |
/* |
* Check the given key's parity, returns 1 on failure, 0 on SUCCESS |
*/ |
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) |
{ |
int i; |
for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) |
if( key[i] != odd_parity_table[key[i] / 2] ) |
return( 1 ); |
return( 0 ); |
} |
/* |
* Table of weak and semi-weak keys |
* |
* Source: http://en.wikipedia.org/wiki/Weak_key |
* |
* Weak: |
* Alternating ones + zeros (0x0101010101010101) |
* Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) |
* '0xE0E0E0E0F1F1F1F1' |
* '0x1F1F1F1F0E0E0E0E' |
* |
* Semi-weak: |
* 0x011F011F010E010E and 0x1F011F010E010E01 |
* 0x01E001E001F101F1 and 0xE001E001F101F101 |
* 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 |
* 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E |
* 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E |
* 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 |
* |
*/ |
#define WEAK_KEY_COUNT 16 |
static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = |
{ |
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, |
{ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, |
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, |
{ 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, |
{ 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, |
{ 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, |
{ 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, |
{ 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, |
{ 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, |
{ 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, |
{ 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, |
{ 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, |
{ 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, |
{ 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, |
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, |
{ 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } |
}; |
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) |
{ |
int i; |
for( i = 0; i < WEAK_KEY_COUNT; i++ ) |
if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 ) |
return( 1 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DES_SETKEY_ALT) |
void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) |
{ |
int i; |
uint32_t X, Y, T; |
GET_UINT32_BE( X, key, 0 ); |
GET_UINT32_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); |
} |
} |
#endif /* !MBEDTLS_DES_SETKEY_ALT */ |
/* |
* DES key schedule (56-bit, encryption) |
*/ |
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) |
{ |
mbedtls_des_setkey( ctx->sk, key ); |
return( 0 ); |
} |
/* |
* DES key schedule (56-bit, decryption) |
*/ |
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) |
{ |
int i; |
mbedtls_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] ); |
} |
return( 0 ); |
} |
static void des3_set2key( uint32_t esk[96], |
uint32_t dsk[96], |
const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] ) |
{ |
int i; |
mbedtls_des_setkey( esk, key ); |
mbedtls_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) |
*/ |
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) |
{ |
uint32_t sk[96]; |
des3_set2key( ctx->sk, sk, key ); |
mbedtls_platform_zeroize( sk, sizeof( sk ) ); |
return( 0 ); |
} |
/* |
* Triple-DES key schedule (112-bit, decryption) |
*/ |
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) |
{ |
uint32_t sk[96]; |
des3_set2key( sk, ctx->sk, key ); |
mbedtls_platform_zeroize( sk, sizeof( sk ) ); |
return( 0 ); |
} |
static void des3_set3key( uint32_t esk[96], |
uint32_t dsk[96], |
const unsigned char key[24] ) |
{ |
int i; |
mbedtls_des_setkey( esk, key ); |
mbedtls_des_setkey( dsk + 32, key + 8 ); |
mbedtls_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) |
*/ |
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) |
{ |
uint32_t sk[96]; |
des3_set3key( ctx->sk, sk, key ); |
mbedtls_platform_zeroize( sk, sizeof( sk ) ); |
return( 0 ); |
} |
/* |
* Triple-DES key schedule (168-bit, decryption) |
*/ |
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, |
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) |
{ |
uint32_t sk[96]; |
des3_set3key( sk, ctx->sk, key ); |
mbedtls_platform_zeroize( sk, sizeof( sk ) ); |
return( 0 ); |
} |
/* |
* DES-ECB block encryption/decryption |
*/ |
#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT) |
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, |
const unsigned char input[8], |
unsigned char output[8] ) |
{ |
int i; |
uint32_t X, Y, T, *SK; |
SK = ctx->sk; |
GET_UINT32_BE( X, input, 0 ); |
GET_UINT32_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_UINT32_BE( Y, output, 0 ); |
PUT_UINT32_BE( X, output, 4 ); |
return( 0 ); |
} |
#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* DES-CBC buffer encryption/decryption |
*/ |
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[8], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int i; |
unsigned char temp[8]; |
if( length % 8 ) |
return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); |
if( mode == MBEDTLS_DES_ENCRYPT ) |
{ |
while( length > 0 ) |
{ |
for( i = 0; i < 8; i++ ) |
output[i] = (unsigned char)( input[i] ^ iv[i] ); |
mbedtls_des_crypt_ecb( ctx, output, output ); |
memcpy( iv, output, 8 ); |
input += 8; |
output += 8; |
length -= 8; |
} |
} |
else /* MBEDTLS_DES_DECRYPT */ |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, 8 ); |
mbedtls_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 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
/* |
* 3DES-ECB block encryption/decryption |
*/ |
#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT) |
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, |
const unsigned char input[8], |
unsigned char output[8] ) |
{ |
int i; |
uint32_t X, Y, T, *SK; |
SK = ctx->sk; |
GET_UINT32_BE( X, input, 0 ); |
GET_UINT32_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_UINT32_BE( Y, output, 0 ); |
PUT_UINT32_BE( X, output, 4 ); |
return( 0 ); |
} |
#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* 3DES-CBC buffer encryption/decryption |
*/ |
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[8], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int i; |
unsigned char temp[8]; |
if( length % 8 ) |
return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); |
if( mode == MBEDTLS_DES_ENCRYPT ) |
{ |
while( length > 0 ) |
{ |
for( i = 0; i < 8; i++ ) |
output[i] = (unsigned char)( input[i] ^ iv[i] ); |
mbedtls_des3_crypt_ecb( ctx, output, output ); |
memcpy( iv, output, 8 ); |
input += 8; |
output += 8; |
length -= 8; |
} |
} |
else /* MBEDTLS_DES_DECRYPT */ |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, 8 ); |
mbedtls_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 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* !MBEDTLS_DES_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* 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_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 } |
}; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
static const unsigned char des3_test_iv[8] = |
{ |
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, |
}; |
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 } |
}; |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
/* |
* Checkup routine |
*/ |
int mbedtls_des_self_test( int verbose ) |
{ |
int i, j, u, v, ret = 0; |
mbedtls_des_context ctx; |
mbedtls_des3_context ctx3; |
unsigned char buf[8]; |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
unsigned char prv[8]; |
unsigned char iv[8]; |
#endif |
mbedtls_des_init( &ctx ); |
mbedtls_des3_init( &ctx3 ); |
/* |
* ECB mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
v = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " DES%c-ECB-%3d (%s): ", |
( u == 0 ) ? ' ' : '3', 56 + u * 56, |
( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); |
memcpy( buf, des3_test_buf, 8 ); |
switch( i ) |
{ |
case 0: |
mbedtls_des_setkey_dec( &ctx, des3_test_keys ); |
break; |
case 1: |
mbedtls_des_setkey_enc( &ctx, des3_test_keys ); |
break; |
case 2: |
mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); |
break; |
case 3: |
mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); |
break; |
case 4: |
mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); |
break; |
case 5: |
mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); |
break; |
default: |
return( 1 ); |
} |
for( j = 0; j < 10000; j++ ) |
{ |
if( u == 0 ) |
mbedtls_des_crypt_ecb( &ctx, buf, buf ); |
else |
mbedtls_des3_crypt_ecb( &ctx3, buf, buf ); |
} |
if( ( v == MBEDTLS_DES_DECRYPT && |
memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || |
( v != MBEDTLS_DES_DECRYPT && |
memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* CBC mode |
*/ |
for( i = 0; i < 6; i++ ) |
{ |
u = i >> 1; |
v = i & 1; |
if( verbose != 0 ) |
mbedtls_printf( " DES%c-CBC-%3d (%s): ", |
( u == 0 ) ? ' ' : '3', 56 + u * 56, |
( v == MBEDTLS_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: |
mbedtls_des_setkey_dec( &ctx, des3_test_keys ); |
break; |
case 1: |
mbedtls_des_setkey_enc( &ctx, des3_test_keys ); |
break; |
case 2: |
mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); |
break; |
case 3: |
mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); |
break; |
case 4: |
mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); |
break; |
case 5: |
mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); |
break; |
default: |
return( 1 ); |
} |
if( v == MBEDTLS_DES_DECRYPT ) |
{ |
for( j = 0; j < 10000; j++ ) |
{ |
if( u == 0 ) |
mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); |
else |
mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); |
} |
} |
else |
{ |
for( j = 0; j < 10000; j++ ) |
{ |
unsigned char tmp[8]; |
if( u == 0 ) |
mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); |
else |
mbedtls_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 == MBEDTLS_DES_DECRYPT && |
memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || |
( v != MBEDTLS_DES_DECRYPT && |
memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
exit: |
mbedtls_des_free( &ctx ); |
mbedtls_des3_free( &ctx3 ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_DES_C */ |
/programs/develop/libraries/kos_mbedtls/library/dhm.c |
---|
0,0 → 1,714 |
/* |
* Diffie-Hellman-Merkle key exchange |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The following sources were referenced in the design of this implementation |
* of the Diffie-Hellman-Merkle algorithm: |
* |
* [1] Handbook of Applied Cryptography - 1997, Chapter 12 |
* Menezes, van Oorschot and Vanstone |
* |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_DHM_C) |
#include "mbedtls/dhm.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PEM_PARSE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_ASN1_PARSE_C) |
#include "mbedtls/asn1.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#include <stdio.h> |
#define mbedtls_printf printf |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#if !defined(MBEDTLS_DHM_ALT) |
#define DHM_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA ) |
#define DHM_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* helper to validate the mbedtls_mpi size and import it |
*/ |
static int dhm_read_bignum( mbedtls_mpi *X, |
unsigned char **p, |
const unsigned char *end ) |
{ |
int ret, n; |
if( end - *p < 2 ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
n = ( (*p)[0] << 8 ) | (*p)[1]; |
(*p) += 2; |
if( (int)( end - *p ) < n ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 ) |
return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret ); |
(*p) += n; |
return( 0 ); |
} |
/* |
* Verify sanity of parameter with regards to P |
* |
* Parameter should be: 2 <= public_param <= P - 2 |
* |
* This means that we need to return an error if |
* public_param < 2 or public_param > P-2 |
* |
* For more information on the attack, see: |
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf |
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 |
*/ |
static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) |
{ |
mbedtls_mpi L, U; |
int ret = 0; |
mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); |
if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 || |
mbedtls_mpi_cmp_mpi( param, &U ) > 0 ) |
{ |
ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; |
} |
cleanup: |
mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U ); |
return( ret ); |
} |
void mbedtls_dhm_init( mbedtls_dhm_context *ctx ) |
{ |
DHM_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); |
} |
/* |
* Parse the ServerKeyExchange parameters |
*/ |
int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, |
unsigned char **p, |
const unsigned char *end ) |
{ |
int ret; |
DHM_VALIDATE_RET( ctx != NULL ); |
DHM_VALIDATE_RET( p != NULL && *p != NULL ); |
DHM_VALIDATE_RET( end != NULL ); |
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 ); |
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) |
return( ret ); |
ctx->len = mbedtls_mpi_size( &ctx->P ); |
return( 0 ); |
} |
/* |
* Setup and write the ServerKeyExchange parameters |
*/ |
int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, |
unsigned char *output, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret, count = 0; |
size_t n1, n2, n3; |
unsigned char *p; |
DHM_VALIDATE_RET( ctx != NULL ); |
DHM_VALIDATE_RET( output != NULL ); |
DHM_VALIDATE_RET( olen != NULL ); |
DHM_VALIDATE_RET( f_rng != NULL ); |
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
/* |
* Generate X as large as possible ( < P ) |
*/ |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); |
while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); |
if( count++ > 10 ) |
return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED ); |
} |
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); |
/* |
* Calculate GX = G^X mod P |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, |
&ctx->P , &ctx->RP ) ); |
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) |
return( ret ); |
/* |
* export P, G, GX |
*/ |
#define DHM_MPI_EXPORT( X, n ) \ |
do { \ |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \ |
p + 2, \ |
( n ) ) ); \ |
*p++ = (unsigned char)( ( n ) >> 8 ); \ |
*p++ = (unsigned char)( ( n ) ); \ |
p += ( n ); \ |
} while( 0 ) |
n1 = mbedtls_mpi_size( &ctx->P ); |
n2 = mbedtls_mpi_size( &ctx->G ); |
n3 = mbedtls_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( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret ); |
return( 0 ); |
} |
/* |
* Set prime modulus and generator |
*/ |
int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, |
const mbedtls_mpi *P, |
const mbedtls_mpi *G ) |
{ |
int ret; |
DHM_VALIDATE_RET( ctx != NULL ); |
DHM_VALIDATE_RET( P != NULL ); |
DHM_VALIDATE_RET( G != NULL ); |
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 || |
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret ); |
} |
ctx->len = mbedtls_mpi_size( &ctx->P ); |
return( 0 ); |
} |
/* |
* Import the peer's public value G^Y |
*/ |
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, |
const unsigned char *input, size_t ilen ) |
{ |
int ret; |
DHM_VALIDATE_RET( ctx != NULL ); |
DHM_VALIDATE_RET( input != NULL ); |
if( ilen < 1 || ilen > ctx->len ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) |
return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret ); |
return( 0 ); |
} |
/* |
* Create own private value X and export G^X |
*/ |
int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, |
unsigned char *output, size_t olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret, count = 0; |
DHM_VALIDATE_RET( ctx != NULL ); |
DHM_VALIDATE_RET( output != NULL ); |
DHM_VALIDATE_RET( f_rng != NULL ); |
if( olen < 1 || olen > ctx->len ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
/* |
* generate X and calculate GX = G^X mod P |
*/ |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); |
while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); |
if( count++ > 10 ) |
return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED ); |
} |
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, |
&ctx->P , &ctx->RP ) ); |
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) |
return( ret ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) ); |
cleanup: |
if( ret != 0 ) |
return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); |
return( 0 ); |
} |
/* |
* Use the blinding method and optimisation suggested in section 10 of: |
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, |
* DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer |
* Berlin Heidelberg, 1996. p. 104-113. |
*/ |
static int dhm_update_blinding( mbedtls_dhm_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret, count; |
/* |
* Don't use any blinding the first time a particular X is used, |
* but remember it to use blinding next time. |
*/ |
if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) ); |
return( 0 ); |
} |
/* |
* Ok, we need blinding. Can we re-use existing values? |
* If yes, just update them by squaring them. |
*/ |
if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); |
return( 0 ); |
} |
/* |
* We need to generate blinding values from scratch |
*/ |
/* Vi = random( 2, P-1 ) */ |
count = 0; |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) ); |
while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) ); |
if( count++ > 10 ) |
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); |
} |
while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 ); |
/* Vf = Vi^-X mod P */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Derive and export the shared secret (G^Y)^X mod P |
*/ |
int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, |
unsigned char *output, size_t output_size, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
mbedtls_mpi GYb; |
DHM_VALIDATE_RET( ctx != NULL ); |
DHM_VALIDATE_RET( output != NULL ); |
DHM_VALIDATE_RET( olen != NULL ); |
if( output_size < ctx->len ) |
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); |
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) |
return( ret ); |
mbedtls_mpi_init( &GYb ); |
/* Blind peer's value */ |
if( f_rng != NULL ) |
{ |
MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); |
} |
else |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) ); |
/* Do modular exponentiation */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X, |
&ctx->P, &ctx->RP ) ); |
/* Unblind secret value */ |
if( f_rng != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) ); |
} |
*olen = mbedtls_mpi_size( &ctx->K ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) ); |
cleanup: |
mbedtls_mpi_free( &GYb ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret ); |
return( 0 ); |
} |
/* |
* Free the components of a DHM key |
*/ |
void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_mpi_free( &ctx->pX ); |
mbedtls_mpi_free( &ctx->Vf ); |
mbedtls_mpi_free( &ctx->Vi ); |
mbedtls_mpi_free( &ctx->RP ); |
mbedtls_mpi_free( &ctx->K ); |
mbedtls_mpi_free( &ctx->GY ); |
mbedtls_mpi_free( &ctx->GX ); |
mbedtls_mpi_free( &ctx->X ); |
mbedtls_mpi_free( &ctx->G ); |
mbedtls_mpi_free( &ctx->P ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); |
} |
#if defined(MBEDTLS_ASN1_PARSE_C) |
/* |
* Parse DHM parameters |
*/ |
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, |
size_t dhminlen ) |
{ |
int ret; |
size_t len; |
unsigned char *p, *end; |
#if defined(MBEDTLS_PEM_PARSE_C) |
mbedtls_pem_context pem; |
#endif /* MBEDTLS_PEM_PARSE_C */ |
DHM_VALIDATE_RET( dhm != NULL ); |
DHM_VALIDATE_RET( dhmin != NULL ); |
#if defined(MBEDTLS_PEM_PARSE_C) |
mbedtls_pem_init( &pem ); |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN DH PARAMETERS-----", |
"-----END DH PARAMETERS-----", |
dhmin, NULL, 0, &dhminlen ); |
if( ret == 0 ) |
{ |
/* |
* Was PEM encoded |
*/ |
dhminlen = pem.buflen; |
} |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
goto exit; |
p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; |
#else |
p = (unsigned char *) dhmin; |
#endif /* MBEDTLS_PEM_PARSE_C */ |
end = p + dhminlen; |
/* |
* DHParams ::= SEQUENCE { |
* prime INTEGER, -- P |
* generator INTEGER, -- g |
* privateValueLength INTEGER OPTIONAL |
* } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; |
goto exit; |
} |
end = p + len; |
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || |
( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) |
{ |
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; |
goto exit; |
} |
if( p != end ) |
{ |
/* This might be the optional privateValueLength. |
* If so, we can cleanly discard it */ |
mbedtls_mpi rec; |
mbedtls_mpi_init( &rec ); |
ret = mbedtls_asn1_get_mpi( &p, end, &rec ); |
mbedtls_mpi_free( &rec ); |
if ( ret != 0 ) |
{ |
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; |
goto exit; |
} |
if ( p != end ) |
{ |
ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; |
goto exit; |
} |
} |
ret = 0; |
dhm->len = mbedtls_mpi_size( &dhm->P ); |
exit: |
#if defined(MBEDTLS_PEM_PARSE_C) |
mbedtls_pem_free( &pem ); |
#endif |
if( ret != 0 ) |
mbedtls_dhm_free( dhm ); |
return( ret ); |
} |
#if defined(MBEDTLS_FS_IO) |
/* |
* Load all data from a file into a given buffer. |
* |
* The file is expected to contain either PEM or DER encoded data. |
* A terminating null byte is always appended. It is included in the announced |
* length only if the data looks like it is PEM encoded. |
*/ |
static int load_file( const char *path, unsigned char **buf, size_t *n ) |
{ |
FILE *f; |
long size; |
if( ( f = fopen( path, "rb" ) ) == NULL ) |
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); |
fseek( f, 0, SEEK_END ); |
if( ( size = ftell( f ) ) == -1 ) |
{ |
fclose( f ); |
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); |
} |
fseek( f, 0, SEEK_SET ); |
*n = (size_t) size; |
if( *n + 1 == 0 || |
( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) |
{ |
fclose( f ); |
return( MBEDTLS_ERR_DHM_ALLOC_FAILED ); |
} |
if( fread( *buf, 1, *n, f ) != *n ) |
{ |
fclose( f ); |
mbedtls_platform_zeroize( *buf, *n + 1 ); |
mbedtls_free( *buf ); |
return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); |
} |
fclose( f ); |
(*buf)[*n] = '\0'; |
if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) |
++*n; |
return( 0 ); |
} |
/* |
* Load and parse DHM parameters |
*/ |
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) |
{ |
int ret; |
size_t n; |
unsigned char *buf; |
DHM_VALIDATE_RET( dhm != NULL ); |
DHM_VALIDATE_RET( path != NULL ); |
if( ( ret = load_file( path, &buf, &n ) ) != 0 ) |
return( ret ); |
ret = mbedtls_dhm_parse_dhm( dhm, buf, n ); |
mbedtls_platform_zeroize( buf, n ); |
mbedtls_free( buf ); |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
#endif /* MBEDTLS_DHM_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PEM_PARSE_C) |
static const char mbedtls_test_dhm_params[] = |
"-----BEGIN DH PARAMETERS-----\r\n" |
"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" |
"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" |
"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" |
"-----END DH PARAMETERS-----\r\n"; |
#else /* MBEDTLS_PEM_PARSE_C */ |
static const char mbedtls_test_dhm_params[] = { |
0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, |
0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, |
0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, |
0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, |
0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, |
0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, |
0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, |
0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, |
0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, |
0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, |
0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, |
0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 }; |
#endif /* MBEDTLS_PEM_PARSE_C */ |
static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); |
/* |
* Checkup routine |
*/ |
int mbedtls_dhm_self_test( int verbose ) |
{ |
int ret; |
mbedtls_dhm_context dhm; |
mbedtls_dhm_init( &dhm ); |
if( verbose != 0 ) |
mbedtls_printf( " DHM parameter load: " ); |
if( ( ret = mbedtls_dhm_parse_dhm( &dhm, |
(const unsigned char *) mbedtls_test_dhm_params, |
mbedtls_test_dhm_params_len ) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n\n" ); |
exit: |
mbedtls_dhm_free( &dhm ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_DHM_C */ |
/programs/develop/libraries/kos_mbedtls/library/ecdh.c |
---|
0,0 → 1,678 |
/* |
* Elliptic curve Diffie-Hellman |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* |
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg |
* RFC 4492 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ECDH_C) |
#include "mbedtls/ecdh.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
/* Parameter validation macros based on platform_util.h */ |
#define ECDH_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) |
#define ECDH_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; |
#endif |
static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( |
const mbedtls_ecdh_context *ctx ) |
{ |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ctx->grp.id ); |
#else |
return( ctx->grp_id ); |
#endif |
} |
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) |
/* |
* Generate public key (restartable version) |
* |
* Note: this internal function relies on its caller preserving the value of |
* the output parameter 'd' across continuation calls. This would not be |
* acceptable for a public function but is OK here as we control call sites. |
*/ |
static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp, |
mbedtls_mpi *d, mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
/* If multiplication is in progress, we already generated a privkey */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx == NULL || rs_ctx->rsm == NULL ) |
#endif |
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G, |
f_rng, p_rng, rs_ctx ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Generate public key |
*/ |
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
ECDH_VALIDATE_RET( grp != NULL ); |
ECDH_VALIDATE_RET( d != NULL ); |
ECDH_VALIDATE_RET( Q != NULL ); |
ECDH_VALIDATE_RET( f_rng != NULL ); |
return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) ); |
} |
#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */ |
#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) |
/* |
* Compute shared secret (SEC1 3.3.1) |
*/ |
static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp, |
mbedtls_mpi *z, |
const mbedtls_ecp_point *Q, const mbedtls_mpi *d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_ecp_point P; |
mbedtls_ecp_point_init( &P ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q, |
f_rng, p_rng, rs_ctx ) ); |
if( mbedtls_ecp_is_zero( &P ) ) |
{ |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); |
cleanup: |
mbedtls_ecp_point_free( &P ); |
return( ret ); |
} |
/* |
* Compute shared secret (SEC1 3.3.1) |
*/ |
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, |
const mbedtls_ecp_point *Q, const mbedtls_mpi *d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
ECDH_VALIDATE_RET( grp != NULL ); |
ECDH_VALIDATE_RET( Q != NULL ); |
ECDH_VALIDATE_RET( d != NULL ); |
ECDH_VALIDATE_RET( z != NULL ); |
return( ecdh_compute_shared_restartable( grp, z, Q, d, |
f_rng, p_rng, NULL ) ); |
} |
#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ |
static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx ) |
{ |
mbedtls_ecp_group_init( &ctx->grp ); |
mbedtls_mpi_init( &ctx->d ); |
mbedtls_ecp_point_init( &ctx->Q ); |
mbedtls_ecp_point_init( &ctx->Qp ); |
mbedtls_mpi_init( &ctx->z ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_ecp_restart_init( &ctx->rs ); |
#endif |
} |
/* |
* Initialize context |
*/ |
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) |
{ |
ECDH_VALIDATE( ctx != NULL ); |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
ecdh_init_internal( ctx ); |
mbedtls_ecp_point_init( &ctx->Vi ); |
mbedtls_ecp_point_init( &ctx->Vf ); |
mbedtls_mpi_init( &ctx->_d ); |
#else |
memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); |
ctx->var = MBEDTLS_ECDH_VARIANT_NONE; |
#endif |
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
ctx->restart_enabled = 0; |
#endif |
} |
static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx, |
mbedtls_ecp_group_id grp_id ) |
{ |
int ret; |
ret = mbedtls_ecp_group_load( &ctx->grp, grp_id ); |
if( ret != 0 ) |
{ |
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
} |
return( 0 ); |
} |
/* |
* Setup context |
*/ |
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id ) |
{ |
ECDH_VALIDATE_RET( ctx != NULL ); |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_setup_internal( ctx, grp_id ) ); |
#else |
switch( grp_id ) |
{ |
default: |
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; |
ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; |
ctx->grp_id = grp_id; |
ecdh_init_internal( &ctx->ctx.mbed_ecdh ); |
return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) ); |
} |
#endif |
} |
static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx ) |
{ |
mbedtls_ecp_group_free( &ctx->grp ); |
mbedtls_mpi_free( &ctx->d ); |
mbedtls_ecp_point_free( &ctx->Q ); |
mbedtls_ecp_point_free( &ctx->Qp ); |
mbedtls_mpi_free( &ctx->z ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_ecp_restart_free( &ctx->rs ); |
#endif |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Enable restartable operations for context |
*/ |
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ) |
{ |
ECDH_VALIDATE( ctx != NULL ); |
ctx->restart_enabled = 1; |
} |
#endif |
/* |
* Free context |
*/ |
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
mbedtls_ecp_point_free( &ctx->Vi ); |
mbedtls_ecp_point_free( &ctx->Vf ); |
mbedtls_mpi_free( &ctx->_d ); |
ecdh_free_internal( ctx ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
ecdh_free_internal( &ctx->ctx.mbed_ecdh ); |
break; |
default: |
break; |
} |
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; |
ctx->var = MBEDTLS_ECDH_VARIANT_NONE; |
ctx->grp_id = MBEDTLS_ECP_DP_NONE; |
#endif |
} |
static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx, |
size_t *olen, int point_format, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, |
unsigned char *, |
size_t), |
void *p_rng, |
int restart_enabled ) |
{ |
int ret; |
size_t grp_len, pt_len; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_ecp_restart_ctx *rs_ctx = NULL; |
#endif |
if( ctx->grp.pbits == 0 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( restart_enabled ) |
rs_ctx = &ctx->rs; |
#else |
(void) restart_enabled; |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q, |
f_rng, p_rng, rs_ctx ) ) != 0 ) |
return( ret ); |
#else |
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, |
f_rng, p_rng ) ) != 0 ) |
return( ret ); |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, |
blen ) ) != 0 ) |
return( ret ); |
buf += grp_len; |
blen -= grp_len; |
if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, |
&pt_len, buf, blen ) ) != 0 ) |
return( ret ); |
*olen = grp_len + pt_len; |
return( 0 ); |
} |
/* |
* Setup and write the ServerKeyExhange parameters (RFC 4492) |
* struct { |
* ECParameters curve_params; |
* ECPoint public; |
* } ServerECDHParams; |
*/ |
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int restart_enabled = 0; |
ECDH_VALIDATE_RET( ctx != NULL ); |
ECDH_VALIDATE_RET( olen != NULL ); |
ECDH_VALIDATE_RET( buf != NULL ); |
ECDH_VALIDATE_RET( f_rng != NULL ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
restart_enabled = ctx->restart_enabled; |
#else |
(void) restart_enabled; |
#endif |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen, |
f_rng, p_rng, restart_enabled ) ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen, |
ctx->point_format, buf, blen, |
f_rng, p_rng, |
restart_enabled ) ); |
default: |
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
} |
#endif |
} |
static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx, |
const unsigned char **buf, |
const unsigned char *end ) |
{ |
return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, |
end - *buf ) ); |
} |
/* |
* Read the ServerKeyExhange parameters (RFC 4492) |
* struct { |
* ECParameters curve_params; |
* ECPoint public; |
* } ServerECDHParams; |
*/ |
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, |
const unsigned char **buf, |
const unsigned char *end ) |
{ |
int ret; |
mbedtls_ecp_group_id grp_id; |
ECDH_VALIDATE_RET( ctx != NULL ); |
ECDH_VALIDATE_RET( buf != NULL ); |
ECDH_VALIDATE_RET( *buf != NULL ); |
ECDH_VALIDATE_RET( end != NULL ); |
if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) ) |
!= 0 ) |
return( ret ); |
if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 ) |
return( ret ); |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_read_params_internal( ctx, buf, end ) ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh, |
buf, end ) ); |
default: |
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
} |
#endif |
} |
static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx, |
const mbedtls_ecp_keypair *key, |
mbedtls_ecdh_side side ) |
{ |
int ret; |
/* If it's not our key, just import the public part as Qp */ |
if( side == MBEDTLS_ECDH_THEIRS ) |
return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) ); |
/* Our key: import public (as Q) and private parts */ |
if( side != MBEDTLS_ECDH_OURS ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 || |
( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
/* |
* Get parameters from a keypair |
*/ |
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, |
const mbedtls_ecp_keypair *key, |
mbedtls_ecdh_side side ) |
{ |
int ret; |
ECDH_VALIDATE_RET( ctx != NULL ); |
ECDH_VALIDATE_RET( key != NULL ); |
ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS || |
side == MBEDTLS_ECDH_THEIRS ); |
if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE ) |
{ |
/* This is the first call to get_params(). Set up the context |
* for use with the group. */ |
if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) |
return( ret ); |
} |
else |
{ |
/* This is not the first call to get_params(). Check that the |
* current key's group is the same as the context's, which was set |
* from the first key's group. */ |
if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_get_params_internal( ctx, key, side ) ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh, |
key, side ) ); |
default: |
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
} |
#endif |
} |
static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx, |
size_t *olen, int point_format, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, |
unsigned char *, |
size_t), |
void *p_rng, |
int restart_enabled ) |
{ |
int ret; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_ecp_restart_ctx *rs_ctx = NULL; |
#endif |
if( ctx->grp.pbits == 0 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( restart_enabled ) |
rs_ctx = &ctx->rs; |
#else |
(void) restart_enabled; |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q, |
f_rng, p_rng, rs_ctx ) ) != 0 ) |
return( ret ); |
#else |
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, |
f_rng, p_rng ) ) != 0 ) |
return( ret ); |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen, |
buf, blen ); |
} |
/* |
* Setup and export the client public value |
*/ |
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int restart_enabled = 0; |
ECDH_VALIDATE_RET( ctx != NULL ); |
ECDH_VALIDATE_RET( olen != NULL ); |
ECDH_VALIDATE_RET( buf != NULL ); |
ECDH_VALIDATE_RET( f_rng != NULL ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
restart_enabled = ctx->restart_enabled; |
#endif |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen, |
f_rng, p_rng, restart_enabled ) ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen, |
ctx->point_format, buf, blen, |
f_rng, p_rng, |
restart_enabled ) ); |
default: |
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
} |
#endif |
} |
static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx, |
const unsigned char *buf, size_t blen ) |
{ |
int ret; |
const unsigned char *p = buf; |
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, |
blen ) ) != 0 ) |
return( ret ); |
if( (size_t)( p - buf ) != blen ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
return( 0 ); |
} |
/* |
* Parse and import the client's public value |
*/ |
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, |
const unsigned char *buf, size_t blen ) |
{ |
ECDH_VALIDATE_RET( ctx != NULL ); |
ECDH_VALIDATE_RET( buf != NULL ); |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_read_public_internal( ctx, buf, blen ) ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh, |
buf, blen ) ); |
default: |
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
} |
#endif |
} |
static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx, |
size_t *olen, unsigned char *buf, |
size_t blen, |
int (*f_rng)(void *, |
unsigned char *, |
size_t), |
void *p_rng, |
int restart_enabled ) |
{ |
int ret; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_ecp_restart_ctx *rs_ctx = NULL; |
#endif |
if( ctx == NULL || ctx->grp.pbits == 0 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( restart_enabled ) |
rs_ctx = &ctx->rs; |
#else |
(void) restart_enabled; |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp, |
&ctx->d, f_rng, p_rng, |
rs_ctx ) ) != 0 ) |
{ |
return( ret ); |
} |
#else |
if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, |
&ctx->d, f_rng, p_rng ) ) != 0 ) |
{ |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
if( mbedtls_mpi_size( &ctx->z ) > blen ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); |
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); |
} |
/* |
* Derive and export the shared secret |
*/ |
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, |
unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int restart_enabled = 0; |
ECDH_VALIDATE_RET( ctx != NULL ); |
ECDH_VALIDATE_RET( olen != NULL ); |
ECDH_VALIDATE_RET( buf != NULL ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
restart_enabled = ctx->restart_enabled; |
#endif |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng, |
restart_enabled ) ); |
#else |
switch( ctx->var ) |
{ |
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: |
return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf, |
blen, f_rng, p_rng, |
restart_enabled ) ); |
default: |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
#endif |
} |
#endif /* MBEDTLS_ECDH_C */ |
/programs/develop/libraries/kos_mbedtls/library/ecdsa.c |
---|
0,0 → 1,993 |
/* |
* Elliptic curve DSA |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* |
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
#include "mbedtls/ecdsa.h" |
#include "mbedtls/asn1write.h" |
#include <string.h> |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
#include "mbedtls/hmac_drbg.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/platform_util.h" |
/* Parameter validation macros based on platform_util.h */ |
#define ECDSA_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) |
#define ECDSA_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Sub-context for ecdsa_verify() |
*/ |
struct mbedtls_ecdsa_restart_ver |
{ |
mbedtls_mpi u1, u2; /* intermediate values */ |
enum { /* what to do next? */ |
ecdsa_ver_init = 0, /* getting started */ |
ecdsa_ver_muladd, /* muladd step */ |
} state; |
}; |
/* |
* Init verify restart sub-context |
*/ |
static void ecdsa_restart_ver_init( mbedtls_ecdsa_restart_ver_ctx *ctx ) |
{ |
mbedtls_mpi_init( &ctx->u1 ); |
mbedtls_mpi_init( &ctx->u2 ); |
ctx->state = ecdsa_ver_init; |
} |
/* |
* Free the components of a verify restart sub-context |
*/ |
static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_mpi_free( &ctx->u1 ); |
mbedtls_mpi_free( &ctx->u2 ); |
ecdsa_restart_ver_init( ctx ); |
} |
/* |
* Sub-context for ecdsa_sign() |
*/ |
struct mbedtls_ecdsa_restart_sig |
{ |
int sign_tries; |
int key_tries; |
mbedtls_mpi k; /* per-signature random */ |
mbedtls_mpi r; /* r value */ |
enum { /* what to do next? */ |
ecdsa_sig_init = 0, /* getting started */ |
ecdsa_sig_mul, /* doing ecp_mul() */ |
ecdsa_sig_modn, /* mod N computations */ |
} state; |
}; |
/* |
* Init verify sign sub-context |
*/ |
static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx ) |
{ |
ctx->sign_tries = 0; |
ctx->key_tries = 0; |
mbedtls_mpi_init( &ctx->k ); |
mbedtls_mpi_init( &ctx->r ); |
ctx->state = ecdsa_sig_init; |
} |
/* |
* Free the components of a sign restart sub-context |
*/ |
static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_mpi_free( &ctx->k ); |
mbedtls_mpi_free( &ctx->r ); |
} |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
/* |
* Sub-context for ecdsa_sign_det() |
*/ |
struct mbedtls_ecdsa_restart_det |
{ |
mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */ |
enum { /* what to do next? */ |
ecdsa_det_init = 0, /* getting started */ |
ecdsa_det_sign, /* make signature */ |
} state; |
}; |
/* |
* Init verify sign_det sub-context |
*/ |
static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx ) |
{ |
mbedtls_hmac_drbg_init( &ctx->rng_ctx ); |
ctx->state = ecdsa_det_init; |
} |
/* |
* Free the components of a sign_det restart sub-context |
*/ |
static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_hmac_drbg_free( &ctx->rng_ctx ); |
ecdsa_restart_det_init( ctx ); |
} |
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ |
#define ECDSA_RS_ECP ( rs_ctx == NULL ? NULL : &rs_ctx->ecp ) |
/* Utility macro for checking and updating ops budget */ |
#define ECDSA_BUDGET( ops ) \ |
MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) ); |
/* Call this when entering a function that needs its own sub-context */ |
#define ECDSA_RS_ENTER( SUB ) do { \ |
/* reset ops count for this call if top-level */ \ |
if( rs_ctx != NULL && rs_ctx->ecp.depth++ == 0 ) \ |
rs_ctx->ecp.ops_done = 0; \ |
\ |
/* set up our own sub-context if needed */ \ |
if( mbedtls_ecp_restart_is_enabled() && \ |
rs_ctx != NULL && rs_ctx->SUB == NULL ) \ |
{ \ |
rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ |
if( rs_ctx->SUB == NULL ) \ |
return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ |
\ |
ecdsa_restart_## SUB ##_init( rs_ctx->SUB ); \ |
} \ |
} while( 0 ) |
/* Call this when leaving a function that needs its own sub-context */ |
#define ECDSA_RS_LEAVE( SUB ) do { \ |
/* clear our sub-context when not in progress (done or error) */ \ |
if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ |
ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ |
{ \ |
ecdsa_restart_## SUB ##_free( rs_ctx->SUB ); \ |
mbedtls_free( rs_ctx->SUB ); \ |
rs_ctx->SUB = NULL; \ |
} \ |
\ |
if( rs_ctx != NULL ) \ |
rs_ctx->ecp.depth--; \ |
} while( 0 ) |
#else /* MBEDTLS_ECP_RESTARTABLE */ |
#define ECDSA_RS_ECP NULL |
#define ECDSA_BUDGET( ops ) /* no-op; for compatibility */ |
#define ECDSA_RS_ENTER( SUB ) (void) rs_ctx |
#define ECDSA_RS_LEAVE( SUB ) (void) rs_ctx |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/* |
* Derive a suitable integer for group grp from a buffer of length len |
* SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 |
*/ |
static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x, |
const unsigned char *buf, size_t blen ) |
{ |
int ret; |
size_t n_size = ( grp->nbits + 7 ) / 8; |
size_t use_size = blen > n_size ? n_size : blen; |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) ); |
if( use_size * 8 > grp->nbits ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) ); |
/* While at it, reduce modulo N */ |
if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) ); |
cleanup: |
return( ret ); |
} |
#if !defined(MBEDTLS_ECDSA_SIGN_ALT) |
/* |
* Compute ECDSA signature of a hashed message (SEC1 4.1.3) |
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) |
*/ |
static int ecdsa_sign_restartable( mbedtls_ecp_group *grp, |
mbedtls_mpi *r, mbedtls_mpi *s, |
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
int (*f_rng_blind)(void *, unsigned char *, size_t), |
void *p_rng_blind, |
mbedtls_ecdsa_restart_ctx *rs_ctx ) |
{ |
int ret, key_tries, sign_tries; |
int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries; |
mbedtls_ecp_point R; |
mbedtls_mpi k, e, t; |
mbedtls_mpi *pk = &k, *pr = r; |
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ |
if( grp->N.p == NULL ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* Make sure d is in range 1..n-1 */ |
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
mbedtls_ecp_point_init( &R ); |
mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); |
ECDSA_RS_ENTER( sig ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->sig != NULL ) |
{ |
/* redirect to our context */ |
p_sign_tries = &rs_ctx->sig->sign_tries; |
p_key_tries = &rs_ctx->sig->key_tries; |
pk = &rs_ctx->sig->k; |
pr = &rs_ctx->sig->r; |
/* jump to current step */ |
if( rs_ctx->sig->state == ecdsa_sig_mul ) |
goto mul; |
if( rs_ctx->sig->state == ecdsa_sig_modn ) |
goto modn; |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
*p_sign_tries = 0; |
do |
{ |
if( (*p_sign_tries)++ > 10 ) |
{ |
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; |
goto cleanup; |
} |
/* |
* Steps 1-3: generate a suitable ephemeral keypair |
* and set r = xR mod n |
*/ |
*p_key_tries = 0; |
do |
{ |
if( (*p_key_tries)++ > 10 ) |
{ |
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->sig != NULL ) |
rs_ctx->sig->state = ecdsa_sig_mul; |
mul: |
#endif |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G, |
f_rng_blind, |
p_rng_blind, |
ECDSA_RS_ECP ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) ); |
} |
while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->sig != NULL ) |
rs_ctx->sig->state = ecdsa_sig_modn; |
modn: |
#endif |
/* |
* Accounting for everything up to the end of the loop |
* (step 6, but checking now avoids saving e and t) |
*/ |
ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 ); |
/* |
* Step 5: derive MPI from hashed message |
*/ |
MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); |
/* |
* Generate a random value to blind inv_mod in next step, |
* avoiding a potential timing leak. |
*/ |
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng_blind, |
p_rng_blind ) ); |
/* |
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); |
} |
while( mbedtls_mpi_cmp_int( s, 0 ) == 0 ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->sig != NULL ) |
mbedtls_mpi_copy( r, pr ); |
#endif |
cleanup: |
mbedtls_ecp_point_free( &R ); |
mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t ); |
ECDSA_RS_LEAVE( sig ); |
return( ret ); |
} |
/* |
* Compute ECDSA signature of a hashed message |
*/ |
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, |
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
ECDSA_VALIDATE_RET( grp != NULL ); |
ECDSA_VALIDATE_RET( r != NULL ); |
ECDSA_VALIDATE_RET( s != NULL ); |
ECDSA_VALIDATE_RET( d != NULL ); |
ECDSA_VALIDATE_RET( f_rng != NULL ); |
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); |
/* Use the same RNG for both blinding and ephemeral key generation */ |
return( ecdsa_sign_restartable( grp, r, s, d, buf, blen, |
f_rng, p_rng, f_rng, p_rng, NULL ) ); |
} |
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
/* |
* Deterministic signature wrapper |
*/ |
static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp, |
mbedtls_mpi *r, mbedtls_mpi *s, |
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, |
mbedtls_md_type_t md_alg, |
int (*f_rng_blind)(void *, unsigned char *, size_t), |
void *p_rng_blind, |
mbedtls_ecdsa_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_hmac_drbg_context rng_ctx; |
mbedtls_hmac_drbg_context *p_rng = &rng_ctx; |
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; |
size_t grp_len = ( grp->nbits + 7 ) / 8; |
const mbedtls_md_info_t *md_info; |
mbedtls_mpi h; |
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
mbedtls_mpi_init( &h ); |
mbedtls_hmac_drbg_init( &rng_ctx ); |
ECDSA_RS_ENTER( det ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->det != NULL ) |
{ |
/* redirect to our context */ |
p_rng = &rs_ctx->det->rng_ctx; |
/* jump to current step */ |
if( rs_ctx->det->state == ecdsa_det_sign ) |
goto sign; |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/* Use private key and message hash (reduced) to initialize HMAC_DRBG */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); |
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); |
mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->det != NULL ) |
rs_ctx->det->state = ecdsa_det_sign; |
sign: |
#endif |
#if defined(MBEDTLS_ECDSA_SIGN_ALT) |
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, |
mbedtls_hmac_drbg_random, p_rng ); |
#else |
if( f_rng_blind != NULL ) |
ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, |
mbedtls_hmac_drbg_random, p_rng, |
f_rng_blind, p_rng_blind, rs_ctx ); |
else |
{ |
mbedtls_hmac_drbg_context *p_rng_blind_det; |
#if !defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* To avoid reusing rng_ctx and risking incorrect behavior we seed a |
* second HMAC-DRBG with the same seed. We also apply a label to avoid |
* reusing the bits of the ephemeral key for blinding and eliminate the |
* risk that they leak this way. |
*/ |
const char* blind_label = "BLINDING CONTEXT"; |
mbedtls_hmac_drbg_context rng_ctx_blind; |
mbedtls_hmac_drbg_init( &rng_ctx_blind ); |
p_rng_blind_det = &rng_ctx_blind; |
mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info, |
data, 2 * grp_len ); |
ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det, |
(const unsigned char*) blind_label, |
strlen( blind_label ) ); |
if( ret != 0 ) |
{ |
mbedtls_hmac_drbg_free( &rng_ctx_blind ); |
goto cleanup; |
} |
#else |
/* |
* In the case of restartable computations we would either need to store |
* the second RNG in the restart context too or set it up at every |
* restart. The first option would penalize the correct application of |
* the function and the second would defeat the purpose of the |
* restartable feature. |
* |
* Therefore in this case we reuse the original RNG. This comes with the |
* price that the resulting signature might not be a valid deterministic |
* ECDSA signature with a very low probability (same magnitude as |
* successfully guessing the private key). However even then it is still |
* a valid ECDSA signature. |
*/ |
p_rng_blind_det = p_rng; |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/* |
* Since the output of the RNGs is always the same for the same key and |
* message, this limits the efficiency of blinding and leaks information |
* through side channels. After mbedtls_ecdsa_sign_det() is removed NULL |
* won't be a valid value for f_rng_blind anymore. Therefore it should |
* be checked by the caller and this branch and check can be removed. |
*/ |
ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, |
mbedtls_hmac_drbg_random, p_rng, |
mbedtls_hmac_drbg_random, p_rng_blind_det, |
rs_ctx ); |
#if !defined(MBEDTLS_ECP_RESTARTABLE) |
mbedtls_hmac_drbg_free( &rng_ctx_blind ); |
#endif |
} |
#endif /* MBEDTLS_ECDSA_SIGN_ALT */ |
cleanup: |
mbedtls_hmac_drbg_free( &rng_ctx ); |
mbedtls_mpi_free( &h ); |
ECDSA_RS_LEAVE( det ); |
return( ret ); |
} |
/* |
* Deterministic signature wrappers |
*/ |
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, |
mbedtls_mpi *s, const mbedtls_mpi *d, |
const unsigned char *buf, size_t blen, |
mbedtls_md_type_t md_alg ) |
{ |
ECDSA_VALIDATE_RET( grp != NULL ); |
ECDSA_VALIDATE_RET( r != NULL ); |
ECDSA_VALIDATE_RET( s != NULL ); |
ECDSA_VALIDATE_RET( d != NULL ); |
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); |
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, |
NULL, NULL, NULL ) ); |
} |
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, |
mbedtls_mpi *s, const mbedtls_mpi *d, |
const unsigned char *buf, size_t blen, |
mbedtls_md_type_t md_alg, |
int (*f_rng_blind)(void *, unsigned char *, |
size_t), |
void *p_rng_blind ) |
{ |
ECDSA_VALIDATE_RET( grp != NULL ); |
ECDSA_VALIDATE_RET( r != NULL ); |
ECDSA_VALIDATE_RET( s != NULL ); |
ECDSA_VALIDATE_RET( d != NULL ); |
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); |
ECDSA_VALIDATE_RET( f_rng_blind != NULL ); |
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, |
f_rng_blind, p_rng_blind, NULL ) ); |
} |
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ |
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) |
/* |
* Verify ECDSA signature of hashed message (SEC1 4.1.4) |
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) |
*/ |
static int ecdsa_verify_restartable( mbedtls_ecp_group *grp, |
const unsigned char *buf, size_t blen, |
const mbedtls_ecp_point *Q, |
const mbedtls_mpi *r, const mbedtls_mpi *s, |
mbedtls_ecdsa_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_mpi e, s_inv, u1, u2; |
mbedtls_ecp_point R; |
mbedtls_mpi *pu1 = &u1, *pu2 = &u2; |
mbedtls_ecp_point_init( &R ); |
mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); |
mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 ); |
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ |
if( grp->N.p == NULL ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
ECDSA_RS_ENTER( ver ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ver != NULL ) |
{ |
/* redirect to our context */ |
pu1 = &rs_ctx->ver->u1; |
pu2 = &rs_ctx->ver->u2; |
/* jump to current step */ |
if( rs_ctx->ver->state == ecdsa_ver_muladd ) |
goto muladd; |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
/* |
* Step 1: make sure r and s are in range 1..n-1 |
*/ |
if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 || |
mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 ) |
{ |
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; |
goto cleanup; |
} |
/* |
* Step 3: derive MPI from hashed message |
*/ |
MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); |
/* |
* Step 4: u1 = e / s mod n, u2 = r / s mod n |
*/ |
ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ver != NULL ) |
rs_ctx->ver->state = ecdsa_ver_muladd; |
muladd: |
#endif |
/* |
* Step 5: R = u1 G + u2 Q |
*/ |
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp, |
&R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) ); |
if( mbedtls_ecp_is_zero( &R ) ) |
{ |
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; |
goto cleanup; |
} |
/* |
* Step 6: convert xR to an integer (no-op) |
* Step 7: reduce xR mod n (gives v) |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); |
/* |
* Step 8: check if v (that is, R.X) is equal to r |
*/ |
if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 ) |
{ |
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; |
goto cleanup; |
} |
cleanup: |
mbedtls_ecp_point_free( &R ); |
mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); |
mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 ); |
ECDSA_RS_LEAVE( ver ); |
return( ret ); |
} |
/* |
* Verify ECDSA signature of hashed message |
*/ |
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, |
const unsigned char *buf, size_t blen, |
const mbedtls_ecp_point *Q, |
const mbedtls_mpi *r, |
const mbedtls_mpi *s) |
{ |
ECDSA_VALIDATE_RET( grp != NULL ); |
ECDSA_VALIDATE_RET( Q != NULL ); |
ECDSA_VALIDATE_RET( r != NULL ); |
ECDSA_VALIDATE_RET( s != NULL ); |
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 ); |
return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) ); |
} |
#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ |
/* |
* Convert a signature (given by context) to ASN.1 |
*/ |
static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, |
unsigned char *sig, size_t *slen ) |
{ |
int ret; |
unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; |
unsigned char *p = buf + sizeof( buf ); |
size_t len = 0; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); |
memcpy( sig, p, len ); |
*slen = len; |
return( 0 ); |
} |
/* |
* Compute and write signature |
*/ |
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hlen, |
unsigned char *sig, size_t *slen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecdsa_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_mpi r, s; |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( hash != NULL ); |
ECDSA_VALIDATE_RET( sig != NULL ); |
ECDSA_VALIDATE_RET( slen != NULL ); |
mbedtls_mpi_init( &r ); |
mbedtls_mpi_init( &s ); |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d, |
hash, hlen, md_alg, f_rng, |
p_rng, rs_ctx ) ); |
#else |
(void) md_alg; |
#if defined(MBEDTLS_ECDSA_SIGN_ALT) |
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d, |
hash, hlen, f_rng, p_rng ) ); |
#else |
/* Use the same RNG for both blinding and ephemeral key generation */ |
MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d, |
hash, hlen, f_rng, p_rng, f_rng, |
p_rng, rs_ctx ) ); |
#endif /* MBEDTLS_ECDSA_SIGN_ALT */ |
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ |
MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) ); |
cleanup: |
mbedtls_mpi_free( &r ); |
mbedtls_mpi_free( &s ); |
return( ret ); |
} |
/* |
* Compute and write signature |
*/ |
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hlen, |
unsigned char *sig, size_t *slen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( hash != NULL ); |
ECDSA_VALIDATE_RET( sig != NULL ); |
ECDSA_VALIDATE_RET( slen != NULL ); |
return( mbedtls_ecdsa_write_signature_restartable( |
ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) && \ |
defined(MBEDTLS_ECDSA_DETERMINISTIC) |
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, |
const unsigned char *hash, size_t hlen, |
unsigned char *sig, size_t *slen, |
mbedtls_md_type_t md_alg ) |
{ |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( hash != NULL ); |
ECDSA_VALIDATE_RET( sig != NULL ); |
ECDSA_VALIDATE_RET( slen != NULL ); |
return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen, |
NULL, NULL ) ); |
} |
#endif |
/* |
* Read and check signature |
*/ |
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, |
const unsigned char *hash, size_t hlen, |
const unsigned char *sig, size_t slen ) |
{ |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( hash != NULL ); |
ECDSA_VALIDATE_RET( sig != NULL ); |
return( mbedtls_ecdsa_read_signature_restartable( |
ctx, hash, hlen, sig, slen, NULL ) ); |
} |
/* |
* Restartable read and check signature |
*/ |
int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, |
const unsigned char *hash, size_t hlen, |
const unsigned char *sig, size_t slen, |
mbedtls_ecdsa_restart_ctx *rs_ctx ) |
{ |
int ret; |
unsigned char *p = (unsigned char *) sig; |
const unsigned char *end = sig + slen; |
size_t len; |
mbedtls_mpi r, s; |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( hash != NULL ); |
ECDSA_VALIDATE_RET( sig != NULL ); |
mbedtls_mpi_init( &r ); |
mbedtls_mpi_init( &s ); |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
if( p + len != end ) |
{ |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; |
goto cleanup; |
} |
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 || |
( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 ) |
{ |
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
#if defined(MBEDTLS_ECDSA_VERIFY_ALT) |
if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen, |
&ctx->Q, &r, &s ) ) != 0 ) |
goto cleanup; |
#else |
if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen, |
&ctx->Q, &r, &s, rs_ctx ) ) != 0 ) |
goto cleanup; |
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ |
/* At this point we know that the buffer starts with a valid signature. |
* Return 0 if the buffer just contains the signature, and a specific |
* error code if the valid signature is followed by more data. */ |
if( p != end ) |
ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; |
cleanup: |
mbedtls_mpi_free( &r ); |
mbedtls_mpi_free( &s ); |
return( ret ); |
} |
#if !defined(MBEDTLS_ECDSA_GENKEY_ALT) |
/* |
* Generate key pair |
*/ |
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret = 0; |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( f_rng != NULL ); |
ret = mbedtls_ecp_group_load( &ctx->grp, gid ); |
if( ret != 0 ) |
return( ret ); |
return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, |
&ctx->Q, f_rng, p_rng ) ); |
} |
#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */ |
/* |
* Set context from an mbedtls_ecp_keypair |
*/ |
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) |
{ |
int ret; |
ECDSA_VALIDATE_RET( ctx != NULL ); |
ECDSA_VALIDATE_RET( key != NULL ); |
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || |
( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || |
( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) |
{ |
mbedtls_ecdsa_free( ctx ); |
} |
return( ret ); |
} |
/* |
* Initialize context |
*/ |
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ) |
{ |
ECDSA_VALIDATE( ctx != NULL ); |
mbedtls_ecp_keypair_init( ctx ); |
} |
/* |
* Free context |
*/ |
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_ecp_keypair_free( ctx ); |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Initialize a restart context |
*/ |
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ) |
{ |
ECDSA_VALIDATE( ctx != NULL ); |
mbedtls_ecp_restart_init( &ctx->ecp ); |
ctx->ver = NULL; |
ctx->sig = NULL; |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
ctx->det = NULL; |
#endif |
} |
/* |
* Free the components of a restart context |
*/ |
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_ecp_restart_free( &ctx->ecp ); |
ecdsa_restart_ver_free( ctx->ver ); |
mbedtls_free( ctx->ver ); |
ctx->ver = NULL; |
ecdsa_restart_sig_free( ctx->sig ); |
mbedtls_free( ctx->sig ); |
ctx->sig = NULL; |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
ecdsa_restart_det_free( ctx->det ); |
mbedtls_free( ctx->det ); |
ctx->det = NULL; |
#endif |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#endif /* MBEDTLS_ECDSA_C */ |
/programs/develop/libraries/kos_mbedtls/library/ecjpake.c |
---|
0,0 → 1,1142 |
/* |
* Elliptic curve J-PAKE |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References in the code are to the Thread v1.0 Specification, |
* available to members of the Thread Group http://threadgroup.org/ |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ECJPAKE_C) |
#include "mbedtls/ecjpake.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if !defined(MBEDTLS_ECJPAKE_ALT) |
/* Parameter validation macros based on platform_util.h */ |
#define ECJPAKE_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) |
#define ECJPAKE_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* Convert a mbedtls_ecjpake_role to identifier string |
*/ |
static const char * const ecjpake_id[] = { |
"client", |
"server" |
}; |
#define ID_MINE ( ecjpake_id[ ctx->role ] ) |
#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] ) |
/* |
* Initialize context |
*/ |
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ) |
{ |
ECJPAKE_VALIDATE( ctx != NULL ); |
ctx->md_info = NULL; |
mbedtls_ecp_group_init( &ctx->grp ); |
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; |
mbedtls_ecp_point_init( &ctx->Xm1 ); |
mbedtls_ecp_point_init( &ctx->Xm2 ); |
mbedtls_ecp_point_init( &ctx->Xp1 ); |
mbedtls_ecp_point_init( &ctx->Xp2 ); |
mbedtls_ecp_point_init( &ctx->Xp ); |
mbedtls_mpi_init( &ctx->xm1 ); |
mbedtls_mpi_init( &ctx->xm2 ); |
mbedtls_mpi_init( &ctx->s ); |
} |
/* |
* Free context |
*/ |
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
ctx->md_info = NULL; |
mbedtls_ecp_group_free( &ctx->grp ); |
mbedtls_ecp_point_free( &ctx->Xm1 ); |
mbedtls_ecp_point_free( &ctx->Xm2 ); |
mbedtls_ecp_point_free( &ctx->Xp1 ); |
mbedtls_ecp_point_free( &ctx->Xp2 ); |
mbedtls_ecp_point_free( &ctx->Xp ); |
mbedtls_mpi_free( &ctx->xm1 ); |
mbedtls_mpi_free( &ctx->xm2 ); |
mbedtls_mpi_free( &ctx->s ); |
} |
/* |
* Setup context |
*/ |
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, |
mbedtls_ecjpake_role role, |
mbedtls_md_type_t hash, |
mbedtls_ecp_group_id curve, |
const unsigned char *secret, |
size_t len ) |
{ |
int ret; |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT || |
role == MBEDTLS_ECJPAKE_SERVER ); |
ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 ); |
ctx->role = role; |
if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL ) |
return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) ); |
cleanup: |
if( ret != 0 ) |
mbedtls_ecjpake_free( ctx ); |
return( ret ); |
} |
/* |
* Check if context is ready for use |
*/ |
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ) |
{ |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
if( ctx->md_info == NULL || |
ctx->grp.id == MBEDTLS_ECP_DP_NONE || |
ctx->s.p == NULL ) |
{ |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
return( 0 ); |
} |
/* |
* Write a point plus its length to a buffer |
*/ |
static int ecjpake_write_len_point( unsigned char **p, |
const unsigned char *end, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *P ) |
{ |
int ret; |
size_t len; |
/* Need at least 4 for length plus 1 for point */ |
if( end < *p || end - *p < 5 ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
ret = mbedtls_ecp_point_write_binary( grp, P, pf, |
&len, *p + 4, end - ( *p + 4 ) ); |
if( ret != 0 ) |
return( ret ); |
(*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF ); |
(*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF ); |
(*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF ); |
(*p)[3] = (unsigned char)( ( len ) & 0xFF ); |
*p += 4 + len; |
return( 0 ); |
} |
/* |
* Size of the temporary buffer for ecjpake_hash: |
* 3 EC points plus their length, plus ID and its length (4 + 6 bytes) |
*/ |
#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 ) |
/* |
* Compute hash for ZKP (7.4.2.2.2.1) |
*/ |
static int ecjpake_hash( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
const mbedtls_ecp_point *V, |
const mbedtls_ecp_point *X, |
const char *id, |
mbedtls_mpi *h ) |
{ |
int ret; |
unsigned char buf[ECJPAKE_HASH_BUF_LEN]; |
unsigned char *p = buf; |
const unsigned char *end = buf + sizeof( buf ); |
const size_t id_len = strlen( id ); |
unsigned char hash[MBEDTLS_MD_MAX_SIZE]; |
/* Write things to temporary buffer */ |
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) ); |
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) ); |
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) ); |
if( end - p < 4 ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
*p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF ); |
*p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF ); |
*p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( id_len ) & 0xFF ); |
if( end < p || (size_t)( end - p ) < id_len ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
memcpy( p, id, id_len ); |
p += id_len; |
/* Compute hash */ |
MBEDTLS_MPI_CHK( mbedtls_md( md_info, buf, p - buf, hash ) ); |
/* Turn it into an integer mod n */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash, |
mbedtls_md_get_size( md_info ) ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) |
*/ |
static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
const mbedtls_ecp_point *X, |
const char *id, |
const unsigned char **p, |
const unsigned char *end ) |
{ |
int ret; |
mbedtls_ecp_point V, VV; |
mbedtls_mpi r, h; |
size_t r_len; |
mbedtls_ecp_point_init( &V ); |
mbedtls_ecp_point_init( &VV ); |
mbedtls_mpi_init( &r ); |
mbedtls_mpi_init( &h ); |
/* |
* struct { |
* ECPoint V; |
* opaque r<1..2^8-1>; |
* } ECSchnorrZKP; |
*/ |
if( end < *p ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) ); |
if( end < *p || (size_t)( end - *p ) < 1 ) |
{ |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
r_len = *(*p)++; |
if( end < *p || (size_t)( end - *p ) < r_len ) |
{ |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) ); |
*p += r_len; |
/* |
* Verification |
*/ |
MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp, |
&VV, &h, X, &r, G ) ); |
if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 ) |
{ |
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; |
goto cleanup; |
} |
cleanup: |
mbedtls_ecp_point_free( &V ); |
mbedtls_ecp_point_free( &VV ); |
mbedtls_mpi_free( &r ); |
mbedtls_mpi_free( &h ); |
return( ret ); |
} |
/* |
* Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) |
*/ |
static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
const mbedtls_mpi *x, |
const mbedtls_ecp_point *X, |
const char *id, |
unsigned char **p, |
const unsigned char *end, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
mbedtls_ecp_point V; |
mbedtls_mpi v; |
mbedtls_mpi h; /* later recycled to hold r */ |
size_t len; |
if( end < *p ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
mbedtls_ecp_point_init( &V ); |
mbedtls_mpi_init( &v ); |
mbedtls_mpi_init( &h ); |
/* Compute signature */ |
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, |
G, &v, &V, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */ |
/* Write it out */ |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V, |
pf, &len, *p, end - *p ) ); |
*p += len; |
len = mbedtls_mpi_size( &h ); /* actually r */ |
if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 ) |
{ |
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; |
goto cleanup; |
} |
*(*p)++ = (unsigned char)( len & 0xFF ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */ |
*p += len; |
cleanup: |
mbedtls_ecp_point_free( &V ); |
mbedtls_mpi_free( &v ); |
mbedtls_mpi_free( &h ); |
return( ret ); |
} |
/* |
* Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof |
* Output: verified public key X |
*/ |
static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
mbedtls_ecp_point *X, |
const char *id, |
const unsigned char **p, |
const unsigned char *end ) |
{ |
int ret; |
if( end < *p ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* |
* struct { |
* ECPoint X; |
* ECSchnorrZKP zkp; |
* } ECJPAKEKeyKP; |
*/ |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) ); |
if( mbedtls_ecp_is_zero( X ) ) |
{ |
ret = MBEDTLS_ERR_ECP_INVALID_KEY; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Generate an ECJPAKEKeyKP |
* Output: the serialized structure, plus private/public key pair |
*/ |
static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
mbedtls_mpi *x, |
mbedtls_ecp_point *X, |
const char *id, |
unsigned char **p, |
const unsigned char *end, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
size_t len; |
if( end < *p ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
/* Generate key (7.4.2.3.1) and write it out */ |
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X, |
f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X, |
pf, &len, *p, end - *p ) ); |
*p += len; |
/* Generate and write proof */ |
MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id, |
p, end, f_rng, p_rng ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs |
* Ouputs: verified peer public keys Xa, Xb |
*/ |
static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
mbedtls_ecp_point *Xa, |
mbedtls_ecp_point *Xb, |
const char *id, |
const unsigned char *buf, |
size_t len ) |
{ |
int ret; |
const unsigned char *p = buf; |
const unsigned char *end = buf + len; |
/* |
* struct { |
* ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; |
* } ECJPAKEKeyKPPairList; |
*/ |
MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) ); |
MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) ); |
if( p != end ) |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
cleanup: |
return( ret ); |
} |
/* |
* Generate a ECJPAKEKeyKPPairList |
* Outputs: the serialized structure, plus two private/public key pairs |
*/ |
static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info, |
const mbedtls_ecp_group *grp, |
const int pf, |
const mbedtls_ecp_point *G, |
mbedtls_mpi *xm1, |
mbedtls_ecp_point *Xa, |
mbedtls_mpi *xm2, |
mbedtls_ecp_point *Xb, |
const char *id, |
unsigned char *buf, |
size_t len, |
size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
unsigned char *p = buf; |
const unsigned char *end = buf + len; |
MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id, |
&p, end, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id, |
&p, end, f_rng, p_rng ) ); |
*olen = p - buf; |
cleanup: |
return( ret ); |
} |
/* |
* Read and process the first round message |
*/ |
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, |
const unsigned char *buf, |
size_t len ) |
{ |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
ECJPAKE_VALIDATE_RET( buf != NULL ); |
return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format, |
&ctx->grp.G, |
&ctx->Xp1, &ctx->Xp2, ID_PEER, |
buf, len ) ); |
} |
/* |
* Generate and write the first round message |
*/ |
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, |
unsigned char *buf, size_t len, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
ECJPAKE_VALIDATE_RET( buf != NULL ); |
ECJPAKE_VALIDATE_RET( olen != NULL ); |
ECJPAKE_VALIDATE_RET( f_rng != NULL ); |
return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format, |
&ctx->grp.G, |
&ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, |
ID_MINE, buf, len, olen, f_rng, p_rng ) ); |
} |
/* |
* Compute the sum of three points R = A + B + C |
*/ |
static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_ecp_point *A, |
const mbedtls_ecp_point *B, |
const mbedtls_ecp_point *C ) |
{ |
int ret; |
mbedtls_mpi one; |
mbedtls_mpi_init( &one ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) ); |
cleanup: |
mbedtls_mpi_free( &one ); |
return( ret ); |
} |
/* |
* Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) |
*/ |
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, |
const unsigned char *buf, |
size_t len ) |
{ |
int ret; |
const unsigned char *p = buf; |
const unsigned char *end = buf + len; |
mbedtls_ecp_group grp; |
mbedtls_ecp_point G; /* C: GB, S: GA */ |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
ECJPAKE_VALIDATE_RET( buf != NULL ); |
mbedtls_ecp_group_init( &grp ); |
mbedtls_ecp_point_init( &G ); |
/* |
* Server: GA = X3 + X4 + X1 (7.4.2.6.1) |
* Client: GB = X1 + X2 + X3 (7.4.2.5.1) |
* Unified: G = Xm1 + Xm2 + Xp1 |
* We need that before parsing in order to check Xp as we read it |
*/ |
MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, |
&ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) ); |
/* |
* struct { |
* ECParameters curve_params; // only client reading server msg |
* ECJPAKEKeyKP ecjpake_key_kp; |
* } Client/ServerECJPAKEParams; |
*/ |
if( ctx->role == MBEDTLS_ECJPAKE_CLIENT ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) ); |
if( grp.id != ctx->grp.id ) |
{ |
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; |
goto cleanup; |
} |
} |
MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp, |
ctx->point_format, |
&G, &ctx->Xp, ID_PEER, &p, end ) ); |
if( p != end ) |
{ |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
cleanup: |
mbedtls_ecp_group_free( &grp ); |
mbedtls_ecp_point_free( &G ); |
return( ret ); |
} |
/* |
* Compute R = +/- X * S mod N, taking care not to leak S |
*/ |
static int ecjpake_mul_secret( mbedtls_mpi *R, int sign, |
const mbedtls_mpi *X, |
const mbedtls_mpi *S, |
const mbedtls_mpi *N, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
mbedtls_mpi b; /* Blinding value, then s + N * blinding */ |
mbedtls_mpi_init( &b ); |
/* b = s + rnd-128-bit * N */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) ); |
/* R = sign * X * b mod N */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) ); |
R->s *= sign; |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) ); |
cleanup: |
mbedtls_mpi_free( &b ); |
return( ret ); |
} |
/* |
* Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) |
*/ |
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, |
unsigned char *buf, size_t len, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
mbedtls_ecp_point G; /* C: GA, S: GB */ |
mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ |
mbedtls_mpi xm; /* C: xc, S: xs */ |
unsigned char *p = buf; |
const unsigned char *end = buf + len; |
size_t ec_len; |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
ECJPAKE_VALIDATE_RET( buf != NULL ); |
ECJPAKE_VALIDATE_RET( olen != NULL ); |
ECJPAKE_VALIDATE_RET( f_rng != NULL ); |
mbedtls_ecp_point_init( &G ); |
mbedtls_ecp_point_init( &Xm ); |
mbedtls_mpi_init( &xm ); |
/* |
* First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) |
* |
* Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA |
* Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB |
* Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G |
*/ |
MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, |
&ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) ); |
MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s, |
&ctx->grp.N, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) ); |
/* |
* Now write things out |
* |
* struct { |
* ECParameters curve_params; // only server writing its message |
* ECJPAKEKeyKP ecjpake_key_kp; |
* } Client/ServerECJPAKEParams; |
*/ |
if( ctx->role == MBEDTLS_ECJPAKE_SERVER ) |
{ |
if( end < p ) |
{ |
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len, |
p, end - p ) ); |
p += ec_len; |
} |
if( end < p ) |
{ |
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm, |
ctx->point_format, &ec_len, p, end - p ) ); |
p += ec_len; |
MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp, |
ctx->point_format, |
&G, &xm, &Xm, ID_MINE, |
&p, end, f_rng, p_rng ) ); |
*olen = p - buf; |
cleanup: |
mbedtls_ecp_point_free( &G ); |
mbedtls_ecp_point_free( &Xm ); |
mbedtls_mpi_free( &xm ); |
return( ret ); |
} |
/* |
* Derive PMS (7.4.2.7 / 7.4.2.8) |
*/ |
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, |
unsigned char *buf, size_t len, size_t *olen, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
mbedtls_ecp_point K; |
mbedtls_mpi m_xm2_s, one; |
unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; |
size_t x_bytes; |
ECJPAKE_VALIDATE_RET( ctx != NULL ); |
ECJPAKE_VALIDATE_RET( buf != NULL ); |
ECJPAKE_VALIDATE_RET( olen != NULL ); |
ECJPAKE_VALIDATE_RET( f_rng != NULL ); |
*olen = mbedtls_md_get_size( ctx->md_info ); |
if( len < *olen ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
mbedtls_ecp_point_init( &K ); |
mbedtls_mpi_init( &m_xm2_s ); |
mbedtls_mpi_init( &one ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); |
/* |
* Client: K = ( Xs - X4 * x2 * s ) * x2 |
* Server: K = ( Xc - X2 * x4 * s ) * x4 |
* Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 |
*/ |
MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, |
&ctx->grp.N, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, |
&one, &ctx->Xp, |
&m_xm2_s, &ctx->Xp2 ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, |
f_rng, p_rng ) ); |
/* PMS = SHA-256( K.X ) */ |
x_bytes = ( ctx->grp.pbits + 7 ) / 8; |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) ); |
MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) ); |
cleanup: |
mbedtls_ecp_point_free( &K ); |
mbedtls_mpi_free( &m_xm2_s ); |
mbedtls_mpi_free( &one ); |
return( ret ); |
} |
#undef ID_MINE |
#undef ID_PEER |
#endif /* ! MBEDTLS_ECJPAKE_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif |
#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ |
!defined(MBEDTLS_SHA256_C) |
int mbedtls_ecjpake_self_test( int verbose ) |
{ |
(void) verbose; |
return( 0 ); |
} |
#else |
static const unsigned char ecjpake_test_password[] = { |
0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, |
0x65, 0x73, 0x74 |
}; |
static const unsigned char ecjpake_test_x1[] = { |
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, |
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, |
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 |
}; |
static const unsigned char ecjpake_test_x2[] = { |
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, |
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 |
}; |
static const unsigned char ecjpake_test_x3[] = { |
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, |
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 |
}; |
static const unsigned char ecjpake_test_x4[] = { |
0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, |
0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, |
0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 |
}; |
static const unsigned char ecjpake_test_cli_one[] = { |
0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, |
0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, |
0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, |
0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, |
0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, |
0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, |
0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, |
0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, |
0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, |
0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, |
0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, |
0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, |
0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, |
0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, |
0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, |
0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, |
0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, |
0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, |
0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, |
0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, |
0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, |
0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, |
0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, |
0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, |
0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, |
0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, |
0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, |
0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 |
}; |
static const unsigned char ecjpake_test_srv_one[] = { |
0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, |
0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, |
0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, |
0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, |
0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, |
0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, |
0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, |
0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, |
0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, |
0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, |
0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, |
0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, |
0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, |
0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, |
0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, |
0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, |
0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, |
0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, |
0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, |
0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, |
0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, |
0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, |
0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, |
0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, |
0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, |
0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, |
0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, |
0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 |
}; |
static const unsigned char ecjpake_test_srv_two[] = { |
0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, |
0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, |
0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, |
0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, |
0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, |
0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, |
0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, |
0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, |
0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, |
0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, |
0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, |
0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, |
0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, |
0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c |
}; |
static const unsigned char ecjpake_test_cli_two[] = { |
0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, |
0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, |
0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, |
0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, |
0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, |
0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, |
0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, |
0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, |
0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, |
0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, |
0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, |
0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, |
0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, |
0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c |
}; |
static const unsigned char ecjpake_test_pms[] = { |
0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, |
0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, |
0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 |
}; |
/* Load my private keys and generate the corresponding public keys */ |
static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, |
const unsigned char *xm1, size_t len1, |
const unsigned char *xm2, size_t len2 ) |
{ |
int ret; |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1, |
&ctx->grp.G, NULL, NULL ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2, |
&ctx->grp.G, NULL, NULL ) ); |
cleanup: |
return( ret ); |
} |
/* For tests we don't need a secure RNG; |
* use the LGC from Numerical Recipes for simplicity */ |
static int ecjpake_lgc( void *p, unsigned char *out, size_t len ) |
{ |
static uint32_t x = 42; |
(void) p; |
while( len > 0 ) |
{ |
size_t use_len = len > 4 ? 4 : len; |
x = 1664525 * x + 1013904223; |
memcpy( out, &x, use_len ); |
out += use_len; |
len -= use_len; |
} |
return( 0 ); |
} |
#define TEST_ASSERT( x ) \ |
do { \ |
if( x ) \ |
ret = 0; \ |
else \ |
{ \ |
ret = 1; \ |
goto cleanup; \ |
} \ |
} while( 0 ) |
/* |
* Checkup routine |
*/ |
int mbedtls_ecjpake_self_test( int verbose ) |
{ |
int ret; |
mbedtls_ecjpake_context cli; |
mbedtls_ecjpake_context srv; |
unsigned char buf[512], pms[32]; |
size_t len, pmslen; |
mbedtls_ecjpake_init( &cli ); |
mbedtls_ecjpake_init( &srv ); |
if( verbose != 0 ) |
mbedtls_printf( " ECJPAKE test #0 (setup): " ); |
TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT, |
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, |
ecjpake_test_password, |
sizeof( ecjpake_test_password ) ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER, |
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, |
ecjpake_test_password, |
sizeof( ecjpake_test_password ) ) == 0 ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " ECJPAKE test #1 (random handshake): " ); |
TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, |
pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( len == pmslen ); |
TEST_ASSERT( memcmp( buf, pms, len ) == 0 ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " ECJPAKE test #2 (reference handshake): " ); |
/* Simulate generation of round one */ |
MBEDTLS_MPI_CHK( ecjpake_test_load( &cli, |
ecjpake_test_x1, sizeof( ecjpake_test_x1 ), |
ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) ); |
MBEDTLS_MPI_CHK( ecjpake_test_load( &srv, |
ecjpake_test_x3, sizeof( ecjpake_test_x3 ), |
ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) ); |
/* Read round one */ |
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, |
ecjpake_test_cli_one, |
sizeof( ecjpake_test_cli_one ) ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, |
ecjpake_test_srv_one, |
sizeof( ecjpake_test_srv_one ) ) == 0 ); |
/* Skip generation of round two, read round two */ |
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, |
ecjpake_test_srv_two, |
sizeof( ecjpake_test_srv_two ) ) == 0 ); |
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, |
ecjpake_test_cli_two, |
sizeof( ecjpake_test_cli_two ) ) == 0 ); |
/* Server derives PMS */ |
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); |
TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); |
memset( buf, 0, len ); /* Avoid interferences with next step */ |
/* Client derives PMS */ |
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, |
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); |
TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); |
TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
cleanup: |
mbedtls_ecjpake_free( &cli ); |
mbedtls_ecjpake_free( &srv ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( ret ); |
} |
#undef TEST_ASSERT |
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_ECJPAKE_C */ |
/programs/develop/libraries/kos_mbedtls/library/ecp.c |
---|
0,0 → 1,3029 |
/* |
* Elliptic curves over GF(p): generic functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* |
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg |
* GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone |
* FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf |
* RFC 4492 for the related TLS structures and constants |
* RFC 7748 for the Curve448 and Curve25519 curve definitions |
* |
* [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf |
* |
* [2] CORON, Jean-S'ebastien. Resistance against differential power analysis |
* for elliptic curve cryptosystems. In : Cryptographic Hardware and |
* Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. |
* <http://link.springer.com/chapter/10.1007/3-540-48059-5_25> |
* |
* [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to |
* render ECC resistant against Side Channel Attacks. IACR Cryptology |
* ePrint Archive, 2004, vol. 2004, p. 342. |
* <http://eprint.iacr.org/2004/342.pdf> |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
/** |
* \brief Function level alternative implementation. |
* |
* The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to |
* replace certain functions in this module. The alternative implementations are |
* typically hardware accelerators and need to activate the hardware before the |
* computation starts and deactivate it after it finishes. The |
* mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve |
* this purpose. |
* |
* To preserve the correct functionality the following conditions must hold: |
* |
* - The alternative implementation must be activated by |
* mbedtls_internal_ecp_init() before any of the replaceable functions is |
* called. |
* - mbedtls_internal_ecp_free() must \b only be called when the alternative |
* implementation is activated. |
* - mbedtls_internal_ecp_init() must \b not be called when the alternative |
* implementation is activated. |
* - Public functions must not return while the alternative implementation is |
* activated. |
* - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and |
* before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) ) |
* \endcode ensures that the alternative implementation supports the current |
* group. |
*/ |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#include "mbedtls/threading.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if !defined(MBEDTLS_ECP_ALT) |
/* Parameter validation macros based on platform_util.h */ |
#define ECP_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) |
#define ECP_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#include <stdio.h> |
#define mbedtls_printf printf |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/ecp_internal.h" |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* Counts of point addition and doubling, and field multiplications. |
* Used to test resistance of point multiplication to simple timing attacks. |
*/ |
static unsigned long add_count, dbl_count, mul_count; |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Maximum number of "basic operations" to be done in a row. |
* |
* Default value 0 means that ECC operations will not yield. |
* Note that regardless of the value of ecp_max_ops, always at |
* least one step is performed before yielding. |
* |
* Setting ecp_max_ops=1 can be suitable for testing purposes |
* as it will interrupt computation at all possible points. |
*/ |
static unsigned ecp_max_ops = 0; |
/* |
* Set ecp_max_ops |
*/ |
void mbedtls_ecp_set_max_ops( unsigned max_ops ) |
{ |
ecp_max_ops = max_ops; |
} |
/* |
* Check if restart is enabled |
*/ |
int mbedtls_ecp_restart_is_enabled( void ) |
{ |
return( ecp_max_ops != 0 ); |
} |
/* |
* Restart sub-context for ecp_mul_comb() |
*/ |
struct mbedtls_ecp_restart_mul |
{ |
mbedtls_ecp_point R; /* current intermediate result */ |
size_t i; /* current index in various loops, 0 outside */ |
mbedtls_ecp_point *T; /* table for precomputed points */ |
unsigned char T_size; /* number of points in table T */ |
enum { /* what were we doing last time we returned? */ |
ecp_rsm_init = 0, /* nothing so far, dummy initial state */ |
ecp_rsm_pre_dbl, /* precompute 2^n multiples */ |
ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */ |
ecp_rsm_pre_add, /* precompute remaining points by adding */ |
ecp_rsm_pre_norm_add, /* normalize all precomputed points */ |
ecp_rsm_comb_core, /* ecp_mul_comb_core() */ |
ecp_rsm_final_norm, /* do the final normalization */ |
} state; |
}; |
/* |
* Init restart_mul sub-context |
*/ |
static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx ) |
{ |
mbedtls_ecp_point_init( &ctx->R ); |
ctx->i = 0; |
ctx->T = NULL; |
ctx->T_size = 0; |
ctx->state = ecp_rsm_init; |
} |
/* |
* Free the components of a restart_mul sub-context |
*/ |
static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx ) |
{ |
unsigned char i; |
if( ctx == NULL ) |
return; |
mbedtls_ecp_point_free( &ctx->R ); |
if( ctx->T != NULL ) |
{ |
for( i = 0; i < ctx->T_size; i++ ) |
mbedtls_ecp_point_free( ctx->T + i ); |
mbedtls_free( ctx->T ); |
} |
ecp_restart_rsm_init( ctx ); |
} |
/* |
* Restart context for ecp_muladd() |
*/ |
struct mbedtls_ecp_restart_muladd |
{ |
mbedtls_ecp_point mP; /* mP value */ |
mbedtls_ecp_point R; /* R intermediate result */ |
enum { /* what should we do next? */ |
ecp_rsma_mul1 = 0, /* first multiplication */ |
ecp_rsma_mul2, /* second multiplication */ |
ecp_rsma_add, /* addition */ |
ecp_rsma_norm, /* normalization */ |
} state; |
}; |
/* |
* Init restart_muladd sub-context |
*/ |
static void ecp_restart_ma_init( mbedtls_ecp_restart_muladd_ctx *ctx ) |
{ |
mbedtls_ecp_point_init( &ctx->mP ); |
mbedtls_ecp_point_init( &ctx->R ); |
ctx->state = ecp_rsma_mul1; |
} |
/* |
* Free the components of a restart_muladd sub-context |
*/ |
static void ecp_restart_ma_free( mbedtls_ecp_restart_muladd_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_ecp_point_free( &ctx->mP ); |
mbedtls_ecp_point_free( &ctx->R ); |
ecp_restart_ma_init( ctx ); |
} |
/* |
* Initialize a restart context |
*/ |
void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ) |
{ |
ECP_VALIDATE( ctx != NULL ); |
ctx->ops_done = 0; |
ctx->depth = 0; |
ctx->rsm = NULL; |
ctx->ma = NULL; |
} |
/* |
* Free the components of a restart context |
*/ |
void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
ecp_restart_rsm_free( ctx->rsm ); |
mbedtls_free( ctx->rsm ); |
ecp_restart_ma_free( ctx->ma ); |
mbedtls_free( ctx->ma ); |
mbedtls_ecp_restart_init( ctx ); |
} |
/* |
* Check if we can do the next step |
*/ |
int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, |
mbedtls_ecp_restart_ctx *rs_ctx, |
unsigned ops ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
if( rs_ctx != NULL && ecp_max_ops != 0 ) |
{ |
/* scale depending on curve size: the chosen reference is 256-bit, |
* and multiplication is quadratic. Round to the closest integer. */ |
if( grp->pbits >= 512 ) |
ops *= 4; |
else if( grp->pbits >= 384 ) |
ops *= 2; |
/* Avoid infinite loops: always allow first step. |
* Because of that, however, it's not generally true |
* that ops_done <= ecp_max_ops, so the check |
* ops_done > ecp_max_ops below is mandatory. */ |
if( ( rs_ctx->ops_done != 0 ) && |
( rs_ctx->ops_done > ecp_max_ops || |
ops > ecp_max_ops - rs_ctx->ops_done ) ) |
{ |
return( MBEDTLS_ERR_ECP_IN_PROGRESS ); |
} |
/* update running count */ |
rs_ctx->ops_done += ops; |
} |
return( 0 ); |
} |
/* Call this when entering a function that needs its own sub-context */ |
#define ECP_RS_ENTER( SUB ) do { \ |
/* reset ops count for this call if top-level */ \ |
if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) \ |
rs_ctx->ops_done = 0; \ |
\ |
/* set up our own sub-context if needed */ \ |
if( mbedtls_ecp_restart_is_enabled() && \ |
rs_ctx != NULL && rs_ctx->SUB == NULL ) \ |
{ \ |
rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \ |
if( rs_ctx->SUB == NULL ) \ |
return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \ |
\ |
ecp_restart_## SUB ##_init( rs_ctx->SUB ); \ |
} \ |
} while( 0 ) |
/* Call this when leaving a function that needs its own sub-context */ |
#define ECP_RS_LEAVE( SUB ) do { \ |
/* clear our sub-context when not in progress (done or error) */ \ |
if( rs_ctx != NULL && rs_ctx->SUB != NULL && \ |
ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \ |
{ \ |
ecp_restart_## SUB ##_free( rs_ctx->SUB ); \ |
mbedtls_free( rs_ctx->SUB ); \ |
rs_ctx->SUB = NULL; \ |
} \ |
\ |
if( rs_ctx != NULL ) \ |
rs_ctx->depth--; \ |
} while( 0 ) |
#else /* MBEDTLS_ECP_RESTARTABLE */ |
#define ECP_RS_ENTER( sub ) (void) rs_ctx; |
#define ECP_RS_LEAVE( sub ) (void) rs_ctx; |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
#define ECP_SHORTWEIERSTRASS |
#endif |
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) |
#define ECP_MONTGOMERY |
#endif |
/* |
* Curve types: internal for now, might be exposed later |
*/ |
typedef enum |
{ |
ECP_TYPE_NONE = 0, |
ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ |
ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ |
} ecp_curve_type; |
/* |
* List of supported curves: |
* - internal ID |
* - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) |
* - size in bits |
* - readable name |
* |
* Curves are listed in order: largest curves first, and for a given size, |
* fastest curves first. This provides the default order for the SSL module. |
* |
* Reminder: update profiles in x509_crt.c when adding a new curves! |
*/ |
static const mbedtls_ecp_curve_info ecp_supported_curves[] = |
{ |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) |
{ MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) |
{ MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) |
{ MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
{ MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, |
#endif |
{ MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, |
}; |
#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ |
sizeof( ecp_supported_curves[0] ) |
static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; |
/* |
* List of supported curves and associated info |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ) |
{ |
return( ecp_supported_curves ); |
} |
/* |
* List of supported curves, group ID only |
*/ |
const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ) |
{ |
static int init_done = 0; |
if( ! init_done ) |
{ |
size_t i = 0; |
const mbedtls_ecp_curve_info *curve_info; |
for( curve_info = mbedtls_ecp_curve_list(); |
curve_info->grp_id != MBEDTLS_ECP_DP_NONE; |
curve_info++ ) |
{ |
ecp_supported_grp_id[i++] = curve_info->grp_id; |
} |
ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE; |
init_done = 1; |
} |
return( ecp_supported_grp_id ); |
} |
/* |
* Get the curve info for the internal identifier |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ) |
{ |
const mbedtls_ecp_curve_info *curve_info; |
for( curve_info = mbedtls_ecp_curve_list(); |
curve_info->grp_id != MBEDTLS_ECP_DP_NONE; |
curve_info++ ) |
{ |
if( curve_info->grp_id == grp_id ) |
return( curve_info ); |
} |
return( NULL ); |
} |
/* |
* Get the curve info from the TLS identifier |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ) |
{ |
const mbedtls_ecp_curve_info *curve_info; |
for( curve_info = mbedtls_ecp_curve_list(); |
curve_info->grp_id != MBEDTLS_ECP_DP_NONE; |
curve_info++ ) |
{ |
if( curve_info->tls_id == tls_id ) |
return( curve_info ); |
} |
return( NULL ); |
} |
/* |
* Get the curve info from the name |
*/ |
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ) |
{ |
const mbedtls_ecp_curve_info *curve_info; |
if( name == NULL ) |
return( NULL ); |
for( curve_info = mbedtls_ecp_curve_list(); |
curve_info->grp_id != MBEDTLS_ECP_DP_NONE; |
curve_info++ ) |
{ |
if( strcmp( curve_info->name, name ) == 0 ) |
return( curve_info ); |
} |
return( NULL ); |
} |
/* |
* Get the type of a curve |
*/ |
static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp ) |
{ |
if( grp->G.X.p == NULL ) |
return( ECP_TYPE_NONE ); |
if( grp->G.Y.p == NULL ) |
return( ECP_TYPE_MONTGOMERY ); |
else |
return( ECP_TYPE_SHORT_WEIERSTRASS ); |
} |
/* |
* Initialize (the components of) a point |
*/ |
void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) |
{ |
ECP_VALIDATE( pt != NULL ); |
mbedtls_mpi_init( &pt->X ); |
mbedtls_mpi_init( &pt->Y ); |
mbedtls_mpi_init( &pt->Z ); |
} |
/* |
* Initialize (the components of) a group |
*/ |
void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) |
{ |
ECP_VALIDATE( grp != NULL ); |
grp->id = MBEDTLS_ECP_DP_NONE; |
mbedtls_mpi_init( &grp->P ); |
mbedtls_mpi_init( &grp->A ); |
mbedtls_mpi_init( &grp->B ); |
mbedtls_ecp_point_init( &grp->G ); |
mbedtls_mpi_init( &grp->N ); |
grp->pbits = 0; |
grp->nbits = 0; |
grp->h = 0; |
grp->modp = NULL; |
grp->t_pre = NULL; |
grp->t_post = NULL; |
grp->t_data = NULL; |
grp->T = NULL; |
grp->T_size = 0; |
} |
/* |
* Initialize (the components of) a key pair |
*/ |
void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ) |
{ |
ECP_VALIDATE( key != NULL ); |
mbedtls_ecp_group_init( &key->grp ); |
mbedtls_mpi_init( &key->d ); |
mbedtls_ecp_point_init( &key->Q ); |
} |
/* |
* Unallocate (the components of) a point |
*/ |
void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ) |
{ |
if( pt == NULL ) |
return; |
mbedtls_mpi_free( &( pt->X ) ); |
mbedtls_mpi_free( &( pt->Y ) ); |
mbedtls_mpi_free( &( pt->Z ) ); |
} |
/* |
* Unallocate (the components of) a group |
*/ |
void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ) |
{ |
size_t i; |
if( grp == NULL ) |
return; |
if( grp->h != 1 ) |
{ |
mbedtls_mpi_free( &grp->P ); |
mbedtls_mpi_free( &grp->A ); |
mbedtls_mpi_free( &grp->B ); |
mbedtls_ecp_point_free( &grp->G ); |
mbedtls_mpi_free( &grp->N ); |
} |
if( grp->T != NULL ) |
{ |
for( i = 0; i < grp->T_size; i++ ) |
mbedtls_ecp_point_free( &grp->T[i] ); |
mbedtls_free( grp->T ); |
} |
mbedtls_platform_zeroize( grp, sizeof( mbedtls_ecp_group ) ); |
} |
/* |
* Unallocate (the components of) a key pair |
*/ |
void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ) |
{ |
if( key == NULL ) |
return; |
mbedtls_ecp_group_free( &key->grp ); |
mbedtls_mpi_free( &key->d ); |
mbedtls_ecp_point_free( &key->Q ); |
} |
/* |
* Copy the contents of a point |
*/ |
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) |
{ |
int ret; |
ECP_VALIDATE_RET( P != NULL ); |
ECP_VALIDATE_RET( Q != NULL ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Copy the contents of a group object |
*/ |
int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ) |
{ |
ECP_VALIDATE_RET( dst != NULL ); |
ECP_VALIDATE_RET( src != NULL ); |
return( mbedtls_ecp_group_load( dst, src->id ) ); |
} |
/* |
* Set point to zero |
*/ |
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ) |
{ |
int ret; |
ECP_VALIDATE_RET( pt != NULL ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Tell if a point is zero |
*/ |
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) |
{ |
ECP_VALIDATE_RET( pt != NULL ); |
return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); |
} |
/* |
* Compare two points lazily |
*/ |
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, |
const mbedtls_ecp_point *Q ) |
{ |
ECP_VALIDATE_RET( P != NULL ); |
ECP_VALIDATE_RET( Q != NULL ); |
if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 && |
mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 && |
mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 ) |
{ |
return( 0 ); |
} |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
/* |
* Import a non-zero point from ASCII strings |
*/ |
int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, |
const char *x, const char *y ) |
{ |
int ret; |
ECP_VALIDATE_RET( P != NULL ); |
ECP_VALIDATE_RET( x != NULL ); |
ECP_VALIDATE_RET( y != NULL ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Export a point into unsigned binary data (SEC1 2.3.3) |
*/ |
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, |
const mbedtls_ecp_point *P, |
int format, size_t *olen, |
unsigned char *buf, size_t buflen ) |
{ |
int ret = 0; |
size_t plen; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( P != NULL ); |
ECP_VALIDATE_RET( olen != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || |
format == MBEDTLS_ECP_PF_COMPRESSED ); |
/* |
* Common case: P == 0 |
*/ |
if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) |
{ |
if( buflen < 1 ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
buf[0] = 0x00; |
*olen = 1; |
return( 0 ); |
} |
plen = mbedtls_mpi_size( &grp->P ); |
if( format == MBEDTLS_ECP_PF_UNCOMPRESSED ) |
{ |
*olen = 2 * plen + 1; |
if( buflen < *olen ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
buf[0] = 0x04; |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); |
} |
else if( format == MBEDTLS_ECP_PF_COMPRESSED ) |
{ |
*olen = plen + 1; |
if( buflen < *olen ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); |
} |
cleanup: |
return( ret ); |
} |
/* |
* Import a point from unsigned binary data (SEC1 2.3.4) |
*/ |
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *pt, |
const unsigned char *buf, size_t ilen ) |
{ |
int ret; |
size_t plen; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( pt != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
if( ilen < 1 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
if( buf[0] == 0x00 ) |
{ |
if( ilen == 1 ) |
return( mbedtls_ecp_set_zero( pt ) ); |
else |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
plen = mbedtls_mpi_size( &grp->P ); |
if( buf[0] != 0x04 ) |
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
if( ilen != 2 * plen + 1 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Import a point from a TLS ECPoint record (RFC 4492) |
* struct { |
* opaque point <1..2^8-1>; |
* } ECPoint; |
*/ |
int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *pt, |
const unsigned char **buf, size_t buf_len ) |
{ |
unsigned char data_len; |
const unsigned char *buf_start; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( pt != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
ECP_VALIDATE_RET( *buf != NULL ); |
/* |
* We must have at least two bytes (1 for length, at least one for data) |
*/ |
if( buf_len < 2 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
data_len = *(*buf)++; |
if( data_len < 1 || data_len > buf_len - 1 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* |
* Save buffer start for read_binary and update buf |
*/ |
buf_start = *buf; |
*buf += data_len; |
return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) ); |
} |
/* |
* Export a point as a TLS ECPoint record (RFC 4492) |
* struct { |
* opaque point <1..2^8-1>; |
* } ECPoint; |
*/ |
int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, |
int format, size_t *olen, |
unsigned char *buf, size_t blen ) |
{ |
int ret; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( pt != NULL ); |
ECP_VALIDATE_RET( olen != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || |
format == MBEDTLS_ECP_PF_COMPRESSED ); |
/* |
* buffer length must be at least one, for our length byte |
*/ |
if( blen < 1 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format, |
olen, buf + 1, blen - 1) ) != 0 ) |
return( ret ); |
/* |
* write length to the first byte and update total length |
*/ |
buf[0] = (unsigned char) *olen; |
++*olen; |
return( 0 ); |
} |
/* |
* Set a group from an ECParameters record (RFC 4492) |
*/ |
int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, |
const unsigned char **buf, size_t len ) |
{ |
int ret; |
mbedtls_ecp_group_id grp_id; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
ECP_VALIDATE_RET( *buf != NULL ); |
if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 ) |
return( ret ); |
return( mbedtls_ecp_group_load( grp, grp_id ) ); |
} |
/* |
* Read a group id from an ECParameters record (RFC 4492) and convert it to |
* mbedtls_ecp_group_id. |
*/ |
int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, |
const unsigned char **buf, size_t len ) |
{ |
uint16_t tls_id; |
const mbedtls_ecp_curve_info *curve_info; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
ECP_VALIDATE_RET( *buf != NULL ); |
/* |
* We expect at least three bytes (see below) |
*/ |
if( len < 3 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* |
* First byte is curve_type; only named_curve is handled |
*/ |
if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* |
* Next two bytes are the namedcurve value |
*/ |
tls_id = *(*buf)++; |
tls_id <<= 8; |
tls_id |= *(*buf)++; |
if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) |
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
*grp = curve_info->grp_id; |
return( 0 ); |
} |
/* |
* Write the ECParameters record corresponding to a group (RFC 4492) |
*/ |
int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, |
unsigned char *buf, size_t blen ) |
{ |
const mbedtls_ecp_curve_info *curve_info; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( buf != NULL ); |
ECP_VALIDATE_RET( olen != NULL ); |
if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* |
* We are going to write 3 bytes (see below) |
*/ |
*olen = 3; |
if( blen < *olen ) |
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); |
/* |
* First byte is curve_type, always named_curve |
*/ |
*buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE; |
/* |
* Next two bytes are the namedcurve value |
*/ |
buf[0] = curve_info->tls_id >> 8; |
buf[1] = curve_info->tls_id & 0xFF; |
return( 0 ); |
} |
/* |
* Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi. |
* See the documentation of struct mbedtls_ecp_group. |
* |
* This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf. |
*/ |
static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp ) |
{ |
int ret; |
if( grp->modp == NULL ) |
return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) ); |
/* N->s < 0 is a much faster test, which fails only if N is 0 */ |
if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) || |
mbedtls_mpi_bitlen( N ) > 2 * grp->pbits ) |
{ |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
MBEDTLS_MPI_CHK( grp->modp( N ) ); |
/* N->s < 0 is a much faster test, which fails only if N is 0 */ |
while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) ); |
while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 ) |
/* we known P, N and the result are positive */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Fast mod-p functions expect their argument to be in the 0..p^2 range. |
* |
* In order to guarantee that, we need to ensure that operands of |
* mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will |
* bring the result back to this range. |
* |
* The following macros are shortcuts for doing that. |
*/ |
/* |
* Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi |
*/ |
#if defined(MBEDTLS_SELF_TEST) |
#define INC_MUL_COUNT mul_count++; |
#else |
#define INC_MUL_COUNT |
#endif |
#define MOD_MUL( N ) \ |
do \ |
{ \ |
MBEDTLS_MPI_CHK( ecp_modp( &(N), grp ) ); \ |
INC_MUL_COUNT \ |
} while( 0 ) |
/* |
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi |
* N->s < 0 is a very fast test, which fails only if N is 0 |
*/ |
#define MOD_SUB( N ) \ |
while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) ) |
/* |
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. |
* We known P, N and the result are positive, so sub_abs is correct, and |
* a bit faster. |
*/ |
#define MOD_ADD( N ) \ |
while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) ) |
#if defined(ECP_SHORTWEIERSTRASS) |
/* |
* For curves in short Weierstrass form, we do all the internal operations in |
* Jacobian coordinates. |
* |
* For multiplication, we'll use a comb method with coutermeasueres against |
* SPA, hence timing attacks. |
*/ |
/* |
* Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) |
* Cost: 1N := 1I + 3M + 1S |
*/ |
static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt ) |
{ |
int ret; |
mbedtls_mpi Zi, ZZi; |
if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ) |
return( 0 ); |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_normalize_jac( grp, pt ) ); |
#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ |
mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); |
/* |
* X = X / Z^2 mod p |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X ); |
/* |
* Y = Y / Z^3 mod p |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y ); |
/* |
* Z = 1 |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); |
cleanup: |
mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); |
return( ret ); |
} |
/* |
* Normalize jacobian coordinates of an array of (pointers to) points, |
* using Montgomery's trick to perform only one inversion mod P. |
* (See for example Cohen's "A Course in Computational Algebraic Number |
* Theory", Algorithm 10.3.4.) |
* |
* Warning: fails (returning an error) if one of the points is zero! |
* This should never happen, see choice of w in ecp_mul_comb(). |
* |
* Cost: 1N(t) := 1I + (6t - 3)M + 1S |
*/ |
static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *T[], size_t T_size ) |
{ |
int ret; |
size_t i; |
mbedtls_mpi *c, u, Zi, ZZi; |
if( T_size < 2 ) |
return( ecp_normalize_jac( grp, *T ) ); |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) ); |
#endif |
if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL ) |
return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); |
for( i = 0; i < T_size; i++ ) |
mbedtls_mpi_init( &c[i] ); |
mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); |
/* |
* c[i] = Z_0 * ... * Z_i |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) ); |
for( i = 1; i < T_size; i++ ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); |
MOD_MUL( c[i] ); |
} |
/* |
* u = 1 / (Z_0 * ... * Z_n) mod P |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) ); |
for( i = T_size - 1; ; i-- ) |
{ |
/* |
* Zi = 1 / Z_i mod p |
* u = 1 / (Z_0 * ... * Z_i) mod P |
*/ |
if( i == 0 ) { |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) ); |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); |
} |
/* |
* proceed as in normalize() |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); |
/* |
* Post-precessing: reclaim some memory by shrinking coordinates |
* - not storing Z (always 1) |
* - shrinking other coordinates, but still keeping the same number of |
* limbs as P, as otherwise it will too likely be regrown too fast. |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) ); |
mbedtls_mpi_free( &T[i]->Z ); |
if( i == 0 ) |
break; |
} |
cleanup: |
mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); |
for( i = 0; i < T_size; i++ ) |
mbedtls_mpi_free( &c[i] ); |
mbedtls_free( c ); |
return( ret ); |
} |
/* |
* Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. |
* "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid |
*/ |
static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *Q, |
unsigned char inv ) |
{ |
int ret; |
unsigned char nonzero; |
mbedtls_mpi mQY; |
mbedtls_mpi_init( &mQY ); |
/* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); |
nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0; |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); |
cleanup: |
mbedtls_mpi_free( &mQY ); |
return( ret ); |
} |
/* |
* Point doubling R = 2 P, Jacobian coordinates |
* |
* Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 . |
* |
* We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR |
* (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring. |
* |
* Standard optimizations are applied when curve parameter A is one of { 0, -3 }. |
* |
* Cost: 1D := 3M + 4S (A == 0) |
* 4M + 4S (A == -3) |
* 3M + 6S + 1a otherwise |
*/ |
static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_ecp_point *P ) |
{ |
int ret; |
mbedtls_mpi M, S, T, U; |
#if defined(MBEDTLS_SELF_TEST) |
dbl_count++; |
#endif |
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_double_jac( grp, R, P ) ); |
#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ |
mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); |
/* Special case for A = -3 */ |
if( grp->A.p == NULL ) |
{ |
/* M = 3(X + Z^2)(X - Z^2) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); |
} |
else |
{ |
/* M = 3.X^2 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); |
/* Optimize away for "koblitz" curves with A = 0 */ |
if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 ) |
{ |
/* M += A.Z^4 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M ); |
} |
} |
/* S = 4.X.Y^2 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S ); |
/* U = 8.Y^4 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); |
/* T = M^2 - 2.S */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); |
/* S = M(S - T) - U */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S ); |
/* U = 2.Y.Z */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) ); |
cleanup: |
mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U ); |
return( ret ); |
} |
/* |
* Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) |
* |
* The coordinates of Q must be normalized (= affine), |
* but those of P don't need to. R is not normalized. |
* |
* Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. |
* None of these cases can happen as intermediate step in ecp_mul_comb(): |
* - at each step, P, Q and R are multiples of the base point, the factor |
* being less than its order, so none of them is zero; |
* - Q is an odd multiple of the base point, P an even multiple, |
* due to the choice of precomputed points in the modified comb method. |
* So branches for these cases do not leak secret information. |
* |
* We accept Q->Z being unset (saving memory in tables) as meaning 1. |
* |
* Cost: 1A := 8M + 3S |
*/ |
static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) |
{ |
int ret; |
mbedtls_mpi T1, T2, T3, T4, X, Y, Z; |
#if defined(MBEDTLS_SELF_TEST) |
add_count++; |
#endif |
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) ); |
#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ |
/* |
* Trivial cases: P == 0 or Q == 0 (case 1) |
*/ |
if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) |
return( mbedtls_ecp_copy( R, Q ) ); |
if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 ) |
return( mbedtls_ecp_copy( R, P ) ); |
/* |
* Make sure Q coordinates are normalized |
*/ |
if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 ); |
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); |
/* Special cases (2) and (3) */ |
if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 ) |
{ |
if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 ) |
{ |
ret = ecp_double_jac( grp, R, P ); |
goto cleanup; |
} |
else |
{ |
ret = mbedtls_ecp_set_zero( R ); |
goto cleanup; |
} |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) ); |
cleanup: |
mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 ); |
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); |
return( ret ); |
} |
/* |
* Randomize jacobian coordinates: |
* (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l |
* This is sort of the reverse operation of ecp_normalize_jac(). |
* |
* This countermeasure was first suggested in [2]. |
*/ |
static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret; |
mbedtls_mpi l, ll; |
size_t p_size; |
int count = 0; |
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) ); |
#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ |
p_size = ( grp->pbits + 7 ) / 8; |
mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll ); |
/* Generate l such that 1 < l < p */ |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); |
while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); |
if( count++ > 10 ) |
return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); |
} |
while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ); |
/* Z = l * Z */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z ); |
/* X = l^2 * X */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X ); |
/* Y = l^3 * Y */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y ); |
cleanup: |
mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll ); |
return( ret ); |
} |
/* |
* Check and define parameters used by the comb method (see below for details) |
*/ |
#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7 |
#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds" |
#endif |
/* d = ceil( n / w ) */ |
#define COMB_MAX_D ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2 |
/* number of precomputed points */ |
#define COMB_MAX_PRE ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) |
/* |
* Compute the representation of m that will be used with our comb method. |
* |
* The basic comb method is described in GECC 3.44 for example. We use a |
* modified version that provides resistance to SPA by avoiding zero |
* digits in the representation as in [3]. We modify the method further by |
* requiring that all K_i be odd, which has the small cost that our |
* representation uses one more K_i, due to carries, but saves on the size of |
* the precomputed table. |
* |
* Summary of the comb method and its modifications: |
* |
* - The goal is to compute m*P for some w*d-bit integer m. |
* |
* - The basic comb method splits m into the w-bit integers |
* x[0] .. x[d-1] where x[i] consists of the bits in m whose |
* index has residue i modulo d, and computes m * P as |
* S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where |
* S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P. |
* |
* - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by |
* .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] .., |
* thereby successively converting it into a form where all summands |
* are nonzero, at the cost of negative summands. This is the basic idea of [3]. |
* |
* - More generally, even if x[i+1] != 0, we can first transform the sum as |
* .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] .., |
* and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]]. |
* Performing and iterating this procedure for those x[i] that are even |
* (keeping track of carry), we can transform the original sum into one of the form |
* S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]] |
* with all x'[i] odd. It is therefore only necessary to know S at odd indices, |
* which is why we are only computing half of it in the first place in |
* ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb. |
* |
* - For the sake of compactness, only the seven low-order bits of x[i] |
* are used to represent its absolute value (K_i in the paper), and the msb |
* of x[i] encodes the sign (s_i in the paper): it is set if and only if |
* if s_i == -1; |
* |
* Calling conventions: |
* - x is an array of size d + 1 |
* - w is the size, ie number of teeth, of the comb, and must be between |
* 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE) |
* - m is the MPI, expected to be odd and such that bitlength(m) <= w * d |
* (the result will be incorrect if these assumptions are not satisfied) |
*/ |
static void ecp_comb_recode_core( unsigned char x[], size_t d, |
unsigned char w, const mbedtls_mpi *m ) |
{ |
size_t i, j; |
unsigned char c, cc, adjust; |
memset( x, 0, d+1 ); |
/* First get the classical comb values (except for x_d = 0) */ |
for( i = 0; i < d; i++ ) |
for( j = 0; j < w; j++ ) |
x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j; |
/* Now make sure x_1 .. x_d are odd */ |
c = 0; |
for( i = 1; i <= d; i++ ) |
{ |
/* Add carry and update it */ |
cc = x[i] & c; |
x[i] = x[i] ^ c; |
c = cc; |
/* Adjust if needed, avoiding branches */ |
adjust = 1 - ( x[i] & 0x01 ); |
c |= x[i] & ( x[i-1] * adjust ); |
x[i] = x[i] ^ ( x[i-1] * adjust ); |
x[i-1] |= adjust << 7; |
} |
} |
/* |
* Precompute points for the adapted comb method |
* |
* Assumption: T must be able to hold 2^{w - 1} elements. |
* |
* Operation: If i = i_{w-1} ... i_1 is the binary representation of i, |
* sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P. |
* |
* Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) |
* |
* Note: Even comb values (those where P would be omitted from the |
* sum defining T[i] above) are not needed in our adaption |
* the comb method. See ecp_comb_recode_core(). |
* |
* This function currently works in four steps: |
* (1) [dbl] Computation of intermediate T[i] for 2-power values of i |
* (2) [norm_dbl] Normalization of coordinates of these T[i] |
* (3) [add] Computation of all T[i] |
* (4) [norm_add] Normalization of all T[i] |
* |
* Step 1 can be interrupted but not the others; together with the final |
* coordinate normalization they are the largest steps done at once, depending |
* on the window size. Here are operation counts for P-256: |
* |
* step (2) (3) (4) |
* w = 5 142 165 208 |
* w = 4 136 77 160 |
* w = 3 130 33 136 |
* w = 2 124 11 124 |
* |
* So if ECC operations are blocking for too long even with a low max_ops |
* value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order |
* to minimize maximum blocking time. |
*/ |
static int ecp_precompute_comb( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point T[], const mbedtls_ecp_point *P, |
unsigned char w, size_t d, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
unsigned char i; |
size_t j = 0; |
const unsigned char T_size = 1U << ( w - 1 ); |
mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1]; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
{ |
if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) |
goto dbl; |
if( rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl ) |
goto norm_dbl; |
if( rs_ctx->rsm->state == ecp_rsm_pre_add ) |
goto add; |
if( rs_ctx->rsm->state == ecp_rsm_pre_norm_add ) |
goto norm_add; |
} |
#else |
(void) rs_ctx; |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
{ |
rs_ctx->rsm->state = ecp_rsm_pre_dbl; |
/* initial state for the loop */ |
rs_ctx->rsm->i = 0; |
} |
dbl: |
#endif |
/* |
* Set T[0] = P and |
* T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) |
*/ |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) |
j = rs_ctx->rsm->i; |
else |
#endif |
j = 0; |
for( ; j < d * ( w - 1 ); j++ ) |
{ |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL ); |
i = 1U << ( j / d ); |
cur = T + i; |
if( j % d == 0 ) |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) ); |
MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) ); |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl; |
norm_dbl: |
#endif |
/* |
* Normalize current elements in T. As T has holes, |
* use an auxiliary array of pointers to elements in T. |
*/ |
j = 0; |
for( i = 1; i < T_size; i <<= 1 ) |
TT[j++] = T + i; |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); |
MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
rs_ctx->rsm->state = ecp_rsm_pre_add; |
add: |
#endif |
/* |
* Compute the remaining ones using the minimal number of additions |
* Be careful to update T[2^l] only after using it! |
*/ |
MBEDTLS_ECP_BUDGET( ( T_size - 1 ) * MBEDTLS_ECP_OPS_ADD ); |
for( i = 1; i < T_size; i <<= 1 ) |
{ |
j = i; |
while( j-- ) |
MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
rs_ctx->rsm->state = ecp_rsm_pre_norm_add; |
norm_add: |
#endif |
/* |
* Normalize final elements in T. Even though there are no holes now, we |
* still need the auxiliary array for homogeneity with the previous |
* call. Also, skip T[0] which is already normalised, being a copy of P. |
*/ |
for( j = 0; j + 1 < T_size; j++ ) |
TT[j] = T + j + 1; |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 ); |
MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) ); |
cleanup: |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && |
ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
{ |
if( rs_ctx->rsm->state == ecp_rsm_pre_dbl ) |
rs_ctx->rsm->i = j; |
} |
#endif |
return( ret ); |
} |
/* |
* Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] |
* |
* See ecp_comb_recode_core() for background |
*/ |
static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_ecp_point T[], unsigned char T_size, |
unsigned char i ) |
{ |
int ret; |
unsigned char ii, j; |
/* Ignore the "sign" bit and scale down */ |
ii = ( i & 0x7Fu ) >> 1; |
/* Read the whole table to thwart cache-based timing attacks */ |
for( j = 0; j < T_size; j++ ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); |
} |
/* Safely invert result if i is "negative" */ |
MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Core multiplication algorithm for the (modified) comb method. |
* This part is actually common with the basic comb method (GECC 3.44) |
* |
* Cost: d A + d D + 1 R |
*/ |
static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_ecp_point T[], unsigned char T_size, |
const unsigned char x[], size_t d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_ecp_point Txi; |
size_t i; |
mbedtls_ecp_point_init( &Txi ); |
#if !defined(MBEDTLS_ECP_RESTARTABLE) |
(void) rs_ctx; |
#endif |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && |
rs_ctx->rsm->state != ecp_rsm_comb_core ) |
{ |
rs_ctx->rsm->i = 0; |
rs_ctx->rsm->state = ecp_rsm_comb_core; |
} |
/* new 'if' instead of nested for the sake of the 'else' branch */ |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 ) |
{ |
/* restore current index (R already pointing to rs_ctx->rsm->R) */ |
i = rs_ctx->rsm->i; |
} |
else |
#endif |
{ |
/* Start with a non-zero point and randomize its coordinates */ |
i = d; |
MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); |
if( f_rng != 0 ) |
MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); |
} |
while( i != 0 ) |
{ |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD ); |
--i; |
MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) ); |
MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) ); |
MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); |
} |
cleanup: |
mbedtls_ecp_point_free( &Txi ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && |
ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
{ |
rs_ctx->rsm->i = i; |
/* no need to save R, already pointing to rs_ctx->rsm->R */ |
} |
#endif |
return( ret ); |
} |
/* |
* Recode the scalar to get constant-time comb multiplication |
* |
* As the actual scalar recoding needs an odd scalar as a starting point, |
* this wrapper ensures that by replacing m by N - m if necessary, and |
* informs the caller that the result of multiplication will be negated. |
* |
* This works because we only support large prime order for Short Weierstrass |
* curves, so N is always odd hence either m or N - m is. |
* |
* See ecp_comb_recode_core() for background. |
*/ |
static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp, |
const mbedtls_mpi *m, |
unsigned char k[COMB_MAX_D + 1], |
size_t d, |
unsigned char w, |
unsigned char *parity_trick ) |
{ |
int ret; |
mbedtls_mpi M, mm; |
mbedtls_mpi_init( &M ); |
mbedtls_mpi_init( &mm ); |
/* N is always odd (see above), just make extra sure */ |
if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
/* do we need the parity trick? */ |
*parity_trick = ( mbedtls_mpi_get_bit( m, 0 ) == 0 ); |
/* execute parity fix in constant time */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, *parity_trick ) ); |
/* actual scalar recoding */ |
ecp_comb_recode_core( k, d, w, &M ); |
cleanup: |
mbedtls_mpi_free( &mm ); |
mbedtls_mpi_free( &M ); |
return( ret ); |
} |
/* |
* Perform comb multiplication (for short Weierstrass curves) |
* once the auxiliary table has been pre-computed. |
* |
* Scalar recoding may use a parity trick that makes us compute -m * P, |
* if that is the case we'll need to recover m * P at the end. |
*/ |
static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *R, |
const mbedtls_mpi *m, |
const mbedtls_ecp_point *T, |
unsigned char T_size, |
unsigned char w, |
size_t d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
unsigned char parity_trick; |
unsigned char k[COMB_MAX_D + 1]; |
mbedtls_ecp_point *RR = R; |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
{ |
RR = &rs_ctx->rsm->R; |
if( rs_ctx->rsm->state == ecp_rsm_final_norm ) |
goto final_norm; |
} |
#endif |
MBEDTLS_MPI_CHK( ecp_comb_recode_scalar( grp, m, k, d, w, |
&parity_trick ) ); |
MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, RR, T, T_size, k, d, |
f_rng, p_rng, rs_ctx ) ); |
MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, RR, parity_trick ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
rs_ctx->rsm->state = ecp_rsm_final_norm; |
final_norm: |
#endif |
/* |
* Knowledge of the jacobian coordinates may leak the last few bits of the |
* scalar [1], and since our MPI implementation isn't constant-flow, |
* inversion (used for coordinate normalization) may leak the full value |
* of its input via side-channels [2]. |
* |
* [1] https://eprint.iacr.org/2003/191 |
* [2] https://eprint.iacr.org/2020/055 |
* |
* Avoid the leak by randomizing coordinates before we normalize them. |
*/ |
if( f_rng != 0 ) |
MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) ); |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); |
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, RR ) ); |
#endif |
cleanup: |
return( ret ); |
} |
/* |
* Pick window size based on curve size and whether we optimize for base point |
*/ |
static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp, |
unsigned char p_eq_g ) |
{ |
unsigned char w; |
/* |
* Minimize the number of multiplications, that is minimize |
* 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) |
* (see costs of the various parts, with 1S = 1M) |
*/ |
w = grp->nbits >= 384 ? 5 : 4; |
/* |
* If P == G, pre-compute a bit more, since this may be re-used later. |
* Just adding one avoids upping the cost of the first mul too much, |
* and the memory cost too. |
*/ |
if( p_eq_g ) |
w++; |
/* |
* Make sure w is within bounds. |
* (The last test is useful only for very small curves in the test suite.) |
*/ |
if( w > MBEDTLS_ECP_WINDOW_SIZE ) |
w = MBEDTLS_ECP_WINDOW_SIZE; |
if( w >= grp->nbits ) |
w = 2; |
return( w ); |
} |
/* |
* Multiplication using the comb method - for curves in short Weierstrass form |
* |
* This function is mainly responsible for administrative work: |
* - managing the restart context if enabled |
* - managing the table of precomputed points (passed between the below two |
* functions): allocation, computation, ownership tranfer, freeing. |
* |
* It delegates the actual arithmetic work to: |
* ecp_precompute_comb() and ecp_mul_comb_with_precomp() |
* |
* See comments on ecp_comb_recode_core() regarding the computation strategy. |
*/ |
static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
unsigned char w, p_eq_g, i; |
size_t d; |
unsigned char T_size, T_ok; |
mbedtls_ecp_point *T; |
ECP_RS_ENTER( rsm ); |
/* Is P the base point ? */ |
#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 |
p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && |
mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); |
#else |
p_eq_g = 0; |
#endif |
/* Pick window size and deduce related sizes */ |
w = ecp_pick_window_size( grp, p_eq_g ); |
T_size = 1U << ( w - 1 ); |
d = ( grp->nbits + w - 1 ) / w; |
/* Pre-computed table: do we have it already for the base point? */ |
if( p_eq_g && grp->T != NULL ) |
{ |
/* second pointer to the same table, will be deleted on exit */ |
T = grp->T; |
T_ok = 1; |
} |
else |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* Pre-computed table: do we have one in progress? complete? */ |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL ) |
{ |
/* transfer ownership of T from rsm to local function */ |
T = rs_ctx->rsm->T; |
rs_ctx->rsm->T = NULL; |
rs_ctx->rsm->T_size = 0; |
/* This effectively jumps to the call to mul_comb_after_precomp() */ |
T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core; |
} |
else |
#endif |
/* Allocate table if we didn't have any */ |
{ |
T = mbedtls_calloc( T_size, sizeof( mbedtls_ecp_point ) ); |
if( T == NULL ) |
{ |
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; |
goto cleanup; |
} |
for( i = 0; i < T_size; i++ ) |
mbedtls_ecp_point_init( &T[i] ); |
T_ok = 0; |
} |
/* Compute table (or finish computing it) if not done already */ |
if( !T_ok ) |
{ |
MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d, rs_ctx ) ); |
if( p_eq_g ) |
{ |
/* almost transfer ownership of T to the group, but keep a copy of |
* the pointer to use for calling the next function more easily */ |
grp->T = T; |
grp->T_size = T_size; |
} |
} |
/* Actual comb multiplication using precomputed points */ |
MBEDTLS_MPI_CHK( ecp_mul_comb_after_precomp( grp, R, m, |
T, T_size, w, d, |
f_rng, p_rng, rs_ctx ) ); |
cleanup: |
/* does T belong to the group? */ |
if( T == grp->T ) |
T = NULL; |
/* does T belong to the restart context? */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL ) |
{ |
/* transfer ownership of T from local function to rsm */ |
rs_ctx->rsm->T_size = T_size; |
rs_ctx->rsm->T = T; |
T = NULL; |
} |
#endif |
/* did T belong to us? then let's destroy it! */ |
if( T != NULL ) |
{ |
for( i = 0; i < T_size; i++ ) |
mbedtls_ecp_point_free( &T[i] ); |
mbedtls_free( T ); |
} |
/* don't free R while in progress in case R == P */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) |
#endif |
/* prevent caller from using invalid value */ |
if( ret != 0 ) |
mbedtls_ecp_point_free( R ); |
ECP_RS_LEAVE( rsm ); |
return( ret ); |
} |
#endif /* ECP_SHORTWEIERSTRASS */ |
#if defined(ECP_MONTGOMERY) |
/* |
* For Montgomery curves, we do all the internal arithmetic in projective |
* coordinates. Import/export of points uses only the x coordinates, which is |
* internaly represented as X / Z. |
* |
* For scalar multiplication, we'll use a Montgomery ladder. |
*/ |
/* |
* Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 |
* Cost: 1M + 1I |
*/ |
static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P ) |
{ |
int ret; |
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_normalize_mxz( grp, P ) ); |
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Randomize projective x/z coordinates: |
* (X, Z) -> (l X, l Z) for random l |
* This is sort of the reverse operation of ecp_normalize_mxz(). |
* |
* This countermeasure was first suggested in [2]. |
* Cost: 2M |
*/ |
static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret; |
mbedtls_mpi l; |
size_t p_size; |
int count = 0; |
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ); |
#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ |
p_size = ( grp->pbits + 7 ) / 8; |
mbedtls_mpi_init( &l ); |
/* Generate l such that 1 < l < p */ |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); |
while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); |
if( count++ > 10 ) |
return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); |
} |
while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); |
cleanup: |
mbedtls_mpi_free( &l ); |
return( ret ); |
} |
/* |
* Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), |
* for Montgomery curves in x/z coordinates. |
* |
* http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 |
* with |
* d = X1 |
* P = (X2, Z2) |
* Q = (X3, Z3) |
* R = (X4, Z4) |
* S = (X5, Z5) |
* and eliminating temporary variables tO, ..., t4. |
* |
* Cost: 5M + 4S |
*/ |
static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, |
mbedtls_ecp_point *R, mbedtls_ecp_point *S, |
const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, |
const mbedtls_mpi *d ) |
{ |
int ret; |
mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; |
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) |
if( mbedtls_internal_ecp_grp_capable( grp ) ) |
return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) ); |
#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ |
mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); |
mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C ); |
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); |
cleanup: |
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B ); |
mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C ); |
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB ); |
return( ret ); |
} |
/* |
* Multiplication with Montgomery ladder in x/z coordinates, |
* for curves in Montgomery form |
*/ |
static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
size_t i; |
unsigned char b; |
mbedtls_ecp_point RP; |
mbedtls_mpi PX; |
mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX ); |
/* Save PX and read from P before writing to R, in case P == R */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) ); |
/* Set R to zero in modified x/z coordinates */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) ); |
mbedtls_mpi_free( &R->Y ); |
/* RP.X might be sligtly larger than P, so reduce it */ |
MOD_ADD( RP.X ); |
/* Randomize coordinates of the starting point */ |
if( f_rng != NULL ) |
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); |
/* Loop invariant: R = result so far, RP = R + P */ |
i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */ |
while( i-- > 0 ) |
{ |
b = mbedtls_mpi_get_bit( m, i ); |
/* |
* if (b) R = 2R + P else R = 2R, |
* which is: |
* if (b) double_add( RP, R, RP, R ) |
* else double_add( R, RP, R, RP ) |
* but using safe conditional swaps to avoid leaks |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); |
MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); |
} |
/* |
* Knowledge of the projective coordinates may leak the last few bits of the |
* scalar [1], and since our MPI implementation isn't constant-flow, |
* inversion (used for coordinate normalization) may leak the full value |
* of its input via side-channels [2]. |
* |
* [1] https://eprint.iacr.org/2003/191 |
* [2] https://eprint.iacr.org/2020/055 |
* |
* Avoid the leak by randomizing coordinates before we normalize them. |
*/ |
if( f_rng != NULL ) |
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); |
cleanup: |
mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX ); |
return( ret ); |
} |
#endif /* ECP_MONTGOMERY */ |
/* |
* Restartable multiplication R = m * P |
*/ |
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
char is_grp_capable = 0; |
#endif |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( R != NULL ); |
ECP_VALIDATE_RET( m != NULL ); |
ECP_VALIDATE_RET( P != NULL ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* reset ops count for this call if top-level */ |
if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) |
rs_ctx->ops_done = 0; |
#endif |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) |
MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); |
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* skip argument check when restarting */ |
if( rs_ctx == NULL || rs_ctx->rsm == NULL ) |
#endif |
{ |
/* check_privkey is free */ |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK ); |
/* Common sanity checks */ |
MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) ); |
} |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
#if defined(ECP_MONTGOMERY) |
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) |
MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); |
#endif |
#if defined(ECP_SHORTWEIERSTRASS) |
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) |
MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) ); |
#endif |
cleanup: |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
if( is_grp_capable ) |
mbedtls_internal_ecp_free( grp ); |
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL ) |
rs_ctx->depth--; |
#endif |
return( ret ); |
} |
/* |
* Multiplication R = m * P |
*/ |
int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( R != NULL ); |
ECP_VALIDATE_RET( m != NULL ); |
ECP_VALIDATE_RET( P != NULL ); |
return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) ); |
} |
#if defined(ECP_SHORTWEIERSTRASS) |
/* |
* Check that an affine point is valid as a public key, |
* short weierstrass curves (SEC1 3.2.3.1) |
*/ |
static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) |
{ |
int ret; |
mbedtls_mpi YY, RHS; |
/* pt coordinates must be normalized for our checks */ |
if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 || |
mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 || |
mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || |
mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS ); |
/* |
* YY = Y^2 |
* RHS = X (X^2 + A) + B = X^3 + A X + B |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); |
/* Special case for A = -3 */ |
if( grp->A.p == NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); |
if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 ) |
ret = MBEDTLS_ERR_ECP_INVALID_KEY; |
cleanup: |
mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS ); |
return( ret ); |
} |
#endif /* ECP_SHORTWEIERSTRASS */ |
/* |
* R = m * P with shortcuts for m == 1 and m == -1 |
* NOT constant-time - ONLY for short Weierstrass! |
*/ |
static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, |
mbedtls_ecp_point *R, |
const mbedtls_mpi *m, |
const mbedtls_ecp_point *P, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
if( mbedtls_mpi_cmp_int( m, 1 ) == 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); |
} |
else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); |
if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) ); |
} |
else |
{ |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P, |
NULL, NULL, rs_ctx ) ); |
} |
cleanup: |
return( ret ); |
} |
/* |
* Restartable linear combination |
* NOT constant-time |
*/ |
int mbedtls_ecp_muladd_restartable( |
mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
const mbedtls_mpi *n, const mbedtls_ecp_point *Q, |
mbedtls_ecp_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_ecp_point mP; |
mbedtls_ecp_point *pmP = &mP; |
mbedtls_ecp_point *pR = R; |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
char is_grp_capable = 0; |
#endif |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( R != NULL ); |
ECP_VALIDATE_RET( m != NULL ); |
ECP_VALIDATE_RET( P != NULL ); |
ECP_VALIDATE_RET( n != NULL ); |
ECP_VALIDATE_RET( Q != NULL ); |
if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) |
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
mbedtls_ecp_point_init( &mP ); |
ECP_RS_ENTER( ma ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ma != NULL ) |
{ |
/* redirect intermediate results to restart context */ |
pmP = &rs_ctx->ma->mP; |
pR = &rs_ctx->ma->R; |
/* jump to next operation */ |
if( rs_ctx->ma->state == ecp_rsma_mul2 ) |
goto mul2; |
if( rs_ctx->ma->state == ecp_rsma_add ) |
goto add; |
if( rs_ctx->ma->state == ecp_rsma_norm ) |
goto norm; |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ma != NULL ) |
rs_ctx->ma->state = ecp_rsma_mul2; |
mul2: |
#endif |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR, n, Q, rs_ctx ) ); |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) ) |
MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); |
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ma != NULL ) |
rs_ctx->ma->state = ecp_rsma_add; |
add: |
#endif |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD ); |
MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ma != NULL ) |
rs_ctx->ma->state = ecp_rsma_norm; |
norm: |
#endif |
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); |
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) ); |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && rs_ctx->ma != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) ); |
#endif |
cleanup: |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
if( is_grp_capable ) |
mbedtls_internal_ecp_free( grp ); |
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ |
mbedtls_ecp_point_free( &mP ); |
ECP_RS_LEAVE( ma ); |
return( ret ); |
} |
/* |
* Linear combination |
* NOT constant-time |
*/ |
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, |
const mbedtls_mpi *m, const mbedtls_ecp_point *P, |
const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( R != NULL ); |
ECP_VALIDATE_RET( m != NULL ); |
ECP_VALIDATE_RET( P != NULL ); |
ECP_VALIDATE_RET( n != NULL ); |
ECP_VALIDATE_RET( Q != NULL ); |
return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) ); |
} |
#if defined(ECP_MONTGOMERY) |
/* |
* Check validity of a public key for Montgomery curves with x-only schemes |
*/ |
static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) |
{ |
/* [Curve25519 p. 5] Just check X is the correct number of bytes */ |
/* Allow any public value, if it's too big then we'll just reduce it mod p |
* (RFC 7748 sec. 5 para. 3). */ |
if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
return( 0 ); |
} |
#endif /* ECP_MONTGOMERY */ |
/* |
* Check that a point is valid as a public key |
*/ |
int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, |
const mbedtls_ecp_point *pt ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( pt != NULL ); |
/* Must use affine coordinates */ |
if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
#if defined(ECP_MONTGOMERY) |
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) |
return( ecp_check_pubkey_mx( grp, pt ) ); |
#endif |
#if defined(ECP_SHORTWEIERSTRASS) |
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) |
return( ecp_check_pubkey_sw( grp, pt ) ); |
#endif |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
/* |
* Check that an mbedtls_mpi is valid as a private key |
*/ |
int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, |
const mbedtls_mpi *d ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( d != NULL ); |
#if defined(ECP_MONTGOMERY) |
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) |
{ |
/* see RFC 7748 sec. 5 para. 5 */ |
if( mbedtls_mpi_get_bit( d, 0 ) != 0 || |
mbedtls_mpi_get_bit( d, 1 ) != 0 || |
mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */ |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
/* see [Curve25519] page 5 */ |
if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 ) |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
return( 0 ); |
} |
#endif /* ECP_MONTGOMERY */ |
#if defined(ECP_SHORTWEIERSTRASS) |
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) |
{ |
/* see SEC1 3.2 */ |
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || |
mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) |
return( MBEDTLS_ERR_ECP_INVALID_KEY ); |
else |
return( 0 ); |
} |
#endif /* ECP_SHORTWEIERSTRASS */ |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
/* |
* Generate a private key |
*/ |
int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, |
mbedtls_mpi *d, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
size_t n_size; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( d != NULL ); |
ECP_VALIDATE_RET( f_rng != NULL ); |
n_size = ( grp->nbits + 7 ) / 8; |
#if defined(ECP_MONTGOMERY) |
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) |
{ |
/* [M225] page 5 */ |
size_t b; |
do { |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); |
} while( mbedtls_mpi_bitlen( d ) == 0); |
/* Make sure the most significant bit is nbits */ |
b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */ |
if( b > grp->nbits ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) ); |
else |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) ); |
/* Make sure the last two bits are unset for Curve448, three bits for |
Curve25519 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) ); |
if( grp->nbits == 254 ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); |
} |
} |
#endif /* ECP_MONTGOMERY */ |
#if defined(ECP_SHORTWEIERSTRASS) |
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) |
{ |
/* SEC1 3.2.1: Generate d such that 1 <= n < N */ |
int count = 0; |
unsigned cmp = 0; |
/* |
* Match the procedure given in RFC 6979 (deterministic ECDSA): |
* - use the same byte ordering; |
* - keep the leftmost nbits bits of the generated octet string; |
* - try until result is in the desired range. |
* This also avoids any biais, which is especially important for ECDSA. |
*/ |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) ); |
/* |
* Each try has at worst a probability 1/2 of failing (the msb has |
* a probability 1/2 of being 0, and then the result will be < N), |
* so after 30 tries failure probability is a most 2**(-30). |
* |
* For most curves, 1 try is enough with overwhelming probability, |
* since N starts with a lot of 1s in binary, but some curves |
* such as secp224k1 are actually very close to the worst case. |
*/ |
if( ++count > 30 ) |
return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); |
ret = mbedtls_mpi_lt_mpi_ct( d, &grp->N, &cmp ); |
if( ret != 0 ) |
{ |
goto cleanup; |
} |
} |
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 ); |
} |
#endif /* ECP_SHORTWEIERSTRASS */ |
cleanup: |
return( ret ); |
} |
/* |
* Generate a keypair with configurable base point |
*/ |
int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, |
const mbedtls_ecp_point *G, |
mbedtls_mpi *d, mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( d != NULL ); |
ECP_VALIDATE_RET( G != NULL ); |
ECP_VALIDATE_RET( Q != NULL ); |
ECP_VALIDATE_RET( f_rng != NULL ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Generate key pair, wrapper for conventional base point |
*/ |
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, |
mbedtls_mpi *d, mbedtls_ecp_point *Q, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
ECP_VALIDATE_RET( d != NULL ); |
ECP_VALIDATE_RET( Q != NULL ); |
ECP_VALIDATE_RET( f_rng != NULL ); |
return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) ); |
} |
/* |
* Generate a keypair, prettier wrapper |
*/ |
int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret; |
ECP_VALIDATE_RET( key != NULL ); |
ECP_VALIDATE_RET( f_rng != NULL ); |
if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) |
return( ret ); |
return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); |
} |
/* |
* Check a public-private key pair |
*/ |
int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ) |
{ |
int ret; |
mbedtls_ecp_point Q; |
mbedtls_ecp_group grp; |
ECP_VALIDATE_RET( pub != NULL ); |
ECP_VALIDATE_RET( prv != NULL ); |
if( pub->grp.id == MBEDTLS_ECP_DP_NONE || |
pub->grp.id != prv->grp.id || |
mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) || |
mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) || |
mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) ) |
{ |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
} |
mbedtls_ecp_point_init( &Q ); |
mbedtls_ecp_group_init( &grp ); |
/* mbedtls_ecp_mul() needs a non-const group... */ |
mbedtls_ecp_group_copy( &grp, &prv->grp ); |
/* Also checks d is valid */ |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) ); |
if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) || |
mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) || |
mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) ) |
{ |
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |
goto cleanup; |
} |
cleanup: |
mbedtls_ecp_point_free( &Q ); |
mbedtls_ecp_group_free( &grp ); |
return( ret ); |
} |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* Checkup routine |
*/ |
int mbedtls_ecp_self_test( int verbose ) |
{ |
int ret; |
size_t i; |
mbedtls_ecp_group grp; |
mbedtls_ecp_point R, P; |
mbedtls_mpi m; |
unsigned long add_c_prev, dbl_c_prev, mul_c_prev; |
/* exponents especially adapted for secp192r1 */ |
const char *exponents[] = |
{ |
"000000000000000000000000000000000000000000000001", /* one */ |
"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ |
"5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ |
"400000000000000000000000000000000000000000000000", /* one and zeros */ |
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ |
"555555555555555555555555555555555555555555555555", /* 101010... */ |
}; |
mbedtls_ecp_group_init( &grp ); |
mbedtls_ecp_point_init( &R ); |
mbedtls_ecp_point_init( &P ); |
mbedtls_mpi_init( &m ); |
/* Use secp192r1 if available, or any available curve */ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) ); |
#else |
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) ); |
#endif |
if( verbose != 0 ) |
mbedtls_printf( " ECP test #1 (constant op_count, base point G): " ); |
/* Do a dummy multiplication first to trigger precomputation */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); |
add_count = 0; |
dbl_count = 0; |
mul_count = 0; |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); |
for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) |
{ |
add_c_prev = add_count; |
dbl_c_prev = dbl_count; |
mul_c_prev = mul_count; |
add_count = 0; |
dbl_count = 0; |
mul_count = 0; |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); |
if( add_count != add_c_prev || |
dbl_count != dbl_c_prev || |
mul_count != mul_c_prev ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed (%u)\n", (unsigned int) i ); |
ret = 1; |
goto cleanup; |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " ECP test #2 (constant op_count, other point): " ); |
/* We computed P = 2G last time, use it */ |
add_count = 0; |
dbl_count = 0; |
mul_count = 0; |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); |
for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) |
{ |
add_c_prev = add_count; |
dbl_c_prev = dbl_count; |
mul_c_prev = mul_count; |
add_count = 0; |
dbl_count = 0; |
mul_count = 0; |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); |
if( add_count != add_c_prev || |
dbl_count != dbl_c_prev || |
mul_count != mul_c_prev ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed (%u)\n", (unsigned int) i ); |
ret = 1; |
goto cleanup; |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
cleanup: |
if( ret < 0 && verbose != 0 ) |
mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); |
mbedtls_ecp_group_free( &grp ); |
mbedtls_ecp_point_free( &R ); |
mbedtls_ecp_point_free( &P ); |
mbedtls_mpi_free( &m ); |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* !MBEDTLS_ECP_ALT */ |
#endif /* MBEDTLS_ECP_C */ |
/programs/develop/libraries/kos_mbedtls/library/ecp_curves.c |
---|
0,0 → 1,1472 |
/* |
* Elliptic curves over GF(p): curve-specific data and functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if !defined(MBEDTLS_ECP_ALT) |
/* Parameter validation macros based on platform_util.h */ |
#define ECP_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) |
#define ECP_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
/* |
* Conversion macros for embedded constants: |
* build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 |
*/ |
#if defined(MBEDTLS_HAVE_INT32) |
#define BYTES_TO_T_UINT_4( a, b, c, d ) \ |
( (mbedtls_mpi_uint) (a) << 0 ) | \ |
( (mbedtls_mpi_uint) (b) << 8 ) | \ |
( (mbedtls_mpi_uint) (c) << 16 ) | \ |
( (mbedtls_mpi_uint) (d) << 24 ) |
#define BYTES_TO_T_UINT_2( a, b ) \ |
BYTES_TO_T_UINT_4( a, b, 0, 0 ) |
#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ |
BYTES_TO_T_UINT_4( a, b, c, d ), \ |
BYTES_TO_T_UINT_4( e, f, g, h ) |
#else /* 64-bits */ |
#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ |
( (mbedtls_mpi_uint) (a) << 0 ) | \ |
( (mbedtls_mpi_uint) (b) << 8 ) | \ |
( (mbedtls_mpi_uint) (c) << 16 ) | \ |
( (mbedtls_mpi_uint) (d) << 24 ) | \ |
( (mbedtls_mpi_uint) (e) << 32 ) | \ |
( (mbedtls_mpi_uint) (f) << 40 ) | \ |
( (mbedtls_mpi_uint) (g) << 48 ) | \ |
( (mbedtls_mpi_uint) (h) << 56 ) |
#define BYTES_TO_T_UINT_4( a, b, c, d ) \ |
BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) |
#define BYTES_TO_T_UINT_2( a, b ) \ |
BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) |
#endif /* bits in mbedtls_mpi_uint */ |
/* |
* Note: the constants are in little-endian order |
* to be directly usable in MPIs |
*/ |
/* |
* Domain parameters for secp192r1 |
*/ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
static const mbedtls_mpi_uint secp192r1_p[] = { |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
static const mbedtls_mpi_uint secp192r1_b[] = { |
BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), |
BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), |
BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), |
}; |
static const mbedtls_mpi_uint secp192r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), |
BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), |
BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), |
}; |
static const mbedtls_mpi_uint secp192r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), |
BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), |
BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), |
}; |
static const mbedtls_mpi_uint secp192r1_n[] = { |
BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), |
BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ |
/* |
* Domain parameters for secp224r1 |
*/ |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
static const mbedtls_mpi_uint secp224r1_p[] = { |
BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), |
BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp224r1_b[] = { |
BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), |
BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), |
BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), |
BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), |
}; |
static const mbedtls_mpi_uint secp224r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), |
BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), |
BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), |
BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), |
}; |
static const mbedtls_mpi_uint secp224r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), |
BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), |
BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), |
BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), |
}; |
static const mbedtls_mpi_uint secp224r1_n[] = { |
BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), |
BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ |
/* |
* Domain parameters for secp256r1 |
*/ |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
static const mbedtls_mpi_uint secp256r1_p[] = { |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), |
BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), |
BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
static const mbedtls_mpi_uint secp256r1_b[] = { |
BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), |
BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), |
BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), |
BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), |
}; |
static const mbedtls_mpi_uint secp256r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), |
BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), |
BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), |
BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), |
}; |
static const mbedtls_mpi_uint secp256r1_gy[] = { |
BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), |
BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), |
BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), |
BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), |
}; |
static const mbedtls_mpi_uint secp256r1_n[] = { |
BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), |
BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ |
/* |
* Domain parameters for secp384r1 |
*/ |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
static const mbedtls_mpi_uint secp384r1_p[] = { |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), |
BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
static const mbedtls_mpi_uint secp384r1_b[] = { |
BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), |
BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), |
BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), |
BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), |
BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), |
BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), |
}; |
static const mbedtls_mpi_uint secp384r1_gx[] = { |
BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), |
BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), |
BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), |
BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), |
BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), |
BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), |
}; |
static const mbedtls_mpi_uint secp384r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), |
BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), |
BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), |
BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), |
BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), |
BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), |
}; |
static const mbedtls_mpi_uint secp384r1_n[] = { |
BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), |
BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), |
BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ |
/* |
* Domain parameters for secp521r1 |
*/ |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
static const mbedtls_mpi_uint secp521r1_p[] = { |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_2( 0xFF, 0x01 ), |
}; |
static const mbedtls_mpi_uint secp521r1_b[] = { |
BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), |
BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), |
BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), |
BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), |
BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), |
BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), |
BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), |
BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), |
BYTES_TO_T_UINT_2( 0x51, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp521r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), |
BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), |
BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), |
BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), |
BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), |
BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), |
BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), |
BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), |
BYTES_TO_T_UINT_2( 0xC6, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp521r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), |
BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), |
BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), |
BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), |
BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), |
BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), |
BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), |
BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), |
BYTES_TO_T_UINT_2( 0x18, 0x01 ), |
}; |
static const mbedtls_mpi_uint secp521r1_n[] = { |
BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), |
BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), |
BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), |
BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), |
BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_2( 0xFF, 0x01 ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
static const mbedtls_mpi_uint secp192k1_p[] = { |
BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
static const mbedtls_mpi_uint secp192k1_a[] = { |
BYTES_TO_T_UINT_2( 0x00, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp192k1_b[] = { |
BYTES_TO_T_UINT_2( 0x03, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp192k1_gx[] = { |
BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), |
BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), |
BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), |
}; |
static const mbedtls_mpi_uint secp192k1_gy[] = { |
BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), |
BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), |
BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), |
}; |
static const mbedtls_mpi_uint secp192k1_n[] = { |
BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), |
BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
static const mbedtls_mpi_uint secp224k1_p[] = { |
BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
static const mbedtls_mpi_uint secp224k1_a[] = { |
BYTES_TO_T_UINT_2( 0x00, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp224k1_b[] = { |
BYTES_TO_T_UINT_2( 0x05, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp224k1_gx[] = { |
BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), |
BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), |
BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), |
BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), |
}; |
static const mbedtls_mpi_uint secp224k1_gy[] = { |
BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), |
BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), |
BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), |
BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), |
}; |
static const mbedtls_mpi_uint secp224k1_n[] = { |
BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), |
BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), |
BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), |
BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
static const mbedtls_mpi_uint secp256k1_p[] = { |
BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
static const mbedtls_mpi_uint secp256k1_a[] = { |
BYTES_TO_T_UINT_2( 0x00, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp256k1_b[] = { |
BYTES_TO_T_UINT_2( 0x07, 0x00 ), |
}; |
static const mbedtls_mpi_uint secp256k1_gx[] = { |
BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), |
BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), |
BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), |
BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), |
}; |
static const mbedtls_mpi_uint secp256k1_gy[] = { |
BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), |
BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), |
BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), |
BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), |
}; |
static const mbedtls_mpi_uint secp256k1_n[] = { |
BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), |
BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), |
BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), |
}; |
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ |
/* |
* Domain parameters for brainpoolP256r1 (RFC 5639 3.4) |
*/ |
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) |
static const mbedtls_mpi_uint brainpoolP256r1_p[] = { |
BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), |
BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), |
BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), |
BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), |
}; |
static const mbedtls_mpi_uint brainpoolP256r1_a[] = { |
BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), |
BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), |
BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), |
BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), |
}; |
static const mbedtls_mpi_uint brainpoolP256r1_b[] = { |
BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), |
BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), |
BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), |
BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), |
}; |
static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), |
BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), |
BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), |
BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), |
}; |
static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), |
BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), |
BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), |
BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), |
}; |
static const mbedtls_mpi_uint brainpoolP256r1_n[] = { |
BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), |
BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), |
BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), |
BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), |
}; |
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ |
/* |
* Domain parameters for brainpoolP384r1 (RFC 5639 3.6) |
*/ |
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) |
static const mbedtls_mpi_uint brainpoolP384r1_p[] = { |
BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), |
BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), |
BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), |
BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), |
BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), |
BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), |
}; |
static const mbedtls_mpi_uint brainpoolP384r1_a[] = { |
BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), |
BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), |
BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), |
BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), |
BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), |
BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), |
}; |
static const mbedtls_mpi_uint brainpoolP384r1_b[] = { |
BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), |
BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), |
BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), |
BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), |
BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), |
BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), |
}; |
static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), |
BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), |
BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), |
BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), |
BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), |
BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), |
}; |
static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), |
BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), |
BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), |
BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), |
BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), |
BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), |
}; |
static const mbedtls_mpi_uint brainpoolP384r1_n[] = { |
BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), |
BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), |
BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), |
BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), |
BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), |
BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), |
}; |
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ |
/* |
* Domain parameters for brainpoolP512r1 (RFC 5639 3.7) |
*/ |
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) |
static const mbedtls_mpi_uint brainpoolP512r1_p[] = { |
BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), |
BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), |
BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), |
BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), |
BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), |
BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), |
BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), |
BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), |
}; |
static const mbedtls_mpi_uint brainpoolP512r1_a[] = { |
BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), |
BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), |
BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), |
BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), |
BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), |
BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), |
BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), |
BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), |
}; |
static const mbedtls_mpi_uint brainpoolP512r1_b[] = { |
BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), |
BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), |
BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), |
BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), |
BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), |
BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), |
BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), |
BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), |
}; |
static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { |
BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), |
BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), |
BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), |
BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), |
BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), |
BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), |
BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), |
BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), |
}; |
static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { |
BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), |
BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), |
BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), |
BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), |
BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), |
BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), |
BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), |
BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), |
}; |
static const mbedtls_mpi_uint brainpoolP512r1_n[] = { |
BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), |
BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), |
BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), |
BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), |
BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), |
BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), |
BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), |
BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), |
}; |
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ |
/* |
* Create an MPI from embedded constants |
* (assumes len is an exact multiple of sizeof mbedtls_mpi_uint) |
*/ |
static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len ) |
{ |
X->s = 1; |
X->n = len / sizeof( mbedtls_mpi_uint ); |
X->p = (mbedtls_mpi_uint *) p; |
} |
/* |
* Set an MPI to static value 1 |
*/ |
static inline void ecp_mpi_set1( mbedtls_mpi *X ) |
{ |
static mbedtls_mpi_uint one[] = { 1 }; |
X->s = 1; |
X->n = 1; |
X->p = one; |
} |
/* |
* Make group available from embedded constants |
*/ |
static int ecp_group_load( mbedtls_ecp_group *grp, |
const mbedtls_mpi_uint *p, size_t plen, |
const mbedtls_mpi_uint *a, size_t alen, |
const mbedtls_mpi_uint *b, size_t blen, |
const mbedtls_mpi_uint *gx, size_t gxlen, |
const mbedtls_mpi_uint *gy, size_t gylen, |
const mbedtls_mpi_uint *n, size_t nlen) |
{ |
ecp_mpi_load( &grp->P, p, plen ); |
if( a != NULL ) |
ecp_mpi_load( &grp->A, a, alen ); |
ecp_mpi_load( &grp->B, b, blen ); |
ecp_mpi_load( &grp->N, n, nlen ); |
ecp_mpi_load( &grp->G.X, gx, gxlen ); |
ecp_mpi_load( &grp->G.Y, gy, gylen ); |
ecp_mpi_set1( &grp->G.Z ); |
grp->pbits = mbedtls_mpi_bitlen( &grp->P ); |
grp->nbits = mbedtls_mpi_bitlen( &grp->N ); |
grp->h = 1; |
return( 0 ); |
} |
#if defined(MBEDTLS_ECP_NIST_OPTIM) |
/* Forward declarations */ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
static int ecp_mod_p192( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
static int ecp_mod_p224( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
static int ecp_mod_p256( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
static int ecp_mod_p384( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
static int ecp_mod_p521( mbedtls_mpi * ); |
#endif |
#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; |
#else |
#define NIST_MODP( P ) |
#endif /* MBEDTLS_ECP_NIST_OPTIM */ |
/* Additional forward declarations */ |
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) |
static int ecp_mod_p255( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) |
static int ecp_mod_p448( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
static int ecp_mod_p192k1( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
static int ecp_mod_p224k1( mbedtls_mpi * ); |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
static int ecp_mod_p256k1( mbedtls_mpi * ); |
#endif |
#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ |
G ## _p, sizeof( G ## _p ), \ |
G ## _a, sizeof( G ## _a ), \ |
G ## _b, sizeof( G ## _b ), \ |
G ## _gx, sizeof( G ## _gx ), \ |
G ## _gy, sizeof( G ## _gy ), \ |
G ## _n, sizeof( G ## _n ) ) |
#define LOAD_GROUP( G ) ecp_group_load( grp, \ |
G ## _p, sizeof( G ## _p ), \ |
NULL, 0, \ |
G ## _b, sizeof( G ## _b ), \ |
G ## _gx, sizeof( G ## _gx ), \ |
G ## _gy, sizeof( G ## _gy ), \ |
G ## _n, sizeof( G ## _n ) ) |
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) |
/* |
* Specialized function for creating the Curve25519 group |
*/ |
static int ecp_use_curve25519( mbedtls_ecp_group *grp ) |
{ |
int ret; |
/* Actually ( A + 2 ) / 4 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) ); |
/* P = 2^255 - 19 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) ); |
grp->pbits = mbedtls_mpi_bitlen( &grp->P ); |
/* N = 2^252 + 27742317777372353535851937790883648493 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->N, 16, |
"14DEF9DEA2F79CD65812631A5CF5D3ED" ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) ); |
/* Y intentionally not set, since we use x/z coordinates. |
* This is used as a marker to identify Montgomery curves! */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); |
mbedtls_mpi_free( &grp->G.Y ); |
/* Actually, the required msb for private keys */ |
grp->nbits = 254; |
cleanup: |
if( ret != 0 ) |
mbedtls_ecp_group_free( grp ); |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) |
/* |
* Specialized function for creating the Curve448 group |
*/ |
static int ecp_use_curve448( mbedtls_ecp_group *grp ) |
{ |
mbedtls_mpi Ns; |
int ret; |
mbedtls_mpi_init( &Ns ); |
/* Actually ( A + 2 ) / 4 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "98AA" ) ); |
/* P = 2^448 - 2^224 - 1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) ); |
grp->pbits = mbedtls_mpi_bitlen( &grp->P ); |
/* Y intentionally not set, since we use x/z coordinates. |
* This is used as a marker to identify Montgomery curves! */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); |
mbedtls_mpi_free( &grp->G.Y ); |
/* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &Ns, 16, |
"8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D" ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) ); |
/* Actually, the required msb for private keys */ |
grp->nbits = 447; |
cleanup: |
mbedtls_mpi_free( &Ns ); |
if( ret != 0 ) |
mbedtls_ecp_group_free( grp ); |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ |
/* |
* Set a group using well-known domain parameters |
*/ |
int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) |
{ |
ECP_VALIDATE_RET( grp != NULL ); |
mbedtls_ecp_group_free( grp ); |
grp->id = id; |
switch( id ) |
{ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
case MBEDTLS_ECP_DP_SECP192R1: |
NIST_MODP( p192 ); |
return( LOAD_GROUP( secp192r1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
case MBEDTLS_ECP_DP_SECP224R1: |
NIST_MODP( p224 ); |
return( LOAD_GROUP( secp224r1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
case MBEDTLS_ECP_DP_SECP256R1: |
NIST_MODP( p256 ); |
return( LOAD_GROUP( secp256r1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
case MBEDTLS_ECP_DP_SECP384R1: |
NIST_MODP( p384 ); |
return( LOAD_GROUP( secp384r1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
case MBEDTLS_ECP_DP_SECP521R1: |
NIST_MODP( p521 ); |
return( LOAD_GROUP( secp521r1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
case MBEDTLS_ECP_DP_SECP192K1: |
grp->modp = ecp_mod_p192k1; |
return( LOAD_GROUP_A( secp192k1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
case MBEDTLS_ECP_DP_SECP224K1: |
grp->modp = ecp_mod_p224k1; |
return( LOAD_GROUP_A( secp224k1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
case MBEDTLS_ECP_DP_SECP256K1: |
grp->modp = ecp_mod_p256k1; |
return( LOAD_GROUP_A( secp256k1 ) ); |
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) |
case MBEDTLS_ECP_DP_BP256R1: |
return( LOAD_GROUP_A( brainpoolP256r1 ) ); |
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) |
case MBEDTLS_ECP_DP_BP384R1: |
return( LOAD_GROUP_A( brainpoolP384r1 ) ); |
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) |
case MBEDTLS_ECP_DP_BP512R1: |
return( LOAD_GROUP_A( brainpoolP512r1 ) ); |
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) |
case MBEDTLS_ECP_DP_CURVE25519: |
grp->modp = ecp_mod_p255; |
return( ecp_use_curve25519( grp ) ); |
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) |
case MBEDTLS_ECP_DP_CURVE448: |
grp->modp = ecp_mod_p448; |
return( ecp_use_curve448( grp ) ); |
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ |
default: |
mbedtls_ecp_group_free( grp ); |
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); |
} |
} |
#if defined(MBEDTLS_ECP_NIST_OPTIM) |
/* |
* Fast reduction modulo the primes used by the NIST curves. |
* |
* These functions are critical for speed, but not needed for correct |
* operations. So, we make the choice to heavily rely on the internals of our |
* bignum library, which creates a tight coupling between these functions and |
* our MPI implementation. However, the coupling between the ECP module and |
* MPI remains loose, since these functions can be deactivated at will. |
*/ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
/* |
* Compared to the way things are presented in FIPS 186-3 D.2, |
* we proceed in columns, from right (least significant chunk) to left, |
* adding chunks to N in place, and keeping a carry for the next chunk. |
* This avoids moving things around in memory, and uselessly adding zeros, |
* compared to the more straightforward, line-oriented approach. |
* |
* For this prime we need to handle data in chunks of 64 bits. |
* Since this is always a multiple of our basic mbedtls_mpi_uint, we can |
* use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. |
*/ |
/* Add 64-bit chunks (dst += src) and update carry */ |
static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry ) |
{ |
unsigned char i; |
mbedtls_mpi_uint c = 0; |
for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ ) |
{ |
*dst += c; c = ( *dst < c ); |
*dst += *src; c += ( *dst < *src ); |
} |
*carry += c; |
} |
/* Add carry to a 64-bit chunk and update carry */ |
static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry ) |
{ |
unsigned char i; |
for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ ) |
{ |
*dst += *carry; |
*carry = ( *dst < *carry ); |
} |
} |
#define WIDTH 8 / sizeof( mbedtls_mpi_uint ) |
#define A( i ) N->p + (i) * WIDTH |
#define ADD( i ) add64( p, A( i ), &c ) |
#define NEXT p += WIDTH; carry64( p, &c ) |
#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 |
/* |
* Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) |
*/ |
static int ecp_mod_p192( mbedtls_mpi *N ) |
{ |
int ret; |
mbedtls_mpi_uint c = 0; |
mbedtls_mpi_uint *p, *end; |
/* Make sure we have enough blocks so that A(5) is legal */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) ); |
p = N->p; |
end = p + N->n; |
ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 |
ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 |
ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 |
cleanup: |
return( ret ); |
} |
#undef WIDTH |
#undef A |
#undef ADD |
#undef NEXT |
#undef LAST |
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
/* |
* The reader is advised to first understand ecp_mod_p192() since the same |
* general structure is used here, but with additional complications: |
* (1) chunks of 32 bits, and (2) subtractions. |
*/ |
/* |
* For these primes, we need to handle data in chunks of 32 bits. |
* This makes it more complicated if we use 64 bits limbs in MPI, |
* which prevents us from using a uniform access method as for p192. |
* |
* So, we define a mini abstraction layer to access 32 bit chunks, |
* load them in 'cur' for work, and store them back from 'cur' when done. |
* |
* While at it, also define the size of N in terms of 32-bit chunks. |
*/ |
#define LOAD32 cur = A( i ); |
#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ |
#define MAX32 N->n |
#define A( j ) N->p[j] |
#define STORE32 N->p[i] = cur; |
#else /* 64-bit */ |
#define MAX32 N->n * 2 |
#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \ |
(uint32_t)( N->p[(j)/2] ) |
#define STORE32 \ |
if( i % 2 ) { \ |
N->p[i/2] &= 0x00000000FFFFFFFF; \ |
N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ |
} else { \ |
N->p[i/2] &= 0xFFFFFFFF00000000; \ |
N->p[i/2] |= (mbedtls_mpi_uint) cur; \ |
} |
#endif /* sizeof( mbedtls_mpi_uint ) */ |
/* |
* Helpers for addition and subtraction of chunks, with signed carry. |
*/ |
static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) |
{ |
*dst += src; |
*carry += ( *dst < src ); |
} |
static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) |
{ |
*carry -= ( *dst < src ); |
*dst -= src; |
} |
#define ADD( j ) add32( &cur, A( j ), &c ); |
#define SUB( j ) sub32( &cur, A( j ), &c ); |
/* |
* Helpers for the main 'loop' |
* (see fix_negative for the motivation of C) |
*/ |
#define INIT( b ) \ |
int ret; \ |
signed char c = 0, cc; \ |
uint32_t cur; \ |
size_t i = 0, bits = (b); \ |
mbedtls_mpi C; \ |
mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ |
\ |
C.s = 1; \ |
C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \ |
C.p = Cp; \ |
memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ |
\ |
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \ |
sizeof( mbedtls_mpi_uint ) ) ); \ |
LOAD32; |
#define NEXT \ |
STORE32; i++; LOAD32; \ |
cc = c; c = 0; \ |
if( cc < 0 ) \ |
sub32( &cur, -cc, &c ); \ |
else \ |
add32( &cur, cc, &c ); \ |
#define LAST \ |
STORE32; i++; \ |
cur = c > 0 ? c : 0; STORE32; \ |
cur = 0; while( ++i < MAX32 ) { STORE32; } \ |
if( c < 0 ) fix_negative( N, c, &C, bits ); |
/* |
* If the result is negative, we get it in the form |
* c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' |
*/ |
static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits ) |
{ |
int ret; |
/* C = - c * 2^(bits + 32) */ |
#if !defined(MBEDTLS_HAVE_INT64) |
((void) bits); |
#else |
if( bits == 224 ) |
C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32; |
else |
#endif |
C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c; |
/* N = - ( C - N ) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) ); |
N->s = -1; |
cleanup: |
return( ret ); |
} |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
/* |
* Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) |
*/ |
static int ecp_mod_p224( mbedtls_mpi *N ) |
{ |
INIT( 224 ); |
SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 |
SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 |
SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 |
SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 |
SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 |
SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 |
SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
/* |
* Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) |
*/ |
static int ecp_mod_p256( mbedtls_mpi *N ) |
{ |
INIT( 256 ); |
ADD( 8 ); ADD( 9 ); |
SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 |
ADD( 9 ); ADD( 10 ); |
SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 |
ADD( 10 ); ADD( 11 ); |
SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 |
ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); |
SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 |
ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); |
SUB( 9 ); SUB( 10 ); NEXT; // A4 |
ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); |
SUB( 10 ); SUB( 11 ); NEXT; // A5 |
ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); |
SUB( 8 ); SUB( 9 ); NEXT; // A6 |
ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); |
SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
/* |
* Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) |
*/ |
static int ecp_mod_p384( mbedtls_mpi *N ) |
{ |
INIT( 384 ); |
ADD( 12 ); ADD( 21 ); ADD( 20 ); |
SUB( 23 ); NEXT; // A0 |
ADD( 13 ); ADD( 22 ); ADD( 23 ); |
SUB( 12 ); SUB( 20 ); NEXT; // A2 |
ADD( 14 ); ADD( 23 ); |
SUB( 13 ); SUB( 21 ); NEXT; // A2 |
ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); |
SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 |
ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); |
SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 |
ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); |
SUB( 16 ); NEXT; // A5 |
ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); |
SUB( 17 ); NEXT; // A6 |
ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); |
SUB( 18 ); NEXT; // A7 |
ADD( 20 ); ADD( 17 ); ADD( 16 ); |
SUB( 19 ); NEXT; // A8 |
ADD( 21 ); ADD( 18 ); ADD( 17 ); |
SUB( 20 ); NEXT; // A9 |
ADD( 22 ); ADD( 19 ); ADD( 18 ); |
SUB( 21 ); NEXT; // A10 |
ADD( 23 ); ADD( 20 ); ADD( 19 ); |
SUB( 22 ); LAST; // A11 |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ |
#undef A |
#undef LOAD32 |
#undef STORE32 |
#undef MAX32 |
#undef INIT |
#undef NEXT |
#undef LAST |
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || |
MBEDTLS_ECP_DP_SECP256R1_ENABLED || |
MBEDTLS_ECP_DP_SECP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
/* |
* Here we have an actual Mersenne prime, so things are more straightforward. |
* However, chunks are aligned on a 'weird' boundary (521 bits). |
*/ |
/* Size of p521 in terms of mbedtls_mpi_uint */ |
#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) |
/* Bits to keep in the most significant mbedtls_mpi_uint */ |
#define P521_MASK 0x01FF |
/* |
* Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) |
* Write N as A1 + 2^521 A0, return A0 + A1 |
*/ |
static int ecp_mod_p521( mbedtls_mpi *N ) |
{ |
int ret; |
size_t i; |
mbedtls_mpi M; |
mbedtls_mpi_uint Mp[P521_WIDTH + 1]; |
/* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: |
* we need to hold bits 513 to 1056, which is 34 limbs, that is |
* P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ |
if( N->n < P521_WIDTH ) |
return( 0 ); |
/* M = A1 */ |
M.s = 1; |
M.n = N->n - ( P521_WIDTH - 1 ); |
if( M.n > P521_WIDTH + 1 ) |
M.n = P521_WIDTH + 1; |
M.p = Mp; |
memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); |
/* N = A0 */ |
N->p[P521_WIDTH - 1] &= P521_MASK; |
for( i = P521_WIDTH; i < N->n; i++ ) |
N->p[i] = 0; |
/* N = A0 + A1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); |
cleanup: |
return( ret ); |
} |
#undef P521_WIDTH |
#undef P521_MASK |
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ |
#endif /* MBEDTLS_ECP_NIST_OPTIM */ |
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) |
/* Size of p255 in terms of mbedtls_mpi_uint */ |
#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) |
/* |
* Fast quasi-reduction modulo p255 = 2^255 - 19 |
* Write N as A0 + 2^255 A1, return A0 + 19 * A1 |
*/ |
static int ecp_mod_p255( mbedtls_mpi *N ) |
{ |
int ret; |
size_t i; |
mbedtls_mpi M; |
mbedtls_mpi_uint Mp[P255_WIDTH + 2]; |
if( N->n < P255_WIDTH ) |
return( 0 ); |
/* M = A1 */ |
M.s = 1; |
M.n = N->n - ( P255_WIDTH - 1 ); |
if( M.n > P255_WIDTH + 1 ) |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
M.p = Mp; |
memset( Mp, 0, sizeof Mp ); |
memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); |
M.n++; /* Make room for multiplication by 19 */ |
/* N = A0 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) ); |
for( i = P255_WIDTH; i < N->n; i++ ) |
N->p[i] = 0; |
/* N = A0 + 19 * A1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) |
/* Size of p448 in terms of mbedtls_mpi_uint */ |
#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) ) |
/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ |
#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) ) |
#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) ) |
#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) ) |
#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 ) |
/* |
* Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 |
* Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return |
* A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference |
* implementation of Curve448, which uses its own special 56-bit limbs rather |
* than a generic bignum library. We could squeeze some extra speed out on |
* 32-bit machines by splitting N up into 32-bit limbs and doing the |
* arithmetic using the limbs directly as we do for the NIST primes above, |
* but for 64-bit targets it should use half the number of operations if we do |
* the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds. |
*/ |
static int ecp_mod_p448( mbedtls_mpi *N ) |
{ |
int ret; |
size_t i; |
mbedtls_mpi M, Q; |
mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH]; |
if( N->n <= P448_WIDTH ) |
return( 0 ); |
/* M = A1 */ |
M.s = 1; |
M.n = N->n - ( P448_WIDTH ); |
if( M.n > P448_WIDTH ) |
/* Shouldn't be called with N larger than 2^896! */ |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); |
M.p = Mp; |
memset( Mp, 0, sizeof( Mp ) ); |
memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) ); |
/* N = A0 */ |
for( i = P448_WIDTH; i < N->n; i++ ) |
N->p[i] = 0; |
/* N += A1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) ); |
/* Q = B1, N += B1 */ |
Q = M; |
Q.p = Qp; |
memcpy( Qp, Mp, sizeof( Qp ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) ); |
/* M = (B0 + B1) * 2^224, N += M */ |
if( sizeof( mbedtls_mpi_uint ) > 4 ) |
Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS ); |
for( i = P224_WIDTH_MAX; i < M.n; ++i ) |
Mp[i] = 0; |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) ); |
M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) ); |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ |
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
/* |
* Fast quasi-reduction modulo P = 2^s - R, |
* with R about 33 bits, used by the Koblitz curves. |
* |
* Write N as A0 + 2^224 A1, return A0 + R * A1. |
* Actually do two passes, since R is big. |
*/ |
#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P |
#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R |
static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs, |
size_t adjust, size_t shift, mbedtls_mpi_uint mask ) |
{ |
int ret; |
size_t i; |
mbedtls_mpi M, R; |
mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; |
if( N->n < p_limbs ) |
return( 0 ); |
/* Init R */ |
R.s = 1; |
R.p = Rp; |
R.n = P_KOBLITZ_R; |
/* Common setup for M */ |
M.s = 1; |
M.p = Mp; |
/* M = A1 */ |
M.n = N->n - ( p_limbs - adjust ); |
if( M.n > p_limbs + adjust ) |
M.n = p_limbs + adjust; |
memset( Mp, 0, sizeof Mp ); |
memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); |
if( shift != 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); |
M.n += R.n; /* Make room for multiplication by R */ |
/* N = A0 */ |
if( mask != 0 ) |
N->p[p_limbs - 1] &= mask; |
for( i = p_limbs; i < N->n; i++ ) |
N->p[i] = 0; |
/* N = A0 + R * A1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); |
/* Second pass */ |
/* M = A1 */ |
M.n = N->n - ( p_limbs - adjust ); |
if( M.n > p_limbs + adjust ) |
M.n = p_limbs + adjust; |
memset( Mp, 0, sizeof Mp ); |
memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); |
if( shift != 0 ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); |
M.n += R.n; /* Make room for multiplication by R */ |
/* N = A0 */ |
if( mask != 0 ) |
N->p[p_limbs - 1] &= mask; |
for( i = p_limbs; i < N->n; i++ ) |
N->p[i] = 0; |
/* N = A0 + R * A1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || |
MBEDTLS_ECP_DP_SECP224K1_ENABLED) || |
MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
/* |
* Fast quasi-reduction modulo p192k1 = 2^192 - R, |
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 |
*/ |
static int ecp_mod_p192k1( mbedtls_mpi *N ) |
{ |
static mbedtls_mpi_uint Rp[] = { |
BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; |
return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); |
} |
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
/* |
* Fast quasi-reduction modulo p224k1 = 2^224 - R, |
* with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 |
*/ |
static int ecp_mod_p224k1( mbedtls_mpi *N ) |
{ |
static mbedtls_mpi_uint Rp[] = { |
BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; |
#if defined(MBEDTLS_HAVE_INT64) |
return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); |
#else |
return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); |
#endif |
} |
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
/* |
* Fast quasi-reduction modulo p256k1 = 2^256 - R, |
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 |
*/ |
static int ecp_mod_p256k1( mbedtls_mpi *N ) |
{ |
static mbedtls_mpi_uint Rp[] = { |
BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; |
return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); |
} |
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ |
#endif /* !MBEDTLS_ECP_ALT */ |
#endif /* MBEDTLS_ECP_C */ |
/programs/develop/libraries/kos_mbedtls/library/entropy.c |
---|
0,0 → 1,749 |
/* |
* Entropy accumulator implementation |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ENTROPY_C) |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) |
#warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! " |
#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES " |
#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE " |
#endif |
#include "mbedtls/entropy.h" |
#include "mbedtls/entropy_poll.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_FS_IO) |
#include <stdio.h> |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
#include "mbedtls/platform.h" |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if defined(MBEDTLS_HAVEGE_C) |
#include "mbedtls/havege.h" |
#endif |
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ |
void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) |
{ |
ctx->source_count = 0; |
memset( ctx->source, 0, sizeof( ctx->source ) ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &ctx->mutex ); |
#endif |
ctx->accumulator_started = 0; |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
mbedtls_sha512_init( &ctx->accumulator ); |
#else |
mbedtls_sha256_init( &ctx->accumulator ); |
#endif |
#if defined(MBEDTLS_HAVEGE_C) |
mbedtls_havege_init( &ctx->havege_data ); |
#endif |
/* Reminder: Update ENTROPY_HAVE_STRONG in the test files |
* when adding more strong entropy sources here. */ |
/* add KolibriOS entropy sources */ |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_3_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_WEAK ); |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_26_9_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_WEAK ); |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_14_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_WEAK ); |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_18_4_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_STRONG ); |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_37_0_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_WEAK ); |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_66_3_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_WEAK ); |
mbedtls_entropy_add_source( ctx, mbedtls_sysfn_68_0_poll, NULL, |
4, MBEDTLS_ENTROPY_SOURCE_STRONG ); |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) |
mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, |
1, MBEDTLS_ENTROPY_SOURCE_STRONG ); |
#endif |
#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) |
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) |
mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, |
MBEDTLS_ENTROPY_MIN_PLATFORM, |
MBEDTLS_ENTROPY_SOURCE_STRONG ); |
#endif |
#if defined(MBEDTLS_TIMING_C) |
mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, |
MBEDTLS_ENTROPY_MIN_HARDCLOCK, |
MBEDTLS_ENTROPY_SOURCE_WEAK ); |
#endif |
#if defined(MBEDTLS_HAVEGE_C) |
mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, |
MBEDTLS_ENTROPY_MIN_HAVEGE, |
MBEDTLS_ENTROPY_SOURCE_STRONG ); |
#endif |
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, |
MBEDTLS_ENTROPY_MIN_HARDWARE, |
MBEDTLS_ENTROPY_SOURCE_STRONG ); |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, |
MBEDTLS_ENTROPY_BLOCK_SIZE, |
MBEDTLS_ENTROPY_SOURCE_STRONG ); |
ctx->initial_entropy_run = 0; |
#endif |
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ |
} |
void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) |
{ |
#if defined(MBEDTLS_HAVEGE_C) |
mbedtls_havege_free( &ctx->havege_data ); |
#endif |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &ctx->mutex ); |
#endif |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
mbedtls_sha512_free( &ctx->accumulator ); |
#else |
mbedtls_sha256_free( &ctx->accumulator ); |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
ctx->initial_entropy_run = 0; |
#endif |
ctx->source_count = 0; |
mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) ); |
ctx->accumulator_started = 0; |
} |
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, |
mbedtls_entropy_f_source_ptr f_source, void *p_source, |
size_t threshold, int strong ) |
{ |
int idx, ret = 0; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
idx = ctx->source_count; |
if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES ) |
{ |
ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; |
goto exit; |
} |
ctx->source[idx].f_source = f_source; |
ctx->source[idx].p_source = p_source; |
ctx->source[idx].threshold = threshold; |
ctx->source[idx].strong = strong; |
ctx->source_count++; |
exit: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
/* |
* Entropy accumulator update |
*/ |
static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id, |
const unsigned char *data, size_t len ) |
{ |
unsigned char header[2]; |
unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; |
size_t use_len = len; |
const unsigned char *p = data; |
int ret = 0; |
if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) |
{ |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 ) |
goto cleanup; |
#else |
if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 ) |
goto cleanup; |
#endif |
p = tmp; |
use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; |
} |
header[0] = source_id; |
header[1] = use_len & 0xFF; |
/* |
* Start the accumulator if this has not already happened. Note that |
* it is sufficient to start the accumulator here only because all calls to |
* gather entropy eventually execute this code. |
*/ |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
if( ctx->accumulator_started == 0 && |
( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) |
goto cleanup; |
else |
ctx->accumulator_started = 1; |
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 ) |
goto cleanup; |
ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len ); |
#else |
if( ctx->accumulator_started == 0 && |
( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) |
goto cleanup; |
else |
ctx->accumulator_started = 1; |
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 ) |
goto cleanup; |
ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len ); |
#endif |
cleanup: |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
return( ret ); |
} |
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, |
const unsigned char *data, size_t len ) |
{ |
int ret; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
/* |
* Run through the different sources to add entropy to our accumulator |
*/ |
static int entropy_gather_internal( mbedtls_entropy_context *ctx ) |
{ |
int ret, i, have_one_strong = 0; |
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; |
size_t olen; |
if( ctx->source_count == 0 ) |
return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED ); |
/* |
* Run through our entropy sources |
*/ |
for( i = 0; i < ctx->source_count; i++ ) |
{ |
if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) |
have_one_strong = 1; |
olen = 0; |
if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, |
buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) |
{ |
goto cleanup; |
} |
/* |
* Add if we actually gathered something |
*/ |
if( olen > 0 ) |
{ |
if( ( ret = entropy_update( ctx, (unsigned char) i, |
buf, olen ) ) != 0 ) |
return( ret ); |
ctx->source[i].size += olen; |
} |
} |
if( have_one_strong == 0 ) |
ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; |
cleanup: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
return( ret ); |
} |
/* |
* Thread-safe wrapper for entropy_gather_internal() |
*/ |
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) |
{ |
int ret; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
ret = entropy_gather_internal( ctx ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) |
{ |
int ret, count = 0, i, done; |
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; |
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; |
if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
/* Update the NV entropy seed before generating any entropy for outside |
* use. |
*/ |
if( ctx->initial_entropy_run == 0 ) |
{ |
ctx->initial_entropy_run = 1; |
if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) |
return( ret ); |
} |
#endif |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
/* |
* Always gather extra entropy before a call |
*/ |
do |
{ |
if( count++ > ENTROPY_MAX_LOOP ) |
{ |
/*for( i = 0; i < ctx->source_count; i++ ) { // rgimad |
mbedtls_printf("ctx->source[%d].size = %d\n", i, ctx->source[i].size); |
}*/ |
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; |
goto exit; |
} |
if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) |
goto exit; |
done = 1; |
for( i = 0; i < ctx->source_count; i++ ) |
if( ctx->source[i].size < ctx->source[i].threshold ) |
done = 0; |
} |
while( ! done ); |
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); |
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) |
/* |
* Note that at this stage it is assumed that the accumulator was started |
* in a previous call to entropy_update(). If this is not guaranteed, the |
* code below will fail. |
*/ |
if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 ) |
goto exit; |
/* |
* Reset accumulator and counters and recycle existing entropy |
*/ |
mbedtls_sha512_free( &ctx->accumulator ); |
mbedtls_sha512_init( &ctx->accumulator ); |
if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf, |
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) |
goto exit; |
/* |
* Perform second SHA-512 on entropy |
*/ |
if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, |
buf, 0 ) ) != 0 ) |
goto exit; |
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ |
if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 ) |
goto exit; |
/* |
* Reset accumulator and counters and recycle existing entropy |
*/ |
mbedtls_sha256_free( &ctx->accumulator ); |
mbedtls_sha256_init( &ctx->accumulator ); |
if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf, |
MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) |
goto exit; |
/* |
* Perform second SHA-256 on entropy |
*/ |
if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, |
buf, 0 ) ) != 0 ) |
goto exit; |
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ |
for( i = 0; i < ctx->source_count; i++ ) |
ctx->source[i].size = 0; |
memcpy( output, buf, len ); |
ret = 0; |
exit: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) |
{ |
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; |
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; |
/* Read new seed and write it to NV */ |
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) |
return( ret ); |
if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) |
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); |
/* Manually update the remaining stream with a separator value to diverge */ |
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); |
ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); |
return( ret ); |
} |
#endif /* MBEDTLS_ENTROPY_NV_SEED */ |
#if defined(MBEDTLS_FS_IO) |
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) |
{ |
int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; |
FILE *f; |
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; |
if( ( f = fopen( path, "wb" ) ) == NULL ) |
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); |
if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) |
goto exit; |
if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE ) |
{ |
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; |
goto exit; |
} |
ret = 0; |
exit: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
fclose( f ); |
return( ret ); |
} |
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ) |
{ |
int ret = 0; |
FILE *f; |
size_t n; |
unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; |
if( ( f = fopen( path, "rb" ) ) == NULL ) |
return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); |
fseek( f, 0, SEEK_END ); |
n = (size_t) ftell( f ); |
fseek( f, 0, SEEK_SET ); |
if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) |
n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; |
if( fread( buf, 1, n, f ) != n ) |
ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; |
else |
ret = mbedtls_entropy_update_manual( ctx, buf, n ); |
fclose( f ); |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
if( ret != 0 ) |
return( ret ); |
return( mbedtls_entropy_write_seed_file( ctx, path ) ); |
} |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_SELF_TEST) |
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) |
/* |
* Dummy source function |
*/ |
static int entropy_dummy_source( void *data, unsigned char *output, |
size_t len, size_t *olen ) |
{ |
((void) data); |
memset( output, 0x2a, len ); |
*olen = len; |
return( 0 ); |
} |
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ |
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) |
{ |
int ret = 0; |
size_t entropy_len = 0; |
size_t olen = 0; |
size_t attempts = buf_len; |
while( attempts > 0 && entropy_len < buf_len ) |
{ |
if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, |
buf_len - entropy_len, &olen ) ) != 0 ) |
return( ret ); |
entropy_len += olen; |
attempts--; |
} |
if( entropy_len < buf_len ) |
{ |
ret = 1; |
} |
return( ret ); |
} |
static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, |
size_t buf_len ) |
{ |
unsigned char set= 0xFF; |
unsigned char unset = 0x00; |
size_t i; |
for( i = 0; i < buf_len; i++ ) |
{ |
set &= buf[i]; |
unset |= buf[i]; |
} |
return( set == 0xFF || unset == 0x00 ); |
} |
/* |
* A test to ensure hat the entropy sources are functioning correctly |
* and there is no obvious failure. The test performs the following checks: |
* - The entropy source is not providing only 0s (all bits unset) or 1s (all |
* bits set). |
* - The entropy source is not providing values in a pattern. Because the |
* hardware could be providing data in an arbitrary length, this check polls |
* the hardware entropy source twice and compares the result to ensure they |
* are not equal. |
* - The error code returned by the entropy source is not an error. |
*/ |
int mbedtls_entropy_source_self_test( int verbose ) |
{ |
int ret = 0; |
unsigned char buf0[2 * sizeof( unsigned long long int )]; |
unsigned char buf1[2 * sizeof( unsigned long long int )]; |
if( verbose != 0 ) |
mbedtls_printf( " ENTROPY_BIAS test: " ); |
memset( buf0, 0x00, sizeof( buf0 ) ); |
memset( buf1, 0x00, sizeof( buf1 ) ); |
if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) |
goto cleanup; |
if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) |
goto cleanup; |
/* Make sure that the returned values are not all 0 or 1 */ |
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) |
goto cleanup; |
if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) |
goto cleanup; |
/* Make sure that the entropy source is not returning values in a |
* pattern */ |
ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; |
cleanup: |
if( verbose != 0 ) |
{ |
if( ret != 0 ) |
mbedtls_printf( "failed\n" ); |
else |
mbedtls_printf( "passed\n" ); |
mbedtls_printf( "\n" ); |
} |
return( ret != 0 ); |
} |
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ |
/* |
* The actual entropy quality is hard to test, but we can at least |
* test that the functions don't cause errors and write the correct |
* amount of data to buffers. |
*/ |
int mbedtls_entropy_self_test( int verbose ) |
{ |
int ret = 1; |
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) |
mbedtls_entropy_context ctx; |
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; |
unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; |
size_t i, j; |
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ |
if( verbose != 0 ) |
mbedtls_printf( " ENTROPY test: " ); |
#if !defined(MBEDTLS_TEST_NULL_ENTROPY) |
mbedtls_entropy_init( &ctx ); |
/* First do a gather to make sure we have default sources */ |
if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 ) |
goto cleanup; |
ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16, |
MBEDTLS_ENTROPY_SOURCE_WEAK ); |
if( ret != 0 ) |
goto cleanup; |
if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) |
goto cleanup; |
/* |
* To test that mbedtls_entropy_func writes correct number of bytes: |
* - use the whole buffer and rely on ASan to detect overruns |
* - collect entropy 8 times and OR the result in an accumulator: |
* any byte should then be 0 with probably 2^(-64), so requiring |
* each of the 32 or 64 bytes to be non-zero has a false failure rate |
* of at most 2^(-58) which is acceptable. |
*/ |
for( i = 0; i < 8; i++ ) |
{ |
if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) |
goto cleanup; |
for( j = 0; j < sizeof( buf ); j++ ) |
acc[j] |= buf[j]; |
} |
for( j = 0; j < sizeof( buf ); j++ ) |
{ |
if( acc[j] == 0 ) |
{ |
ret = 1; |
goto cleanup; |
} |
} |
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) |
goto cleanup; |
#endif |
cleanup: |
mbedtls_entropy_free( &ctx ); |
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ |
if( verbose != 0 ) |
{ |
if( ret != 0 ) |
mbedtls_printf( "failed\n" ); |
else |
mbedtls_printf( "passed\n" ); |
mbedtls_printf( "\n" ); |
} |
return( ret != 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_ENTROPY_C */ |
/programs/develop/libraries/kos_mbedtls/library/entropy_poll.c |
---|
0,0 → 1,379 |
/* |
* Platform-specific and custom entropy polling functions |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if defined(__linux__) |
/* Ensure that syscall() is available even when compiling with -std=c99 */ |
#define _GNU_SOURCE |
#endif |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include <string.h> |
/*rgimad*/ |
#include <stdio.h> |
#if defined(MBEDTLS_ENTROPY_C) |
#include "mbedtls/entropy.h" |
#include "mbedtls/entropy_poll.h" |
#if defined(MBEDTLS_TIMING_C) |
#include "mbedtls/timing.h" |
#endif |
#if defined(MBEDTLS_HAVEGE_C) |
#include "mbedtls/havege.h" |
#endif |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
#include "mbedtls/platform.h" |
#endif |
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) |
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ |
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ |
!defined(__HAIKU__) |
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" |
#endif |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
#if !defined(_WIN32_WINNT) |
#define _WIN32_WINNT 0x0400 |
#endif |
#include <windows.h> |
#include <wincrypt.h> |
int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, |
size_t *olen ) |
{ |
HCRYPTPROV provider; |
((void) data); |
*olen = 0; |
if( CryptAcquireContext( &provider, NULL, NULL, |
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) |
{ |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
} |
if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) |
{ |
CryptReleaseContext( provider, 0 ); |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
} |
CryptReleaseContext( provider, 0 ); |
*olen = len; |
return( 0 ); |
} |
#else /* _WIN32 && !EFIX64 && !EFI32 */ |
/* |
* Test for Linux getrandom() support. |
* Since there is no wrapper in the libc yet, use the generic syscall wrapper |
* available in GNU libc and compatible libc's (eg uClibc). |
*/ |
#if defined(__linux__) && defined(__GLIBC__) |
#include <unistd.h> |
#include <sys/syscall.h> |
#if defined(SYS_getrandom) |
#define HAVE_GETRANDOM |
#include <errno.h> |
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) |
{ |
/* MemSan cannot understand that the syscall writes to the buffer */ |
#if defined(__has_feature) |
#if __has_feature(memory_sanitizer) |
memset( buf, 0, buflen ); |
#endif |
#endif |
return( syscall( SYS_getrandom, buf, buflen, flags ) ); |
} |
#endif /* SYS_getrandom */ |
#endif /* __linux__ */ |
#include <stdio.h> |
int mbedtls_platform_entropy_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ) |
{ |
FILE *file; |
size_t read_len; |
int ret; |
((void) data); |
#if defined(HAVE_GETRANDOM) |
ret = getrandom_wrapper( output, len, 0 ); |
if( ret >= 0 ) |
{ |
*olen = ret; |
return( 0 ); |
} |
else if( errno != ENOSYS ) |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
/* Fall through if the system call isn't known. */ |
#else |
((void) ret); |
#endif /* HAVE_GETRANDOM */ |
*olen = 0; |
file = fopen( "/dev/urandom", "rb" ); |
if( file == NULL ) |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
read_len = fread( output, 1, len, file ); |
if( read_len != len ) |
{ |
fclose( file ); |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
} |
fclose( file ); |
*olen = len; |
return( 0 ); |
} |
#endif /* _WIN32 && !EFIX64 && !EFI32 */ |
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ |
/* -------------------------------------------------------------------------- */ |
/* entropy sources polls for KolibriOS */ |
int mbedtls_sysfn_3_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long kos_time, bcd_sec, bcd_min, bcd_hr, secs, mins, hrs, seconds; |
((void) data); |
asm volatile("int $0x40" : "=a"(kos_time) : "a"(3)); |
bcd_sec = (kos_time >> 16); |
bcd_min = ((kos_time & 0xFF00) >> 8); |
bcd_hr = (kos_time & 0xFF); |
secs = ((bcd_sec & 0xF0)>>4)*10 + (bcd_sec & 0x0F); |
mins = ((bcd_min & 0xF0)>>4)*10 + (bcd_min & 0x0F); |
hrs = ((bcd_hr & 0xF0)>>4)*10 + (bcd_hr & 0x0F); |
seconds = hrs*3600 + mins*60 + secs; |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &seconds, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
int mbedtls_sysfn_26_9_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long res; |
((void) data); |
asm volatile("int $0x40" : "=a"(res) : "a"(26), "b"(9)); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &res, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
int mbedtls_sysfn_14_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long res; |
((void) data); |
asm volatile("int $0x40" : "=a"(res) : "a"(14)); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &res, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
int mbedtls_sysfn_18_4_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long res; |
((void) data); |
asm volatile("int $0x40" : "=a"(res) : "a"(18), "b"(4)); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &res, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
int mbedtls_sysfn_37_0_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long res; |
((void) data); |
asm volatile("int $0x40" : "=a"(res) : "a"(37), "b"(0)); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &res, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
int mbedtls_sysfn_66_3_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long res; |
((void) data); |
asm volatile("int $0x40" : "=a"(res) : "a"(66), "b"(3)); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &res, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
int mbedtls_sysfn_68_0_poll( void *data, unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long res; |
((void) data); |
asm volatile("int $0x40" : "=a"(res) : "a"(68), "b"(0)); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &res, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
/* -------------------------------------------------------------------------- */ |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) |
int mbedtls_null_entropy_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ) |
{ |
((void) data); |
((void) output); |
*olen = 0; |
if( len < sizeof(unsigned char) ) |
return( 0 ); |
*olen = sizeof(unsigned char); |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_TIMING_C) |
int mbedtls_hardclock_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned long timer = mbedtls_timing_hardclock(); |
((void) data); |
*olen = 0; |
if( len < sizeof(unsigned long) ) |
return( 0 ); |
memcpy( output, &timer, sizeof(unsigned long) ); |
*olen = sizeof(unsigned long); |
return( 0 ); |
} |
#endif /* MBEDTLS_TIMING_C */ |
#if defined(MBEDTLS_HAVEGE_C) |
int mbedtls_havege_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ) |
{ |
mbedtls_havege_state *hs = (mbedtls_havege_state *) data; |
*olen = 0; |
if( mbedtls_havege_random( hs, output, len ) != 0 ) |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
*olen = len; |
return( 0 ); |
} |
#endif /* MBEDTLS_HAVEGE_C */ |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
int mbedtls_nv_seed_poll( void *data, |
unsigned char *output, size_t len, size_t *olen ) |
{ |
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; |
size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; |
((void) data); |
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); |
if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) |
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); |
if( len < use_len ) |
use_len = len; |
memcpy( output, buf, use_len ); |
*olen = use_len; |
return( 0 ); |
} |
#endif /* MBEDTLS_ENTROPY_NV_SEED */ |
#endif /* MBEDTLS_ENTROPY_C */ |
/programs/develop/libraries/kos_mbedtls/library/error.c |
---|
0,0 → 1,918 |
/* |
* Error message information |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) |
#include "mbedtls/error.h" |
#include <string.h> |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#define mbedtls_snprintf snprintf |
#define mbedtls_time_t time_t |
#endif |
#if defined(MBEDTLS_ERROR_C) |
#include <stdio.h> |
#if defined(MBEDTLS_AES_C) |
#include "mbedtls/aes.h" |
#endif |
#if defined(MBEDTLS_ARC4_C) |
#include "mbedtls/arc4.h" |
#endif |
#if defined(MBEDTLS_ARIA_C) |
#include "mbedtls/aria.h" |
#endif |
#if defined(MBEDTLS_BASE64_C) |
#include "mbedtls/base64.h" |
#endif |
#if defined(MBEDTLS_BIGNUM_C) |
#include "mbedtls/bignum.h" |
#endif |
#if defined(MBEDTLS_BLOWFISH_C) |
#include "mbedtls/blowfish.h" |
#endif |
#if defined(MBEDTLS_CAMELLIA_C) |
#include "mbedtls/camellia.h" |
#endif |
#if defined(MBEDTLS_CCM_C) |
#include "mbedtls/ccm.h" |
#endif |
#if defined(MBEDTLS_CHACHA20_C) |
#include "mbedtls/chacha20.h" |
#endif |
#if defined(MBEDTLS_CHACHAPOLY_C) |
#include "mbedtls/chachapoly.h" |
#endif |
#if defined(MBEDTLS_CIPHER_C) |
#include "mbedtls/cipher.h" |
#endif |
#if defined(MBEDTLS_CMAC_C) |
#include "mbedtls/cmac.h" |
#endif |
#if defined(MBEDTLS_CTR_DRBG_C) |
#include "mbedtls/ctr_drbg.h" |
#endif |
#if defined(MBEDTLS_DES_C) |
#include "mbedtls/des.h" |
#endif |
#if defined(MBEDTLS_DHM_C) |
#include "mbedtls/dhm.h" |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#endif |
#if defined(MBEDTLS_ENTROPY_C) |
#include "mbedtls/entropy.h" |
#endif |
#if defined(MBEDTLS_GCM_C) |
#include "mbedtls/gcm.h" |
#endif |
#if defined(MBEDTLS_HKDF_C) |
#include "mbedtls/hkdf.h" |
#endif |
#if defined(MBEDTLS_HMAC_DRBG_C) |
#include "mbedtls/hmac_drbg.h" |
#endif |
#if defined(MBEDTLS_MD_C) |
#include "mbedtls/md.h" |
#endif |
#if defined(MBEDTLS_MD2_C) |
#include "mbedtls/md2.h" |
#endif |
#if defined(MBEDTLS_MD4_C) |
#include "mbedtls/md4.h" |
#endif |
#if defined(MBEDTLS_MD5_C) |
#include "mbedtls/md5.h" |
#endif |
#if defined(MBEDTLS_NET_C) |
#include "mbedtls/net_sockets.h" |
#endif |
#if defined(MBEDTLS_OID_C) |
#include "mbedtls/oid.h" |
#endif |
#if defined(MBEDTLS_PADLOCK_C) |
#include "mbedtls/padlock.h" |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PK_C) |
#include "mbedtls/pk.h" |
#endif |
#if defined(MBEDTLS_PKCS12_C) |
#include "mbedtls/pkcs12.h" |
#endif |
#if defined(MBEDTLS_PKCS5_C) |
#include "mbedtls/pkcs5.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#endif |
#if defined(MBEDTLS_POLY1305_C) |
#include "mbedtls/poly1305.h" |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
#include "mbedtls/ripemd160.h" |
#endif |
#if defined(MBEDTLS_RSA_C) |
#include "mbedtls/rsa.h" |
#endif |
#if defined(MBEDTLS_SHA1_C) |
#include "mbedtls/sha1.h" |
#endif |
#if defined(MBEDTLS_SHA256_C) |
#include "mbedtls/sha256.h" |
#endif |
#if defined(MBEDTLS_SHA512_C) |
#include "mbedtls/sha512.h" |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) |
#include "mbedtls/ssl.h" |
#endif |
#if defined(MBEDTLS_THREADING_C) |
#include "mbedtls/threading.h" |
#endif |
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) |
#include "mbedtls/x509.h" |
#endif |
#if defined(MBEDTLS_XTEA_C) |
#include "mbedtls/xtea.h" |
#endif |
void mbedtls_strerror( int ret, char *buf, size_t buflen ) |
{ |
size_t len; |
int use_ret; |
if( buflen == 0 ) |
return; |
memset( buf, 0x00, buflen ); |
if( ret < 0 ) |
ret = -ret; |
if( ret & 0xFF80 ) |
{ |
use_ret = ret & 0xFF80; |
// High level error codes |
// |
// BEGIN generated code |
#if defined(MBEDTLS_CIPHER_C) |
if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" ); |
if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" ); |
#endif /* MBEDTLS_CIPHER_C */ |
#if defined(MBEDTLS_DHM_C) |
if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) ) |
mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" ); |
#endif /* MBEDTLS_DHM_C */ |
#if defined(MBEDTLS_ECP_C) |
if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) ) |
mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_ECP_IN_PROGRESS) ) |
mbedtls_snprintf( buf, buflen, "ECP - Operation in progress, call again with the same parameters to continue" ); |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_MD_C) |
if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" ); |
if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" ); |
if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" ); |
if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" ); |
#endif /* MBEDTLS_MD_C */ |
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) |
if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) ) |
mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) ) |
mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) ) |
mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) ) |
mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) ) |
mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" ); |
if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" ); |
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ |
#if defined(MBEDTLS_PK_C) |
if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" ); |
if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" ); |
if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" ); |
if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) ) |
mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" ); |
if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ) |
mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" ); |
if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) ) |
mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" ); |
if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) ) |
mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" ); |
if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" ); |
if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) ) |
mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" ); |
if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) ) |
mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) ) |
mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); |
if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); |
if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" ); |
if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" ); |
#endif /* MBEDTLS_PK_C */ |
#if defined(MBEDTLS_PKCS12_C) |
if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" ); |
if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) ) |
mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" ); |
if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" ); |
#endif /* MBEDTLS_PKCS12_C */ |
#if defined(MBEDTLS_PKCS5_C) |
if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) ) |
mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" ); |
if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" ); |
if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" ); |
#endif /* MBEDTLS_PKCS5_C */ |
#if defined(MBEDTLS_RSA_C) |
if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) ) |
mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) ) |
mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) ) |
mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" ); |
if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" ); |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_SSL_TLS_C) |
if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) ) |
mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) ) |
mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) ) |
mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) ) |
mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) ) |
mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) ) |
mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) ) |
mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) ) |
mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) ) |
mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) ) |
mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) ) |
mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) ) |
{ |
mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" ); |
return; |
} |
if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) ) |
mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) |
mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) ) |
mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) ) |
mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) ) |
mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) ) |
mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) ) |
mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) ) |
mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) |
mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) ) |
mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) ) |
mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) ) |
mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) ) |
mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) |
mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) ) |
mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) ) |
mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) ) |
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) ) |
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) ) |
mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) ) |
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" ); |
if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) ) |
mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" ); |
#endif /* MBEDTLS_SSL_TLS_C */ |
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) |
if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); |
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) ) |
mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) ) |
mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) ) |
mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) ) |
mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) ) |
mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) ) |
mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) ) |
mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) ) |
mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) ) |
mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) ) |
mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" ); |
if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) ) |
mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" ); |
if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" ); |
if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ) |
mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); |
if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) ) |
mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" ); |
if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "X509 - Input invalid" ); |
if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" ); |
if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); |
if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); |
if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) ) |
mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" ); |
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ |
// END generated code |
if( strlen( buf ) == 0 ) |
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); |
} |
use_ret = ret & ~0xFF80; |
if( use_ret == 0 ) |
return; |
// If high level code is present, make a concatenation between both |
// error strings. |
// |
len = strlen( buf ); |
if( len > 0 ) |
{ |
if( buflen - len < 5 ) |
return; |
mbedtls_snprintf( buf + len, buflen - len, " : " ); |
buf += len + 3; |
buflen -= len + 3; |
} |
// Low level error codes |
// |
// BEGIN generated code |
#if defined(MBEDTLS_AES_C) |
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); |
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" ); |
if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "AES - Invalid input data" ); |
if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" ); |
if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" ); |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_ARC4_C) |
if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" ); |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_ARIA_C) |
if( use_ret == -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" ); |
if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" ); |
if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" ); |
if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" ); |
#endif /* MBEDTLS_ARIA_C */ |
#if defined(MBEDTLS_ASN1_PARSE_C) |
if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" ); |
if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" ); |
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" ); |
if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" ); |
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" ); |
if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" ); |
if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" ); |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
#if defined(MBEDTLS_BASE64_C) |
if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" ); |
if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) ) |
mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" ); |
#endif /* MBEDTLS_BASE64_C */ |
#if defined(MBEDTLS_BIGNUM_C) |
if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" ); |
if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) ) |
mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" ); |
#endif /* MBEDTLS_BIGNUM_C */ |
#if defined(MBEDTLS_BLOWFISH_C) |
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" ); |
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" ); |
if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" ); |
#endif /* MBEDTLS_BLOWFISH_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" ); |
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); |
if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" ); |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_CCM_C) |
if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) ) |
mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" ); |
if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); |
if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" ); |
#endif /* MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_CHACHA20_C) |
if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" ); |
if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" ); |
if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" ); |
#endif /* MBEDTLS_CHACHA20_C */ |
#if defined(MBEDTLS_CHACHAPOLY_C) |
if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) ) |
mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" ); |
if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" ); |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
#if defined(MBEDTLS_CMAC_C) |
if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" ); |
#endif /* MBEDTLS_CMAC_C */ |
#if defined(MBEDTLS_CTR_DRBG_C) |
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) |
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); |
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) ) |
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" ); |
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) ) |
mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" ); |
if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" ); |
#endif /* MBEDTLS_CTR_DRBG_C */ |
#if defined(MBEDTLS_DES_C) |
if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" ); |
if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" ); |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ENTROPY_C) |
if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) ) |
mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" ); |
if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) ) |
mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); |
if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) ) |
mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); |
if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) ) |
mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" ); |
if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); |
#endif /* MBEDTLS_ENTROPY_C */ |
#if defined(MBEDTLS_GCM_C) |
if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) ) |
mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" ); |
if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) ) |
mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_HKDF_C) |
if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" ); |
#endif /* MBEDTLS_HKDF_C */ |
#if defined(MBEDTLS_HMAC_DRBG_C) |
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) |
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); |
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) ) |
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" ); |
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) ) |
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" ); |
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) ) |
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); |
#endif /* MBEDTLS_HMAC_DRBG_C */ |
#if defined(MBEDTLS_MD2_C) |
if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" ); |
#endif /* MBEDTLS_MD2_C */ |
#if defined(MBEDTLS_MD4_C) |
if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" ); |
#endif /* MBEDTLS_MD4_C */ |
#if defined(MBEDTLS_MD5_C) |
if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" ); |
#endif /* MBEDTLS_MD5_C */ |
#if defined(MBEDTLS_NET_C) |
if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" ); |
if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" ); |
if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" ); |
if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" ); |
if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" ); |
if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" ); |
if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" ); |
if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) ) |
mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" ); |
if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) ) |
mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); |
if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" ); |
if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) ) |
mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" ); |
if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" ); |
if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "NET - Input invalid" ); |
#endif /* MBEDTLS_NET_C */ |
#if defined(MBEDTLS_OID_C) |
if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) ) |
mbedtls_snprintf( buf, buflen, "OID - OID is not found" ); |
if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) ) |
mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" ); |
#endif /* MBEDTLS_OID_C */ |
#if defined(MBEDTLS_PADLOCK_C) |
if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) ) |
mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); |
#endif /* MBEDTLS_PADLOCK_C */ |
#if defined(MBEDTLS_PLATFORM_C) |
if( use_ret == -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "PLATFORM - Hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) ) |
mbedtls_snprintf( buf, buflen, "PLATFORM - The requested feature is not supported by the platform" ); |
#endif /* MBEDTLS_PLATFORM_C */ |
#if defined(MBEDTLS_POLY1305_C) |
if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" ); |
if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" ); |
if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" ); |
#endif /* MBEDTLS_POLY1305_C */ |
#if defined(MBEDTLS_RIPEMD160_C) |
if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" ); |
#endif /* MBEDTLS_RIPEMD160_C */ |
#if defined(MBEDTLS_SHA1_C) |
if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" ); |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" ); |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" ); |
if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" ); |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_THREADING_C) |
if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) ) |
mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" ); |
if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) ) |
mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" ); |
if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) ) |
mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" ); |
#endif /* MBEDTLS_THREADING_C */ |
#if defined(MBEDTLS_XTEA_C) |
if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) ) |
mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); |
if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) ) |
mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" ); |
#endif /* MBEDTLS_XTEA_C */ |
// END generated code |
if( strlen( buf ) != 0 ) |
return; |
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); |
} |
#else /* MBEDTLS_ERROR_C */ |
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) |
/* |
* Provide an non-function in case MBEDTLS_ERROR_C is not defined |
*/ |
void mbedtls_strerror( int ret, char *buf, size_t buflen ) |
{ |
((void) ret); |
if( buflen > 0 ) |
buf[0] = '\0'; |
} |
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ |
#endif /* MBEDTLS_ERROR_C */ |
/programs/develop/libraries/kos_mbedtls/library/gcm.c |
---|
0,0 → 1,996 |
/* |
* NIST SP800-38D compliant GCM implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf |
* |
* See also: |
* [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf |
* |
* We use the algorithm described as Shoup's method with 4-bit tables in |
* [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_GCM_C) |
#include "mbedtls/gcm.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_AESNI_C) |
#include "mbedtls/aesni.h" |
#endif |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
#include "mbedtls/aes.h" |
#include "mbedtls/platform.h" |
#if !defined(MBEDTLS_PLATFORM_C) |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#if !defined(MBEDTLS_GCM_ALT) |
/* Parameter validation macros */ |
#define GCM_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT ) |
#define GCM_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_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 |
/* |
* Initialize a context |
*/ |
void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) |
{ |
GCM_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); |
} |
/* |
* Precompute small multiples of H, that is set |
* HH[i] || HL[i] = H times i, |
* where i is seen as a field element as in [MGV], ie high-order bits |
* correspond to low powers of P. The result is stored in the same way, that |
* is the high-order bit of HH corresponds to P^0 and the low-order bit of HL |
* corresponds to P^127. |
*/ |
static int gcm_gen_table( mbedtls_gcm_context *ctx ) |
{ |
int ret, i, j; |
uint64_t hi, lo; |
uint64_t vl, vh; |
unsigned char h[16]; |
size_t olen = 0; |
memset( h, 0, 16 ); |
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) |
return( ret ); |
/* pack h as two 64-bits ints, big-endian */ |
GET_UINT32_BE( hi, h, 0 ); |
GET_UINT32_BE( lo, h, 4 ); |
vh = (uint64_t) hi << 32 | lo; |
GET_UINT32_BE( hi, h, 8 ); |
GET_UINT32_BE( lo, h, 12 ); |
vl = (uint64_t) hi << 32 | lo; |
/* 8 = 1000 corresponds to 1 in GF(2^128) */ |
ctx->HL[8] = vl; |
ctx->HH[8] = vh; |
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) |
/* With CLMUL support, we need only h, not the rest of the table */ |
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) |
return( 0 ); |
#endif |
/* 0 corresponds to 0 in GF(2^128) */ |
ctx->HH[0] = 0; |
ctx->HL[0] = 0; |
for( i = 4; i > 0; i >>= 1 ) |
{ |
uint32_t T = ( vl & 1 ) * 0xe1000000U; |
vl = ( vh << 63 ) | ( vl >> 1 ); |
vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); |
ctx->HL[i] = vl; |
ctx->HH[i] = vh; |
} |
for( i = 2; i <= 8; i *= 2 ) |
{ |
uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; |
vh = *HiH; |
vl = *HiL; |
for( j = 1; j < i; j++ ) |
{ |
HiH[j] = vh ^ ctx->HH[j]; |
HiL[j] = vl ^ ctx->HL[j]; |
} |
} |
return( 0 ); |
} |
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, |
mbedtls_cipher_id_t cipher, |
const unsigned char *key, |
unsigned int keybits ) |
{ |
int ret; |
const mbedtls_cipher_info_t *cipher_info; |
GCM_VALIDATE_RET( ctx != NULL ); |
GCM_VALIDATE_RET( key != NULL ); |
GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 ); |
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_GCM_BAD_INPUT ); |
if( cipher_info->block_size != 16 ) |
return( MBEDTLS_ERR_GCM_BAD_INPUT ); |
mbedtls_cipher_free( &ctx->cipher_ctx ); |
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, |
MBEDTLS_ENCRYPT ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = gcm_gen_table( ctx ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
/* |
* Shoup's method for multiplication use this table with |
* last4[x] = x times P^128 |
* where x and last4[x] are seen as elements of GF(2^128) as in [MGV] |
*/ |
static const uint64_t last4[16] = |
{ |
0x0000, 0x1c20, 0x3840, 0x2460, |
0x7080, 0x6ca0, 0x48c0, 0x54e0, |
0xe100, 0xfd20, 0xd940, 0xc560, |
0x9180, 0x8da0, 0xa9c0, 0xb5e0 |
}; |
/* |
* Sets output to x times H using the precomputed tables. |
* x and output are seen as elements of GF(2^128) as in [MGV]. |
*/ |
static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], |
unsigned char output[16] ) |
{ |
int i = 0; |
unsigned char lo, hi, rem; |
uint64_t zh, zl; |
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) |
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { |
unsigned char h[16]; |
PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); |
PUT_UINT32_BE( ctx->HH[8], h, 4 ); |
PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); |
PUT_UINT32_BE( ctx->HL[8], h, 12 ); |
mbedtls_aesni_gcm_mult( output, x, h ); |
return; |
} |
#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ |
lo = x[15] & 0xf; |
zh = ctx->HH[lo]; |
zl = ctx->HL[lo]; |
for( i = 15; i >= 0; i-- ) |
{ |
lo = x[i] & 0xf; |
hi = x[i] >> 4; |
if( i != 15 ) |
{ |
rem = (unsigned char) zl & 0xf; |
zl = ( zh << 60 ) | ( zl >> 4 ); |
zh = ( zh >> 4 ); |
zh ^= (uint64_t) last4[rem] << 48; |
zh ^= ctx->HH[lo]; |
zl ^= ctx->HL[lo]; |
} |
rem = (unsigned char) zl & 0xf; |
zl = ( zh << 60 ) | ( zl >> 4 ); |
zh = ( zh >> 4 ); |
zh ^= (uint64_t) last4[rem] << 48; |
zh ^= ctx->HH[hi]; |
zl ^= ctx->HL[hi]; |
} |
PUT_UINT32_BE( zh >> 32, output, 0 ); |
PUT_UINT32_BE( zh, output, 4 ); |
PUT_UINT32_BE( zl >> 32, output, 8 ); |
PUT_UINT32_BE( zl, output, 12 ); |
} |
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, |
int mode, |
const unsigned char *iv, |
size_t iv_len, |
const unsigned char *add, |
size_t add_len ) |
{ |
int ret; |
unsigned char work_buf[16]; |
size_t i; |
const unsigned char *p; |
size_t use_len, olen = 0; |
GCM_VALIDATE_RET( ctx != NULL ); |
GCM_VALIDATE_RET( iv != NULL ); |
GCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
/* IV and AD are limited to 2^64 bits, so 2^61 bytes */ |
/* IV is not allowed to be zero length */ |
if( iv_len == 0 || |
( (uint64_t) iv_len ) >> 61 != 0 || |
( (uint64_t) add_len ) >> 61 != 0 ) |
{ |
return( MBEDTLS_ERR_GCM_BAD_INPUT ); |
} |
memset( ctx->y, 0x00, sizeof(ctx->y) ); |
memset( ctx->buf, 0x00, sizeof(ctx->buf) ); |
ctx->mode = mode; |
ctx->len = 0; |
ctx->add_len = 0; |
if( iv_len == 12 ) |
{ |
memcpy( ctx->y, iv, iv_len ); |
ctx->y[15] = 1; |
} |
else |
{ |
memset( work_buf, 0x00, 16 ); |
PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); |
p = iv; |
while( iv_len > 0 ) |
{ |
use_len = ( iv_len < 16 ) ? iv_len : 16; |
for( i = 0; i < use_len; i++ ) |
ctx->y[i] ^= p[i]; |
gcm_mult( ctx, ctx->y, ctx->y ); |
iv_len -= use_len; |
p += use_len; |
} |
for( i = 0; i < 16; i++ ) |
ctx->y[i] ^= work_buf[i]; |
gcm_mult( ctx, ctx->y, ctx->y ); |
} |
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, |
&olen ) ) != 0 ) |
{ |
return( ret ); |
} |
ctx->add_len = add_len; |
p = add; |
while( add_len > 0 ) |
{ |
use_len = ( add_len < 16 ) ? add_len : 16; |
for( i = 0; i < use_len; i++ ) |
ctx->buf[i] ^= p[i]; |
gcm_mult( ctx, ctx->buf, ctx->buf ); |
add_len -= use_len; |
p += use_len; |
} |
return( 0 ); |
} |
int mbedtls_gcm_update( mbedtls_gcm_context *ctx, |
size_t length, |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
unsigned char ectr[16]; |
size_t i; |
const unsigned char *p; |
unsigned char *out_p = output; |
size_t use_len, olen = 0; |
GCM_VALIDATE_RET( ctx != NULL ); |
GCM_VALIDATE_RET( length == 0 || input != NULL ); |
GCM_VALIDATE_RET( length == 0 || output != NULL ); |
if( output > input && (size_t) ( output - input ) < length ) |
return( MBEDTLS_ERR_GCM_BAD_INPUT ); |
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes |
* Also check for possible overflow */ |
if( ctx->len + length < ctx->len || |
(uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) |
{ |
return( MBEDTLS_ERR_GCM_BAD_INPUT ); |
} |
ctx->len += length; |
p = input; |
while( length > 0 ) |
{ |
use_len = ( length < 16 ) ? length : 16; |
for( i = 16; i > 12; i-- ) |
if( ++ctx->y[i - 1] != 0 ) |
break; |
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, |
&olen ) ) != 0 ) |
{ |
return( ret ); |
} |
for( i = 0; i < use_len; i++ ) |
{ |
if( ctx->mode == MBEDTLS_GCM_DECRYPT ) |
ctx->buf[i] ^= p[i]; |
out_p[i] = ectr[i] ^ p[i]; |
if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) |
ctx->buf[i] ^= out_p[i]; |
} |
gcm_mult( ctx, ctx->buf, ctx->buf ); |
length -= use_len; |
p += use_len; |
out_p += use_len; |
} |
return( 0 ); |
} |
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, |
unsigned char *tag, |
size_t tag_len ) |
{ |
unsigned char work_buf[16]; |
size_t i; |
uint64_t orig_len; |
uint64_t orig_add_len; |
GCM_VALIDATE_RET( ctx != NULL ); |
GCM_VALIDATE_RET( tag != NULL ); |
orig_len = ctx->len * 8; |
orig_add_len = ctx->add_len * 8; |
if( tag_len > 16 || tag_len < 4 ) |
return( MBEDTLS_ERR_GCM_BAD_INPUT ); |
memcpy( tag, ctx->base_ectr, tag_len ); |
if( orig_len || orig_add_len ) |
{ |
memset( work_buf, 0x00, 16 ); |
PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); |
PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); |
PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); |
PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); |
for( i = 0; i < 16; i++ ) |
ctx->buf[i] ^= work_buf[i]; |
gcm_mult( ctx, ctx->buf, ctx->buf ); |
for( i = 0; i < tag_len; i++ ) |
tag[i] ^= ctx->buf[i]; |
} |
return( 0 ); |
} |
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, |
int mode, |
size_t length, |
const unsigned char *iv, |
size_t iv_len, |
const unsigned char *add, |
size_t add_len, |
const unsigned char *input, |
unsigned char *output, |
size_t tag_len, |
unsigned char *tag ) |
{ |
int ret; |
GCM_VALIDATE_RET( ctx != NULL ); |
GCM_VALIDATE_RET( iv != NULL ); |
GCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
GCM_VALIDATE_RET( length == 0 || input != NULL ); |
GCM_VALIDATE_RET( length == 0 || output != NULL ); |
GCM_VALIDATE_RET( tag != NULL ); |
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, |
size_t length, |
const unsigned char *iv, |
size_t iv_len, |
const unsigned char *add, |
size_t add_len, |
const unsigned char *tag, |
size_t tag_len, |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
unsigned char check_tag[16]; |
size_t i; |
int diff; |
GCM_VALIDATE_RET( ctx != NULL ); |
GCM_VALIDATE_RET( iv != NULL ); |
GCM_VALIDATE_RET( add_len == 0 || add != NULL ); |
GCM_VALIDATE_RET( tag != NULL ); |
GCM_VALIDATE_RET( length == 0 || input != NULL ); |
GCM_VALIDATE_RET( length == 0 || output != NULL ); |
if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, |
iv, iv_len, add, add_len, |
input, output, tag_len, check_tag ) ) != 0 ) |
{ |
return( ret ); |
} |
/* Check tag in "constant-time" */ |
for( diff = 0, i = 0; i < tag_len; i++ ) |
diff |= tag[i] ^ check_tag[i]; |
if( diff != 0 ) |
{ |
mbedtls_platform_zeroize( output, length ); |
return( MBEDTLS_ERR_GCM_AUTH_FAILED ); |
} |
return( 0 ); |
} |
void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_cipher_free( &ctx->cipher_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); |
} |
#endif /* !MBEDTLS_GCM_ALT */ |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
/* |
* AES-GCM test vectors from: |
* |
* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip |
*/ |
#define MAX_TESTS 6 |
static const int key_index[MAX_TESTS] = |
{ 0, 0, 1, 1, 1, 1 }; |
static const unsigned char key[MAX_TESTS][32] = |
{ |
{ 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 }, |
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, |
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, |
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, |
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, |
}; |
static const size_t iv_len[MAX_TESTS] = |
{ 12, 12, 12, 12, 8, 60 }; |
static const int iv_index[MAX_TESTS] = |
{ 0, 0, 1, 1, 1, 2 }; |
static const unsigned char iv[MAX_TESTS][64] = |
{ |
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00 }, |
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, |
0xde, 0xca, 0xf8, 0x88 }, |
{ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, |
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, |
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, |
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, |
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, |
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, |
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, |
0xa6, 0x37, 0xb3, 0x9b }, |
}; |
static const size_t add_len[MAX_TESTS] = |
{ 0, 0, 0, 20, 20, 20 }; |
static const int add_index[MAX_TESTS] = |
{ 0, 0, 0, 1, 1, 1 }; |
static const unsigned char additional[MAX_TESTS][64] = |
{ |
{ 0x00 }, |
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, |
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, |
0xab, 0xad, 0xda, 0xd2 }, |
}; |
static const size_t pt_len[MAX_TESTS] = |
{ 0, 16, 64, 60, 60, 60 }; |
static const int pt_index[MAX_TESTS] = |
{ 0, 0, 1, 1, 1, 1 }; |
static const unsigned char pt[MAX_TESTS][64] = |
{ |
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, |
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, |
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, |
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, |
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, |
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, |
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, |
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, |
}; |
static const unsigned char ct[MAX_TESTS * 3][64] = |
{ |
{ 0x00 }, |
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, |
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, |
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, |
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, |
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, |
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, |
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, |
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, |
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, |
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, |
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, |
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, |
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, |
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, |
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, |
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, |
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, |
0x3d, 0x58, 0xe0, 0x91 }, |
{ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, |
0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, |
0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, |
0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, |
0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, |
0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, |
0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, |
0xc2, 0x3f, 0x45, 0x98 }, |
{ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, |
0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, |
0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, |
0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, |
0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, |
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, |
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, |
0x4c, 0x34, 0xae, 0xe5 }, |
{ 0x00 }, |
{ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, |
0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, |
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, |
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, |
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, |
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, |
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, |
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, |
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, |
0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, |
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, |
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, |
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, |
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, |
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, |
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, |
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, |
0xcc, 0xda, 0x27, 0x10 }, |
{ 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, |
0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, |
0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, |
0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, |
0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, |
0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, |
0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, |
0xa0, 0xf0, 0x62, 0xf7 }, |
{ 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, |
0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, |
0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, |
0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, |
0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, |
0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, |
0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, |
0xe9, 0xb7, 0x37, 0x3b }, |
{ 0x00 }, |
{ 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, |
0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, |
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, |
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, |
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, |
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, |
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, |
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, |
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, |
0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, |
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, |
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, |
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, |
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, |
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, |
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, |
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, |
0xbc, 0xc9, 0xf6, 0x62 }, |
{ 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, |
0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, |
0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, |
0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, |
0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, |
0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, |
0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, |
0xf4, 0x7c, 0x9b, 0x1f }, |
{ 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, |
0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, |
0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, |
0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, |
0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, |
0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, |
0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, |
0x44, 0xae, 0x7e, 0x3f }, |
}; |
static const unsigned char tag[MAX_TESTS * 3][16] = |
{ |
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, |
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, |
{ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, |
0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, |
{ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, |
0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, |
{ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, |
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, |
{ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, |
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, |
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, |
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, |
{ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, |
0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, |
{ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, |
0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, |
{ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, |
0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, |
{ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, |
0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, |
{ 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, |
0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, |
{ 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, |
0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, |
{ 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, |
0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, |
{ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, |
0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, |
{ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, |
0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, |
{ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, |
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, |
{ 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, |
0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, |
{ 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, |
0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, |
}; |
int mbedtls_gcm_self_test( int verbose ) |
{ |
mbedtls_gcm_context ctx; |
unsigned char buf[64]; |
unsigned char tag_buf[16]; |
int i, j, ret; |
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; |
for( j = 0; j < 3; j++ ) |
{ |
int key_len = 128 + 64 * j; |
for( i = 0; i < MAX_TESTS; i++ ) |
{ |
mbedtls_gcm_init( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( " AES-GCM-%3d #%d (%s): ", |
key_len, i, "enc" ); |
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], |
key_len ); |
/* |
* AES-192 is an optional feature that may be unavailable when |
* there is an alternative underlying implementation i.e. when |
* MBEDTLS_AES_ALT is defined. |
*/ |
if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 ) |
{ |
mbedtls_printf( "skipped\n" ); |
break; |
} |
else if( ret != 0 ) |
{ |
goto exit; |
} |
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, |
pt_len[i], |
iv[iv_index[i]], iv_len[i], |
additional[add_index[i]], add_len[i], |
pt[pt_index[i]], buf, 16, tag_buf ); |
if( ret != 0 ) |
goto exit; |
if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || |
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
mbedtls_gcm_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
mbedtls_gcm_init( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( " AES-GCM-%3d #%d (%s): ", |
key_len, i, "dec" ); |
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], |
key_len ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, |
pt_len[i], |
iv[iv_index[i]], iv_len[i], |
additional[add_index[i]], add_len[i], |
ct[j * 6 + i], buf, 16, tag_buf ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || |
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
mbedtls_gcm_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
mbedtls_gcm_init( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", |
key_len, i, "enc" ); |
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], |
key_len ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, |
iv[iv_index[i]], iv_len[i], |
additional[add_index[i]], add_len[i] ); |
if( ret != 0 ) |
goto exit; |
if( pt_len[i] > 32 ) |
{ |
size_t rest_len = pt_len[i] - 32; |
ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, |
buf + 32 ); |
if( ret != 0 ) |
goto exit; |
} |
else |
{ |
ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); |
if( ret != 0 ) |
goto exit; |
} |
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || |
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
mbedtls_gcm_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
mbedtls_gcm_init( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", |
key_len, i, "dec" ); |
ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], |
key_len ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, |
iv[iv_index[i]], iv_len[i], |
additional[add_index[i]], add_len[i] ); |
if( ret != 0 ) |
goto exit; |
if( pt_len[i] > 32 ) |
{ |
size_t rest_len = pt_len[i] - 32; |
ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, |
buf + 32 ); |
if( ret != 0 ) |
goto exit; |
} |
else |
{ |
ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], |
buf ); |
if( ret != 0 ) |
goto exit; |
} |
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); |
if( ret != 0 ) |
goto exit; |
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || |
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
mbedtls_gcm_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
ret = 0; |
exit: |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
mbedtls_gcm_free( &ctx ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#endif /* MBEDTLS_GCM_C */ |
/programs/develop/libraries/kos_mbedtls/library/havege.c |
---|
0,0 → 1,255 |
/** |
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* 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 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_HAVEGE_C) |
#include "mbedtls/havege.h" |
#include "mbedtls/timing.h" |
#include "mbedtls/platform_util.h" |
#include <limits.h> |
#include <string.h> |
/* If int isn't capable of storing 2^32 distinct values, the code of this |
* module may cause a processor trap or a miscalculation. If int is more |
* than 32 bits, the code may not calculate the intended values. */ |
#if INT_MIN + 1 != -0x7fffffff |
#error "The HAVEGE module requires int to be exactly 32 bits, with INT_MIN = -2^31." |
#endif |
#if UINT_MAX != 0xffffffff |
#error "The HAVEGE module requires unsigned to be exactly 32 bits." |
#endif |
/* ------------------------------------------------------------------------ |
* 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) { unsigned *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 = (unsigned) mbedtls_timing_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 = (unsigned) mbedtls_timing_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++ ) \ |
POOL[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i]; |
/* |
* Entropy gathering function |
*/ |
static void havege_fill( mbedtls_havege_state *hs ) |
{ |
unsigned i, n = 0; |
unsigned U1, U2, *A, *B, *C, *D; |
unsigned PT1, PT2, *WALK, *POOL, RES[16]; |
unsigned PTX, PTY, CLK, PTEST, IN; |
WALK = (unsigned *) hs->WALK; |
POOL = (unsigned *) hs->pool; |
PT1 = hs->PT1; |
PT2 = hs->PT2; |
PTX = U1 = 0; |
PTY = U2 = 0; |
(void)PTX; |
memset( RES, 0, sizeof( RES ) ); |
while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) |
{ |
ONE_ITERATION |
ONE_ITERATION |
ONE_ITERATION |
ONE_ITERATION |
} |
hs->PT1 = PT1; |
hs->PT2 = PT2; |
hs->offset[0] = 0; |
hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2; |
} |
/* |
* HAVEGE initialization |
*/ |
void mbedtls_havege_init( mbedtls_havege_state *hs ) |
{ |
memset( hs, 0, sizeof( mbedtls_havege_state ) ); |
havege_fill( hs ); |
} |
void mbedtls_havege_free( mbedtls_havege_state *hs ) |
{ |
if( hs == NULL ) |
return; |
mbedtls_platform_zeroize( hs, sizeof( mbedtls_havege_state ) ); |
} |
/* |
* HAVEGE rand function |
*/ |
int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len ) |
{ |
int val; |
size_t use_len; |
mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng; |
unsigned char *p = buf; |
while( len > 0 ) |
{ |
use_len = len; |
if( use_len > sizeof(int) ) |
use_len = sizeof(int); |
if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE ) |
havege_fill( hs ); |
val = hs->pool[hs->offset[0]++]; |
val ^= hs->pool[hs->offset[1]++]; |
memcpy( p, &val, use_len ); |
len -= use_len; |
p += use_len; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_HAVEGE_C */ |
/programs/develop/libraries/kos_mbedtls/library/hkdf.c |
---|
0,0 → 1,194 |
/* |
* HKDF implementation -- RFC 5869 |
* |
* Copyright (C) 2016-2018, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_HKDF_C) |
#include <string.h> |
#include "mbedtls/hkdf.h" |
#include "mbedtls/platform_util.h" |
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, |
size_t salt_len, const unsigned char *ikm, size_t ikm_len, |
const unsigned char *info, size_t info_len, |
unsigned char *okm, size_t okm_len ) |
{ |
int ret; |
unsigned char prk[MBEDTLS_MD_MAX_SIZE]; |
ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk ); |
if( ret == 0 ) |
{ |
ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ), |
info, info_len, okm, okm_len ); |
} |
mbedtls_platform_zeroize( prk, sizeof( prk ) ); |
return( ret ); |
} |
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, |
const unsigned char *salt, size_t salt_len, |
const unsigned char *ikm, size_t ikm_len, |
unsigned char *prk ) |
{ |
unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; |
if( salt == NULL ) |
{ |
size_t hash_len; |
if( salt_len != 0 ) |
{ |
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; |
} |
hash_len = mbedtls_md_get_size( md ); |
if( hash_len == 0 ) |
{ |
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; |
} |
salt = null_salt; |
salt_len = hash_len; |
} |
return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) ); |
} |
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, |
size_t prk_len, const unsigned char *info, |
size_t info_len, unsigned char *okm, size_t okm_len ) |
{ |
size_t hash_len; |
size_t where = 0; |
size_t n; |
size_t t_len = 0; |
size_t i; |
int ret = 0; |
mbedtls_md_context_t ctx; |
unsigned char t[MBEDTLS_MD_MAX_SIZE]; |
if( okm == NULL ) |
{ |
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); |
} |
hash_len = mbedtls_md_get_size( md ); |
if( prk_len < hash_len || hash_len == 0 ) |
{ |
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); |
} |
if( info == NULL ) |
{ |
info = (const unsigned char *) ""; |
info_len = 0; |
} |
n = okm_len / hash_len; |
if( (okm_len % hash_len) != 0 ) |
{ |
n++; |
} |
/* |
* Per RFC 5869 Section 2.3, okm_len must not exceed |
* 255 times the hash length |
*/ |
if( n > 255 ) |
{ |
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); |
} |
mbedtls_md_init( &ctx ); |
if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 ) |
{ |
goto exit; |
} |
/* |
* Compute T = T(1) | T(2) | T(3) | ... | T(N) |
* Where T(N) is defined in RFC 5869 Section 2.3 |
*/ |
for( i = 1; i <= n; i++ ) |
{ |
size_t num_to_copy; |
unsigned char c = i & 0xff; |
ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len ); |
if( ret != 0 ) |
{ |
goto exit; |
} |
ret = mbedtls_md_hmac_update( &ctx, t, t_len ); |
if( ret != 0 ) |
{ |
goto exit; |
} |
ret = mbedtls_md_hmac_update( &ctx, info, info_len ); |
if( ret != 0 ) |
{ |
goto exit; |
} |
/* The constant concatenated to the end of each T(n) is a single octet. |
* */ |
ret = mbedtls_md_hmac_update( &ctx, &c, 1 ); |
if( ret != 0 ) |
{ |
goto exit; |
} |
ret = mbedtls_md_hmac_finish( &ctx, t ); |
if( ret != 0 ) |
{ |
goto exit; |
} |
num_to_copy = i != n ? hash_len : okm_len - where; |
memcpy( okm + where, t, num_to_copy ); |
where += hash_len; |
t_len = hash_len; |
} |
exit: |
mbedtls_md_free( &ctx ); |
mbedtls_platform_zeroize( t, sizeof( t ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_HKDF_C */ |
/programs/develop/libraries/kos_mbedtls/library/hmac_drbg.c |
---|
0,0 → 1,627 |
/* |
* HMAC_DRBG implementation (NIST SP 800-90) |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The NIST SP 800-90A DRBGs are described in the following publication. |
* http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf |
* References below are based on rev. 1 (January 2012). |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_HMAC_DRBG_C) |
#include "mbedtls/hmac_drbg.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_FS_IO) |
#include <stdio.h> |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_PLATFORM_C */ |
/* |
* HMAC_DRBG context initialization |
*/ |
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &ctx->mutex ); |
#endif |
} |
/* |
* HMAC_DRBG update, using optional additional data (10.1.2.2) |
*/ |
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, |
size_t add_len ) |
{ |
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); |
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; |
unsigned char sep[1]; |
unsigned char K[MBEDTLS_MD_MAX_SIZE]; |
int ret; |
for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) |
{ |
/* Step 1 or 4 */ |
if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, |
ctx->V, md_len ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, |
sep, 1 ) ) != 0 ) |
goto exit; |
if( rounds == 2 ) |
{ |
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, |
additional, add_len ) ) != 0 ) |
goto exit; |
} |
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 ) |
goto exit; |
/* Step 2 or 5 */ |
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, |
ctx->V, md_len ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) |
goto exit; |
} |
exit: |
mbedtls_platform_zeroize( K, sizeof( K ) ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, |
size_t add_len ) |
{ |
(void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len ); |
} |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
/* |
* Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) |
*/ |
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, |
const mbedtls_md_info_t * md_info, |
const unsigned char *data, size_t data_len ) |
{ |
int ret; |
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) |
return( ret ); |
/* |
* Set initial working state. |
* Use the V memory location, which is currently all 0, to initialize the |
* MD context with an all-zero key. Then set V to its initial value. |
*/ |
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, |
mbedtls_md_get_size( md_info ) ) ) != 0 ) |
return( ret ); |
memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); |
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
/* |
* Internal function used both for seeding and reseeding the DRBG. |
* Comments starting with arabic numbers refer to section 10.1.2.4 |
* of SP800-90A, while roman numbers refer to section 9.2. |
*/ |
static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, size_t len, |
int use_nonce ) |
{ |
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; |
size_t seedlen = 0; |
int ret; |
{ |
size_t total_entropy_len; |
if( use_nonce == 0 ) |
total_entropy_len = ctx->entropy_len; |
else |
total_entropy_len = ctx->entropy_len * 3 / 2; |
/* III. Check input length */ |
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || |
total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) |
{ |
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); |
} |
} |
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); |
/* IV. Gather entropy_len bytes of entropy for the seed */ |
if( ( ret = ctx->f_entropy( ctx->p_entropy, |
seed, ctx->entropy_len ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); |
} |
seedlen += ctx->entropy_len; |
/* For initial seeding, allow adding of nonce generated |
* from the entropy source. See Sect 8.6.7 in SP800-90A. */ |
if( use_nonce ) |
{ |
/* Note: We don't merge the two calls to f_entropy() in order |
* to avoid requesting too much entropy from f_entropy() |
* at once. Specifically, if the underlying digest is not |
* SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which |
* is larger than the maximum of 32 Bytes that our own |
* entropy source implementation can emit in a single |
* call in configurations disabling SHA-512. */ |
if( ( ret = ctx->f_entropy( ctx->p_entropy, |
seed + seedlen, |
ctx->entropy_len / 2 ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); |
} |
seedlen += ctx->entropy_len / 2; |
} |
/* 1. Concatenate entropy and additional data if any */ |
if( additional != NULL && len != 0 ) |
{ |
memcpy( seed + seedlen, additional, len ); |
seedlen += len; |
} |
/* 2. Update state */ |
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 ) |
goto exit; |
/* 3. Reset reseed_counter */ |
ctx->reseed_counter = 1; |
exit: |
/* 4. Done */ |
mbedtls_platform_zeroize( seed, seedlen ); |
return( ret ); |
} |
/* |
* HMAC_DRBG reseeding: 10.1.2.4 + 9.2 |
*/ |
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, |
const unsigned char *additional, size_t len ) |
{ |
return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) ); |
} |
/* |
* HMAC_DRBG initialisation (10.1.2.3 + 9.1) |
* |
* The nonce is not passed as a separate parameter but extracted |
* from the entropy source as suggested in 8.6.7. |
*/ |
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, |
const mbedtls_md_info_t * md_info, |
int (*f_entropy)(void *, unsigned char *, size_t), |
void *p_entropy, |
const unsigned char *custom, |
size_t len ) |
{ |
int ret; |
size_t md_size; |
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) |
return( ret ); |
md_size = mbedtls_md_get_size( md_info ); |
/* |
* Set initial working state. |
* Use the V memory location, which is currently all 0, to initialize the |
* MD context with an all-zero key. Then set V to its initial value. |
*/ |
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 ) |
return( ret ); |
memset( ctx->V, 0x01, md_size ); |
ctx->f_entropy = f_entropy; |
ctx->p_entropy = p_entropy; |
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; |
if( ctx->entropy_len == 0 ) |
{ |
/* |
* See SP800-57 5.6.1 (p. 65-66) for the security strength provided by |
* each hash function, then according to SP800-90A rev1 10.1 table 2, |
* min_entropy_len (in bits) is security_strength. |
* |
* (This also matches the sizes used in the NIST test vectors.) |
*/ |
ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ |
md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ |
32; /* better (256+) -> 256 bits */ |
} |
if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, |
1 /* add nonce */ ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
/* |
* Set prediction resistance |
*/ |
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, |
int resistance ) |
{ |
ctx->prediction_resistance = resistance; |
} |
/* |
* Set entropy length grabbed for seeding |
*/ |
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) |
{ |
ctx->entropy_len = len; |
} |
/* |
* Set reseed interval |
*/ |
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) |
{ |
ctx->reseed_interval = interval; |
} |
/* |
* HMAC_DRBG random function with optional additional data: |
* 10.1.2.5 (arabic) + 9.3 (Roman) |
*/ |
int mbedtls_hmac_drbg_random_with_add( void *p_rng, |
unsigned char *output, size_t out_len, |
const unsigned char *additional, size_t add_len ) |
{ |
int ret; |
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; |
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); |
size_t left = out_len; |
unsigned char *out = output; |
/* II. Check request length */ |
if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) |
return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); |
/* III. Check input length */ |
if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) |
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); |
/* 1. (aka VII and IX) Check reseed counter and PR */ |
if( ctx->f_entropy != NULL && /* For no-reseeding instances */ |
( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || |
ctx->reseed_counter > ctx->reseed_interval ) ) |
{ |
if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) |
return( ret ); |
add_len = 0; /* VII.4 */ |
} |
/* 2. Use additional data if any */ |
if( additional != NULL && add_len != 0 ) |
{ |
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, |
additional, add_len ) ) != 0 ) |
goto exit; |
} |
/* 3, 4, 5. Generate bytes */ |
while( left != 0 ) |
{ |
size_t use_len = left > md_len ? md_len : left; |
if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, |
ctx->V, md_len ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) |
goto exit; |
memcpy( out, ctx->V, use_len ); |
out += use_len; |
left -= use_len; |
} |
/* 6. Update */ |
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, |
additional, add_len ) ) != 0 ) |
goto exit; |
/* 7. Update reseed counter */ |
ctx->reseed_counter++; |
exit: |
/* 8. Done */ |
return( ret ); |
} |
/* |
* HMAC_DRBG random function |
*/ |
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) |
{ |
int ret; |
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
/* |
* Free an HMAC_DRBG context |
*/ |
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &ctx->mutex ); |
#endif |
mbedtls_md_free( &ctx->md_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); |
} |
#if defined(MBEDTLS_FS_IO) |
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) |
{ |
int ret; |
FILE *f; |
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; |
if( ( f = fopen( path, "wb" ) ) == NULL ) |
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); |
if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) |
goto exit; |
if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) |
{ |
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; |
goto exit; |
} |
ret = 0; |
exit: |
fclose( f ); |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
return( ret ); |
} |
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) |
{ |
int ret = 0; |
FILE *f = NULL; |
size_t n; |
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; |
unsigned char c; |
if( ( f = fopen( path, "rb" ) ) == NULL ) |
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); |
n = fread( buf, 1, sizeof( buf ), f ); |
if( fread( &c, 1, 1, f ) != 0 ) |
{ |
ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; |
goto exit; |
} |
if( n == 0 || ferror( f ) ) |
{ |
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; |
goto exit; |
} |
fclose( f ); |
f = NULL; |
ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n ); |
exit: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
if( f != NULL ) |
fclose( f ); |
if( ret != 0 ) |
return( ret ); |
return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); |
} |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_SELF_TEST) |
#if !defined(MBEDTLS_SHA1_C) |
/* Dummy checkup routine */ |
int mbedtls_hmac_drbg_self_test( int verbose ) |
{ |
(void) verbose; |
return( 0 ); |
} |
#else |
#define OUTPUT_LEN 80 |
/* From a NIST PR=true test vector */ |
static const unsigned char entropy_pr[] = { |
0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, |
0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, |
0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, |
0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, |
0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; |
static const unsigned char result_pr[OUTPUT_LEN] = { |
0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, |
0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, |
0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, |
0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, |
0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, |
0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, |
0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; |
/* From a NIST PR=false test vector */ |
static const unsigned char entropy_nopr[] = { |
0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, |
0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, |
0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, |
0xe9, 0x9d, 0xfe, 0xdf }; |
static const unsigned char result_nopr[OUTPUT_LEN] = { |
0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, |
0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, |
0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, |
0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, |
0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, |
0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, |
0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; |
/* "Entropy" from buffer */ |
static size_t test_offset; |
static int hmac_drbg_self_test_entropy( void *data, |
unsigned char *buf, size_t len ) |
{ |
const unsigned char *p = data; |
memcpy( buf, p + test_offset, len ); |
test_offset += len; |
return( 0 ); |
} |
#define CHK( c ) if( (c) != 0 ) \ |
{ \ |
if( verbose != 0 ) \ |
mbedtls_printf( "failed\n" ); \ |
return( 1 ); \ |
} |
/* |
* Checkup routine for HMAC_DRBG with SHA-1 |
*/ |
int mbedtls_hmac_drbg_self_test( int verbose ) |
{ |
mbedtls_hmac_drbg_context ctx; |
unsigned char buf[OUTPUT_LEN]; |
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); |
mbedtls_hmac_drbg_init( &ctx ); |
/* |
* PR = True |
*/ |
if( verbose != 0 ) |
mbedtls_printf( " HMAC_DRBG (PR = True) : " ); |
test_offset = 0; |
CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, |
hmac_drbg_self_test_entropy, (void *) entropy_pr, |
NULL, 0 ) ); |
mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); |
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); |
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); |
CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); |
mbedtls_hmac_drbg_free( &ctx ); |
mbedtls_hmac_drbg_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
/* |
* PR = False |
*/ |
if( verbose != 0 ) |
mbedtls_printf( " HMAC_DRBG (PR = False) : " ); |
mbedtls_hmac_drbg_init( &ctx ); |
test_offset = 0; |
CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, |
hmac_drbg_self_test_entropy, (void *) entropy_nopr, |
NULL, 0 ) ); |
CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); |
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); |
CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); |
CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); |
mbedtls_hmac_drbg_free( &ctx ); |
mbedtls_hmac_drbg_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_HMAC_DRBG_C */ |
/programs/develop/libraries/kos_mbedtls/library/md.c |
---|
0,0 → 1,477 |
/** |
* \file mbedtls_md.c |
* |
* \brief Generic message digest wrapper for mbed TLS |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_MD_C) |
#include "mbedtls/md.h" |
#include "mbedtls/md_internal.h" |
#include "mbedtls/platform_util.h" |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include <string.h> |
#if defined(MBEDTLS_FS_IO) |
#include <stdio.h> |
#endif |
/* |
* Reminder: update profiles in x509_crt.c when adding a new hash! |
*/ |
static const int supported_digests[] = { |
#if defined(MBEDTLS_SHA512_C) |
MBEDTLS_MD_SHA512, |
MBEDTLS_MD_SHA384, |
#endif |
#if defined(MBEDTLS_SHA256_C) |
MBEDTLS_MD_SHA256, |
MBEDTLS_MD_SHA224, |
#endif |
#if defined(MBEDTLS_SHA1_C) |
MBEDTLS_MD_SHA1, |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
MBEDTLS_MD_RIPEMD160, |
#endif |
#if defined(MBEDTLS_MD5_C) |
MBEDTLS_MD_MD5, |
#endif |
#if defined(MBEDTLS_MD4_C) |
MBEDTLS_MD_MD4, |
#endif |
#if defined(MBEDTLS_MD2_C) |
MBEDTLS_MD_MD2, |
#endif |
MBEDTLS_MD_NONE |
}; |
const int *mbedtls_md_list( void ) |
{ |
return( supported_digests ); |
} |
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) |
{ |
if( NULL == md_name ) |
return( NULL ); |
/* Get the appropriate digest information */ |
#if defined(MBEDTLS_MD2_C) |
if( !strcmp( "MD2", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); |
#endif |
#if defined(MBEDTLS_MD4_C) |
if( !strcmp( "MD4", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); |
#endif |
#if defined(MBEDTLS_MD5_C) |
if( !strcmp( "MD5", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
if( !strcmp( "RIPEMD160", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); |
#endif |
#if defined(MBEDTLS_SHA1_C) |
if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); |
#endif |
#if defined(MBEDTLS_SHA256_C) |
if( !strcmp( "SHA224", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); |
if( !strcmp( "SHA256", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
if( !strcmp( "SHA384", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); |
if( !strcmp( "SHA512", md_name ) ) |
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); |
#endif |
return( NULL ); |
} |
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) |
{ |
switch( md_type ) |
{ |
#if defined(MBEDTLS_MD2_C) |
case MBEDTLS_MD_MD2: |
return( &mbedtls_md2_info ); |
#endif |
#if defined(MBEDTLS_MD4_C) |
case MBEDTLS_MD_MD4: |
return( &mbedtls_md4_info ); |
#endif |
#if defined(MBEDTLS_MD5_C) |
case MBEDTLS_MD_MD5: |
return( &mbedtls_md5_info ); |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
case MBEDTLS_MD_RIPEMD160: |
return( &mbedtls_ripemd160_info ); |
#endif |
#if defined(MBEDTLS_SHA1_C) |
case MBEDTLS_MD_SHA1: |
return( &mbedtls_sha1_info ); |
#endif |
#if defined(MBEDTLS_SHA256_C) |
case MBEDTLS_MD_SHA224: |
return( &mbedtls_sha224_info ); |
case MBEDTLS_MD_SHA256: |
return( &mbedtls_sha256_info ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
case MBEDTLS_MD_SHA384: |
return( &mbedtls_sha384_info ); |
case MBEDTLS_MD_SHA512: |
return( &mbedtls_sha512_info ); |
#endif |
default: |
return( NULL ); |
} |
} |
void mbedtls_md_init( mbedtls_md_context_t *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); |
} |
void mbedtls_md_free( mbedtls_md_context_t *ctx ) |
{ |
if( ctx == NULL || ctx->md_info == NULL ) |
return; |
if( ctx->md_ctx != NULL ) |
ctx->md_info->ctx_free_func( ctx->md_ctx ); |
if( ctx->hmac_ctx != NULL ) |
{ |
mbedtls_platform_zeroize( ctx->hmac_ctx, |
2 * ctx->md_info->block_size ); |
mbedtls_free( ctx->hmac_ctx ); |
} |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); |
} |
int mbedtls_md_clone( mbedtls_md_context_t *dst, |
const mbedtls_md_context_t *src ) |
{ |
if( dst == NULL || dst->md_info == NULL || |
src == NULL || src->md_info == NULL || |
dst->md_info != src->md_info ) |
{ |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
} |
dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); |
return( 0 ); |
} |
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) |
{ |
return mbedtls_md_setup( ctx, md_info, 1 ); |
} |
#endif |
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) |
{ |
if( md_info == NULL || ctx == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) |
return( MBEDTLS_ERR_MD_ALLOC_FAILED ); |
if( hmac != 0 ) |
{ |
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); |
if( ctx->hmac_ctx == NULL ) |
{ |
md_info->ctx_free_func( ctx->md_ctx ); |
return( MBEDTLS_ERR_MD_ALLOC_FAILED ); |
} |
} |
ctx->md_info = md_info; |
return( 0 ); |
} |
int mbedtls_md_starts( mbedtls_md_context_t *ctx ) |
{ |
if( ctx == NULL || ctx->md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
return( ctx->md_info->starts_func( ctx->md_ctx ) ); |
} |
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) |
{ |
if( ctx == NULL || ctx->md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); |
} |
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) |
{ |
if( ctx == NULL || ctx->md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); |
} |
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
if( md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
return( md_info->digest_func( input, ilen, output ) ); |
} |
#if defined(MBEDTLS_FS_IO) |
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) |
{ |
int ret; |
FILE *f; |
size_t n; |
mbedtls_md_context_t ctx; |
unsigned char buf[1024]; |
if( md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
if( ( f = fopen( path, "rb" ) ) == NULL ) |
return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); |
mbedtls_md_init( &ctx ); |
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) |
goto cleanup; |
if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) |
goto cleanup; |
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) |
if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) |
goto cleanup; |
if( ferror( f ) != 0 ) |
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; |
else |
ret = md_info->finish_func( ctx.md_ctx, output ); |
cleanup: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
fclose( f ); |
mbedtls_md_free( &ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) |
{ |
int ret; |
unsigned char sum[MBEDTLS_MD_MAX_SIZE]; |
unsigned char *ipad, *opad; |
size_t i; |
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
if( keylen > (size_t) ctx->md_info->block_size ) |
{ |
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) |
goto cleanup; |
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) |
goto cleanup; |
if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) |
goto cleanup; |
keylen = ctx->md_info->size; |
key = sum; |
} |
ipad = (unsigned char *) ctx->hmac_ctx; |
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; |
memset( ipad, 0x36, ctx->md_info->block_size ); |
memset( opad, 0x5C, ctx->md_info->block_size ); |
for( i = 0; i < keylen; i++ ) |
{ |
ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); |
opad[i] = (unsigned char)( opad[i] ^ key[i] ); |
} |
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) |
goto cleanup; |
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, |
ctx->md_info->block_size ) ) != 0 ) |
goto cleanup; |
cleanup: |
mbedtls_platform_zeroize( sum, sizeof( sum ) ); |
return( ret ); |
} |
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) |
{ |
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); |
} |
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) |
{ |
int ret; |
unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; |
unsigned char *opad; |
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; |
if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) |
return( ret ); |
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) |
return( ret ); |
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, |
ctx->md_info->block_size ) ) != 0 ) |
return( ret ); |
if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, |
ctx->md_info->size ) ) != 0 ) |
return( ret ); |
return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); |
} |
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) |
{ |
int ret; |
unsigned char *ipad; |
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
ipad = (unsigned char *) ctx->hmac_ctx; |
if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) |
return( ret ); |
return( ctx->md_info->update_func( ctx->md_ctx, ipad, |
ctx->md_info->block_size ) ); |
} |
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, |
const unsigned char *key, size_t keylen, |
const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
mbedtls_md_context_t ctx; |
int ret; |
if( md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
mbedtls_md_init( &ctx ); |
if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) |
goto cleanup; |
if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) |
goto cleanup; |
if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) |
goto cleanup; |
if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) |
goto cleanup; |
cleanup: |
mbedtls_md_free( &ctx ); |
return( ret ); |
} |
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) |
{ |
if( ctx == NULL || ctx->md_info == NULL ) |
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
return( ctx->md_info->process_func( ctx->md_ctx, data ) ); |
} |
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) |
{ |
if( md_info == NULL ) |
return( 0 ); |
return md_info->size; |
} |
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) |
{ |
if( md_info == NULL ) |
return( MBEDTLS_MD_NONE ); |
return md_info->type; |
} |
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) |
{ |
if( md_info == NULL ) |
return( NULL ); |
return md_info->name; |
} |
#endif /* MBEDTLS_MD_C */ |
/programs/develop/libraries/kos_mbedtls/library/md2.c |
---|
0,0 → 1,365 |
/* |
* RFC 1115/1319 compliant MD2 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The MD2 algorithm was designed by Ron Rivest in 1989. |
* |
* http://www.ietf.org/rfc/rfc1115.txt |
* http://www.ietf.org/rfc/rfc1319.txt |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_MD2_C) |
#include "mbedtls/md2.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_MD2_ALT) |
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 |
}; |
void mbedtls_md2_init( mbedtls_md2_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_md2_context ) ); |
} |
void mbedtls_md2_free( mbedtls_md2_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) ); |
} |
void mbedtls_md2_clone( mbedtls_md2_context *dst, |
const mbedtls_md2_context *src ) |
{ |
*dst = *src; |
} |
/* |
* MD2 context setup |
*/ |
int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ) |
{ |
memset( ctx->cksum, 0, 16 ); |
memset( ctx->state, 0, 46 ); |
memset( ctx->buffer, 0, 16 ); |
ctx->left = 0; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md2_starts( mbedtls_md2_context *ctx ) |
{ |
mbedtls_md2_starts_ret( ctx ); |
} |
#endif |
#if !defined(MBEDTLS_MD2_PROCESS_ALT) |
int mbedtls_internal_md2_process( mbedtls_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]; |
} |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md2_process( mbedtls_md2_context *ctx ) |
{ |
mbedtls_internal_md2_process( ctx ); |
} |
#endif |
#endif /* !MBEDTLS_MD2_PROCESS_ALT */ |
/* |
* MD2 process buffer |
*/ |
int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
while( ilen > 0 ) |
{ |
if( ilen > 16 - ctx->left ) |
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; |
if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) |
return( ret ); |
} |
} |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md2_update( mbedtls_md2_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_md2_update_ret( ctx, input, ilen ); |
} |
#endif |
/* |
* MD2 final digest |
*/ |
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, |
unsigned char output[16] ) |
{ |
int ret; |
size_t i; |
unsigned char x; |
x = (unsigned char)( 16 - ctx->left ); |
for( i = ctx->left; i < 16; i++ ) |
ctx->buffer[i] = x; |
if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) |
return( ret ); |
memcpy( ctx->buffer, ctx->cksum, 16 ); |
if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 ) |
return( ret ); |
memcpy( output, ctx->state, 16 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md2_finish( mbedtls_md2_context *ctx, |
unsigned char output[16] ) |
{ |
mbedtls_md2_finish_ret( ctx, output ); |
} |
#endif |
#endif /* !MBEDTLS_MD2_ALT */ |
/* |
* output = MD2( input buffer ) |
*/ |
int mbedtls_md2_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ) |
{ |
int ret; |
mbedtls_md2_context ctx; |
mbedtls_md2_init( &ctx ); |
if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_md2_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md2( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ) |
{ |
mbedtls_md2_ret( input, ilen, output ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* RFC 1319 test vectors |
*/ |
static const unsigned char md2_test_str[7][81] = |
{ |
{ "" }, |
{ "a" }, |
{ "abc" }, |
{ "message digest" }, |
{ "abcdefghijklmnopqrstuvwxyz" }, |
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, |
{ "12345678901234567890123456789012345678901234567890123456789012" |
"345678901234567890" } |
}; |
static const size_t md2_test_strlen[7] = |
{ |
0, 1, 3, 14, 26, 62, 80 |
}; |
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 mbedtls_md2_self_test( int verbose ) |
{ |
int i, ret = 0; |
unsigned char md2sum[16]; |
for( i = 0; i < 7; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " MD2 test #%d: ", i + 1 ); |
ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum ); |
if( ret != 0 ) |
goto fail; |
if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_MD2_C */ |
/programs/develop/libraries/kos_mbedtls/library/md4.c |
---|
0,0 → 1,486 |
/* |
* RFC 1186/1320 compliant MD4 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The MD4 algorithm was designed by Ron Rivest in 1990. |
* |
* http://www.ietf.org/rfc/rfc1186.txt |
* http://www.ietf.org/rfc/rfc1320.txt |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_MD4_C) |
#include "mbedtls/md4.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_MD4_ALT) |
/* |
* 32-bit integer manipulation macros (little endian) |
*/ |
#ifndef GET_UINT32_LE |
#define GET_UINT32_LE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] ) \ |
| ( (uint32_t) (b)[(i) + 1] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 3] << 24 ); \ |
} |
#endif |
#ifndef PUT_UINT32_LE |
#define PUT_UINT32_LE(n,b,i) \ |
{ \ |
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ |
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ |
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ |
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ |
} |
#endif |
void mbedtls_md4_init( mbedtls_md4_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_md4_context ) ); |
} |
void mbedtls_md4_free( mbedtls_md4_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) ); |
} |
void mbedtls_md4_clone( mbedtls_md4_context *dst, |
const mbedtls_md4_context *src ) |
{ |
*dst = *src; |
} |
/* |
* MD4 context setup |
*/ |
int mbedtls_md4_starts_ret( mbedtls_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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md4_starts( mbedtls_md4_context *ctx ) |
{ |
mbedtls_md4_starts_ret( ctx ); |
} |
#endif |
#if !defined(MBEDTLS_MD4_PROCESS_ALT) |
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, |
const unsigned char data[64] ) |
{ |
uint32_t X[16], A, B, C, D; |
GET_UINT32_LE( X[ 0], data, 0 ); |
GET_UINT32_LE( X[ 1], data, 4 ); |
GET_UINT32_LE( X[ 2], data, 8 ); |
GET_UINT32_LE( X[ 3], data, 12 ); |
GET_UINT32_LE( X[ 4], data, 16 ); |
GET_UINT32_LE( X[ 5], data, 20 ); |
GET_UINT32_LE( X[ 6], data, 24 ); |
GET_UINT32_LE( X[ 7], data, 28 ); |
GET_UINT32_LE( X[ 8], data, 32 ); |
GET_UINT32_LE( X[ 9], data, 36 ); |
GET_UINT32_LE( X[10], data, 40 ); |
GET_UINT32_LE( X[11], data, 44 ); |
GET_UINT32_LE( X[12], data, 48 ); |
GET_UINT32_LE( X[13], data, 52 ); |
GET_UINT32_LE( X[14], data, 56 ); |
GET_UINT32_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) \ |
do \ |
{ \ |
(a) += F((b),(c),(d)) + (x); \ |
(a) = S((a),(s)); \ |
} while( 0 ) |
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) \ |
do \ |
{ \ |
(a) += F((b),(c),(d)) + (x) + 0x5A827999; \ |
(a) = S((a),(s)); \ |
} while( 0 ) |
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) \ |
do \ |
{ \ |
(a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \ |
(a) = S((a),(s)); \ |
} while( 0 ) |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md4_process( mbedtls_md4_context *ctx, |
const unsigned char data[64] ) |
{ |
mbedtls_internal_md4_process( ctx, data ); |
} |
#endif |
#endif /* !MBEDTLS_MD4_PROCESS_ALT */ |
/* |
* MD4 process buffer |
*/ |
int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
uint32_t left; |
if( ilen == 0 ) |
return( 0 ); |
left = ctx->total[0] & 0x3F; |
fill = 64 - left; |
ctx->total[0] += (uint32_t) ilen; |
ctx->total[0] &= 0xFFFFFFFF; |
if( ctx->total[0] < (uint32_t) ilen ) |
ctx->total[1]++; |
if( left && ilen >= fill ) |
{ |
memcpy( (void *) (ctx->buffer + left), |
(void *) input, fill ); |
if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
input += fill; |
ilen -= fill; |
left = 0; |
} |
while( ilen >= 64 ) |
{ |
if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 ) |
return( ret ); |
input += 64; |
ilen -= 64; |
} |
if( ilen > 0 ) |
{ |
memcpy( (void *) (ctx->buffer + left), |
(void *) input, ilen ); |
} |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md4_update( mbedtls_md4_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_md4_update_ret( ctx, input, ilen ); |
} |
#endif |
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 |
*/ |
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, |
unsigned char output[16] ) |
{ |
int ret; |
uint32_t last, padn; |
uint32_t high, low; |
unsigned char msglen[8]; |
high = ( ctx->total[0] >> 29 ) |
| ( ctx->total[1] << 3 ); |
low = ( ctx->total[0] << 3 ); |
PUT_UINT32_LE( low, msglen, 0 ); |
PUT_UINT32_LE( high, msglen, 4 ); |
last = ctx->total[0] & 0x3F; |
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); |
ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn ); |
if( ret != 0 ) |
return( ret ); |
if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 ) |
return( ret ); |
PUT_UINT32_LE( ctx->state[0], output, 0 ); |
PUT_UINT32_LE( ctx->state[1], output, 4 ); |
PUT_UINT32_LE( ctx->state[2], output, 8 ); |
PUT_UINT32_LE( ctx->state[3], output, 12 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md4_finish( mbedtls_md4_context *ctx, |
unsigned char output[16] ) |
{ |
mbedtls_md4_finish_ret( ctx, output ); |
} |
#endif |
#endif /* !MBEDTLS_MD4_ALT */ |
/* |
* output = MD4( input buffer ) |
*/ |
int mbedtls_md4_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ) |
{ |
int ret; |
mbedtls_md4_context ctx; |
mbedtls_md4_init( &ctx ); |
if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_md4_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md4( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ) |
{ |
mbedtls_md4_ret( input, ilen, output ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* RFC 1320 test vectors |
*/ |
static const unsigned char md4_test_str[7][81] = |
{ |
{ "" }, |
{ "a" }, |
{ "abc" }, |
{ "message digest" }, |
{ "abcdefghijklmnopqrstuvwxyz" }, |
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, |
{ "12345678901234567890123456789012345678901234567890123456789012" |
"345678901234567890" } |
}; |
static const size_t md4_test_strlen[7] = |
{ |
0, 1, 3, 14, 26, 62, 80 |
}; |
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 mbedtls_md4_self_test( int verbose ) |
{ |
int i, ret = 0; |
unsigned char md4sum[16]; |
for( i = 0; i < 7; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " MD4 test #%d: ", i + 1 ); |
ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum ); |
if( ret != 0 ) |
goto fail; |
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_MD4_C */ |
/programs/develop/libraries/kos_mbedtls/library/md5.c |
---|
0,0 → 1,500 |
/* |
* RFC 1321 compliant MD5 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The MD5 algorithm was designed by Ron Rivest in 1991. |
* |
* http://www.ietf.org/rfc/rfc1321.txt |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_MD5_C) |
#include "mbedtls/md5.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_MD5_ALT) |
/* |
* 32-bit integer manipulation macros (little endian) |
*/ |
#ifndef GET_UINT32_LE |
#define GET_UINT32_LE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] ) \ |
| ( (uint32_t) (b)[(i) + 1] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 3] << 24 ); \ |
} |
#endif |
#ifndef PUT_UINT32_LE |
#define PUT_UINT32_LE(n,b,i) \ |
{ \ |
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ |
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ |
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ |
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ |
} |
#endif |
void mbedtls_md5_init( mbedtls_md5_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_md5_context ) ); |
} |
void mbedtls_md5_free( mbedtls_md5_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) ); |
} |
void mbedtls_md5_clone( mbedtls_md5_context *dst, |
const mbedtls_md5_context *src ) |
{ |
*dst = *src; |
} |
/* |
* MD5 context setup |
*/ |
int mbedtls_md5_starts_ret( mbedtls_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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md5_starts( mbedtls_md5_context *ctx ) |
{ |
mbedtls_md5_starts_ret( ctx ); |
} |
#endif |
#if !defined(MBEDTLS_MD5_PROCESS_ALT) |
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, |
const unsigned char data[64] ) |
{ |
uint32_t X[16], A, B, C, D; |
GET_UINT32_LE( X[ 0], data, 0 ); |
GET_UINT32_LE( X[ 1], data, 4 ); |
GET_UINT32_LE( X[ 2], data, 8 ); |
GET_UINT32_LE( X[ 3], data, 12 ); |
GET_UINT32_LE( X[ 4], data, 16 ); |
GET_UINT32_LE( X[ 5], data, 20 ); |
GET_UINT32_LE( X[ 6], data, 24 ); |
GET_UINT32_LE( X[ 7], data, 28 ); |
GET_UINT32_LE( X[ 8], data, 32 ); |
GET_UINT32_LE( X[ 9], data, 36 ); |
GET_UINT32_LE( X[10], data, 40 ); |
GET_UINT32_LE( X[11], data, 44 ); |
GET_UINT32_LE( X[12], data, 48 ); |
GET_UINT32_LE( X[13], data, 52 ); |
GET_UINT32_LE( X[14], data, 56 ); |
GET_UINT32_LE( X[15], data, 60 ); |
#define S(x,n) \ |
( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) ) |
#define P(a,b,c,d,k,s,t) \ |
do \ |
{ \ |
(a) += F((b),(c),(d)) + X[(k)] + (t); \ |
(a) = S((a),(s)) + (b); \ |
} while( 0 ) |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md5_process( mbedtls_md5_context *ctx, |
const unsigned char data[64] ) |
{ |
mbedtls_internal_md5_process( ctx, data ); |
} |
#endif |
#endif /* !MBEDTLS_MD5_PROCESS_ALT */ |
/* |
* MD5 process buffer |
*/ |
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
uint32_t left; |
if( ilen == 0 ) |
return( 0 ); |
left = ctx->total[0] & 0x3F; |
fill = 64 - left; |
ctx->total[0] += (uint32_t) ilen; |
ctx->total[0] &= 0xFFFFFFFF; |
if( ctx->total[0] < (uint32_t) ilen ) |
ctx->total[1]++; |
if( left && ilen >= fill ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, fill ); |
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
input += fill; |
ilen -= fill; |
left = 0; |
} |
while( ilen >= 64 ) |
{ |
if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 ) |
return( ret ); |
input += 64; |
ilen -= 64; |
} |
if( ilen > 0 ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, ilen ); |
} |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md5_update( mbedtls_md5_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_md5_update_ret( ctx, input, ilen ); |
} |
#endif |
/* |
* MD5 final digest |
*/ |
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, |
unsigned char output[16] ) |
{ |
int ret; |
uint32_t used; |
uint32_t high, low; |
/* |
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length |
*/ |
used = ctx->total[0] & 0x3F; |
ctx->buffer[used++] = 0x80; |
if( used <= 56 ) |
{ |
/* Enough room for padding + length in current block */ |
memset( ctx->buffer + used, 0, 56 - used ); |
} |
else |
{ |
/* We'll need an extra block */ |
memset( ctx->buffer + used, 0, 64 - used ); |
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
memset( ctx->buffer, 0, 56 ); |
} |
/* |
* Add message length |
*/ |
high = ( ctx->total[0] >> 29 ) |
| ( ctx->total[1] << 3 ); |
low = ( ctx->total[0] << 3 ); |
PUT_UINT32_LE( low, ctx->buffer, 56 ); |
PUT_UINT32_LE( high, ctx->buffer, 60 ); |
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
/* |
* Output final state |
*/ |
PUT_UINT32_LE( ctx->state[0], output, 0 ); |
PUT_UINT32_LE( ctx->state[1], output, 4 ); |
PUT_UINT32_LE( ctx->state[2], output, 8 ); |
PUT_UINT32_LE( ctx->state[3], output, 12 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md5_finish( mbedtls_md5_context *ctx, |
unsigned char output[16] ) |
{ |
mbedtls_md5_finish_ret( ctx, output ); |
} |
#endif |
#endif /* !MBEDTLS_MD5_ALT */ |
/* |
* output = MD5( input buffer ) |
*/ |
int mbedtls_md5_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ) |
{ |
int ret; |
mbedtls_md5_context ctx; |
mbedtls_md5_init( &ctx ); |
if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_md5_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_md5( const unsigned char *input, |
size_t ilen, |
unsigned char output[16] ) |
{ |
mbedtls_md5_ret( input, ilen, output ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* RFC 1321 test vectors |
*/ |
static const unsigned char md5_test_buf[7][81] = |
{ |
{ "" }, |
{ "a" }, |
{ "abc" }, |
{ "message digest" }, |
{ "abcdefghijklmnopqrstuvwxyz" }, |
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, |
{ "12345678901234567890123456789012345678901234567890123456789012" |
"345678901234567890" } |
}; |
static const size_t 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 } |
}; |
/* |
* Checkup routine |
*/ |
int mbedtls_md5_self_test( int verbose ) |
{ |
int i, ret = 0; |
unsigned char md5sum[16]; |
for( i = 0; i < 7; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " MD5 test #%d: ", i + 1 ); |
ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum ); |
if( ret != 0 ) |
goto fail; |
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_MD5_C */ |
/programs/develop/libraries/kos_mbedtls/library/md_wrap.c |
---|
0,0 → 1,588 |
/** |
* \file md_wrap.c |
* |
* \brief Generic message digest wrapper for mbed TLS |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_MD_C) |
#include "mbedtls/md_internal.h" |
#if defined(MBEDTLS_MD2_C) |
#include "mbedtls/md2.h" |
#endif |
#if defined(MBEDTLS_MD4_C) |
#include "mbedtls/md4.h" |
#endif |
#if defined(MBEDTLS_MD5_C) |
#include "mbedtls/md5.h" |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
#include "mbedtls/ripemd160.h" |
#endif |
#if defined(MBEDTLS_SHA1_C) |
#include "mbedtls/sha1.h" |
#endif |
#if defined(MBEDTLS_SHA256_C) |
#include "mbedtls/sha256.h" |
#endif |
#if defined(MBEDTLS_SHA512_C) |
#include "mbedtls/sha512.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#if defined(MBEDTLS_MD2_C) |
static int md2_starts_wrap( void *ctx ) |
{ |
return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) ); |
} |
static int md2_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) ); |
} |
static int md2_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) ); |
} |
static void *md2_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); |
if( ctx != NULL ) |
mbedtls_md2_init( (mbedtls_md2_context *) ctx ); |
return( ctx ); |
} |
static void md2_ctx_free( void *ctx ) |
{ |
mbedtls_md2_free( (mbedtls_md2_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void md2_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_md2_clone( (mbedtls_md2_context *) dst, |
(const mbedtls_md2_context *) src ); |
} |
static int md2_process_wrap( void *ctx, const unsigned char *data ) |
{ |
((void) data); |
return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); |
} |
const mbedtls_md_info_t mbedtls_md2_info = { |
MBEDTLS_MD_MD2, |
"MD2", |
16, |
16, |
md2_starts_wrap, |
md2_update_wrap, |
md2_finish_wrap, |
mbedtls_md2_ret, |
md2_ctx_alloc, |
md2_ctx_free, |
md2_clone_wrap, |
md2_process_wrap, |
}; |
#endif /* MBEDTLS_MD2_C */ |
#if defined(MBEDTLS_MD4_C) |
static int md4_starts_wrap( void *ctx ) |
{ |
return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) ); |
} |
static int md4_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) ); |
} |
static int md4_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) ); |
} |
static void *md4_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); |
if( ctx != NULL ) |
mbedtls_md4_init( (mbedtls_md4_context *) ctx ); |
return( ctx ); |
} |
static void md4_ctx_free( void *ctx ) |
{ |
mbedtls_md4_free( (mbedtls_md4_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void md4_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_md4_clone( (mbedtls_md4_context *) dst, |
(const mbedtls_md4_context *) src ); |
} |
static int md4_process_wrap( void *ctx, const unsigned char *data ) |
{ |
return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); |
} |
const mbedtls_md_info_t mbedtls_md4_info = { |
MBEDTLS_MD_MD4, |
"MD4", |
16, |
64, |
md4_starts_wrap, |
md4_update_wrap, |
md4_finish_wrap, |
mbedtls_md4_ret, |
md4_ctx_alloc, |
md4_ctx_free, |
md4_clone_wrap, |
md4_process_wrap, |
}; |
#endif /* MBEDTLS_MD4_C */ |
#if defined(MBEDTLS_MD5_C) |
static int md5_starts_wrap( void *ctx ) |
{ |
return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) ); |
} |
static int md5_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) ); |
} |
static int md5_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) ); |
} |
static void *md5_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); |
if( ctx != NULL ) |
mbedtls_md5_init( (mbedtls_md5_context *) ctx ); |
return( ctx ); |
} |
static void md5_ctx_free( void *ctx ) |
{ |
mbedtls_md5_free( (mbedtls_md5_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void md5_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_md5_clone( (mbedtls_md5_context *) dst, |
(const mbedtls_md5_context *) src ); |
} |
static int md5_process_wrap( void *ctx, const unsigned char *data ) |
{ |
return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); |
} |
const mbedtls_md_info_t mbedtls_md5_info = { |
MBEDTLS_MD_MD5, |
"MD5", |
16, |
64, |
md5_starts_wrap, |
md5_update_wrap, |
md5_finish_wrap, |
mbedtls_md5_ret, |
md5_ctx_alloc, |
md5_ctx_free, |
md5_clone_wrap, |
md5_process_wrap, |
}; |
#endif /* MBEDTLS_MD5_C */ |
#if defined(MBEDTLS_RIPEMD160_C) |
static int ripemd160_starts_wrap( void *ctx ) |
{ |
return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) ); |
} |
static int ripemd160_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx, |
input, ilen ) ); |
} |
static int ripemd160_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx, |
output ) ); |
} |
static void *ripemd160_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); |
if( ctx != NULL ) |
mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); |
return( ctx ); |
} |
static void ripemd160_ctx_free( void *ctx ) |
{ |
mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void ripemd160_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, |
(const mbedtls_ripemd160_context *) src ); |
} |
static int ripemd160_process_wrap( void *ctx, const unsigned char *data ) |
{ |
return( mbedtls_internal_ripemd160_process( |
(mbedtls_ripemd160_context *) ctx, data ) ); |
} |
const mbedtls_md_info_t mbedtls_ripemd160_info = { |
MBEDTLS_MD_RIPEMD160, |
"RIPEMD160", |
20, |
64, |
ripemd160_starts_wrap, |
ripemd160_update_wrap, |
ripemd160_finish_wrap, |
mbedtls_ripemd160_ret, |
ripemd160_ctx_alloc, |
ripemd160_ctx_free, |
ripemd160_clone_wrap, |
ripemd160_process_wrap, |
}; |
#endif /* MBEDTLS_RIPEMD160_C */ |
#if defined(MBEDTLS_SHA1_C) |
static int sha1_starts_wrap( void *ctx ) |
{ |
return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) ); |
} |
static int sha1_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx, |
input, ilen ) ); |
} |
static int sha1_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) ); |
} |
static void *sha1_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); |
if( ctx != NULL ) |
mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); |
return( ctx ); |
} |
static void sha1_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, |
(const mbedtls_sha1_context *) src ); |
} |
static void sha1_ctx_free( void *ctx ) |
{ |
mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static int sha1_process_wrap( void *ctx, const unsigned char *data ) |
{ |
return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx, |
data ) ); |
} |
const mbedtls_md_info_t mbedtls_sha1_info = { |
MBEDTLS_MD_SHA1, |
"SHA1", |
20, |
64, |
sha1_starts_wrap, |
sha1_update_wrap, |
sha1_finish_wrap, |
mbedtls_sha1_ret, |
sha1_ctx_alloc, |
sha1_ctx_free, |
sha1_clone_wrap, |
sha1_process_wrap, |
}; |
#endif /* MBEDTLS_SHA1_C */ |
/* |
* Wrappers for generic message digests |
*/ |
#if defined(MBEDTLS_SHA256_C) |
static int sha224_starts_wrap( void *ctx ) |
{ |
return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) ); |
} |
static int sha224_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx, |
input, ilen ) ); |
} |
static int sha224_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx, |
output ) ); |
} |
static int sha224_wrap( const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); |
} |
static void *sha224_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); |
if( ctx != NULL ) |
mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); |
return( ctx ); |
} |
static void sha224_ctx_free( void *ctx ) |
{ |
mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void sha224_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, |
(const mbedtls_sha256_context *) src ); |
} |
static int sha224_process_wrap( void *ctx, const unsigned char *data ) |
{ |
return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx, |
data ) ); |
} |
const mbedtls_md_info_t mbedtls_sha224_info = { |
MBEDTLS_MD_SHA224, |
"SHA224", |
28, |
64, |
sha224_starts_wrap, |
sha224_update_wrap, |
sha224_finish_wrap, |
sha224_wrap, |
sha224_ctx_alloc, |
sha224_ctx_free, |
sha224_clone_wrap, |
sha224_process_wrap, |
}; |
static int sha256_starts_wrap( void *ctx ) |
{ |
return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) ); |
} |
static int sha256_wrap( const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); |
} |
const mbedtls_md_info_t mbedtls_sha256_info = { |
MBEDTLS_MD_SHA256, |
"SHA256", |
32, |
64, |
sha256_starts_wrap, |
sha224_update_wrap, |
sha224_finish_wrap, |
sha256_wrap, |
sha224_ctx_alloc, |
sha224_ctx_free, |
sha224_clone_wrap, |
sha224_process_wrap, |
}; |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
static int sha384_starts_wrap( void *ctx ) |
{ |
return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) ); |
} |
static int sha384_update_wrap( void *ctx, const unsigned char *input, |
size_t ilen ) |
{ |
return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx, |
input, ilen ) ); |
} |
static int sha384_finish_wrap( void *ctx, unsigned char *output ) |
{ |
return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx, |
output ) ); |
} |
static int sha384_wrap( const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); |
} |
static void *sha384_ctx_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); |
if( ctx != NULL ) |
mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); |
return( ctx ); |
} |
static void sha384_ctx_free( void *ctx ) |
{ |
mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void sha384_clone_wrap( void *dst, const void *src ) |
{ |
mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, |
(const mbedtls_sha512_context *) src ); |
} |
static int sha384_process_wrap( void *ctx, const unsigned char *data ) |
{ |
return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx, |
data ) ); |
} |
const mbedtls_md_info_t mbedtls_sha384_info = { |
MBEDTLS_MD_SHA384, |
"SHA384", |
48, |
128, |
sha384_starts_wrap, |
sha384_update_wrap, |
sha384_finish_wrap, |
sha384_wrap, |
sha384_ctx_alloc, |
sha384_ctx_free, |
sha384_clone_wrap, |
sha384_process_wrap, |
}; |
static int sha512_starts_wrap( void *ctx ) |
{ |
return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) ); |
} |
static int sha512_wrap( const unsigned char *input, size_t ilen, |
unsigned char *output ) |
{ |
return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); |
} |
const mbedtls_md_info_t mbedtls_sha512_info = { |
MBEDTLS_MD_SHA512, |
"SHA512", |
64, |
128, |
sha512_starts_wrap, |
sha384_update_wrap, |
sha384_finish_wrap, |
sha512_wrap, |
sha384_ctx_alloc, |
sha384_ctx_free, |
sha384_clone_wrap, |
sha384_process_wrap, |
}; |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_MD_C */ |
/programs/develop/libraries/kos_mbedtls/library/memory_buffer_alloc.c |
---|
0,0 → 1,752 |
/* |
* Buffer-based memory allocator |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) |
#include "mbedtls/memory_buffer_alloc.h" |
/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C |
is dependent upon MBEDTLS_PLATFORM_C */ |
#include "mbedtls/platform.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
#include <execinfo.h> |
#endif |
#if defined(MBEDTLS_THREADING_C) |
#include "mbedtls/threading.h" |
#endif |
#define MAGIC1 0xFF00AA55 |
#define MAGIC2 0xEE119966 |
#define MAX_BT 20 |
typedef struct _memory_header memory_header; |
struct _memory_header |
{ |
size_t magic1; |
size_t size; |
size_t alloc; |
memory_header *prev; |
memory_header *next; |
memory_header *prev_free; |
memory_header *next_free; |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
char **trace; |
size_t trace_count; |
#endif |
size_t magic2; |
}; |
typedef struct |
{ |
unsigned char *buf; |
size_t len; |
memory_header *first; |
memory_header *first_free; |
int verify; |
#if defined(MBEDTLS_MEMORY_DEBUG) |
size_t alloc_count; |
size_t free_count; |
size_t total_used; |
size_t maximum_used; |
size_t header_count; |
size_t maximum_header_count; |
#endif |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_threading_mutex_t mutex; |
#endif |
} |
buffer_alloc_ctx; |
static buffer_alloc_ctx heap; |
#if defined(MBEDTLS_MEMORY_DEBUG) |
static void debug_header( memory_header *hdr ) |
{ |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
size_t i; |
#endif |
mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " |
"ALLOC(%zu), SIZE(%10zu)\n", |
(size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, |
hdr->alloc, hdr->size ); |
mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n", |
(size_t) hdr->prev_free, (size_t) hdr->next_free ); |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
mbedtls_fprintf( stderr, "TRACE: \n" ); |
for( i = 0; i < hdr->trace_count; i++ ) |
mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] ); |
mbedtls_fprintf( stderr, "\n" ); |
#endif |
} |
static void debug_chain( void ) |
{ |
memory_header *cur = heap.first; |
mbedtls_fprintf( stderr, "\nBlock list\n" ); |
while( cur != NULL ) |
{ |
debug_header( cur ); |
cur = cur->next; |
} |
mbedtls_fprintf( stderr, "Free list\n" ); |
cur = heap.first_free; |
while( cur != NULL ) |
{ |
debug_header( cur ); |
cur = cur->next_free; |
} |
} |
#endif /* MBEDTLS_MEMORY_DEBUG */ |
static int verify_header( memory_header *hdr ) |
{ |
if( hdr->magic1 != MAGIC1 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); |
#endif |
return( 1 ); |
} |
if( hdr->magic2 != MAGIC2 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); |
#endif |
return( 1 ); |
} |
if( hdr->alloc > 1 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" ); |
#endif |
return( 1 ); |
} |
if( hdr->prev != NULL && hdr->prev == hdr->next ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: prev == next\n" ); |
#endif |
return( 1 ); |
} |
if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" ); |
#endif |
return( 1 ); |
} |
return( 0 ); |
} |
static int verify_chain( void ) |
{ |
memory_header *prv = heap.first, *cur; |
if( prv == NULL || verify_header( prv ) != 0 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: verification of first header " |
"failed\n" ); |
#endif |
return( 1 ); |
} |
if( heap.first->prev != NULL ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: verification failed: " |
"first->prev != NULL\n" ); |
#endif |
return( 1 ); |
} |
cur = heap.first->next; |
while( cur != NULL ) |
{ |
if( verify_header( cur ) != 0 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: verification of header " |
"failed\n" ); |
#endif |
return( 1 ); |
} |
if( cur->prev != prv ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: verification failed: " |
"cur->prev != prv\n" ); |
#endif |
return( 1 ); |
} |
prv = cur; |
cur = cur->next; |
} |
return( 0 ); |
} |
static void *buffer_alloc_calloc( size_t n, size_t size ) |
{ |
memory_header *new, *cur = heap.first_free; |
unsigned char *p; |
void *ret; |
size_t original_len, len; |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
void *trace_buffer[MAX_BT]; |
size_t trace_cnt; |
#endif |
if( heap.buf == NULL || heap.first == NULL ) |
return( NULL ); |
original_len = len = n * size; |
if( n == 0 || size == 0 || len / n != size ) |
return( NULL ); |
else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE ) |
return( NULL ); |
if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) |
{ |
len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; |
len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; |
} |
// Find block that fits |
// |
while( cur != NULL ) |
{ |
if( cur->size >= len ) |
break; |
cur = cur->next_free; |
} |
if( cur == NULL ) |
return( NULL ); |
if( cur->alloc != 0 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated " |
"data\n" ); |
#endif |
mbedtls_exit( 1 ); |
} |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.alloc_count++; |
#endif |
// Found location, split block if > memory_header + 4 room left |
// |
if( cur->size - len < sizeof(memory_header) + |
MBEDTLS_MEMORY_ALIGN_MULTIPLE ) |
{ |
cur->alloc = 1; |
// Remove from free_list |
// |
if( cur->prev_free != NULL ) |
cur->prev_free->next_free = cur->next_free; |
else |
heap.first_free = cur->next_free; |
if( cur->next_free != NULL ) |
cur->next_free->prev_free = cur->prev_free; |
cur->prev_free = NULL; |
cur->next_free = NULL; |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.total_used += cur->size; |
if( heap.total_used > heap.maximum_used ) |
heap.maximum_used = heap.total_used; |
#endif |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
trace_cnt = backtrace( trace_buffer, MAX_BT ); |
cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); |
cur->trace_count = trace_cnt; |
#endif |
if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) |
mbedtls_exit( 1 ); |
ret = (unsigned char *) cur + sizeof( memory_header ); |
memset( ret, 0, original_len ); |
return( ret ); |
} |
p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; |
new = (memory_header *) p; |
new->size = cur->size - len - sizeof(memory_header); |
new->alloc = 0; |
new->prev = cur; |
new->next = cur->next; |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
new->trace = NULL; |
new->trace_count = 0; |
#endif |
new->magic1 = MAGIC1; |
new->magic2 = MAGIC2; |
if( new->next != NULL ) |
new->next->prev = new; |
// Replace cur with new in free_list |
// |
new->prev_free = cur->prev_free; |
new->next_free = cur->next_free; |
if( new->prev_free != NULL ) |
new->prev_free->next_free = new; |
else |
heap.first_free = new; |
if( new->next_free != NULL ) |
new->next_free->prev_free = new; |
cur->alloc = 1; |
cur->size = len; |
cur->next = new; |
cur->prev_free = NULL; |
cur->next_free = NULL; |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.header_count++; |
if( heap.header_count > heap.maximum_header_count ) |
heap.maximum_header_count = heap.header_count; |
heap.total_used += cur->size; |
if( heap.total_used > heap.maximum_used ) |
heap.maximum_used = heap.total_used; |
#endif |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
trace_cnt = backtrace( trace_buffer, MAX_BT ); |
cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); |
cur->trace_count = trace_cnt; |
#endif |
if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) |
mbedtls_exit( 1 ); |
ret = (unsigned char *) cur + sizeof( memory_header ); |
memset( ret, 0, original_len ); |
return( ret ); |
} |
static void buffer_alloc_free( void *ptr ) |
{ |
memory_header *hdr, *old = NULL; |
unsigned char *p = (unsigned char *) ptr; |
if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) |
return; |
if( p < heap.buf || p >= heap.buf + heap.len ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " |
"space\n" ); |
#endif |
mbedtls_exit( 1 ); |
} |
p -= sizeof(memory_header); |
hdr = (memory_header *) p; |
if( verify_header( hdr ) != 0 ) |
mbedtls_exit( 1 ); |
if( hdr->alloc != 1 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated " |
"data\n" ); |
#endif |
mbedtls_exit( 1 ); |
} |
hdr->alloc = 0; |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.free_count++; |
heap.total_used -= hdr->size; |
#endif |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
free( hdr->trace ); |
hdr->trace = NULL; |
hdr->trace_count = 0; |
#endif |
// Regroup with block before |
// |
if( hdr->prev != NULL && hdr->prev->alloc == 0 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.header_count--; |
#endif |
hdr->prev->size += sizeof(memory_header) + hdr->size; |
hdr->prev->next = hdr->next; |
old = hdr; |
hdr = hdr->prev; |
if( hdr->next != NULL ) |
hdr->next->prev = hdr; |
memset( old, 0, sizeof(memory_header) ); |
} |
// Regroup with block after |
// |
if( hdr->next != NULL && hdr->next->alloc == 0 ) |
{ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.header_count--; |
#endif |
hdr->size += sizeof(memory_header) + hdr->next->size; |
old = hdr->next; |
hdr->next = hdr->next->next; |
if( hdr->prev_free != NULL || hdr->next_free != NULL ) |
{ |
if( hdr->prev_free != NULL ) |
hdr->prev_free->next_free = hdr->next_free; |
else |
heap.first_free = hdr->next_free; |
if( hdr->next_free != NULL ) |
hdr->next_free->prev_free = hdr->prev_free; |
} |
hdr->prev_free = old->prev_free; |
hdr->next_free = old->next_free; |
if( hdr->prev_free != NULL ) |
hdr->prev_free->next_free = hdr; |
else |
heap.first_free = hdr; |
if( hdr->next_free != NULL ) |
hdr->next_free->prev_free = hdr; |
if( hdr->next != NULL ) |
hdr->next->prev = hdr; |
memset( old, 0, sizeof(memory_header) ); |
} |
// Prepend to free_list if we have not merged |
// (Does not have to stay in same order as prev / next list) |
// |
if( old == NULL ) |
{ |
hdr->next_free = heap.first_free; |
if( heap.first_free != NULL ) |
heap.first_free->prev_free = hdr; |
heap.first_free = hdr; |
} |
if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) |
mbedtls_exit( 1 ); |
} |
void mbedtls_memory_buffer_set_verify( int verify ) |
{ |
heap.verify = verify; |
} |
int mbedtls_memory_buffer_alloc_verify( void ) |
{ |
return verify_chain(); |
} |
#if defined(MBEDTLS_MEMORY_DEBUG) |
void mbedtls_memory_buffer_alloc_status( void ) |
{ |
mbedtls_fprintf( stderr, |
"Current use: %zu blocks / %zu bytes, max: %zu blocks / " |
"%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", |
heap.header_count, heap.total_used, |
heap.maximum_header_count, heap.maximum_used, |
heap.maximum_header_count * sizeof( memory_header ) |
+ heap.maximum_used, |
heap.alloc_count, heap.free_count ); |
if( heap.first->next == NULL ) |
{ |
mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); |
} |
else |
{ |
mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); |
debug_chain(); |
} |
} |
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ) |
{ |
*max_used = heap.maximum_used; |
*max_blocks = heap.maximum_header_count; |
} |
void mbedtls_memory_buffer_alloc_max_reset( void ) |
{ |
heap.maximum_used = 0; |
heap.maximum_header_count = 0; |
} |
void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ) |
{ |
*cur_used = heap.total_used; |
*cur_blocks = heap.header_count; |
} |
#endif /* MBEDTLS_MEMORY_DEBUG */ |
#if defined(MBEDTLS_THREADING_C) |
static void *buffer_alloc_calloc_mutexed( size_t n, size_t size ) |
{ |
void *buf; |
if( mbedtls_mutex_lock( &heap.mutex ) != 0 ) |
return( NULL ); |
buf = buffer_alloc_calloc( n, size ); |
if( mbedtls_mutex_unlock( &heap.mutex ) ) |
return( NULL ); |
return( buf ); |
} |
static void buffer_alloc_free_mutexed( void *ptr ) |
{ |
/* We have to good option here, but corrupting the heap seems |
* worse than loosing memory. */ |
if( mbedtls_mutex_lock( &heap.mutex ) ) |
return; |
buffer_alloc_free( ptr ); |
(void) mbedtls_mutex_unlock( &heap.mutex ); |
} |
#endif /* MBEDTLS_THREADING_C */ |
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) |
{ |
memset( &heap, 0, sizeof( buffer_alloc_ctx ) ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &heap.mutex ); |
mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed, |
buffer_alloc_free_mutexed ); |
#else |
mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); |
#endif |
if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE ) |
return; |
else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) |
{ |
/* Adjust len first since buf is used in the computation */ |
len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE |
- (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; |
buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE |
- (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; |
} |
memset( buf, 0, len ); |
heap.buf = buf; |
heap.len = len; |
heap.first = (memory_header *)buf; |
heap.first->size = len - sizeof( memory_header ); |
heap.first->magic1 = MAGIC1; |
heap.first->magic2 = MAGIC2; |
heap.first_free = heap.first; |
} |
void mbedtls_memory_buffer_alloc_free( void ) |
{ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &heap.mutex ); |
#endif |
mbedtls_platform_zeroize( &heap, sizeof(buffer_alloc_ctx) ); |
} |
#if defined(MBEDTLS_SELF_TEST) |
static int check_pointer( void *p ) |
{ |
if( p == NULL ) |
return( -1 ); |
if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 ) |
return( -1 ); |
return( 0 ); |
} |
static int check_all_free( void ) |
{ |
if( |
#if defined(MBEDTLS_MEMORY_DEBUG) |
heap.total_used != 0 || |
#endif |
heap.first != heap.first_free || |
(void *) heap.first != (void *) heap.buf ) |
{ |
return( -1 ); |
} |
return( 0 ); |
} |
#define TEST_ASSERT( condition ) \ |
if( ! (condition) ) \ |
{ \ |
if( verbose != 0 ) \ |
mbedtls_printf( "failed\n" ); \ |
\ |
ret = 1; \ |
goto cleanup; \ |
} |
int mbedtls_memory_buffer_alloc_self_test( int verbose ) |
{ |
unsigned char buf[1024]; |
unsigned char *p, *q, *r, *end; |
int ret = 0; |
if( verbose != 0 ) |
mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " ); |
mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); |
p = mbedtls_calloc( 1, 1 ); |
q = mbedtls_calloc( 1, 128 ); |
r = mbedtls_calloc( 1, 16 ); |
TEST_ASSERT( check_pointer( p ) == 0 && |
check_pointer( q ) == 0 && |
check_pointer( r ) == 0 ); |
mbedtls_free( r ); |
mbedtls_free( q ); |
mbedtls_free( p ); |
TEST_ASSERT( check_all_free( ) == 0 ); |
/* Memorize end to compare with the next test */ |
end = heap.buf + heap.len; |
mbedtls_memory_buffer_alloc_free( ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " MBA test #2 (buf not aligned): " ); |
mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 ); |
TEST_ASSERT( heap.buf + heap.len == end ); |
p = mbedtls_calloc( 1, 1 ); |
q = mbedtls_calloc( 1, 128 ); |
r = mbedtls_calloc( 1, 16 ); |
TEST_ASSERT( check_pointer( p ) == 0 && |
check_pointer( q ) == 0 && |
check_pointer( r ) == 0 ); |
mbedtls_free( r ); |
mbedtls_free( q ); |
mbedtls_free( p ); |
TEST_ASSERT( check_all_free( ) == 0 ); |
mbedtls_memory_buffer_alloc_free( ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " MBA test #3 (full): " ); |
mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); |
p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) ); |
TEST_ASSERT( check_pointer( p ) == 0 ); |
TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); |
mbedtls_free( p ); |
p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 ); |
q = mbedtls_calloc( 1, 16 ); |
TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 ); |
TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); |
mbedtls_free( q ); |
TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL ); |
mbedtls_free( p ); |
TEST_ASSERT( check_all_free( ) == 0 ); |
mbedtls_memory_buffer_alloc_free( ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
cleanup: |
mbedtls_memory_buffer_alloc_free( ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ |
/programs/develop/libraries/kos_mbedtls/library/net_sockets.c |
---|
0,0 → 1,213 |
/* |
* TCP/IP or UDP/IP networking functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must |
* be set before config.h, which pulls in glibc's features.h indirectly. |
* Harmless on other platforms. */ |
#define _POSIX_C_SOURCE 200112L |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_NET_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#endif |
#include "mbedtls/net_sockets.h" |
#include <string.h> |
#include "kosnet/socket.h" |
#include "kosnet/network.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> |
*/ |
#define IS_EINTR( ret ) ( ( ret ) == EINTR ) |
#include <stdio.h> |
//#include <time.h> |
#include <stdint.h> |
/* |
* Prepare for using the sockets interface |
*/ |
static int net_prepare( void ) |
{ |
load_network_obj(); |
return( 0 ); |
} |
/* |
* Initialize a context |
*/ |
void mbedtls_net_init( mbedtls_net_context *ctx ) |
{ |
ctx->fd = -1; |
} |
/* |
* Initiate a TCP connection with host:port and the given protocol |
*/ |
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, |
const char *port, int proto ) |
{ |
int ret; |
struct addrinfo hints, *addr_list, *cur; |
if( ( ret = net_prepare() ) != 0 ) |
return( ret ); |
/* Do name resolution with both IPv6 and IPv4 */ |
memset( &hints, 0, sizeof( hints ) ); |
hints.ai_family = AF_UNSPEC; |
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; |
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; |
if( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) |
return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); |
/* Try the sockaddrs until a connection succeeds */ |
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; |
for( cur = addr_list; cur != NULL; cur = cur->ai_next ) |
{ |
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, |
cur->ai_protocol ); |
if( ctx->fd < 0 ) |
{ |
ret = MBEDTLS_ERR_NET_SOCKET_FAILED; |
continue; |
} |
if( connect( ctx->fd, cur->ai_addr, (int) cur->ai_addrlen ) == 0 ) |
{ |
ret = 0; |
break; |
} |
closesocket( ctx->fd ); |
ret = MBEDTLS_ERR_NET_CONNECT_FAILED; |
} |
freeaddrinfo( addr_list ); |
return( ret ); |
} |
/**************************/ |
/* |
* Read at most 'len' characters |
*/ |
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ) |
{ |
int ret; |
int fd = ((mbedtls_net_context *) ctx)->fd; |
if( fd < 0 ) |
return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); |
ret = (int) recv( fd, (char*)( buf ), (int)( len ), 0 ); |
if( ret < 0 ) |
{ |
/*if( net_would_block( ctx ) != 0 ) |
return( MBEDTLS_ERR_SSL_WANT_READ ); |
if( errno == EPIPE || errno == ECONNRESET ) |
return( MBEDTLS_ERR_NET_CONN_RESET ); |
if( errno == EINTR ) |
return( MBEDTLS_ERR_SSL_WANT_READ ); |
*/ |
return( MBEDTLS_ERR_NET_RECV_FAILED ); |
} |
return( ret ); |
} |
/*******/ |
/* |
* Write at most 'len' characters |
*/ |
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) |
{ |
int ret; |
int fd = ((mbedtls_net_context *) ctx)->fd; |
if( fd < 0 ) |
return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); |
ret = (int) send( fd, (char*)( buf ), (int)( len ), 0 ); |
if( ret < 0 ) |
{ |
/*if( net_would_block( ctx ) != 0 ) |
return( MBEDTLS_ERR_SSL_WANT_WRITE ); |
if( errno == EPIPE || errno == ECONNRESET ) |
return( MBEDTLS_ERR_NET_CONN_RESET ); |
if( errno == EINTR ) |
return( MBEDTLS_ERR_SSL_WANT_WRITE ); |
*/ |
return( MBEDTLS_ERR_NET_SEND_FAILED ); |
} |
return( ret ); |
} |
/* |
* Gracefully close the connection |
*/ |
void mbedtls_net_free( mbedtls_net_context *ctx ) |
{ |
if( ctx->fd == -1 ) |
return; |
//shutdown( ctx->fd, 2 ); |
closesocket( ctx->fd ); |
ctx->fd = -1; |
} |
#endif /* MBEDTLS_NET_C */ |
/programs/develop/libraries/kos_mbedtls/library/nist_kw.c |
---|
0,0 → 1,757 |
/* |
* Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes |
* only |
* |
* Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* Definition of Key Wrapping: |
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf |
* RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm" |
* RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm" |
* |
* Note: RFC 3394 defines different methodology for intermediate operations for |
* the wrapping and unwrapping operation than the definition in NIST SP 800-38F. |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_NIST_KW_C) |
#include "mbedtls/nist_kw.h" |
#include "mbedtls/platform_util.h" |
#include <stdint.h> |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#if !defined(MBEDTLS_NIST_KW_ALT) |
#define KW_SEMIBLOCK_LENGTH 8 |
#define MIN_SEMIBLOCKS_COUNT 3 |
/* constant-time buffer comparison */ |
static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ) |
{ |
size_t i; |
volatile const unsigned char *A = (volatile const unsigned char *) a; |
volatile const unsigned char *B = (volatile const unsigned char *) b; |
volatile unsigned char diff = 0; |
for( i = 0; i < n; i++ ) |
{ |
/* Read volatile data in order before computing diff. |
* This avoids IAR compiler warning: |
* 'the order of volatile accesses is undefined ..' */ |
unsigned char x = A[i], y = B[i]; |
diff |= x ^ y; |
} |
return( diff ); |
} |
/*! The 64-bit default integrity check value (ICV) for KW mode. */ |
static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; |
/*! The 32-bit default integrity check value (ICV) for KWP mode. */ |
static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6}; |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
do { \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} while( 0 ) |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_BE(n,b,i) \ |
do { \ |
(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) ); \ |
} while( 0 ) |
#endif |
/* |
* Initialize context |
*/ |
void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) ); |
} |
int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, |
mbedtls_cipher_id_t cipher, |
const unsigned char *key, |
unsigned int keybits, |
const int is_wrap ) |
{ |
int ret; |
const mbedtls_cipher_info_t *cipher_info; |
cipher_info = mbedtls_cipher_info_from_values( cipher, |
keybits, |
MBEDTLS_MODE_ECB ); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
if( cipher_info->block_size != 16 ) |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
/* |
* SP 800-38F currently defines AES cipher as the only block cipher allowed: |
* "For KW and KWP, the underlying block cipher shall be approved, and the |
* block size shall be 128 bits. Currently, the AES block cipher, with key |
* lengths of 128, 192, or 256 bits, is the only block cipher that fits |
* this profile." |
* Currently we don't support other 128 bit block ciphers for key wrapping, |
* such as Camellia and Aria. |
*/ |
if( cipher != MBEDTLS_CIPHER_ID_AES ) |
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); |
mbedtls_cipher_free( &ctx->cipher_ctx ); |
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, |
is_wrap ? MBEDTLS_ENCRYPT : |
MBEDTLS_DECRYPT ) |
) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
/* |
* Free context |
*/ |
void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ) |
{ |
mbedtls_cipher_free( &ctx->cipher_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) ); |
} |
/* |
* Helper function for Xoring the uint64_t "t" with the encrypted A. |
* Defined in NIST SP 800-38F section 6.1 |
*/ |
static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t ) |
{ |
size_t i = 0; |
for( i = 0; i < sizeof( t ); i++ ) |
{ |
A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff; |
} |
} |
/* |
* KW-AE as defined in SP 800-38F section 6.2 |
* KWP-AE as defined in SP 800-38F section 6.3 |
*/ |
int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, |
mbedtls_nist_kw_mode_t mode, |
const unsigned char *input, size_t in_len, |
unsigned char *output, size_t *out_len, size_t out_size ) |
{ |
int ret = 0; |
size_t semiblocks = 0; |
size_t s; |
size_t olen, padlen = 0; |
uint64_t t = 0; |
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; |
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; |
unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH; |
unsigned char *A = output; |
*out_len = 0; |
/* |
* Generate the String to work on |
*/ |
if( mode == MBEDTLS_KW_MODE_KW ) |
{ |
if( out_size < in_len + KW_SEMIBLOCK_LENGTH ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
/* |
* According to SP 800-38F Table 1, the plaintext length for KW |
* must be between 2 to 2^54-1 semiblocks inclusive. |
*/ |
if( in_len < 16 || |
#if SIZE_MAX > 0x1FFFFFFFFFFFFF8 |
in_len > 0x1FFFFFFFFFFFFF8 || |
#endif |
in_len % KW_SEMIBLOCK_LENGTH != 0 ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH ); |
memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len ); |
} |
else |
{ |
if( in_len % 8 != 0 ) |
{ |
padlen = ( 8 - ( in_len % 8 ) ); |
} |
if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
/* |
* According to SP 800-38F Table 1, the plaintext length for KWP |
* must be between 1 and 2^32-1 octets inclusive. |
*/ |
if( in_len < 1 |
#if SIZE_MAX > 0xFFFFFFFF |
|| in_len > 0xFFFFFFFF |
#endif |
) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 ); |
PUT_UINT32_BE( ( in_len & 0xffffffff ), output, |
KW_SEMIBLOCK_LENGTH / 2 ); |
memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len ); |
memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen ); |
} |
semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1; |
s = 6 * ( semiblocks - 1 ); |
if( mode == MBEDTLS_KW_MODE_KWP |
&& in_len <= KW_SEMIBLOCK_LENGTH ) |
{ |
memcpy( inbuff, output, 16 ); |
ret = mbedtls_cipher_update( &ctx->cipher_ctx, |
inbuff, 16, output, &olen ); |
if( ret != 0 ) |
goto cleanup; |
} |
else |
{ |
/* |
* Do the wrapping function W, as defined in RFC 3394 section 2.2.1 |
*/ |
if( semiblocks < MIN_SEMIBLOCKS_COUNT ) |
{ |
ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
goto cleanup; |
} |
/* Calculate intermediate values */ |
for( t = 1; t <= s; t++ ) |
{ |
memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); |
memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH ); |
ret = mbedtls_cipher_update( &ctx->cipher_ctx, |
inbuff, 16, outbuff, &olen ); |
if( ret != 0 ) |
goto cleanup; |
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); |
calc_a_xor_t( A, t ); |
memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); |
R2 += KW_SEMIBLOCK_LENGTH; |
if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) ) |
R2 = output + KW_SEMIBLOCK_LENGTH; |
} |
} |
*out_len = semiblocks * KW_SEMIBLOCK_LENGTH; |
cleanup: |
if( ret != 0) |
{ |
memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH ); |
} |
mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 ); |
mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 ); |
return( ret ); |
} |
/* |
* W-1 function as defined in RFC 3394 section 2.2.2 |
* This function assumes the following: |
* 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH. |
* 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH. |
* 3. Minimal number of semiblocks is 3. |
* 4. A is a buffer to hold the first semiblock of the input buffer. |
*/ |
static int unwrap( mbedtls_nist_kw_context *ctx, |
const unsigned char *input, size_t semiblocks, |
unsigned char A[KW_SEMIBLOCK_LENGTH], |
unsigned char *output, size_t* out_len ) |
{ |
int ret = 0; |
const size_t s = 6 * ( semiblocks - 1 ); |
size_t olen; |
uint64_t t = 0; |
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; |
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; |
unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; |
*out_len = 0; |
if( semiblocks < MIN_SEMIBLOCKS_COUNT ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
memcpy( A, input, KW_SEMIBLOCK_LENGTH ); |
memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); |
/* Calculate intermediate values */ |
for( t = s; t >= 1; t-- ) |
{ |
calc_a_xor_t( A, t ); |
memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); |
memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH ); |
ret = mbedtls_cipher_update( &ctx->cipher_ctx, |
inbuff, 16, outbuff, &olen ); |
if( ret != 0 ) |
goto cleanup; |
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); |
/* Set R as LSB64 of outbuff */ |
memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); |
if( R == output ) |
R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; |
else |
R -= KW_SEMIBLOCK_LENGTH; |
} |
*out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH; |
cleanup: |
if( ret != 0) |
memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); |
mbedtls_platform_zeroize( inbuff, sizeof( inbuff ) ); |
mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); |
return( ret ); |
} |
/* |
* KW-AD as defined in SP 800-38F section 6.2 |
* KWP-AD as defined in SP 800-38F section 6.3 |
*/ |
int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, |
mbedtls_nist_kw_mode_t mode, |
const unsigned char *input, size_t in_len, |
unsigned char *output, size_t *out_len, size_t out_size ) |
{ |
int ret = 0; |
size_t i, olen; |
unsigned char A[KW_SEMIBLOCK_LENGTH]; |
unsigned char diff, bad_padding = 0; |
*out_len = 0; |
if( out_size < in_len - KW_SEMIBLOCK_LENGTH ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
if( mode == MBEDTLS_KW_MODE_KW ) |
{ |
/* |
* According to SP 800-38F Table 1, the ciphertext length for KW |
* must be between 3 to 2^54 semiblocks inclusive. |
*/ |
if( in_len < 24 || |
#if SIZE_MAX > 0x200000000000000 |
in_len > 0x200000000000000 || |
#endif |
in_len % KW_SEMIBLOCK_LENGTH != 0 ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, |
A, output, out_len ); |
if( ret != 0 ) |
goto cleanup; |
/* Check ICV in "constant-time" */ |
diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH ); |
if( diff != 0 ) |
{ |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
goto cleanup; |
} |
} |
else if( mode == MBEDTLS_KW_MODE_KWP ) |
{ |
size_t padlen = 0; |
uint32_t Plen; |
/* |
* According to SP 800-38F Table 1, the ciphertext length for KWP |
* must be between 2 to 2^29 semiblocks inclusive. |
*/ |
if( in_len < KW_SEMIBLOCK_LENGTH * 2 || |
#if SIZE_MAX > 0x100000000 |
in_len > 0x100000000 || |
#endif |
in_len % KW_SEMIBLOCK_LENGTH != 0 ) |
{ |
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); |
} |
if( in_len == KW_SEMIBLOCK_LENGTH * 2 ) |
{ |
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; |
ret = mbedtls_cipher_update( &ctx->cipher_ctx, |
input, 16, outbuff, &olen ); |
if( ret != 0 ) |
goto cleanup; |
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); |
memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); |
mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); |
*out_len = KW_SEMIBLOCK_LENGTH; |
} |
else |
{ |
/* in_len >= KW_SEMIBLOCK_LENGTH * 3 */ |
ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, |
A, output, out_len ); |
if( ret != 0 ) |
goto cleanup; |
} |
/* Check ICV in "constant-time" */ |
diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 ); |
if( diff != 0 ) |
{ |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
} |
GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 ); |
/* |
* Plen is the length of the plaintext, when the input is valid. |
* If Plen is larger than the plaintext and padding, padlen will be |
* larger than 8, because of the type wrap around. |
*/ |
padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen; |
if ( padlen > 7 ) |
{ |
padlen &= 7; |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
} |
/* Check padding in "constant-time" */ |
for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ ) |
{ |
if( i >= KW_SEMIBLOCK_LENGTH - padlen ) |
diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; |
else |
bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; |
} |
if( diff != 0 ) |
{ |
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; |
} |
if( ret != 0 ) |
{ |
goto cleanup; |
} |
memset( output + Plen, 0, padlen ); |
*out_len = Plen; |
} |
else |
{ |
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; |
goto cleanup; |
} |
cleanup: |
if( ret != 0 ) |
{ |
memset( output, 0, *out_len ); |
*out_len = 0; |
} |
mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) ); |
mbedtls_platform_zeroize( &diff, sizeof( diff ) ); |
mbedtls_platform_zeroize( A, sizeof( A ) ); |
return( ret ); |
} |
#endif /* !MBEDTLS_NIST_KW_ALT */ |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) |
#define KW_TESTS 3 |
/* |
* Test vectors taken from NIST |
* https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW |
*/ |
static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 }; |
static const unsigned char kw_key[KW_TESTS][32] = { |
{ 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2, |
0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 }, |
{ 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b, |
0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d, |
0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 }, |
{ 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25, |
0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33, |
0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d, |
0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 } |
}; |
static const unsigned char kw_msg[KW_TESTS][40] = { |
{ 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea, |
0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f }, |
{ 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb, |
0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d, |
0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45, |
0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d, |
0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c }, |
{ 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7, |
0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8, |
0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 } |
}; |
static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 }; |
static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 }; |
static const unsigned char kw_res[KW_TESTS][48] = { |
{ 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d, |
0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3, |
0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb }, |
{ 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91, |
0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec, |
0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d, |
0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8, |
0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19, |
0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d }, |
{ 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d, |
0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87, |
0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9, |
0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 } |
}; |
static const unsigned char kwp_key[KW_TESTS][32] = { |
{ 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a, |
0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 }, |
{ 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98, |
0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7, |
0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 }, |
{ 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5, |
0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f, |
0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae, |
0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a } |
}; |
static const unsigned char kwp_msg[KW_TESTS][31] = { |
{ 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8, |
0x96 }, |
{ 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb, |
0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19, |
0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66, |
0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f }, |
{ 0xd1 } |
}; |
static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 }; |
static const unsigned char kwp_res[KW_TESTS][48] = { |
{ 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e, |
0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7, |
0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 }, |
{ 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13, |
0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88, |
0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63, |
0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90, |
0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 }, |
{ 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd, |
0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 } |
}; |
static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 }; |
int mbedtls_nist_kw_self_test( int verbose ) |
{ |
mbedtls_nist_kw_context ctx; |
unsigned char out[48]; |
size_t olen; |
int i; |
int ret = 0; |
mbedtls_nist_kw_init( &ctx ); |
for( i = 0; i < KW_TESTS; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " KW-AES-%u ", (unsigned int) key_len[i] * 8 ); |
ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, |
kw_key[i], key_len[i] * 8, 1 ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " KW: setup failed " ); |
goto end; |
} |
ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i], |
kw_msg_len[i], out, &olen, sizeof( out ) ); |
if( ret != 0 || kw_out_len[i] != olen || |
memcmp( out, kw_res[i], kw_out_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed. "); |
ret = 1; |
goto end; |
} |
if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, |
kw_key[i], key_len[i] * 8, 0 ) ) |
!= 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " KW: setup failed "); |
goto end; |
} |
ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW, |
out, olen, out, &olen, sizeof( out ) ); |
if( ret != 0 || olen != kw_msg_len[i] || |
memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto end; |
} |
if( verbose != 0 ) |
mbedtls_printf( " passed\n" ); |
} |
for( i = 0; i < KW_TESTS; i++ ) |
{ |
olen = sizeof( out ); |
if( verbose != 0 ) |
mbedtls_printf( " KWP-AES-%u ", (unsigned int) key_len[i] * 8 ); |
ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i], |
key_len[i] * 8, 1 ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " KWP: setup failed " ); |
goto end; |
} |
ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i], |
kwp_msg_len[i], out, &olen, sizeof( out ) ); |
if( ret != 0 || kwp_out_len[i] != olen || |
memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed. "); |
ret = 1; |
goto end; |
} |
if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, |
kwp_key[i], key_len[i] * 8, 0 ) ) |
!= 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " KWP: setup failed "); |
goto end; |
} |
ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KWP, out, |
olen, out, &olen, sizeof( out ) ); |
if( ret != 0 || olen != kwp_msg_len[i] || |
memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed. "); |
ret = 1; |
goto end; |
} |
if( verbose != 0 ) |
mbedtls_printf( " passed\n" ); |
} |
end: |
mbedtls_nist_kw_free( &ctx ); |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ |
#endif /* MBEDTLS_NIST_KW_C */ |
/programs/develop/libraries/kos_mbedtls/library/oid.c |
---|
0,0 → 1,760 |
/** |
* \file oid.c |
* |
* \brief Object Identifier (OID) database |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_OID_C) |
#include "mbedtls/oid.h" |
#include "mbedtls/rsa.h" |
#include <stdio.h> |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#define mbedtls_snprintf snprintf |
#endif |
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) |
#include "mbedtls/x509.h" |
#endif |
/* |
* Macro to automatically add the size of #define'd OIDs |
*/ |
#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s) |
/* |
* Macro to generate an internal function for oid_XXX_from_asn1() (used by |
* the other functions) |
*/ |
#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ |
static const TYPE_T * oid_ ## NAME ## _from_asn1( \ |
const mbedtls_asn1_buf *oid ) \ |
{ \ |
const TYPE_T *p = (LIST); \ |
const mbedtls_oid_descriptor_t *cur = \ |
(const mbedtls_oid_descriptor_t *) p; \ |
if( p == NULL || oid == NULL ) return( NULL ); \ |
while( cur->asn1 != NULL ) { \ |
if( cur->asn1_len == oid->len && \ |
memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ |
return( p ); \ |
} \ |
p++; \ |
cur = (const mbedtls_oid_descriptor_t *) p; \ |
} \ |
return( NULL ); \ |
} |
/* |
* Macro to generate a function for retrieving a single attribute from the |
* descriptor of an mbedtls_oid_descriptor_t wrapper. |
*/ |
#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ |
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ |
{ \ |
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ |
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ |
*ATTR1 = data->descriptor.ATTR1; \ |
return( 0 ); \ |
} |
/* |
* Macro to generate a function for retrieving a single attribute from an |
* mbedtls_oid_descriptor_t wrapper. |
*/ |
#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ |
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ |
{ \ |
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ |
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ |
*ATTR1 = data->ATTR1; \ |
return( 0 ); \ |
} |
/* |
* Macro to generate a function for retrieving two attributes from an |
* mbedtls_oid_descriptor_t wrapper. |
*/ |
#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ |
ATTR2_TYPE, ATTR2) \ |
int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ |
ATTR2_TYPE * ATTR2 ) \ |
{ \ |
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ |
if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ |
*(ATTR1) = data->ATTR1; \ |
*(ATTR2) = data->ATTR2; \ |
return( 0 ); \ |
} |
/* |
* Macro to generate a function for retrieving the OID based on a single |
* attribute from a mbedtls_oid_descriptor_t wrapper. |
*/ |
#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ |
int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ |
{ \ |
const TYPE_T *cur = (LIST); \ |
while( cur->descriptor.asn1 != NULL ) { \ |
if( cur->ATTR1 == (ATTR1) ) { \ |
*oid = cur->descriptor.asn1; \ |
*olen = cur->descriptor.asn1_len; \ |
return( 0 ); \ |
} \ |
cur++; \ |
} \ |
return( MBEDTLS_ERR_OID_NOT_FOUND ); \ |
} |
/* |
* Macro to generate a function for retrieving the OID based on two |
* attributes from a mbedtls_oid_descriptor_t wrapper. |
*/ |
#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ |
ATTR2_TYPE, ATTR2) \ |
int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ |
size_t *olen ) \ |
{ \ |
const TYPE_T *cur = (LIST); \ |
while( cur->descriptor.asn1 != NULL ) { \ |
if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \ |
*oid = cur->descriptor.asn1; \ |
*olen = cur->descriptor.asn1_len; \ |
return( 0 ); \ |
} \ |
cur++; \ |
} \ |
return( MBEDTLS_ERR_OID_NOT_FOUND ); \ |
} |
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) |
/* |
* For X520 attribute types |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
const char *short_name; |
} oid_x520_attr_t; |
static const oid_x520_attr_t oid_x520_attr_type[] = |
{ |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" }, |
"CN", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" }, |
"C", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" }, |
"L", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" }, |
"ST", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, |
"O", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, |
"OU", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, |
"emailAddress", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, |
"serialNumber", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, |
"postalAddress", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, |
"postalCode", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, |
"SN", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, |
"GN", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" }, |
"initials", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, |
"generationQualifier", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" }, |
"title", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, |
"dnQualifier", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, |
"pseudonym", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, |
"DC", |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" }, |
"uniqueIdentifier", |
}, |
{ |
{ NULL, 0, NULL, NULL }, |
NULL, |
} |
}; |
FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) |
FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name) |
/* |
* For X509 extensions |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
int ext_type; |
} oid_x509_ext_t; |
static const oid_x509_ext_t oid_x509_ext[] = |
{ |
{ |
{ ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, |
MBEDTLS_X509_EXT_BASIC_CONSTRAINTS, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, |
MBEDTLS_X509_EXT_KEY_USAGE, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" }, |
MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, |
MBEDTLS_X509_EXT_SUBJECT_ALT_NAME, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, |
MBEDTLS_X509_EXT_NS_CERT_TYPE, |
}, |
{ |
{ NULL, 0, NULL, NULL }, |
0, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) |
FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) |
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = |
{ |
{ ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, |
{ ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, |
{ ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, |
{ ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, |
{ ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, |
{ ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, |
{ NULL, 0, NULL, NULL }, |
}; |
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) |
FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description) |
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ |
#if defined(MBEDTLS_MD_C) |
/* |
* For SignatureAlgorithmIdentifier |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_md_type_t md_alg; |
mbedtls_pk_type_t pk_alg; |
} oid_sig_alg_t; |
static const oid_sig_alg_t oid_sig_alg[] = |
{ |
#if defined(MBEDTLS_RSA_C) |
#if defined(MBEDTLS_MD2_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, |
MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_MD2_C */ |
#if defined(MBEDTLS_MD4_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, |
MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_MD4_C */ |
#if defined(MBEDTLS_MD5_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, |
MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_MD5_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, |
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, |
MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, |
MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, |
MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, |
MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, |
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, |
}, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECDSA_C) |
#if defined(MBEDTLS_SHA1_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, |
MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, |
}, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, |
MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, |
MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, |
}, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, |
MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, |
MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, |
}, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_ECDSA_C */ |
#if defined(MBEDTLS_RSA_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, |
MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, |
}, |
#endif /* MBEDTLS_RSA_C */ |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg) |
FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description) |
FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg) |
FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg) |
#endif /* MBEDTLS_MD_C */ |
/* |
* For PublicKeyInfo (PKCS1, RFC 5480) |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_pk_type_t pk_alg; |
} oid_pk_alg_t; |
static const oid_pk_alg_t oid_pk_alg[] = |
{ |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, |
MBEDTLS_PK_RSA, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, |
MBEDTLS_PK_ECKEY, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, |
MBEDTLS_PK_ECKEY_DH, |
}, |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_PK_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg) |
FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg) |
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg) |
#if defined(MBEDTLS_ECP_C) |
/* |
* For namedCurve (RFC 5480) |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_ecp_group_id grp_id; |
} oid_ecp_grp_t; |
static const oid_ecp_grp_t oid_ecp_grp[] = |
{ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, |
MBEDTLS_ECP_DP_SECP192R1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, |
MBEDTLS_ECP_DP_SECP224R1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, |
MBEDTLS_ECP_DP_SECP256R1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, |
MBEDTLS_ECP_DP_SECP384R1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, |
MBEDTLS_ECP_DP_SECP521R1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, |
MBEDTLS_ECP_DP_SECP192K1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, |
MBEDTLS_ECP_DP_SECP224K1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, |
MBEDTLS_ECP_DP_SECP256K1, |
}, |
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, |
MBEDTLS_ECP_DP_BP256R1, |
}, |
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, |
MBEDTLS_ECP_DP_BP384R1, |
}, |
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) |
{ |
{ ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, |
MBEDTLS_ECP_DP_BP512R1, |
}, |
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_ECP_DP_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) |
FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id) |
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id) |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_CIPHER_C) |
/* |
* For PKCS#5 PBES2 encryption algorithm |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_cipher_type_t cipher_alg; |
} oid_cipher_alg_t; |
static const oid_cipher_alg_t oid_cipher_alg[] = |
{ |
{ |
{ ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" }, |
MBEDTLS_CIPHER_DES_CBC, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, |
MBEDTLS_CIPHER_DES_EDE3_CBC, |
}, |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_CIPHER_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg) |
FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, mbedtls_cipher_type_t, cipher_alg) |
#endif /* MBEDTLS_CIPHER_C */ |
#if defined(MBEDTLS_MD_C) |
/* |
* For digestAlgorithm |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_md_type_t md_alg; |
} oid_md_alg_t; |
static const oid_md_alg_t oid_md_alg[] = |
{ |
#if defined(MBEDTLS_MD2_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, |
MBEDTLS_MD_MD2, |
}, |
#endif /* MBEDTLS_MD2_C */ |
#if defined(MBEDTLS_MD4_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, |
MBEDTLS_MD_MD4, |
}, |
#endif /* MBEDTLS_MD4_C */ |
#if defined(MBEDTLS_MD5_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, |
MBEDTLS_MD_MD5, |
}, |
#endif /* MBEDTLS_MD5_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, |
MBEDTLS_MD_SHA1, |
}, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, |
MBEDTLS_MD_SHA224, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, |
MBEDTLS_MD_SHA256, |
}, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, |
MBEDTLS_MD_SHA384, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, |
MBEDTLS_MD_SHA512, |
}, |
#endif /* MBEDTLS_SHA512_C */ |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_MD_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) |
FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) |
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) |
/* |
* For HMAC digestAlgorithm |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_md_type_t md_hmac; |
} oid_md_hmac_t; |
static const oid_md_hmac_t oid_md_hmac[] = |
{ |
#if defined(MBEDTLS_SHA1_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" }, |
MBEDTLS_MD_SHA1, |
}, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" }, |
MBEDTLS_MD_SHA224, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" }, |
MBEDTLS_MD_SHA256, |
}, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ |
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" }, |
MBEDTLS_MD_SHA384, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" }, |
MBEDTLS_MD_SHA512, |
}, |
#endif /* MBEDTLS_SHA512_C */ |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_MD_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac) |
FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac) |
#endif /* MBEDTLS_MD_C */ |
#if defined(MBEDTLS_PKCS12_C) |
/* |
* For PKCS#12 PBEs |
*/ |
typedef struct { |
mbedtls_oid_descriptor_t descriptor; |
mbedtls_md_type_t md_alg; |
mbedtls_cipher_type_t cipher_alg; |
} oid_pkcs12_pbe_alg_t; |
static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = |
{ |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, |
MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC, |
}, |
{ |
{ ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, |
MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC, |
}, |
{ |
{ NULL, 0, NULL, NULL }, |
MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE, |
}, |
}; |
FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg) |
FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, mbedtls_md_type_t, md_alg, mbedtls_cipher_type_t, cipher_alg) |
#endif /* MBEDTLS_PKCS12_C */ |
#define OID_SAFE_SNPRINTF \ |
do { \ |
if( ret < 0 || (size_t) ret >= n ) \ |
return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \ |
\ |
n -= (size_t) ret; \ |
p += (size_t) ret; \ |
} while( 0 ) |
/* Return the x.y.z.... style numeric string for the given OID */ |
int mbedtls_oid_get_numeric_string( char *buf, size_t size, |
const mbedtls_asn1_buf *oid ) |
{ |
int ret; |
size_t i, n; |
unsigned int value; |
char *p; |
p = buf; |
n = size; |
/* First byte contains first two dots */ |
if( oid->len > 0 ) |
{ |
ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 ); |
OID_SAFE_SNPRINTF; |
} |
value = 0; |
for( i = 1; i < oid->len; i++ ) |
{ |
/* Prevent overflow in value. */ |
if( ( ( value << 7 ) >> 7 ) != value ) |
return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); |
value <<= 7; |
value += oid->p[i] & 0x7F; |
if( !( oid->p[i] & 0x80 ) ) |
{ |
/* Last byte */ |
ret = mbedtls_snprintf( p, n, ".%d", value ); |
OID_SAFE_SNPRINTF; |
value = 0; |
} |
} |
return( (int) ( size - n ) ); |
} |
#endif /* MBEDTLS_OID_C */ |
/programs/develop/libraries/kos_mbedtls/library/padlock.c |
---|
0,0 → 1,172 |
/* |
* VIA PadLock support functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* This implementation is based on the VIA PadLock Programming Guide: |
* |
* http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ |
* programming_guide.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PADLOCK_C) |
#include "mbedtls/padlock.h" |
#include <string.h> |
#ifndef asm |
#define asm __asm |
#endif |
#if defined(MBEDTLS_HAVE_X86) |
/* |
* PadLock detection routine |
*/ |
int mbedtls_padlock_has_support( int feature ) |
{ |
static int flags = -1; |
int ebx = 0, edx = 0; |
if( flags == -1 ) |
{ |
asm( "movl %%ebx, %0 \n\t" |
"movl $0xC0000000, %%eax \n\t" |
"cpuid \n\t" |
"cmpl $0xC0000001, %%eax \n\t" |
"movl $0, %%edx \n\t" |
"jb unsupported \n\t" |
"movl $0xC0000001, %%eax \n\t" |
"cpuid \n\t" |
"unsupported: \n\t" |
"movl %%edx, %1 \n\t" |
"movl %2, %%ebx \n\t" |
: "=m" (ebx), "=m" (edx) |
: "m" (ebx) |
: "eax", "ecx", "edx" ); |
flags = edx; |
} |
return( flags & feature ); |
} |
/* |
* PadLock AES-ECB block en(de)cryption |
*/ |
int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, |
int mode, |
const unsigned char input[16], |
unsigned char output[16] ) |
{ |
int ebx = 0; |
uint32_t *rk; |
uint32_t *blk; |
uint32_t *ctrl; |
unsigned char buf[256]; |
rk = ctx->rk; |
blk = MBEDTLS_PADLOCK_ALIGN16( buf ); |
memcpy( blk, input, 16 ); |
ctrl = blk + 4; |
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); |
asm( "pushfl \n\t" |
"popfl \n\t" |
"movl %%ebx, %0 \n\t" |
"movl $1, %%ecx \n\t" |
"movl %2, %%edx \n\t" |
"movl %3, %%ebx \n\t" |
"movl %4, %%esi \n\t" |
"movl %4, %%edi \n\t" |
".byte 0xf3,0x0f,0xa7,0xc8 \n\t" |
"movl %1, %%ebx \n\t" |
: "=m" (ebx) |
: "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) |
: "memory", "ecx", "edx", "esi", "edi" ); |
memcpy( output, blk, 16 ); |
return( 0 ); |
} |
/* |
* PadLock AES-CBC buffer en(de)cryption |
*/ |
int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, |
int mode, |
size_t length, |
unsigned char iv[16], |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ebx = 0; |
size_t count; |
uint32_t *rk; |
uint32_t *iw; |
uint32_t *ctrl; |
unsigned char buf[256]; |
if( ( (long) input & 15 ) != 0 || |
( (long) output & 15 ) != 0 ) |
return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); |
rk = ctx->rk; |
iw = MBEDTLS_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 \n\t" |
"popfl \n\t" |
"movl %%ebx, %0 \n\t" |
"movl %2, %%ecx \n\t" |
"movl %3, %%edx \n\t" |
"movl %4, %%ebx \n\t" |
"movl %5, %%esi \n\t" |
"movl %6, %%edi \n\t" |
"movl %7, %%eax \n\t" |
".byte 0xf3,0x0f,0xa7,0xd0 \n\t" |
"movl %1, %%ebx \n\t" |
: "=m" (ebx) |
: "m" (ebx), "m" (count), "m" (ctrl), |
"m" (rk), "m" (input), "m" (output), "m" (iw) |
: "memory", "eax", "ecx", "edx", "esi", "edi" ); |
memcpy( iv, iw, 16 ); |
return( 0 ); |
} |
#endif /* MBEDTLS_HAVE_X86 */ |
#endif /* MBEDTLS_PADLOCK_C */ |
/programs/develop/libraries/kos_mbedtls/library/pem.c |
---|
0,0 → 1,492 |
/* |
* Privacy Enhanced Mail (PEM) decoding |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) |
#include "mbedtls/pem.h" |
#include "mbedtls/base64.h" |
#include "mbedtls/des.h" |
#include "mbedtls/aes.h" |
#include "mbedtls/md5.h" |
#include "mbedtls/cipher.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) |
void mbedtls_pem_init( mbedtls_pem_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_pem_context ) ); |
} |
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) |
/* |
* Read a 16-byte hex string and convert it to binary |
*/ |
static int pem_get_iv( const unsigned char *s, unsigned char *iv, |
size_t iv_len ) |
{ |
size_t i, j, k; |
memset( iv, 0, iv_len ); |
for( i = 0; i < iv_len * 2; i++, s++ ) |
{ |
if( *s >= '0' && *s <= '9' ) j = *s - '0'; else |
if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else |
if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else |
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); |
k = ( ( i & 1 ) != 0 ) ? j : j << 4; |
iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); |
} |
return( 0 ); |
} |
static int pem_pbkdf1( unsigned char *key, size_t keylen, |
unsigned char *iv, |
const unsigned char *pwd, size_t pwdlen ) |
{ |
mbedtls_md5_context md5_ctx; |
unsigned char md5sum[16]; |
size_t use_len; |
int ret; |
mbedtls_md5_init( &md5_ctx ); |
/* |
* key[ 0..15] = MD5(pwd || IV) |
*/ |
if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 ) |
goto exit; |
if( keylen <= 16 ) |
{ |
memcpy( key, md5sum, keylen ); |
goto exit; |
} |
memcpy( key, md5sum, 16 ); |
/* |
* key[16..23] = MD5(key[ 0..15] || pwd || IV]) |
*/ |
if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 ) |
goto exit; |
use_len = 16; |
if( keylen < 32 ) |
use_len = keylen - 16; |
memcpy( key + 16, md5sum, use_len ); |
exit: |
mbedtls_md5_free( &md5_ctx ); |
mbedtls_platform_zeroize( md5sum, 16 ); |
return( ret ); |
} |
#if defined(MBEDTLS_DES_C) |
/* |
* Decrypt with DES-CBC, using PBKDF1 for key derivation |
*/ |
static int pem_des_decrypt( unsigned char des_iv[8], |
unsigned char *buf, size_t buflen, |
const unsigned char *pwd, size_t pwdlen ) |
{ |
mbedtls_des_context des_ctx; |
unsigned char des_key[8]; |
int ret; |
mbedtls_des_init( &des_ctx ); |
if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 ) |
goto exit; |
ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen, |
des_iv, buf, buf ); |
exit: |
mbedtls_des_free( &des_ctx ); |
mbedtls_platform_zeroize( des_key, 8 ); |
return( ret ); |
} |
/* |
* Decrypt with 3DES-CBC, using PBKDF1 for key derivation |
*/ |
static int pem_des3_decrypt( unsigned char des3_iv[8], |
unsigned char *buf, size_t buflen, |
const unsigned char *pwd, size_t pwdlen ) |
{ |
mbedtls_des3_context des3_ctx; |
unsigned char des3_key[24]; |
int ret; |
mbedtls_des3_init( &des3_ctx ); |
if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 ) |
goto exit; |
ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen, |
des3_iv, buf, buf ); |
exit: |
mbedtls_des3_free( &des3_ctx ); |
mbedtls_platform_zeroize( des3_key, 24 ); |
return( ret ); |
} |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_AES_C) |
/* |
* Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation |
*/ |
static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, |
unsigned char *buf, size_t buflen, |
const unsigned char *pwd, size_t pwdlen ) |
{ |
mbedtls_aes_context aes_ctx; |
unsigned char aes_key[32]; |
int ret; |
mbedtls_aes_init( &aes_ctx ); |
if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 ) |
goto exit; |
ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen, |
aes_iv, buf, buf ); |
exit: |
mbedtls_aes_free( &aes_ctx ); |
mbedtls_platform_zeroize( aes_key, keylen ); |
return( ret ); |
} |
#endif /* MBEDTLS_AES_C */ |
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && |
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ |
int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer, |
const unsigned char *data, const unsigned char *pwd, |
size_t pwdlen, size_t *use_len ) |
{ |
int ret, enc; |
size_t len; |
unsigned char *buf; |
const unsigned char *s1, *s2, *end; |
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) |
unsigned char pem_iv[16]; |
mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE; |
#else |
((void) pwd); |
((void) pwdlen); |
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && |
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ |
if( ctx == NULL ) |
return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA ); |
s1 = (unsigned char *) strstr( (const char *) data, header ); |
if( s1 == NULL ) |
return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); |
s2 = (unsigned char *) strstr( (const char *) data, footer ); |
if( s2 == NULL || s2 <= s1 ) |
return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); |
s1 += strlen( header ); |
if( *s1 == ' ' ) s1++; |
if( *s1 == '\r' ) s1++; |
if( *s1 == '\n' ) s1++; |
else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); |
end = s2; |
end += strlen( footer ); |
if( *end == ' ' ) end++; |
if( *end == '\r' ) end++; |
if( *end == '\n' ) end++; |
*use_len = end - data; |
enc = 0; |
if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) |
{ |
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) |
enc++; |
s1 += 22; |
if( *s1 == '\r' ) s1++; |
if( *s1 == '\n' ) s1++; |
else return( MBEDTLS_ERR_PEM_INVALID_DATA ); |
#if defined(MBEDTLS_DES_C) |
if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) |
{ |
enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; |
s1 += 23; |
if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 ) |
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); |
s1 += 16; |
} |
else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) |
{ |
enc_alg = MBEDTLS_CIPHER_DES_CBC; |
s1 += 18; |
if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 ) |
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); |
s1 += 16; |
} |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_AES_C) |
if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) |
{ |
if( s2 - s1 < 22 ) |
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); |
else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) |
enc_alg = MBEDTLS_CIPHER_AES_128_CBC; |
else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) |
enc_alg = MBEDTLS_CIPHER_AES_192_CBC; |
else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) |
enc_alg = MBEDTLS_CIPHER_AES_256_CBC; |
else |
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); |
s1 += 22; |
if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 ) |
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); |
s1 += 32; |
} |
#endif /* MBEDTLS_AES_C */ |
if( enc_alg == MBEDTLS_CIPHER_NONE ) |
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); |
if( *s1 == '\r' ) s1++; |
if( *s1 == '\n' ) s1++; |
else return( MBEDTLS_ERR_PEM_INVALID_DATA ); |
#else |
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); |
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && |
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ |
} |
if( s1 >= s2 ) |
return( MBEDTLS_ERR_PEM_INVALID_DATA ); |
ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); |
if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) |
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); |
if( ( buf = mbedtls_calloc( 1, len ) ) == NULL ) |
return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); |
if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 ) |
{ |
mbedtls_platform_zeroize( buf, len ); |
mbedtls_free( buf ); |
return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); |
} |
if( enc != 0 ) |
{ |
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) |
if( pwd == NULL ) |
{ |
mbedtls_platform_zeroize( buf, len ); |
mbedtls_free( buf ); |
return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); |
} |
ret = 0; |
#if defined(MBEDTLS_DES_C) |
if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC ) |
ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); |
else if( enc_alg == MBEDTLS_CIPHER_DES_CBC ) |
ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_AES_C) |
if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC ) |
ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); |
else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC ) |
ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); |
else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC ) |
ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); |
#endif /* MBEDTLS_AES_C */ |
if( ret != 0 ) |
{ |
mbedtls_free( buf ); |
return( ret ); |
} |
/* |
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 |
* length bytes (allow 4 to be sure) in all known use cases. |
* |
* Use that as a heuristic to try to detect password mismatches. |
*/ |
if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) |
{ |
mbedtls_platform_zeroize( buf, len ); |
mbedtls_free( buf ); |
return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); |
} |
#else |
mbedtls_platform_zeroize( buf, len ); |
mbedtls_free( buf ); |
return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); |
#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && |
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ |
} |
ctx->buf = buf; |
ctx->buflen = len; |
return( 0 ); |
} |
void mbedtls_pem_free( mbedtls_pem_context *ctx ) |
{ |
if ( ctx->buf != NULL ) |
{ |
mbedtls_platform_zeroize( ctx->buf, ctx->buflen ); |
mbedtls_free( ctx->buf ); |
} |
mbedtls_free( ctx->info ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) ); |
} |
#endif /* MBEDTLS_PEM_PARSE_C */ |
#if defined(MBEDTLS_PEM_WRITE_C) |
int mbedtls_pem_write_buffer( const char *header, const char *footer, |
const unsigned char *der_data, size_t der_len, |
unsigned char *buf, size_t buf_len, size_t *olen ) |
{ |
int ret; |
unsigned char *encode_buf = NULL, *c, *p = buf; |
size_t len = 0, use_len, add_len = 0; |
mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); |
add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; |
if( use_len + add_len > buf_len ) |
{ |
*olen = use_len + add_len; |
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); |
} |
if( use_len != 0 && |
( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) ) |
return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); |
if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, |
der_len ) ) != 0 ) |
{ |
mbedtls_free( encode_buf ); |
return( ret ); |
} |
memcpy( p, header, strlen( header ) ); |
p += strlen( header ); |
c = encode_buf; |
while( use_len ) |
{ |
len = ( use_len > 64 ) ? 64 : use_len; |
memcpy( p, c, len ); |
use_len -= len; |
p += len; |
c += len; |
*p++ = '\n'; |
} |
memcpy( p, footer, strlen( footer ) ); |
p += strlen( footer ); |
*p++ = '\0'; |
*olen = p - buf; |
mbedtls_free( encode_buf ); |
return( 0 ); |
} |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ |
/programs/develop/libraries/kos_mbedtls/library/pk.c |
---|
0,0 → 1,548 |
/* |
* Public Key abstraction layer |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PK_C) |
#include "mbedtls/pk.h" |
#include "mbedtls/pk_internal.h" |
#include "mbedtls/platform_util.h" |
#if defined(MBEDTLS_RSA_C) |
#include "mbedtls/rsa.h" |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
#include "mbedtls/ecdsa.h" |
#endif |
#include <limits.h> |
#include <stdint.h> |
/* Parameter validation macros based on platform_util.h */ |
#define PK_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) |
#define PK_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
/* |
* Initialise a mbedtls_pk_context |
*/ |
void mbedtls_pk_init( mbedtls_pk_context *ctx ) |
{ |
PK_VALIDATE( ctx != NULL ); |
ctx->pk_info = NULL; |
ctx->pk_ctx = NULL; |
} |
/* |
* Free (the components of) a mbedtls_pk_context |
*/ |
void mbedtls_pk_free( mbedtls_pk_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
if ( ctx->pk_info != NULL ) |
ctx->pk_info->ctx_free_func( ctx->pk_ctx ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) ); |
} |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Initialize a restart context |
*/ |
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ) |
{ |
PK_VALIDATE( ctx != NULL ); |
ctx->pk_info = NULL; |
ctx->rs_ctx = NULL; |
} |
/* |
* Free the components of a restart context |
*/ |
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ) |
{ |
if( ctx == NULL || ctx->pk_info == NULL || |
ctx->pk_info->rs_free_func == NULL ) |
{ |
return; |
} |
ctx->pk_info->rs_free_func( ctx->rs_ctx ); |
ctx->pk_info = NULL; |
ctx->rs_ctx = NULL; |
} |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/* |
* Get pk_info structure from type |
*/ |
const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) |
{ |
switch( pk_type ) { |
#if defined(MBEDTLS_RSA_C) |
case MBEDTLS_PK_RSA: |
return( &mbedtls_rsa_info ); |
#endif |
#if defined(MBEDTLS_ECP_C) |
case MBEDTLS_PK_ECKEY: |
return( &mbedtls_eckey_info ); |
case MBEDTLS_PK_ECKEY_DH: |
return( &mbedtls_eckeydh_info ); |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
case MBEDTLS_PK_ECDSA: |
return( &mbedtls_ecdsa_info ); |
#endif |
/* MBEDTLS_PK_RSA_ALT omitted on purpose */ |
default: |
return( NULL ); |
} |
} |
/* |
* Initialise context |
*/ |
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
if( info == NULL || ctx->pk_info != NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) |
return( MBEDTLS_ERR_PK_ALLOC_FAILED ); |
ctx->pk_info = info; |
return( 0 ); |
} |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
/* |
* Initialize an RSA-alt context |
*/ |
int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, |
mbedtls_pk_rsa_alt_decrypt_func decrypt_func, |
mbedtls_pk_rsa_alt_sign_func sign_func, |
mbedtls_pk_rsa_alt_key_len_func key_len_func ) |
{ |
mbedtls_rsa_alt_context *rsa_alt; |
const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; |
PK_VALIDATE_RET( ctx != NULL ); |
if( ctx->pk_info != NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) |
return( MBEDTLS_ERR_PK_ALLOC_FAILED ); |
ctx->pk_info = info; |
rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; |
rsa_alt->key = key; |
rsa_alt->decrypt_func = decrypt_func; |
rsa_alt->sign_func = sign_func; |
rsa_alt->key_len_func = key_len_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
/* |
* Tell if a PK can do the operations of the given type |
*/ |
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) |
{ |
/* A context with null pk_info is not set up yet and can't do anything. |
* For backward compatibility, also accept NULL instead of a context |
* pointer. */ |
if( ctx == NULL || ctx->pk_info == NULL ) |
return( 0 ); |
return( ctx->pk_info->can_do( type ) ); |
} |
/* |
* Helper for mbedtls_pk_sign and mbedtls_pk_verify |
*/ |
static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ) |
{ |
const mbedtls_md_info_t *md_info; |
if( *hash_len != 0 ) |
return( 0 ); |
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) |
return( -1 ); |
*hash_len = mbedtls_md_get_size( md_info ); |
return( 0 ); |
} |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Helper to set up a restart context if needed |
*/ |
static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx, |
const mbedtls_pk_info_t *info ) |
{ |
/* Don't do anything if already set up or invalid */ |
if( ctx == NULL || ctx->pk_info != NULL ) |
return( 0 ); |
/* Should never happen when we're called */ |
if( info->rs_alloc_func == NULL || info->rs_free_func == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL ) |
return( MBEDTLS_ERR_PK_ALLOC_FAILED ); |
ctx->pk_info = info; |
return( 0 ); |
} |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
/* |
* Verify a signature (restartable) |
*/ |
int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len, |
mbedtls_pk_restart_ctx *rs_ctx ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || |
hash != NULL ); |
PK_VALIDATE_RET( sig != NULL ); |
if( ctx->pk_info == NULL || |
pk_hashlen_helper( md_alg, &hash_len ) != 0 ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* optimization: use non-restartable version if restart disabled */ |
if( rs_ctx != NULL && |
mbedtls_ecp_restart_is_enabled() && |
ctx->pk_info->verify_rs_func != NULL ) |
{ |
int ret; |
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) |
return( ret ); |
ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx, |
md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx ); |
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) |
mbedtls_pk_restart_free( rs_ctx ); |
return( ret ); |
} |
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
(void) rs_ctx; |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
if( ctx->pk_info->verify_func == NULL ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, |
sig, sig_len ) ); |
} |
/* |
* Verify a signature |
*/ |
int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ) |
{ |
return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len, |
sig, sig_len, NULL ) ); |
} |
/* |
* Verify a signature with options |
*/ |
int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, |
mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || |
hash != NULL ); |
PK_VALIDATE_RET( sig != NULL ); |
if( ctx->pk_info == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ! mbedtls_pk_can_do( ctx, type ) ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
if( type == MBEDTLS_PK_RSASSA_PSS ) |
{ |
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) |
int ret; |
const mbedtls_pk_rsassa_pss_options *pss_opts; |
#if SIZE_MAX > UINT_MAX |
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
#endif /* SIZE_MAX > UINT_MAX */ |
if( options == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; |
if( sig_len < mbedtls_pk_get_len( ctx ) ) |
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); |
ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ), |
NULL, NULL, MBEDTLS_RSA_PUBLIC, |
md_alg, (unsigned int) hash_len, hash, |
pss_opts->mgf1_hash_id, |
pss_opts->expected_salt_len, |
sig ); |
if( ret != 0 ) |
return( ret ); |
if( sig_len > mbedtls_pk_get_len( ctx ) ) |
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); |
return( 0 ); |
#else |
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ |
} |
/* General case: no options */ |
if( options != NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); |
} |
/* |
* Make a signature (restartable) |
*/ |
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, |
mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
mbedtls_pk_restart_ctx *rs_ctx ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) || |
hash != NULL ); |
PK_VALIDATE_RET( sig != NULL ); |
if( ctx->pk_info == NULL || |
pk_hashlen_helper( md_alg, &hash_len ) != 0 ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* optimization: use non-restartable version if restart disabled */ |
if( rs_ctx != NULL && |
mbedtls_ecp_restart_is_enabled() && |
ctx->pk_info->sign_rs_func != NULL ) |
{ |
int ret; |
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 ) |
return( ret ); |
ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg, |
hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx ); |
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) |
mbedtls_pk_restart_free( rs_ctx ); |
return( ret ); |
} |
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
(void) rs_ctx; |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
if( ctx->pk_info->sign_func == NULL ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, |
sig, sig_len, f_rng, p_rng ) ); |
} |
/* |
* Make a signature |
*/ |
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len, |
sig, sig_len, f_rng, p_rng, NULL ) ); |
} |
/* |
* Decrypt message |
*/ |
int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( input != NULL || ilen == 0 ); |
PK_VALIDATE_RET( output != NULL || osize == 0 ); |
PK_VALIDATE_RET( olen != NULL ); |
if( ctx->pk_info == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ctx->pk_info->decrypt_func == NULL ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, |
output, olen, osize, f_rng, p_rng ) ); |
} |
/* |
* Encrypt message |
*/ |
int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( input != NULL || ilen == 0 ); |
PK_VALIDATE_RET( output != NULL || osize == 0 ); |
PK_VALIDATE_RET( olen != NULL ); |
if( ctx->pk_info == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ctx->pk_info->encrypt_func == NULL ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, |
output, olen, osize, f_rng, p_rng ) ); |
} |
/* |
* Check public-private key pair |
*/ |
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) |
{ |
PK_VALIDATE_RET( pub != NULL ); |
PK_VALIDATE_RET( prv != NULL ); |
if( pub->pk_info == NULL || |
prv->pk_info == NULL || |
prv->pk_info->check_pair_func == NULL ) |
{ |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
} |
if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT ) |
{ |
if( pub->pk_info->type != MBEDTLS_PK_RSA ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
} |
else |
{ |
if( pub->pk_info != prv->pk_info ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
} |
return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) ); |
} |
/* |
* Get key size in bits |
*/ |
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) |
{ |
/* For backward compatibility, accept NULL or a context that |
* isn't set up yet, and return a fake value that should be safe. */ |
if( ctx == NULL || ctx->pk_info == NULL ) |
return( 0 ); |
return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) ); |
} |
/* |
* Export debug information |
*/ |
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) |
{ |
PK_VALIDATE_RET( ctx != NULL ); |
if( ctx->pk_info == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
if( ctx->pk_info->debug_func == NULL ) |
return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); |
ctx->pk_info->debug_func( ctx->pk_ctx, items ); |
return( 0 ); |
} |
/* |
* Access the PK type name |
*/ |
const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx ) |
{ |
if( ctx == NULL || ctx->pk_info == NULL ) |
return( "invalid PK" ); |
return( ctx->pk_info->name ); |
} |
/* |
* Access the PK type |
*/ |
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ) |
{ |
if( ctx == NULL || ctx->pk_info == NULL ) |
return( MBEDTLS_PK_NONE ); |
return( ctx->pk_info->type ); |
} |
#endif /* MBEDTLS_PK_C */ |
/programs/develop/libraries/kos_mbedtls/library/pk_wrap.c |
---|
0,0 → 1,721 |
/* |
* Public Key abstraction layer: wrapper functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PK_C) |
#include "mbedtls/pk_internal.h" |
/* Even if RSA not activated, for the sake of RSA-alt */ |
#include "mbedtls/rsa.h" |
#include <string.h> |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
#include "mbedtls/ecdsa.h" |
#endif |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
#include "mbedtls/platform_util.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include <limits.h> |
#include <stdint.h> |
#if defined(MBEDTLS_RSA_C) |
static int rsa_can_do( mbedtls_pk_type_t type ) |
{ |
return( type == MBEDTLS_PK_RSA || |
type == MBEDTLS_PK_RSASSA_PSS ); |
} |
static size_t rsa_get_bitlen( const void *ctx ) |
{ |
const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx; |
return( 8 * mbedtls_rsa_get_len( rsa ) ); |
} |
static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ) |
{ |
int ret; |
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; |
size_t rsa_len = mbedtls_rsa_get_len( rsa ); |
#if SIZE_MAX > UINT_MAX |
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
#endif /* SIZE_MAX > UINT_MAX */ |
if( sig_len < rsa_len ) |
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); |
if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL, |
MBEDTLS_RSA_PUBLIC, md_alg, |
(unsigned int) hash_len, hash, sig ) ) != 0 ) |
return( ret ); |
/* The buffer contains a valid signature followed by extra data. |
* We have a special error code for that so that so that callers can |
* use mbedtls_pk_verify() to check "Does the buffer start with a |
* valid signature?" and not just "Does the buffer contain a valid |
* signature?". */ |
if( sig_len > rsa_len ) |
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); |
return( 0 ); |
} |
static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; |
#if SIZE_MAX > UINT_MAX |
if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
#endif /* SIZE_MAX > UINT_MAX */ |
*sig_len = mbedtls_rsa_get_len( rsa ); |
return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, |
md_alg, (unsigned int) hash_len, hash, sig ) ); |
} |
static int rsa_decrypt_wrap( void *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; |
if( ilen != mbedtls_rsa_get_len( rsa ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng, |
MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); |
} |
static int rsa_encrypt_wrap( void *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx; |
*olen = mbedtls_rsa_get_len( rsa ); |
if( *olen > osize ) |
return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); |
return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC, |
ilen, input, output ) ); |
} |
static int rsa_check_pair_wrap( const void *pub, const void *prv ) |
{ |
return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, |
(const mbedtls_rsa_context *) prv ) ); |
} |
static void *rsa_alloc_wrap( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); |
if( ctx != NULL ) |
mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); |
return( ctx ); |
} |
static void rsa_free_wrap( void *ctx ) |
{ |
mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); |
mbedtls_free( ctx ); |
} |
static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) |
{ |
items->type = MBEDTLS_PK_DEBUG_MPI; |
items->name = "rsa.N"; |
items->value = &( ((mbedtls_rsa_context *) ctx)->N ); |
items++; |
items->type = MBEDTLS_PK_DEBUG_MPI; |
items->name = "rsa.E"; |
items->value = &( ((mbedtls_rsa_context *) ctx)->E ); |
} |
const mbedtls_pk_info_t mbedtls_rsa_info = { |
MBEDTLS_PK_RSA, |
"RSA", |
rsa_get_bitlen, |
rsa_can_do, |
rsa_verify_wrap, |
rsa_sign_wrap, |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
NULL, |
NULL, |
#endif |
rsa_decrypt_wrap, |
rsa_encrypt_wrap, |
rsa_check_pair_wrap, |
rsa_alloc_wrap, |
rsa_free_wrap, |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
NULL, |
NULL, |
#endif |
rsa_debug, |
}; |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
/* |
* Generic EC key |
*/ |
static int eckey_can_do( mbedtls_pk_type_t type ) |
{ |
return( type == MBEDTLS_PK_ECKEY || |
type == MBEDTLS_PK_ECKEY_DH || |
type == MBEDTLS_PK_ECDSA ); |
} |
static size_t eckey_get_bitlen( const void *ctx ) |
{ |
return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); |
} |
#if defined(MBEDTLS_ECDSA_C) |
/* Forward declarations */ |
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ); |
static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); |
static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ) |
{ |
int ret; |
mbedtls_ecdsa_context ecdsa; |
mbedtls_ecdsa_init( &ecdsa ); |
if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) |
ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); |
mbedtls_ecdsa_free( &ecdsa ); |
return( ret ); |
} |
static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret; |
mbedtls_ecdsa_context ecdsa; |
mbedtls_ecdsa_init( &ecdsa ); |
if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) |
ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, |
f_rng, p_rng ); |
mbedtls_ecdsa_free( &ecdsa ); |
return( ret ); |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
/* Forward declarations */ |
static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len, |
void *rs_ctx ); |
static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
void *rs_ctx ); |
/* |
* Restart context for ECDSA operations with ECKEY context |
* |
* We need to store an actual ECDSA context, as we need to pass the same to |
* the underlying ecdsa function, so we can't create it on the fly every time. |
*/ |
typedef struct |
{ |
mbedtls_ecdsa_restart_ctx ecdsa_rs; |
mbedtls_ecdsa_context ecdsa_ctx; |
} eckey_restart_ctx; |
static void *eckey_rs_alloc( void ) |
{ |
eckey_restart_ctx *rs_ctx; |
void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) ); |
if( ctx != NULL ) |
{ |
rs_ctx = ctx; |
mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs ); |
mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx ); |
} |
return( ctx ); |
} |
static void eckey_rs_free( void *ctx ) |
{ |
eckey_restart_ctx *rs_ctx; |
if( ctx == NULL) |
return; |
rs_ctx = ctx; |
mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs ); |
mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx ); |
mbedtls_free( ctx ); |
} |
static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len, |
void *rs_ctx ) |
{ |
int ret; |
eckey_restart_ctx *rs = rs_ctx; |
/* Should never happen */ |
if( rs == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
/* set up our own sub-context if needed (that is, on first run) */ |
if( rs->ecdsa_ctx.grp.pbits == 0 ) |
MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); |
MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, |
md_alg, hash, hash_len, |
sig, sig_len, &rs->ecdsa_rs ) ); |
cleanup: |
return( ret ); |
} |
static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
void *rs_ctx ) |
{ |
int ret; |
eckey_restart_ctx *rs = rs_ctx; |
/* Should never happen */ |
if( rs == NULL ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
/* set up our own sub-context if needed (that is, on first run) */ |
if( rs->ecdsa_ctx.grp.pbits == 0 ) |
MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); |
MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg, |
hash, hash_len, sig, sig_len, |
f_rng, p_rng, &rs->ecdsa_rs ) ); |
cleanup: |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#endif /* MBEDTLS_ECDSA_C */ |
static int eckey_check_pair( const void *pub, const void *prv ) |
{ |
return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, |
(const mbedtls_ecp_keypair *) prv ) ); |
} |
static void *eckey_alloc_wrap( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); |
if( ctx != NULL ) |
mbedtls_ecp_keypair_init( ctx ); |
return( ctx ); |
} |
static void eckey_free_wrap( void *ctx ) |
{ |
mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); |
mbedtls_free( ctx ); |
} |
static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) |
{ |
items->type = MBEDTLS_PK_DEBUG_ECP; |
items->name = "eckey.Q"; |
items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); |
} |
const mbedtls_pk_info_t mbedtls_eckey_info = { |
MBEDTLS_PK_ECKEY, |
"EC", |
eckey_get_bitlen, |
eckey_can_do, |
#if defined(MBEDTLS_ECDSA_C) |
eckey_verify_wrap, |
eckey_sign_wrap, |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
eckey_verify_rs_wrap, |
eckey_sign_rs_wrap, |
#endif |
#else /* MBEDTLS_ECDSA_C */ |
NULL, |
NULL, |
#endif /* MBEDTLS_ECDSA_C */ |
NULL, |
NULL, |
eckey_check_pair, |
eckey_alloc_wrap, |
eckey_free_wrap, |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
eckey_rs_alloc, |
eckey_rs_free, |
#endif |
eckey_debug, |
}; |
/* |
* EC key restricted to ECDH |
*/ |
static int eckeydh_can_do( mbedtls_pk_type_t type ) |
{ |
return( type == MBEDTLS_PK_ECKEY || |
type == MBEDTLS_PK_ECKEY_DH ); |
} |
const mbedtls_pk_info_t mbedtls_eckeydh_info = { |
MBEDTLS_PK_ECKEY_DH, |
"EC_DH", |
eckey_get_bitlen, /* Same underlying key structure */ |
eckeydh_can_do, |
NULL, |
NULL, |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
NULL, |
NULL, |
#endif |
NULL, |
NULL, |
eckey_check_pair, |
eckey_alloc_wrap, /* Same underlying key structure */ |
eckey_free_wrap, /* Same underlying key structure */ |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
NULL, |
NULL, |
#endif |
eckey_debug, /* Same underlying key structure */ |
}; |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_ECDSA_C) |
static int ecdsa_can_do( mbedtls_pk_type_t type ) |
{ |
return( type == MBEDTLS_PK_ECDSA ); |
} |
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len ) |
{ |
int ret; |
((void) md_alg); |
ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, |
hash, hash_len, sig, sig_len ); |
if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) |
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); |
return( ret ); |
} |
static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, |
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
const unsigned char *sig, size_t sig_len, |
void *rs_ctx ) |
{ |
int ret; |
((void) md_alg); |
ret = mbedtls_ecdsa_read_signature_restartable( |
(mbedtls_ecdsa_context *) ctx, |
hash, hash_len, sig, sig_len, |
(mbedtls_ecdsa_restart_ctx *) rs_ctx ); |
if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) |
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); |
return( ret ); |
} |
static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
void *rs_ctx ) |
{ |
return( mbedtls_ecdsa_write_signature_restartable( |
(mbedtls_ecdsa_context *) ctx, |
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng, |
(mbedtls_ecdsa_restart_ctx *) rs_ctx ) ); |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
static void *ecdsa_alloc_wrap( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); |
if( ctx != NULL ) |
mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); |
return( ctx ); |
} |
static void ecdsa_free_wrap( void *ctx ) |
{ |
mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); |
mbedtls_free( ctx ); |
} |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
static void *ecdsa_rs_alloc( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) ); |
if( ctx != NULL ) |
mbedtls_ecdsa_restart_init( ctx ); |
return( ctx ); |
} |
static void ecdsa_rs_free( void *ctx ) |
{ |
mbedtls_ecdsa_restart_free( ctx ); |
mbedtls_free( ctx ); |
} |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
const mbedtls_pk_info_t mbedtls_ecdsa_info = { |
MBEDTLS_PK_ECDSA, |
"ECDSA", |
eckey_get_bitlen, /* Compatible key structures */ |
ecdsa_can_do, |
ecdsa_verify_wrap, |
ecdsa_sign_wrap, |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
ecdsa_verify_rs_wrap, |
ecdsa_sign_rs_wrap, |
#endif |
NULL, |
NULL, |
eckey_check_pair, /* Compatible key structures */ |
ecdsa_alloc_wrap, |
ecdsa_free_wrap, |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
ecdsa_rs_alloc, |
ecdsa_rs_free, |
#endif |
eckey_debug, /* Compatible key structures */ |
}; |
#endif /* MBEDTLS_ECDSA_C */ |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
/* |
* Support for alternative RSA-private implementations |
*/ |
static int rsa_alt_can_do( mbedtls_pk_type_t type ) |
{ |
return( type == MBEDTLS_PK_RSA ); |
} |
static size_t rsa_alt_get_bitlen( const void *ctx ) |
{ |
const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; |
return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); |
} |
static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, |
const unsigned char *hash, size_t hash_len, |
unsigned char *sig, size_t *sig_len, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; |
#if SIZE_MAX > UINT_MAX |
if( UINT_MAX < hash_len ) |
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); |
#endif /* SIZE_MAX > UINT_MAX */ |
*sig_len = rsa_alt->key_len_func( rsa_alt->key ); |
return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, |
md_alg, (unsigned int) hash_len, hash, sig ) ); |
} |
static int rsa_alt_decrypt_wrap( void *ctx, |
const unsigned char *input, size_t ilen, |
unsigned char *output, size_t *olen, size_t osize, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; |
((void) f_rng); |
((void) p_rng); |
if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
return( rsa_alt->decrypt_func( rsa_alt->key, |
MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); |
} |
#if defined(MBEDTLS_RSA_C) |
static int rsa_alt_check_pair( const void *pub, const void *prv ) |
{ |
unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; |
unsigned char hash[32]; |
size_t sig_len = 0; |
int ret; |
if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
memset( hash, 0x2a, sizeof( hash ) ); |
if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, |
hash, sizeof( hash ), |
sig, &sig_len, NULL, NULL ) ) != 0 ) |
{ |
return( ret ); |
} |
if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, |
hash, sizeof( hash ), sig, sig_len ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_RSA_C */ |
static void *rsa_alt_alloc_wrap( void ) |
{ |
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); |
if( ctx != NULL ) |
memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); |
return( ctx ); |
} |
static void rsa_alt_free_wrap( void *ctx ) |
{ |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); |
mbedtls_free( ctx ); |
} |
const mbedtls_pk_info_t mbedtls_rsa_alt_info = { |
MBEDTLS_PK_RSA_ALT, |
"RSA-alt", |
rsa_alt_get_bitlen, |
rsa_alt_can_do, |
NULL, |
rsa_alt_sign_wrap, |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
NULL, |
NULL, |
#endif |
rsa_alt_decrypt_wrap, |
NULL, |
#if defined(MBEDTLS_RSA_C) |
rsa_alt_check_pair, |
#else |
NULL, |
#endif |
rsa_alt_alloc_wrap, |
rsa_alt_free_wrap, |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
NULL, |
NULL, |
#endif |
NULL, |
}; |
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
#endif /* MBEDTLS_PK_C */ |
/programs/develop/libraries/kos_mbedtls/library/pkcs11.c |
---|
0,0 → 1,242 |
/** |
* \file pkcs11.c |
* |
* \brief Wrapper for PKCS#11 library libpkcs11-helper |
* |
* \author Adriaan de Jong <dejong@fox-it.com> |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#include "mbedtls/pkcs11.h" |
#if defined(MBEDTLS_PKCS11_C) |
#include "mbedtls/md.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/x509_crt.h" |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include <string.h> |
void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) ); |
} |
int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) |
{ |
int ret = 1; |
unsigned char *cert_blob = NULL; |
size_t cert_blob_size = 0; |
if( cert == NULL ) |
{ |
ret = 2; |
goto cleanup; |
} |
if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, |
&cert_blob_size ) != CKR_OK ) |
{ |
ret = 3; |
goto cleanup; |
} |
cert_blob = mbedtls_calloc( 1, cert_blob_size ); |
if( NULL == cert_blob ) |
{ |
ret = 4; |
goto cleanup; |
} |
if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, |
&cert_blob_size ) != CKR_OK ) |
{ |
ret = 5; |
goto cleanup; |
} |
if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) ) |
{ |
ret = 6; |
goto cleanup; |
} |
ret = 0; |
cleanup: |
if( NULL != cert_blob ) |
mbedtls_free( cert_blob ); |
return( ret ); |
} |
int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, |
pkcs11h_certificate_t pkcs11_cert ) |
{ |
int ret = 1; |
mbedtls_x509_crt cert; |
mbedtls_x509_crt_init( &cert ); |
if( priv_key == NULL ) |
goto cleanup; |
if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) ) |
goto cleanup; |
priv_key->len = mbedtls_pk_get_len( &cert.pk ); |
priv_key->pkcs11h_cert = pkcs11_cert; |
ret = 0; |
cleanup: |
mbedtls_x509_crt_free( &cert ); |
return( ret ); |
} |
void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ) |
{ |
if( NULL != priv_key ) |
pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); |
} |
int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, |
int mode, size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ) |
{ |
size_t input_len, output_len; |
if( NULL == ctx ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( MBEDTLS_RSA_PRIVATE != mode ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
output_len = input_len = ctx->len; |
if( input_len < 16 || input_len > output_max_len ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* Determine size of output buffer */ |
if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, |
input_len, NULL, &output_len ) != CKR_OK ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
if( output_len > output_max_len ) |
return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); |
if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, |
input_len, output, &output_len ) != CKR_OK ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
*olen = output_len; |
return( 0 ); |
} |
int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ) |
{ |
size_t sig_len = 0, asn_len = 0, oid_size = 0; |
unsigned char *p = sig; |
const char *oid; |
if( NULL == ctx ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( MBEDTLS_RSA_PRIVATE != mode ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hashlen = mbedtls_md_get_size( md_info ); |
asn_len = 10 + oid_size; |
} |
sig_len = ctx->len; |
if( hashlen > sig_len || asn_len > sig_len || |
hashlen + asn_len > sig_len ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
/* |
* DigestInfo ::= SEQUENCE { |
* digestAlgorithm DigestAlgorithmIdentifier, |
* digest Digest } |
* |
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier |
* |
* Digest ::= OCTET STRING |
*/ |
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
*p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); |
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
*p++ = (unsigned char) ( 0x04 + oid_size ); |
*p++ = MBEDTLS_ASN1_OID; |
*p++ = oid_size & 0xFF; |
memcpy( p, oid, oid_size ); |
p += oid_size; |
*p++ = MBEDTLS_ASN1_NULL; |
*p++ = 0x00; |
*p++ = MBEDTLS_ASN1_OCTET_STRING; |
*p++ = hashlen; |
} |
memcpy( p, hash, hashlen ); |
if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, |
asn_len + hashlen, sig, &sig_len ) != CKR_OK ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
return( 0 ); |
} |
#endif /* defined(MBEDTLS_PKCS11_C) */ |
/programs/develop/libraries/kos_mbedtls/library/pkcs12.c |
---|
0,0 → 1,367 |
/* |
* PKCS#12 Personal Information Exchange Syntax |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The PKCS #12 Personal Information Exchange Syntax Standard v1.1 |
* |
* http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf |
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PKCS12_C) |
#include "mbedtls/pkcs12.h" |
#include "mbedtls/asn1.h" |
#include "mbedtls/cipher.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_ARC4_C) |
#include "mbedtls/arc4.h" |
#endif |
#if defined(MBEDTLS_DES_C) |
#include "mbedtls/des.h" |
#endif |
#if defined(MBEDTLS_ASN1_PARSE_C) |
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, |
mbedtls_asn1_buf *salt, int *iterations ) |
{ |
int ret; |
unsigned char **p = ¶ms->p; |
const unsigned char *end = params->p + params->len; |
/* |
* pkcs-12PbeParams ::= SEQUENCE { |
* salt OCTET STRING, |
* iterations INTEGER |
* } |
* |
*/ |
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) |
return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); |
salt->p = *p; |
*p += salt->len; |
if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) |
return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); |
if( *p != end ) |
return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
#define PKCS12_MAX_PWDLEN 128 |
static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, |
const unsigned char *pwd, size_t pwdlen, |
unsigned char *key, size_t keylen, |
unsigned char *iv, size_t ivlen ) |
{ |
int ret, iterations = 0; |
mbedtls_asn1_buf salt; |
size_t i; |
unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; |
if( pwdlen > PKCS12_MAX_PWDLEN ) |
return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); |
memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); |
memset( &unipwd, 0, sizeof(unipwd) ); |
if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, |
&iterations ) ) != 0 ) |
return( ret ); |
for( i = 0; i < pwdlen; i++ ) |
unipwd[i * 2 + 1] = pwd[i]; |
if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, |
salt.p, salt.len, md_type, |
MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) |
{ |
return( ret ); |
} |
if( iv == NULL || ivlen == 0 ) |
return( 0 ); |
if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, |
salt.p, salt.len, md_type, |
MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
#undef PKCS12_MAX_PWDLEN |
int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *data, size_t len, |
unsigned char *output ) |
{ |
#if !defined(MBEDTLS_ARC4_C) |
((void) pbe_params); |
((void) mode); |
((void) pwd); |
((void) pwdlen); |
((void) data); |
((void) len); |
((void) output); |
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); |
#else |
int ret; |
unsigned char key[16]; |
mbedtls_arc4_context ctx; |
((void) mode); |
mbedtls_arc4_init( &ctx ); |
if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, |
pwd, pwdlen, |
key, 16, NULL, 0 ) ) != 0 ) |
{ |
return( ret ); |
} |
mbedtls_arc4_setup( &ctx, key, 16 ); |
if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_platform_zeroize( key, sizeof( key ) ); |
mbedtls_arc4_free( &ctx ); |
return( ret ); |
#endif /* MBEDTLS_ARC4_C */ |
} |
int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, |
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *data, size_t len, |
unsigned char *output ) |
{ |
int ret, keylen = 0; |
unsigned char key[32]; |
unsigned char iv[16]; |
const mbedtls_cipher_info_t *cipher_info; |
mbedtls_cipher_context_t cipher_ctx; |
size_t olen = 0; |
cipher_info = mbedtls_cipher_info_from_type( cipher_type ); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); |
keylen = cipher_info->key_bitlen / 8; |
if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, |
key, keylen, |
iv, cipher_info->iv_size ) ) != 0 ) |
{ |
return( ret ); |
} |
mbedtls_cipher_init( &cipher_ctx ); |
if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, |
output, &olen ) ) != 0 ) |
{ |
goto exit; |
} |
if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) |
ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; |
exit: |
mbedtls_platform_zeroize( key, sizeof( key ) ); |
mbedtls_platform_zeroize( iv, sizeof( iv ) ); |
mbedtls_cipher_free( &cipher_ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, |
const unsigned char *filler, size_t fill_len ) |
{ |
unsigned char *p = data; |
size_t use_len; |
while( data_len > 0 ) |
{ |
use_len = ( data_len > fill_len ) ? fill_len : data_len; |
memcpy( p, filler, use_len ); |
p += use_len; |
data_len -= use_len; |
} |
} |
int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *salt, size_t saltlen, |
mbedtls_md_type_t md_type, int id, int iterations ) |
{ |
int ret; |
unsigned int j; |
unsigned char diversifier[128]; |
unsigned char salt_block[128], pwd_block[128], hash_block[128]; |
unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; |
unsigned char *p; |
unsigned char c; |
size_t hlen, use_len, v, i; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
// This version only allows max of 64 bytes of password or salt |
if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) |
return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); |
md_info = mbedtls_md_info_from_type( md_type ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); |
mbedtls_md_init( &md_ctx ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) |
return( ret ); |
hlen = mbedtls_md_get_size( md_info ); |
if( hlen <= 32 ) |
v = 64; |
else |
v = 128; |
memset( diversifier, (unsigned char) id, v ); |
pkcs12_fill_buffer( salt_block, v, salt, saltlen ); |
pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); |
p = data; |
while( datalen > 0 ) |
{ |
// Calculate hash( diversifier || salt_block || pwd_block ) |
if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) |
goto exit; |
// Perform remaining ( iterations - 1 ) recursive hash calculations |
for( i = 1; i < (size_t) iterations; i++ ) |
{ |
if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) |
goto exit; |
} |
use_len = ( datalen > hlen ) ? hlen : datalen; |
memcpy( p, hash_output, use_len ); |
datalen -= use_len; |
p += use_len; |
if( datalen == 0 ) |
break; |
// Concatenating copies of hash_output into hash_block (B) |
pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); |
// B += 1 |
for( i = v; i > 0; i-- ) |
if( ++hash_block[i - 1] != 0 ) |
break; |
// salt_block += B |
c = 0; |
for( i = v; i > 0; i-- ) |
{ |
j = salt_block[i - 1] + hash_block[i - 1] + c; |
c = (unsigned char) (j >> 8); |
salt_block[i - 1] = j & 0xFF; |
} |
// pwd_block += B |
c = 0; |
for( i = v; i > 0; i-- ) |
{ |
j = pwd_block[i - 1] + hash_block[i - 1] + c; |
c = (unsigned char) (j >> 8); |
pwd_block[i - 1] = j & 0xFF; |
} |
} |
ret = 0; |
exit: |
mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) ); |
mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) ); |
mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) ); |
mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) ); |
mbedtls_md_free( &md_ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS12_C */ |
/programs/develop/libraries/kos_mbedtls/library/pkcs5.c |
---|
0,0 → 1,413 |
/** |
* \file pkcs5.c |
* |
* \brief PKCS#5 functions |
* |
* \author Mathias Olsson <mathias@kompetensum.com> |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* PKCS#5 includes PBKDF2 and more |
* |
* http://tools.ietf.org/html/rfc2898 (Specification) |
* http://tools.ietf.org/html/rfc6070 (Test vectors) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PKCS5_C) |
#include "mbedtls/pkcs5.h" |
#if defined(MBEDTLS_ASN1_PARSE_C) |
#include "mbedtls/asn1.h" |
#include "mbedtls/cipher.h" |
#include "mbedtls/oid.h" |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
#include <string.h> |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif |
#if defined(MBEDTLS_ASN1_PARSE_C) |
static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, |
mbedtls_asn1_buf *salt, int *iterations, |
int *keylen, mbedtls_md_type_t *md_type ) |
{ |
int ret; |
mbedtls_asn1_buf prf_alg_oid; |
unsigned char *p = params->p; |
const unsigned char *end = params->p + params->len; |
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
/* |
* PBKDF2-params ::= SEQUENCE { |
* salt OCTET STRING, |
* iterationCount INTEGER, |
* keyLength INTEGER OPTIONAL |
* prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 |
* } |
* |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); |
salt->p = p; |
p += salt->len; |
if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); |
if( p == end ) |
return( 0 ); |
if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 ) |
{ |
if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); |
} |
if( p == end ) |
return( 0 ); |
if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); |
if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); |
if( p != end ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, |
const unsigned char *pwd, size_t pwdlen, |
const unsigned char *data, size_t datalen, |
unsigned char *output ) |
{ |
int ret, iterations = 0, keylen = 0; |
unsigned char *p, *end; |
mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; |
mbedtls_asn1_buf salt; |
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; |
unsigned char key[32], iv[32]; |
size_t olen = 0; |
const mbedtls_md_info_t *md_info; |
const mbedtls_cipher_info_t *cipher_info; |
mbedtls_md_context_t md_ctx; |
mbedtls_cipher_type_t cipher_alg; |
mbedtls_cipher_context_t cipher_ctx; |
p = pbe_params->p; |
end = p + pbe_params->len; |
/* |
* PBES2-params ::= SEQUENCE { |
* keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, |
* encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} |
* } |
*/ |
if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); |
// Only PBKDF2 supported at the moment |
// |
if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); |
if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params, |
&salt, &iterations, &keylen, |
&md_type ) ) != 0 ) |
{ |
return( ret ); |
} |
md_info = mbedtls_md_info_from_type( md_type ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); |
if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid, |
&enc_scheme_params ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); |
} |
if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) |
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); |
cipher_info = mbedtls_cipher_info_from_type( cipher_alg ); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); |
/* |
* The value of keylen from pkcs5_parse_pbkdf2_params() is ignored |
* since it is optional and we don't know if it was set or not |
*/ |
keylen = cipher_info->key_bitlen / 8; |
if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || |
enc_scheme_params.len != cipher_info->iv_size ) |
{ |
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT ); |
} |
mbedtls_md_init( &md_ctx ); |
mbedtls_cipher_init( &cipher_ctx ); |
memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, |
iterations, keylen, key ) ) != 0 ) |
{ |
goto exit; |
} |
if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, |
data, datalen, output, &olen ) ) != 0 ) |
ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH; |
exit: |
mbedtls_md_free( &md_ctx ); |
mbedtls_cipher_free( &cipher_ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, |
size_t plen, const unsigned char *salt, size_t slen, |
unsigned int iteration_count, |
uint32_t key_length, unsigned char *output ) |
{ |
int ret, j; |
unsigned int i; |
unsigned char md1[MBEDTLS_MD_MAX_SIZE]; |
unsigned char work[MBEDTLS_MD_MAX_SIZE]; |
unsigned char md_size = mbedtls_md_get_size( ctx->md_info ); |
size_t use_len; |
unsigned char *out_p = output; |
unsigned char counter[4]; |
memset( counter, 0, 4 ); |
counter[3] = 1; |
#if UINT_MAX > 0xFFFFFFFF |
if( iteration_count > 0xFFFFFFFF ) |
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); |
#endif |
while( key_length ) |
{ |
// U1 ends up in work |
// |
if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) |
return( ret ); |
memcpy( md1, work, md_size ); |
for( i = 1; i < iteration_count; i++ ) |
{ |
// U2 ends up in md1 |
// |
if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 ) |
return( ret ); |
// U1 xor U2 |
// |
for( j = 0; j < md_size; j++ ) |
work[j] ^= md1[j]; |
} |
use_len = ( key_length < md_size ) ? key_length : md_size; |
memcpy( out_p, work, use_len ); |
key_length -= (uint32_t) use_len; |
out_p += use_len; |
for( i = 4; i > 0; i-- ) |
if( ++counter[i - 1] != 0 ) |
break; |
} |
return( 0 ); |
} |
#if defined(MBEDTLS_SELF_TEST) |
#if !defined(MBEDTLS_SHA1_C) |
int mbedtls_pkcs5_self_test( int verbose ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" ); |
return( 0 ); |
} |
#else |
#define MAX_TESTS 6 |
static const size_t plen[MAX_TESTS] = |
{ 8, 8, 8, 24, 9 }; |
static const unsigned char password[MAX_TESTS][32] = |
{ |
"password", |
"password", |
"password", |
"passwordPASSWORDpassword", |
"pass\0word", |
}; |
static const size_t slen[MAX_TESTS] = |
{ 4, 4, 4, 36, 5 }; |
static const unsigned char salt[MAX_TESTS][40] = |
{ |
"salt", |
"salt", |
"salt", |
"saltSALTsaltSALTsaltSALTsaltSALTsalt", |
"sa\0lt", |
}; |
static const uint32_t it_cnt[MAX_TESTS] = |
{ 1, 2, 4096, 4096, 4096 }; |
static const uint32_t key_len[MAX_TESTS] = |
{ 20, 20, 20, 25, 16 }; |
static const unsigned char result_key[MAX_TESTS][32] = |
{ |
{ 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, |
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, |
0x2f, 0xe0, 0x37, 0xa6 }, |
{ 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, |
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, |
0xd8, 0xde, 0x89, 0x57 }, |
{ 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, |
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, |
0x65, 0xa4, 0x29, 0xc1 }, |
{ 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, |
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, |
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, |
0x38 }, |
{ 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, |
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }, |
}; |
int mbedtls_pkcs5_self_test( int verbose ) |
{ |
mbedtls_md_context_t sha1_ctx; |
const mbedtls_md_info_t *info_sha1; |
int ret, i; |
unsigned char key[64]; |
mbedtls_md_init( &sha1_ctx ); |
info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); |
if( info_sha1 == NULL ) |
{ |
ret = 1; |
goto exit; |
} |
if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 ) |
{ |
ret = 1; |
goto exit; |
} |
for( i = 0; i < MAX_TESTS; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i ); |
ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], |
slen[i], it_cnt[i], key_len[i], key ); |
if( ret != 0 || |
memcmp( result_key[i], key, key_len[i] ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
exit: |
mbedtls_md_free( &sha1_ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_PKCS5_C */ |
/programs/develop/libraries/kos_mbedtls/library/pkparse.c |
---|
0,0 → 1,1540 |
/* |
* Public Key layer for parsing key files and structures |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PK_PARSE_C) |
#include "mbedtls/pk.h" |
#include "mbedtls/asn1.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_RSA_C) |
#include "mbedtls/rsa.h" |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
#include "mbedtls/ecdsa.h" |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PKCS5_C) |
#include "mbedtls/pkcs5.h" |
#endif |
#if defined(MBEDTLS_PKCS12_C) |
#include "mbedtls/pkcs12.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
/* Parameter validation macros based on platform_util.h */ |
#define PK_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) |
#define PK_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_FS_IO) |
/* |
* Load all data from a file into a given buffer. |
* |
* The file is expected to contain either PEM or DER encoded data. |
* A terminating null byte is always appended. It is included in the announced |
* length only if the data looks like it is PEM encoded. |
*/ |
int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) |
{ |
FILE *f; |
long size; |
PK_VALIDATE_RET( path != NULL ); |
PK_VALIDATE_RET( buf != NULL ); |
PK_VALIDATE_RET( n != NULL ); |
if( ( f = fopen( path, "rb" ) ) == NULL ) |
return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); |
fseek( f, 0, SEEK_END ); |
if( ( size = ftell( f ) ) == -1 ) |
{ |
fclose( f ); |
return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); |
} |
fseek( f, 0, SEEK_SET ); |
*n = (size_t) size; |
if( *n + 1 == 0 || |
( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) |
{ |
fclose( f ); |
return( MBEDTLS_ERR_PK_ALLOC_FAILED ); |
} |
if( fread( *buf, 1, *n, f ) != *n ) |
{ |
fclose( f ); |
mbedtls_platform_zeroize( *buf, *n ); |
mbedtls_free( *buf ); |
return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); |
} |
fclose( f ); |
(*buf)[*n] = '\0'; |
if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) |
++*n; |
return( 0 ); |
} |
/* |
* Load and parse a private key |
*/ |
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, |
const char *path, const char *pwd ) |
{ |
int ret; |
size_t n; |
unsigned char *buf; |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( path != NULL ); |
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) |
return( ret ); |
if( pwd == NULL ) |
ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 ); |
else |
ret = mbedtls_pk_parse_key( ctx, buf, n, |
(const unsigned char *) pwd, strlen( pwd ) ); |
mbedtls_platform_zeroize( buf, n ); |
mbedtls_free( buf ); |
return( ret ); |
} |
/* |
* Load and parse a public key |
*/ |
int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) |
{ |
int ret; |
size_t n; |
unsigned char *buf; |
PK_VALIDATE_RET( ctx != NULL ); |
PK_VALIDATE_RET( path != NULL ); |
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) |
return( ret ); |
ret = mbedtls_pk_parse_public_key( ctx, buf, n ); |
mbedtls_platform_zeroize( buf, n ); |
mbedtls_free( buf ); |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_ECP_C) |
/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf |
* |
* ECParameters ::= CHOICE { |
* namedCurve OBJECT IDENTIFIER |
* specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } |
* -- implicitCurve NULL |
* } |
*/ |
static int pk_get_ecparams( unsigned char **p, const unsigned char *end, |
mbedtls_asn1_buf *params ) |
{ |
int ret; |
if ( end - *p < 1 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
/* Tag may be either OID or SEQUENCE */ |
params->tag = **p; |
if( params->tag != MBEDTLS_ASN1_OID |
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) |
&& params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) |
#endif |
) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
} |
if( ( ret = mbedtls_asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
params->p = *p; |
*p += params->len; |
if( *p != end ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) |
/* |
* Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. |
* WARNING: the resulting group should only be used with |
* pk_group_id_from_specified(), since its base point may not be set correctly |
* if it was encoded compressed. |
* |
* SpecifiedECDomain ::= SEQUENCE { |
* version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), |
* fieldID FieldID {{FieldTypes}}, |
* curve Curve, |
* base ECPoint, |
* order INTEGER, |
* cofactor INTEGER OPTIONAL, |
* hash HashAlgorithm OPTIONAL, |
* ... |
* } |
* |
* We only support prime-field as field type, and ignore hash and cofactor. |
*/ |
static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) |
{ |
int ret; |
unsigned char *p = params->p; |
const unsigned char * const end = params->p + params->len; |
const unsigned char *end_field, *end_curve; |
size_t len; |
int ver; |
/* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ |
if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( ver < 1 || ver > 3 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
/* |
* FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field |
* fieldType FIELD-ID.&id({IOSet}), |
* parameters FIELD-ID.&Type({IOSet}{@fieldType}) |
* } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( ret ); |
end_field = p + len; |
/* |
* FIELD-ID ::= TYPE-IDENTIFIER |
* FieldTypes FIELD-ID ::= { |
* { Prime-p IDENTIFIED BY prime-field } | |
* { Characteristic-two IDENTIFIED BY characteristic-two-field } |
* } |
* prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 ) |
return( ret ); |
if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || |
memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
} |
p += len; |
/* Prime-p ::= INTEGER -- Field of size p. */ |
if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
grp->pbits = mbedtls_mpi_bitlen( &grp->P ); |
if( p != end_field ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
/* |
* Curve ::= SEQUENCE { |
* a FieldElement, |
* b FieldElement, |
* seed BIT STRING OPTIONAL |
* -- Shall be present if used in SpecifiedECDomain |
* -- with version equal to ecdpVer2 or ecdpVer3 |
* } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( ret ); |
end_curve = p + len; |
/* |
* FieldElement ::= OCTET STRING |
* containing an integer in the case of a prime field |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || |
( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
p += len; |
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || |
( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
p += len; |
/* Ignore seed BIT STRING OPTIONAL */ |
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 ) |
p += len; |
if( p != end_curve ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
/* |
* ECPoint ::= OCTET STRING |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G, |
( const unsigned char *) p, len ) ) != 0 ) |
{ |
/* |
* If we can't read the point because it's compressed, cheat by |
* reading only the X coordinate and the parity bit of Y. |
*/ |
if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || |
( p[0] != 0x02 && p[0] != 0x03 ) || |
len != mbedtls_mpi_size( &grp->P ) + 1 || |
mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || |
mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || |
mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
} |
} |
p += len; |
/* |
* order INTEGER |
*/ |
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
grp->nbits = mbedtls_mpi_bitlen( &grp->N ); |
/* |
* Allow optional elements by purposefully not enforcing p == end here. |
*/ |
return( 0 ); |
} |
/* |
* Find the group id associated with an (almost filled) group as generated by |
* pk_group_from_specified(), or return an error if unknown. |
*/ |
static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id ) |
{ |
int ret = 0; |
mbedtls_ecp_group ref; |
const mbedtls_ecp_group_id *id; |
mbedtls_ecp_group_init( &ref ); |
for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ ) |
{ |
/* Load the group associated to that id */ |
mbedtls_ecp_group_free( &ref ); |
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) ); |
/* Compare to the group we were given, starting with easy tests */ |
if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && |
mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 && |
mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 && |
mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 && |
mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 && |
mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 && |
mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 && |
/* For Y we may only know the parity bit, so compare only that */ |
mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) ) |
{ |
break; |
} |
} |
cleanup: |
mbedtls_ecp_group_free( &ref ); |
*grp_id = *id; |
if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE ) |
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; |
return( ret ); |
} |
/* |
* Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID |
*/ |
static int pk_group_id_from_specified( const mbedtls_asn1_buf *params, |
mbedtls_ecp_group_id *grp_id ) |
{ |
int ret; |
mbedtls_ecp_group grp; |
mbedtls_ecp_group_init( &grp ); |
if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) |
goto cleanup; |
ret = pk_group_id_from_group( &grp, grp_id ); |
cleanup: |
mbedtls_ecp_group_free( &grp ); |
return( ret ); |
} |
#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ |
/* |
* Use EC parameters to initialise an EC group |
* |
* ECParameters ::= CHOICE { |
* namedCurve OBJECT IDENTIFIER |
* specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } |
* -- implicitCurve NULL |
*/ |
static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) |
{ |
int ret; |
mbedtls_ecp_group_id grp_id; |
if( params->tag == MBEDTLS_ASN1_OID ) |
{ |
if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 ) |
return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); |
} |
else |
{ |
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) |
if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) |
return( ret ); |
#else |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
#endif |
} |
/* |
* grp may already be initilialized; if so, make sure IDs match |
*/ |
if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
/* |
* EC public key is an EC point |
* |
* The caller is responsible for clearing the structure upon failure if |
* desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE |
* return code of mbedtls_ecp_point_read_binary() and leave p in a usable state. |
*/ |
static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, |
mbedtls_ecp_keypair *key ) |
{ |
int ret; |
if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q, |
(const unsigned char *) *p, end - *p ) ) == 0 ) |
{ |
ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q ); |
} |
/* |
* We know mbedtls_ecp_point_read_binary consumed all bytes or failed |
*/ |
*p = (unsigned char *) end; |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_RSA_C) |
/* |
* RSAPublicKey ::= SEQUENCE { |
* modulus INTEGER, -- n |
* publicExponent INTEGER -- e |
* } |
*/ |
static int pk_get_rsapubkey( unsigned char **p, |
const unsigned char *end, |
mbedtls_rsa_context *rsa ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); |
if( *p + len != end ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
/* Import N */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); |
if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0, |
NULL, 0, NULL, 0 ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); |
*p += len; |
/* Import E */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); |
if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0, |
NULL, 0, *p, len ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); |
*p += len; |
if( mbedtls_rsa_complete( rsa ) != 0 || |
mbedtls_rsa_check_pubkey( rsa ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); |
} |
if( *p != end ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
#endif /* MBEDTLS_RSA_C */ |
/* Get a PK algorithm identifier |
* |
* AlgorithmIdentifier ::= SEQUENCE { |
* algorithm OBJECT IDENTIFIER, |
* parameters ANY DEFINED BY algorithm OPTIONAL } |
*/ |
static int pk_get_pk_alg( unsigned char **p, |
const unsigned char *end, |
mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params ) |
{ |
int ret; |
mbedtls_asn1_buf alg_oid; |
memset( params, 0, sizeof(mbedtls_asn1_buf) ); |
if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_ALG + ret ); |
if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) |
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
/* |
* No parameters with RSA (only for EC) |
*/ |
if( *pk_alg == MBEDTLS_PK_RSA && |
( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) || |
params->len != 0 ) ) |
{ |
return( MBEDTLS_ERR_PK_INVALID_ALG ); |
} |
return( 0 ); |
} |
/* |
* SubjectPublicKeyInfo ::= SEQUENCE { |
* algorithm AlgorithmIdentifier, |
* subjectPublicKey BIT STRING } |
*/ |
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, |
mbedtls_pk_context *pk ) |
{ |
int ret; |
size_t len; |
mbedtls_asn1_buf alg_params; |
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; |
const mbedtls_pk_info_t *pk_info; |
PK_VALIDATE_RET( p != NULL ); |
PK_VALIDATE_RET( *p != NULL ); |
PK_VALIDATE_RET( end != NULL ); |
PK_VALIDATE_RET( pk != NULL ); |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
end = *p + len; |
if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); |
if( *p + len != end ) |
return( MBEDTLS_ERR_PK_INVALID_PUBKEY + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) |
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) |
return( ret ); |
#if defined(MBEDTLS_RSA_C) |
if( pk_alg == MBEDTLS_PK_RSA ) |
{ |
ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) ); |
} else |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY ) |
{ |
ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp ); |
if( ret == 0 ) |
ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) ); |
} else |
#endif /* MBEDTLS_ECP_C */ |
ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; |
if( ret == 0 && *p != end ) |
ret = MBEDTLS_ERR_PK_INVALID_PUBKEY |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; |
if( ret != 0 ) |
mbedtls_pk_free( pk ); |
return( ret ); |
} |
#if defined(MBEDTLS_RSA_C) |
/* |
* Wrapper around mbedtls_asn1_get_mpi() that rejects zero. |
* |
* The value zero is: |
* - never a valid value for an RSA parameter |
* - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). |
* |
* Since values can't be omitted in PKCS#1, passing a zero value to |
* rsa_complete() would be incorrect, so reject zero values early. |
*/ |
static int asn1_get_nonzero_mpi( unsigned char **p, |
const unsigned char *end, |
mbedtls_mpi *X ) |
{ |
int ret; |
ret = mbedtls_asn1_get_mpi( p, end, X ); |
if( ret != 0 ) |
return( ret ); |
if( mbedtls_mpi_cmp_int( X, 0 ) == 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
return( 0 ); |
} |
/* |
* Parse a PKCS#1 encoded private RSA key |
*/ |
static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, |
const unsigned char *key, |
size_t keylen ) |
{ |
int ret, version; |
size_t len; |
unsigned char *p, *end; |
mbedtls_mpi T; |
mbedtls_mpi_init( &T ); |
p = (unsigned char *) key; |
end = p + keylen; |
/* |
* This function parses the RSAPrivateKey (PKCS#1) |
* |
* RSAPrivateKey ::= SEQUENCE { |
* version Version, |
* modulus INTEGER, -- n |
* publicExponent INTEGER, -- e |
* privateExponent INTEGER, -- d |
* prime1 INTEGER, -- p |
* prime2 INTEGER, -- q |
* exponent1 INTEGER, -- d mod (p-1) |
* exponent2 INTEGER, -- d mod (q-1) |
* coefficient INTEGER, -- (inverse of q) mod p |
* otherPrimeInfos OtherPrimeInfos OPTIONAL |
* } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
end = p + len; |
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
if( version != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); |
} |
/* Import N */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_rsa_import( rsa, &T, NULL, NULL, |
NULL, NULL ) ) != 0 ) |
goto cleanup; |
/* Import E */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, |
NULL, &T ) ) != 0 ) |
goto cleanup; |
/* Import D */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL, |
&T, NULL ) ) != 0 ) |
goto cleanup; |
/* Import P */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_rsa_import( rsa, NULL, &T, NULL, |
NULL, NULL ) ) != 0 ) |
goto cleanup; |
/* Import Q */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_rsa_import( rsa, NULL, NULL, &T, |
NULL, NULL ) ) != 0 ) |
goto cleanup; |
#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT) |
/* |
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in |
* that they can be easily recomputed from D, P and Q. However by |
* parsing them from the PKCS1 structure it is possible to avoid |
* recalculating them which both reduces the overhead of loading |
* RSA private keys into memory and also avoids side channels which |
* can arise when computing those values, since all of D, P, and Q |
* are secret. See https://eprint.iacr.org/2020/055 for a |
* description of one such attack. |
*/ |
/* Import DP */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_mpi_copy( &rsa->DP, &T ) ) != 0 ) |
goto cleanup; |
/* Import DQ */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_mpi_copy( &rsa->DQ, &T ) ) != 0 ) |
goto cleanup; |
/* Import QP */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = mbedtls_mpi_copy( &rsa->QP, &T ) ) != 0 ) |
goto cleanup; |
#else |
/* Verify existance of the CRT params */ |
if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 || |
( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ) |
goto cleanup; |
#endif |
/* rsa_complete() doesn't complete anything with the default |
* implementation but is still called: |
* - for the benefit of alternative implementation that may want to |
* pre-compute stuff beyond what's provided (eg Montgomery factors) |
* - as is also sanity-checks the key |
* |
* Furthermore, we also check the public part for consistency with |
* mbedtls_pk_parse_pubkey(), as it includes size minima for example. |
*/ |
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 || |
( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) |
{ |
goto cleanup; |
} |
if( p != end ) |
{ |
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ; |
} |
cleanup: |
mbedtls_mpi_free( &T ); |
if( ret != 0 ) |
{ |
/* Wrap error code if it's coming from a lower level */ |
if( ( ret & 0xff80 ) == 0 ) |
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret; |
else |
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; |
mbedtls_rsa_free( rsa ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
/* |
* Parse a SEC1 encoded private EC key |
*/ |
static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, |
const unsigned char *key, |
size_t keylen ) |
{ |
int ret; |
int version, pubkey_done; |
size_t len; |
mbedtls_asn1_buf params; |
unsigned char *p = (unsigned char *) key; |
unsigned char *end = p + keylen; |
unsigned char *end2; |
/* |
* RFC 5915, or SEC1 Appendix C.4 |
* |
* ECPrivateKey ::= SEQUENCE { |
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), |
* privateKey OCTET STRING, |
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, |
* publicKey [1] BIT STRING OPTIONAL |
* } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
end = p + len; |
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( version != 1 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 ) |
{ |
mbedtls_ecp_keypair_free( eck ); |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
p += len; |
pubkey_done = 0; |
if( p != end ) |
{ |
/* |
* Is 'parameters' present? |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) |
{ |
if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || |
( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) |
{ |
mbedtls_ecp_keypair_free( eck ); |
return( ret ); |
} |
} |
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
{ |
mbedtls_ecp_keypair_free( eck ); |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
} |
if( p != end ) |
{ |
/* |
* Is 'publickey' present? If not, or if we can't read it (eg because it |
* is compressed), create it from the private key. |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) |
{ |
end2 = p + len; |
if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( p + len != end2 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) |
pubkey_done = 1; |
else |
{ |
/* |
* The only acceptable failure mode of pk_get_ecpubkey() above |
* is if the point format is not recognized. |
*/ |
if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
} |
} |
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
{ |
mbedtls_ecp_keypair_free( eck ); |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
} |
if( ! pubkey_done && |
( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, |
NULL, NULL ) ) != 0 ) |
{ |
mbedtls_ecp_keypair_free( eck ); |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) |
{ |
mbedtls_ecp_keypair_free( eck ); |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_ECP_C */ |
/* |
* Parse an unencrypted PKCS#8 encoded private key |
* |
* Notes: |
* |
* - This function does not own the key buffer. It is the |
* responsibility of the caller to take care of zeroizing |
* and freeing it after use. |
* |
* - The function is responsible for freeing the provided |
* PK context on failure. |
* |
*/ |
static int pk_parse_key_pkcs8_unencrypted_der( |
mbedtls_pk_context *pk, |
const unsigned char* key, |
size_t keylen ) |
{ |
int ret, version; |
size_t len; |
mbedtls_asn1_buf params; |
unsigned char *p = (unsigned char *) key; |
unsigned char *end = p + keylen; |
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; |
const mbedtls_pk_info_t *pk_info; |
/* |
* This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208) |
* |
* PrivateKeyInfo ::= SEQUENCE { |
* version Version, |
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, |
* privateKey PrivateKey, |
* attributes [0] IMPLICIT Attributes OPTIONAL } |
* |
* Version ::= INTEGER |
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier |
* PrivateKey ::= OCTET STRING |
* |
* The PrivateKey OCTET STRING is a SEC1 ECPrivateKey |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
end = p + len; |
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( version != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret ); |
if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( len < 1 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) |
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) |
return( ret ); |
#if defined(MBEDTLS_RSA_C) |
if( pk_alg == MBEDTLS_PK_RSA ) |
{ |
if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 ) |
{ |
mbedtls_pk_free( pk ); |
return( ret ); |
} |
} else |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) |
{ |
if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 || |
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 ) |
{ |
mbedtls_pk_free( pk ); |
return( ret ); |
} |
} else |
#endif /* MBEDTLS_ECP_C */ |
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
return( 0 ); |
} |
/* |
* Parse an encrypted PKCS#8 encoded private key |
* |
* To save space, the decryption happens in-place on the given key buffer. |
* Also, while this function may modify the keybuffer, it doesn't own it, |
* and instead it is the responsibility of the caller to zeroize and properly |
* free it after use. |
* |
*/ |
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) |
static int pk_parse_key_pkcs8_encrypted_der( |
mbedtls_pk_context *pk, |
unsigned char *key, size_t keylen, |
const unsigned char *pwd, size_t pwdlen ) |
{ |
int ret, decrypted = 0; |
size_t len; |
unsigned char *buf; |
unsigned char *p, *end; |
mbedtls_asn1_buf pbe_alg_oid, pbe_params; |
#if defined(MBEDTLS_PKCS12_C) |
mbedtls_cipher_type_t cipher_alg; |
mbedtls_md_type_t md_alg; |
#endif |
p = key; |
end = p + keylen; |
if( pwdlen == 0 ) |
return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); |
/* |
* This function parses the EncryptedPrivateKeyInfo object (PKCS#8) |
* |
* EncryptedPrivateKeyInfo ::= SEQUENCE { |
* encryptionAlgorithm EncryptionAlgorithmIdentifier, |
* encryptedData EncryptedData |
* } |
* |
* EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier |
* |
* EncryptedData ::= OCTET STRING |
* |
* The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo |
* |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
} |
end = p + len; |
if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); |
buf = p; |
/* |
* Decrypt EncryptedData with appropriate PBE |
*/ |
#if defined(MBEDTLS_PKCS12_C) |
if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) |
{ |
if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, |
cipher_alg, md_alg, |
pwd, pwdlen, p, len, buf ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH ) |
return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); |
return( ret ); |
} |
decrypted = 1; |
} |
else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 ) |
{ |
if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params, |
MBEDTLS_PKCS12_PBE_DECRYPT, |
pwd, pwdlen, |
p, len, buf ) ) != 0 ) |
{ |
return( ret ); |
} |
// Best guess for password mismatch when using RC4. If first tag is |
// not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE |
// |
if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) |
return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); |
decrypted = 1; |
} |
else |
#endif /* MBEDTLS_PKCS12_C */ |
#if defined(MBEDTLS_PKCS5_C) |
if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 ) |
{ |
if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, |
p, len, buf ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH ) |
return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); |
return( ret ); |
} |
decrypted = 1; |
} |
else |
#endif /* MBEDTLS_PKCS5_C */ |
{ |
((void) pwd); |
} |
if( decrypted == 0 ) |
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); |
} |
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ |
/* |
* Parse a private key |
*/ |
int mbedtls_pk_parse_key( mbedtls_pk_context *pk, |
const unsigned char *key, size_t keylen, |
const unsigned char *pwd, size_t pwdlen ) |
{ |
int ret; |
const mbedtls_pk_info_t *pk_info; |
#if defined(MBEDTLS_PEM_PARSE_C) |
size_t len; |
mbedtls_pem_context pem; |
#endif |
PK_VALIDATE_RET( pk != NULL ); |
if( keylen == 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
PK_VALIDATE_RET( key != NULL ); |
#if defined(MBEDTLS_PEM_PARSE_C) |
mbedtls_pem_init( &pem ); |
#if defined(MBEDTLS_RSA_C) |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( key[keylen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN RSA PRIVATE KEY-----", |
"-----END RSA PRIVATE KEY-----", |
key, pwd, pwdlen, &len ); |
if( ret == 0 ) |
{ |
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ); |
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || |
( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), |
pem.buf, pem.buflen ) ) != 0 ) |
{ |
mbedtls_pk_free( pk ); |
} |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) |
return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); |
else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) |
return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
return( ret ); |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( key[keylen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN EC PRIVATE KEY-----", |
"-----END EC PRIVATE KEY-----", |
key, pwd, pwdlen, &len ); |
if( ret == 0 ) |
{ |
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); |
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || |
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), |
pem.buf, pem.buflen ) ) != 0 ) |
{ |
mbedtls_pk_free( pk ); |
} |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) |
return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); |
else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) |
return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
return( ret ); |
#endif /* MBEDTLS_ECP_C */ |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( key[keylen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN PRIVATE KEY-----", |
"-----END PRIVATE KEY-----", |
key, NULL, 0, &len ); |
if( ret == 0 ) |
{ |
if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, |
pem.buf, pem.buflen ) ) != 0 ) |
{ |
mbedtls_pk_free( pk ); |
} |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
return( ret ); |
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( key[keylen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN ENCRYPTED PRIVATE KEY-----", |
"-----END ENCRYPTED PRIVATE KEY-----", |
key, NULL, 0, &len ); |
if( ret == 0 ) |
{ |
if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, |
pem.buf, pem.buflen, |
pwd, pwdlen ) ) != 0 ) |
{ |
mbedtls_pk_free( pk ); |
} |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
return( ret ); |
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ |
#else |
((void) pwd); |
((void) pwdlen); |
#endif /* MBEDTLS_PEM_PARSE_C */ |
/* |
* At this point we only know it's not a PEM formatted key. Could be any |
* of the known DER encoded private key formats |
* |
* We try the different DER format parsers to see if one passes without |
* error |
*/ |
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) |
{ |
unsigned char *key_copy; |
if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL ) |
return( MBEDTLS_ERR_PK_ALLOC_FAILED ); |
memcpy( key_copy, key, keylen ); |
ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen, |
pwd, pwdlen ); |
mbedtls_platform_zeroize( key_copy, keylen ); |
mbedtls_free( key_copy ); |
} |
if( ret == 0 ) |
return( 0 ); |
mbedtls_pk_free( pk ); |
mbedtls_pk_init( pk ); |
if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH ) |
{ |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ |
if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) |
return( 0 ); |
mbedtls_pk_free( pk ); |
mbedtls_pk_init( pk ); |
#if defined(MBEDTLS_RSA_C) |
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ); |
if( mbedtls_pk_setup( pk, pk_info ) == 0 && |
pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 ) |
{ |
return( 0 ); |
} |
mbedtls_pk_free( pk ); |
mbedtls_pk_init( pk ); |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); |
if( mbedtls_pk_setup( pk, pk_info ) == 0 && |
pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), |
key, keylen ) == 0 ) |
{ |
return( 0 ); |
} |
mbedtls_pk_free( pk ); |
#endif /* MBEDTLS_ECP_C */ |
/* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't, |
* it is ok to leave the PK context initialized but not |
* freed: It is the caller's responsibility to call pk_init() |
* before calling this function, and to call pk_free() |
* when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C |
* isn't, this leads to mbedtls_pk_free() being called |
* twice, once here and once by the caller, but this is |
* also ok and in line with the mbedtls_pk_free() calls |
* on failed PEM parsing attempts. */ |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
} |
/* |
* Parse a public key |
*/ |
int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, |
const unsigned char *key, size_t keylen ) |
{ |
int ret; |
unsigned char *p; |
#if defined(MBEDTLS_RSA_C) |
const mbedtls_pk_info_t *pk_info; |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) |
size_t len; |
mbedtls_pem_context pem; |
#endif |
PK_VALIDATE_RET( ctx != NULL ); |
if( keylen == 0 ) |
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); |
PK_VALIDATE_RET( key != NULL || keylen == 0 ); |
#if defined(MBEDTLS_PEM_PARSE_C) |
mbedtls_pem_init( &pem ); |
#if defined(MBEDTLS_RSA_C) |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( key[keylen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN RSA PUBLIC KEY-----", |
"-----END RSA PUBLIC KEY-----", |
key, NULL, 0, &len ); |
if( ret == 0 ) |
{ |
p = pem.buf; |
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) |
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) |
return( ret ); |
if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) |
mbedtls_pk_free( ctx ); |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
{ |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
#endif /* MBEDTLS_RSA_C */ |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( key[keylen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN PUBLIC KEY-----", |
"-----END PUBLIC KEY-----", |
key, NULL, 0, &len ); |
if( ret == 0 ) |
{ |
/* |
* Was PEM encoded |
*/ |
p = pem.buf; |
ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx ); |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
{ |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
mbedtls_pem_free( &pem ); |
#endif /* MBEDTLS_PEM_PARSE_C */ |
#if defined(MBEDTLS_RSA_C) |
if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) |
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); |
if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) |
return( ret ); |
p = (unsigned char *)key; |
ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) ); |
if( ret == 0 ) |
{ |
return( ret ); |
} |
mbedtls_pk_free( ctx ); |
if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) |
{ |
return( ret ); |
} |
#endif /* MBEDTLS_RSA_C */ |
p = (unsigned char *) key; |
ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_PK_PARSE_C */ |
/programs/develop/libraries/kos_mbedtls/library/pkwrite.c |
---|
0,0 → 1,568 |
/* |
* Public Key layer for writing key files and structures |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PK_WRITE_C) |
#include "mbedtls/pk.h" |
#include "mbedtls/asn1write.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_RSA_C) |
#include "mbedtls/rsa.h" |
#endif |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/bignum.h" |
#include "mbedtls/ecp.h" |
#include "mbedtls/platform_util.h" |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
#include "mbedtls/ecdsa.h" |
#endif |
#if defined(MBEDTLS_PEM_WRITE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
/* Parameter validation macros based on platform_util.h */ |
#define PK_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA ) |
#define PK_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_RSA_C) |
/* |
* RSAPublicKey ::= SEQUENCE { |
* modulus INTEGER, -- n |
* publicExponent INTEGER -- e |
* } |
*/ |
static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, |
mbedtls_rsa_context *rsa ) |
{ |
int ret; |
size_t len = 0; |
mbedtls_mpi T; |
mbedtls_mpi_init( &T ); |
/* Export E */ |
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export N */ |
if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
end_of_export: |
mbedtls_mpi_free( &T ); |
if( ret < 0 ) |
return( ret ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
/* |
* EC public key is an EC point |
*/ |
static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, |
mbedtls_ecp_keypair *ec ) |
{ |
int ret; |
size_t len = 0; |
unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; |
if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, |
MBEDTLS_ECP_PF_UNCOMPRESSED, |
&len, buf, sizeof( buf ) ) ) != 0 ) |
{ |
return( ret ); |
} |
if( *p < start || (size_t)( *p - start ) < len ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*p -= len; |
memcpy( *p, buf, len ); |
return( (int) len ); |
} |
/* |
* ECParameters ::= CHOICE { |
* namedCurve OBJECT IDENTIFIER |
* } |
*/ |
static int pk_write_ec_param( unsigned char **p, unsigned char *start, |
mbedtls_ecp_keypair *ec ) |
{ |
int ret; |
size_t len = 0; |
const char *oid; |
size_t oid_len; |
if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) |
return( ret ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); |
return( (int) len ); |
} |
/* |
* privateKey OCTET STRING -- always of length ceil(log2(n)/8) |
*/ |
static int pk_write_ec_private( unsigned char **p, unsigned char *start, |
mbedtls_ecp_keypair *ec ) |
{ |
int ret; |
size_t byte_length = ( ec->grp.pbits + 7 ) / 8; |
unsigned char tmp[MBEDTLS_ECP_MAX_BYTES]; |
ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length ); |
if( ret != 0 ) |
goto exit; |
ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length ); |
exit: |
mbedtls_platform_zeroize( tmp, byte_length ); |
return( ret ); |
} |
#endif /* MBEDTLS_ECP_C */ |
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, |
const mbedtls_pk_context *key ) |
{ |
int ret; |
size_t len = 0; |
PK_VALIDATE_RET( p != NULL ); |
PK_VALIDATE_RET( *p != NULL ); |
PK_VALIDATE_RET( start != NULL ); |
PK_VALIDATE_RET( key != NULL ); |
#if defined(MBEDTLS_RSA_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) |
MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); |
else |
#endif |
#if defined(MBEDTLS_ECP_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); |
else |
#endif |
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
return( (int) len ); |
} |
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
{ |
int ret; |
unsigned char *c; |
size_t len = 0, par_len = 0, oid_len; |
const char *oid; |
PK_VALIDATE_RET( key != NULL ); |
if( size == 0 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
PK_VALIDATE_RET( buf != NULL ); |
c = buf + size; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); |
if( c - buf < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
/* |
* SubjectPublicKeyInfo ::= SEQUENCE { |
* algorithm AlgorithmIdentifier, |
* subjectPublicKey BIT STRING } |
*/ |
*--c = 0; |
len += 1; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); |
if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), |
&oid, &oid_len ) ) != 0 ) |
{ |
return( ret ); |
} |
#if defined(MBEDTLS_ECP_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
{ |
MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); |
} |
#endif |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, |
par_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
{ |
int ret; |
unsigned char *c; |
size_t len = 0; |
PK_VALIDATE_RET( key != NULL ); |
if( size == 0 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
PK_VALIDATE_RET( buf != NULL ); |
c = buf + size; |
#if defined(MBEDTLS_RSA_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) |
{ |
mbedtls_mpi T; /* Temporary holding the exported parameters */ |
mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); |
/* |
* Export the parameters one after another to avoid simultaneous copies. |
*/ |
mbedtls_mpi_init( &T ); |
/* Export QP */ |
if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export DQ */ |
if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export DP */ |
if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export Q */ |
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, |
&T, NULL, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export P */ |
if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T, |
NULL, NULL, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export D */ |
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, |
NULL, &T, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export E */ |
if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, |
NULL, NULL, &T ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
/* Export N */ |
if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, |
NULL, NULL, NULL ) ) != 0 || |
( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 ) |
goto end_of_export; |
len += ret; |
end_of_export: |
mbedtls_mpi_free( &T ); |
if( ret < 0 ) |
return( ret ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, |
buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
} |
else |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
{ |
mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); |
size_t pub_len = 0, par_len = 0; |
/* |
* RFC 5915, or SEC1 Appendix C.4 |
* |
* ECPrivateKey ::= SEQUENCE { |
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), |
* privateKey OCTET STRING, |
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, |
* publicKey [1] BIT STRING OPTIONAL |
* } |
*/ |
/* publicKey */ |
MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); |
if( c - buf < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--c = 0; |
pub_len += 1; |
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); |
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); |
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); |
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); |
len += pub_len; |
/* parameters */ |
MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); |
MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); |
MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); |
len += par_len; |
/* privateKey */ |
MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_private( &c, buf, ec ) ); |
/* version */ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
} |
else |
#endif /* MBEDTLS_ECP_C */ |
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
return( (int) len ); |
} |
#if defined(MBEDTLS_PEM_WRITE_C) |
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" |
#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" |
#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" |
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" |
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" |
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" |
/* |
* Max sizes of key per types. Shown as tag + len (+ content). |
*/ |
#if defined(MBEDTLS_RSA_C) |
/* |
* RSA public keys: |
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 |
* algorithm AlgorithmIdentifier, 1 + 1 (sequence) |
* + 1 + 1 + 9 (rsa oid) |
* + 1 + 1 (params null) |
* subjectPublicKey BIT STRING } 1 + 3 + (1 + below) |
* RSAPublicKey ::= SEQUENCE { 1 + 3 |
* modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 |
* publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 |
* } |
*/ |
#define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE |
/* |
* RSA private keys: |
* RSAPrivateKey ::= SEQUENCE { 1 + 3 |
* version Version, 1 + 1 + 1 |
* modulus INTEGER, 1 + 3 + MPI_MAX + 1 |
* publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 |
* privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 |
* prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
* prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
* exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
* exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
* coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 |
* otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) |
* } |
*/ |
#define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \ |
MBEDTLS_MPI_MAX_SIZE % 2 |
#define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ |
+ 5 * MPI_MAX_SIZE_2 |
#else /* MBEDTLS_RSA_C */ |
#define RSA_PUB_DER_MAX_BYTES 0 |
#define RSA_PRV_DER_MAX_BYTES 0 |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_ECP_C) |
/* |
* EC public keys: |
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 |
* algorithm AlgorithmIdentifier, 1 + 1 (sequence) |
* + 1 + 1 + 7 (ec oid) |
* + 1 + 1 + 9 (namedCurve oid) |
* subjectPublicKey BIT STRING 1 + 2 + 1 [1] |
* + 1 (point format) [1] |
* + 2 * ECP_MAX (coords) [1] |
* } |
*/ |
#define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES |
/* |
* EC private keys: |
* ECPrivateKey ::= SEQUENCE { 1 + 2 |
* version INTEGER , 1 + 1 + 1 |
* privateKey OCTET STRING, 1 + 1 + ECP_MAX |
* parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) |
* publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above |
* } |
*/ |
#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES |
#else /* MBEDTLS_ECP_C */ |
#define ECP_PUB_DER_MAX_BYTES 0 |
#define ECP_PRV_DER_MAX_BYTES 0 |
#endif /* MBEDTLS_ECP_C */ |
#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ |
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES |
#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ |
RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES |
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
{ |
int ret; |
unsigned char output_buf[PUB_DER_MAX_BYTES]; |
size_t olen = 0; |
PK_VALIDATE_RET( key != NULL ); |
PK_VALIDATE_RET( buf != NULL || size == 0 ); |
if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, |
sizeof(output_buf) ) ) < 0 ) |
{ |
return( ret ); |
} |
if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, |
output_buf + sizeof(output_buf) - ret, |
ret, buf, size, &olen ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) |
{ |
int ret; |
unsigned char output_buf[PRV_DER_MAX_BYTES]; |
const char *begin, *end; |
size_t olen = 0; |
PK_VALIDATE_RET( key != NULL ); |
PK_VALIDATE_RET( buf != NULL || size == 0 ); |
if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) |
return( ret ); |
#if defined(MBEDTLS_RSA_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) |
{ |
begin = PEM_BEGIN_PRIVATE_KEY_RSA; |
end = PEM_END_PRIVATE_KEY_RSA; |
} |
else |
#endif |
#if defined(MBEDTLS_ECP_C) |
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) |
{ |
begin = PEM_BEGIN_PRIVATE_KEY_EC; |
end = PEM_END_PRIVATE_KEY_EC; |
} |
else |
#endif |
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); |
if( ( ret = mbedtls_pem_write_buffer( begin, end, |
output_buf + sizeof(output_buf) - ret, |
ret, buf, size, &olen ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_PK_WRITE_C */ |
/programs/develop/libraries/kos_mbedtls/library/platform.c |
---|
0,0 → 1,350 |
/* |
* Platform abstraction layer |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#include "mbedtls/platform_util.h" |
/* The compile time configuration of memory allocation via the macros |
* MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime |
* configuration via mbedtls_platform_set_calloc_free(). So, omit everything |
* related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ |
#if defined(MBEDTLS_PLATFORM_MEMORY) && \ |
!( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ |
defined(MBEDTLS_PLATFORM_FREE_MACRO) ) |
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) |
static void *platform_calloc_uninit( size_t n, size_t size ) |
{ |
((void) n); |
((void) size); |
return( NULL ); |
} |
#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ |
#if !defined(MBEDTLS_PLATFORM_STD_FREE) |
static void platform_free_uninit( void *ptr ) |
{ |
((void) ptr); |
} |
#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_FREE */ |
static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; |
static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; |
void * mbedtls_calloc( size_t nmemb, size_t size ) |
{ |
return (*mbedtls_calloc_func)( nmemb, size ); |
} |
void mbedtls_free( void * ptr ) |
{ |
(*mbedtls_free_func)( ptr ); |
} |
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), |
void (*free_func)( void * ) ) |
{ |
mbedtls_calloc_func = calloc_func; |
mbedtls_free_func = free_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_MEMORY && |
!( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && |
defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ |
#if defined(_WIN32) |
#include <stdarg.h> |
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) |
{ |
int ret; |
va_list argp; |
/* Avoid calling the invalid parameter handler by checking ourselves */ |
if( s == NULL || n == 0 || fmt == NULL ) |
return( -1 ); |
va_start( argp, fmt ); |
#if defined(_TRUNCATE) && !defined(__MINGW32__) |
ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); |
#else |
ret = _vsnprintf( s, n, fmt, argp ); |
if( ret < 0 || (size_t) ret == n ) |
{ |
s[n-1] = '\0'; |
ret = -1; |
} |
#endif |
va_end( argp ); |
return( ret ); |
} |
#endif |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) |
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static int platform_snprintf_uninit( char * s, size_t n, |
const char * format, ... ) |
{ |
((void) s); |
((void) n); |
((void) format); |
return( 0 ); |
} |
#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ |
int (*mbedtls_snprintf)( char * s, size_t n, |
const char * format, |
... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; |
int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, |
const char * format, |
... ) ) |
{ |
mbedtls_snprintf = snprintf_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) |
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static int platform_printf_uninit( const char *format, ... ) |
{ |
((void) format); |
return( 0 ); |
} |
#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ |
int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; |
int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) |
{ |
mbedtls_printf = printf_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) |
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) |
{ |
((void) stream); |
((void) format); |
return( 0 ); |
} |
#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ |
int (*mbedtls_fprintf)( FILE *, const char *, ... ) = |
MBEDTLS_PLATFORM_STD_FPRINTF; |
int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) |
{ |
mbedtls_fprintf = fprintf_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) |
#if !defined(MBEDTLS_PLATFORM_STD_EXIT) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static void platform_exit_uninit( int status ) |
{ |
((void) status); |
} |
#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ |
void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; |
int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) |
{ |
mbedtls_exit = exit_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ |
#if defined(MBEDTLS_HAVE_TIME) |
#if defined(MBEDTLS_PLATFORM_TIME_ALT) |
#if !defined(MBEDTLS_PLATFORM_STD_TIME) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) |
{ |
((void) timer); |
return( 0 ); |
} |
#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_TIME */ |
mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; |
int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) |
{ |
mbedtls_time = time_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_TIME_ALT */ |
#endif /* MBEDTLS_HAVE_TIME */ |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) |
/* Default implementations for the platform independent seed functions use |
* standard libc file functions to read from and write to a pre-defined filename |
*/ |
int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) |
{ |
FILE *file; |
size_t n; |
if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) |
return( -1 ); |
if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) |
{ |
fclose( file ); |
mbedtls_platform_zeroize( buf, buf_len ); |
return( -1 ); |
} |
fclose( file ); |
return( (int)n ); |
} |
int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) |
{ |
FILE *file; |
size_t n; |
if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) |
return -1; |
if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) |
{ |
fclose( file ); |
return -1; |
} |
fclose( file ); |
return( (int)n ); |
} |
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ |
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) |
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) |
{ |
((void) buf); |
((void) buf_len); |
return( -1 ); |
} |
#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ |
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) |
/* |
* Make dummy function to prevent NULL pointer dereferences |
*/ |
static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) |
{ |
((void) buf); |
((void) buf_len); |
return( -1 ); |
} |
#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit |
#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ |
int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = |
MBEDTLS_PLATFORM_STD_NV_SEED_READ; |
int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = |
MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; |
int mbedtls_platform_set_nv_seed( |
int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), |
int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) |
{ |
mbedtls_nv_seed_read = nv_seed_read_func; |
mbedtls_nv_seed_write = nv_seed_write_func; |
return( 0 ); |
} |
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ |
#endif /* MBEDTLS_ENTROPY_NV_SEED */ |
#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) |
/* |
* Placeholder platform setup that does nothing by default |
*/ |
int mbedtls_platform_setup( mbedtls_platform_context *ctx ) |
{ |
(void)ctx; |
return( 0 ); |
} |
/* |
* Placeholder platform teardown that does nothing by default |
*/ |
void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) |
{ |
(void)ctx; |
} |
#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ |
#endif /* MBEDTLS_PLATFORM_C */ |
/programs/develop/libraries/kos_mbedtls/library/platform_util.c |
---|
0,0 → 1,141 |
/* |
* Common and shared functions used by multiple modules in the Mbed TLS |
* library. |
* |
* Copyright (C) 2018, Arm Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of Mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* Ensure gmtime_r is available even with -std=c99; must be defined before |
* config.h, which pulls in glibc's features.h. Harmless on other platforms. |
*/ |
#if !defined(_POSIX_C_SOURCE) |
#define _POSIX_C_SOURCE 200112L |
#endif |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#include "mbedtls/platform_util.h" |
#include "mbedtls/platform.h" |
#include "mbedtls/threading.h" |
#include <stddef.h> |
#include <string.h> |
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) |
/* |
* This implementation should never be optimized out by the compiler |
* |
* This implementation for mbedtls_platform_zeroize() was inspired from Colin |
* Percival's blog article at: |
* |
* http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html |
* |
* It uses a volatile function pointer to the standard memset(). Because the |
* pointer is volatile the compiler expects it to change at |
* any time and will not optimize out the call that could potentially perform |
* other operations on the input buffer instead of just setting it to 0. |
* Nevertheless, as pointed out by davidtgoldblatt on Hacker News |
* (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for |
* details), optimizations of the following form are still possible: |
* |
* if( memset_func != memset ) |
* memset_func( buf, 0, len ); |
* |
* Note that it is extremely difficult to guarantee that |
* mbedtls_platform_zeroize() will not be optimized out by aggressive compilers |
* in a portable way. For this reason, Mbed TLS also provides the configuration |
* option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure |
* mbedtls_platform_zeroize() to use a suitable implementation for their |
* platform and needs. |
*/ |
static void * (* const volatile memset_func)( void *, int, size_t ) = memset; |
void mbedtls_platform_zeroize( void *buf, size_t len ) |
{ |
MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL ); |
if( len > 0 ) |
memset_func( buf, 0, len ); |
} |
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ |
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) |
#include <time.h> |
#if !defined(_WIN32) && (defined(unix) || \ |
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ |
defined(__MACH__))) |
#include <unistd.h> |
#endif /* !_WIN32 && (unix || __unix || __unix__ || |
* (__APPLE__ && __MACH__)) */ |
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) |
/* |
* This is a convenience shorthand macro to avoid checking the long |
* preprocessor conditions above. Ideally, we could expose this macro in |
* platform_util.h and simply use it in platform_util.c, threading.c and |
* threading.h. However, this macro is not part of the Mbed TLS public API, so |
* we keep it private by only defining it in this file |
*/ |
#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) |
#define PLATFORM_UTIL_USE_GMTIME |
#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ |
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ |
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, |
struct tm *tm_buf ) |
{ |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); |
#elif !defined(PLATFORM_UTIL_USE_GMTIME) |
return( gmtime_r( tt, tm_buf ) ); |
#else |
struct tm *lt; |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) |
return( NULL ); |
#endif /* MBEDTLS_THREADING_C */ |
lt = gmtime( tt ); |
if( lt != NULL ) |
{ |
memcpy( tm_buf, lt, sizeof( struct tm ) ); |
} |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) |
return( NULL ); |
#endif /* MBEDTLS_THREADING_C */ |
return( ( lt == NULL ) ? NULL : tm_buf ); |
#endif /* _WIN32 && !EFIX64 && !EFI32 */ |
} |
#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ |
/programs/develop/libraries/kos_mbedtls/library/poly1305.c |
---|
0,0 → 1,561 |
/** |
* \file poly1305.c |
* |
* \brief Poly1305 authentication algorithm. |
* |
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_POLY1305_C) |
#include "mbedtls/poly1305.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_POLY1305_ALT) |
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ |
!defined(inline) && !defined(__cplusplus) |
#define inline __inline |
#endif |
/* Parameter validation macros */ |
#define POLY1305_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ) |
#define POLY1305_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#define POLY1305_BLOCK_SIZE_BYTES ( 16U ) |
#define BYTES_TO_U32_LE( data, offset ) \ |
( (uint32_t) (data)[offset] \ |
| (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ |
| (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ |
| (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ |
) |
/* |
* Our implementation is tuned for 32-bit platforms with a 64-bit multiplier. |
* However we provided an alternative for platforms without such a multiplier. |
*/ |
#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) |
static uint64_t mul64( uint32_t a, uint32_t b ) |
{ |
/* a = al + 2**16 ah, b = bl + 2**16 bh */ |
const uint16_t al = (uint16_t) a; |
const uint16_t bl = (uint16_t) b; |
const uint16_t ah = a >> 16; |
const uint16_t bh = b >> 16; |
/* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */ |
const uint32_t lo = (uint32_t) al * bl; |
const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh; |
const uint32_t hi = (uint32_t) ah * bh; |
return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) ); |
} |
#else |
static inline uint64_t mul64( uint32_t a, uint32_t b ) |
{ |
return( (uint64_t) a * b ); |
} |
#endif |
/** |
* \brief Process blocks with Poly1305. |
* |
* \param ctx The Poly1305 context. |
* \param nblocks Number of blocks to process. Note that this |
* function only processes full blocks. |
* \param input Buffer containing the input block(s). |
* \param needs_padding Set to 0 if the padding bit has already been |
* applied to the input data before calling this |
* function. Otherwise, set this parameter to 1. |
*/ |
static void poly1305_process( mbedtls_poly1305_context *ctx, |
size_t nblocks, |
const unsigned char *input, |
uint32_t needs_padding ) |
{ |
uint64_t d0, d1, d2, d3; |
uint32_t acc0, acc1, acc2, acc3, acc4; |
uint32_t r0, r1, r2, r3; |
uint32_t rs1, rs2, rs3; |
size_t offset = 0U; |
size_t i; |
r0 = ctx->r[0]; |
r1 = ctx->r[1]; |
r2 = ctx->r[2]; |
r3 = ctx->r[3]; |
rs1 = r1 + ( r1 >> 2U ); |
rs2 = r2 + ( r2 >> 2U ); |
rs3 = r3 + ( r3 >> 2U ); |
acc0 = ctx->acc[0]; |
acc1 = ctx->acc[1]; |
acc2 = ctx->acc[2]; |
acc3 = ctx->acc[3]; |
acc4 = ctx->acc[4]; |
/* Process full blocks */ |
for( i = 0U; i < nblocks; i++ ) |
{ |
/* The input block is treated as a 128-bit little-endian integer */ |
d0 = BYTES_TO_U32_LE( input, offset + 0 ); |
d1 = BYTES_TO_U32_LE( input, offset + 4 ); |
d2 = BYTES_TO_U32_LE( input, offset + 8 ); |
d3 = BYTES_TO_U32_LE( input, offset + 12 ); |
/* Compute: acc += (padded) block as a 130-bit integer */ |
d0 += (uint64_t) acc0; |
d1 += (uint64_t) acc1 + ( d0 >> 32U ); |
d2 += (uint64_t) acc2 + ( d1 >> 32U ); |
d3 += (uint64_t) acc3 + ( d2 >> 32U ); |
acc0 = (uint32_t) d0; |
acc1 = (uint32_t) d1; |
acc2 = (uint32_t) d2; |
acc3 = (uint32_t) d3; |
acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding; |
/* Compute: acc *= r */ |
d0 = mul64( acc0, r0 ) + |
mul64( acc1, rs3 ) + |
mul64( acc2, rs2 ) + |
mul64( acc3, rs1 ); |
d1 = mul64( acc0, r1 ) + |
mul64( acc1, r0 ) + |
mul64( acc2, rs3 ) + |
mul64( acc3, rs2 ) + |
mul64( acc4, rs1 ); |
d2 = mul64( acc0, r2 ) + |
mul64( acc1, r1 ) + |
mul64( acc2, r0 ) + |
mul64( acc3, rs3 ) + |
mul64( acc4, rs2 ); |
d3 = mul64( acc0, r3 ) + |
mul64( acc1, r2 ) + |
mul64( acc2, r1 ) + |
mul64( acc3, r0 ) + |
mul64( acc4, rs3 ); |
acc4 *= r0; |
/* Compute: acc %= (2^130 - 5) (partial remainder) */ |
d1 += ( d0 >> 32 ); |
d2 += ( d1 >> 32 ); |
d3 += ( d2 >> 32 ); |
acc0 = (uint32_t) d0; |
acc1 = (uint32_t) d1; |
acc2 = (uint32_t) d2; |
acc3 = (uint32_t) d3; |
acc4 = (uint32_t) ( d3 >> 32 ) + acc4; |
d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU ); |
acc4 &= 3U; |
acc0 = (uint32_t) d0; |
d0 = (uint64_t) acc1 + ( d0 >> 32U ); |
acc1 = (uint32_t) d0; |
d0 = (uint64_t) acc2 + ( d0 >> 32U ); |
acc2 = (uint32_t) d0; |
d0 = (uint64_t) acc3 + ( d0 >> 32U ); |
acc3 = (uint32_t) d0; |
d0 = (uint64_t) acc4 + ( d0 >> 32U ); |
acc4 = (uint32_t) d0; |
offset += POLY1305_BLOCK_SIZE_BYTES; |
} |
ctx->acc[0] = acc0; |
ctx->acc[1] = acc1; |
ctx->acc[2] = acc2; |
ctx->acc[3] = acc3; |
ctx->acc[4] = acc4; |
} |
/** |
* \brief Compute the Poly1305 MAC |
* |
* \param ctx The Poly1305 context. |
* \param mac The buffer to where the MAC is written. Must be |
* big enough to contain the 16-byte MAC. |
*/ |
static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, |
unsigned char mac[16] ) |
{ |
uint64_t d; |
uint32_t g0, g1, g2, g3, g4; |
uint32_t acc0, acc1, acc2, acc3, acc4; |
uint32_t mask; |
uint32_t mask_inv; |
acc0 = ctx->acc[0]; |
acc1 = ctx->acc[1]; |
acc2 = ctx->acc[2]; |
acc3 = ctx->acc[3]; |
acc4 = ctx->acc[4]; |
/* Before adding 's' we ensure that the accumulator is mod 2^130 - 5. |
* We do this by calculating acc - (2^130 - 5), then checking if |
* the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5) |
*/ |
/* Calculate acc + -(2^130 - 5) */ |
d = ( (uint64_t) acc0 + 5U ); |
g0 = (uint32_t) d; |
d = ( (uint64_t) acc1 + ( d >> 32 ) ); |
g1 = (uint32_t) d; |
d = ( (uint64_t) acc2 + ( d >> 32 ) ); |
g2 = (uint32_t) d; |
d = ( (uint64_t) acc3 + ( d >> 32 ) ); |
g3 = (uint32_t) d; |
g4 = acc4 + (uint32_t) ( d >> 32U ); |
/* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ |
mask = (uint32_t) 0U - ( g4 >> 2U ); |
mask_inv = ~mask; |
/* If 131st bit is set then acc=g, otherwise, acc is unmodified */ |
acc0 = ( acc0 & mask_inv ) | ( g0 & mask ); |
acc1 = ( acc1 & mask_inv ) | ( g1 & mask ); |
acc2 = ( acc2 & mask_inv ) | ( g2 & mask ); |
acc3 = ( acc3 & mask_inv ) | ( g3 & mask ); |
/* Add 's' */ |
d = (uint64_t) acc0 + ctx->s[0]; |
acc0 = (uint32_t) d; |
d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U ); |
acc1 = (uint32_t) d; |
d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U ); |
acc2 = (uint32_t) d; |
acc3 += ctx->s[3] + (uint32_t) ( d >> 32U ); |
/* Compute MAC (128 least significant bits of the accumulator) */ |
mac[ 0] = (unsigned char)( acc0 ); |
mac[ 1] = (unsigned char)( acc0 >> 8 ); |
mac[ 2] = (unsigned char)( acc0 >> 16 ); |
mac[ 3] = (unsigned char)( acc0 >> 24 ); |
mac[ 4] = (unsigned char)( acc1 ); |
mac[ 5] = (unsigned char)( acc1 >> 8 ); |
mac[ 6] = (unsigned char)( acc1 >> 16 ); |
mac[ 7] = (unsigned char)( acc1 >> 24 ); |
mac[ 8] = (unsigned char)( acc2 ); |
mac[ 9] = (unsigned char)( acc2 >> 8 ); |
mac[10] = (unsigned char)( acc2 >> 16 ); |
mac[11] = (unsigned char)( acc2 >> 24 ); |
mac[12] = (unsigned char)( acc3 ); |
mac[13] = (unsigned char)( acc3 >> 8 ); |
mac[14] = (unsigned char)( acc3 >> 16 ); |
mac[15] = (unsigned char)( acc3 >> 24 ); |
} |
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) |
{ |
POLY1305_VALIDATE( ctx != NULL ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); |
} |
void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); |
} |
int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, |
const unsigned char key[32] ) |
{ |
POLY1305_VALIDATE_RET( ctx != NULL ); |
POLY1305_VALIDATE_RET( key != NULL ); |
/* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */ |
ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU; |
ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU; |
ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU; |
ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU; |
ctx->s[0] = BYTES_TO_U32_LE( key, 16 ); |
ctx->s[1] = BYTES_TO_U32_LE( key, 20 ); |
ctx->s[2] = BYTES_TO_U32_LE( key, 24 ); |
ctx->s[3] = BYTES_TO_U32_LE( key, 28 ); |
/* Initial accumulator state */ |
ctx->acc[0] = 0U; |
ctx->acc[1] = 0U; |
ctx->acc[2] = 0U; |
ctx->acc[3] = 0U; |
ctx->acc[4] = 0U; |
/* Queue initially empty */ |
mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) ); |
ctx->queue_len = 0U; |
return( 0 ); |
} |
int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
size_t offset = 0U; |
size_t remaining = ilen; |
size_t queue_free_len; |
size_t nblocks; |
POLY1305_VALIDATE_RET( ctx != NULL ); |
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL ); |
if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) ) |
{ |
queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); |
if( ilen < queue_free_len ) |
{ |
/* Not enough data to complete the block. |
* Store this data with the other leftovers. |
*/ |
memcpy( &ctx->queue[ctx->queue_len], |
input, |
ilen ); |
ctx->queue_len += ilen; |
remaining = 0U; |
} |
else |
{ |
/* Enough data to produce a complete block */ |
memcpy( &ctx->queue[ctx->queue_len], |
input, |
queue_free_len ); |
ctx->queue_len = 0U; |
poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */ |
offset += queue_free_len; |
remaining -= queue_free_len; |
} |
} |
if( remaining >= POLY1305_BLOCK_SIZE_BYTES ) |
{ |
nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; |
poly1305_process( ctx, nblocks, &input[offset], 1U ); |
offset += nblocks * POLY1305_BLOCK_SIZE_BYTES; |
remaining %= POLY1305_BLOCK_SIZE_BYTES; |
} |
if( remaining > 0U ) |
{ |
/* Store partial block */ |
ctx->queue_len = remaining; |
memcpy( ctx->queue, &input[offset], remaining ); |
} |
return( 0 ); |
} |
int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, |
unsigned char mac[16] ) |
{ |
POLY1305_VALIDATE_RET( ctx != NULL ); |
POLY1305_VALIDATE_RET( mac != NULL ); |
/* Process any leftover data */ |
if( ctx->queue_len > 0U ) |
{ |
/* Add padding bit */ |
ctx->queue[ctx->queue_len] = 1U; |
ctx->queue_len++; |
/* Pad with zeroes */ |
memset( &ctx->queue[ctx->queue_len], |
0, |
POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); |
poly1305_process( ctx, 1U, /* Process 1 block */ |
ctx->queue, 0U ); /* Already padded above */ |
} |
poly1305_compute_mac( ctx, mac ); |
return( 0 ); |
} |
int mbedtls_poly1305_mac( const unsigned char key[32], |
const unsigned char *input, |
size_t ilen, |
unsigned char mac[16] ) |
{ |
mbedtls_poly1305_context ctx; |
int ret; |
POLY1305_VALIDATE_RET( key != NULL ); |
POLY1305_VALIDATE_RET( mac != NULL ); |
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL ); |
mbedtls_poly1305_init( &ctx ); |
ret = mbedtls_poly1305_starts( &ctx, key ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_poly1305_update( &ctx, input, ilen ); |
if( ret != 0 ) |
goto cleanup; |
ret = mbedtls_poly1305_finish( &ctx, mac ); |
cleanup: |
mbedtls_poly1305_free( &ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_POLY1305_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
static const unsigned char test_keys[2][32] = |
{ |
{ |
0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, |
0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, |
0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, |
0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b |
}, |
{ |
0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, |
0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, |
0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, |
0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 |
} |
}; |
static const unsigned char test_data[2][127] = |
{ |
{ |
0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, |
0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, |
0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, |
0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, |
0x75, 0x70 |
}, |
{ |
0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, |
0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, |
0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, |
0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, |
0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, |
0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, |
0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, |
0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, |
0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c, |
0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, |
0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, |
0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, |
0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, |
0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20, |
0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, |
0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e |
} |
}; |
static const size_t test_data_len[2] = |
{ |
34U, |
127U |
}; |
static const unsigned char test_mac[2][16] = |
{ |
{ |
0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, |
0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9 |
}, |
{ |
0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, |
0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62 |
} |
}; |
#define ASSERT( cond, args ) \ |
do \ |
{ \ |
if( ! ( cond ) ) \ |
{ \ |
if( verbose != 0 ) \ |
mbedtls_printf args; \ |
\ |
return( -1 ); \ |
} \ |
} \ |
while( 0 ) |
int mbedtls_poly1305_self_test( int verbose ) |
{ |
unsigned char mac[16]; |
unsigned i; |
int ret; |
for( i = 0U; i < 2U; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " Poly1305 test %u ", i ); |
ret = mbedtls_poly1305_mac( test_keys[i], |
test_data[i], |
test_data_len[i], |
mac ); |
ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); |
ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) ); |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_POLY1305_C */ |
/programs/develop/libraries/kos_mbedtls/library/ripemd160.c |
---|
0,0 → 1,561 |
/* |
* RIPE MD-160 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The RIPEMD-160 algorithm was designed by RIPE in 1996 |
* http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html |
* http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_RIPEMD160_C) |
#include "mbedtls/ripemd160.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_RIPEMD160_ALT) |
/* |
* 32-bit integer manipulation macros (little endian) |
*/ |
#ifndef GET_UINT32_LE |
#define GET_UINT32_LE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] ) \ |
| ( (uint32_t) (b)[(i) + 1] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 3] << 24 ); \ |
} |
#endif |
#ifndef PUT_UINT32_LE |
#define PUT_UINT32_LE(n,b,i) \ |
{ \ |
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ |
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ |
(b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ |
(b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ |
} |
#endif |
void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); |
} |
void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); |
} |
void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, |
const mbedtls_ripemd160_context *src ) |
{ |
*dst = *src; |
} |
/* |
* RIPEMD-160 context setup |
*/ |
int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) |
{ |
mbedtls_ripemd160_starts_ret( ctx ); |
} |
#endif |
#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) |
/* |
* Process one block |
*/ |
int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, |
const unsigned char data[64] ) |
{ |
uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; |
GET_UINT32_LE( X[ 0], data, 0 ); |
GET_UINT32_LE( X[ 1], data, 4 ); |
GET_UINT32_LE( X[ 2], data, 8 ); |
GET_UINT32_LE( X[ 3], data, 12 ); |
GET_UINT32_LE( X[ 4], data, 16 ); |
GET_UINT32_LE( X[ 5], data, 20 ); |
GET_UINT32_LE( X[ 6], data, 24 ); |
GET_UINT32_LE( X[ 7], data, 28 ); |
GET_UINT32_LE( X[ 8], data, 32 ); |
GET_UINT32_LE( X[ 9], data, 36 ); |
GET_UINT32_LE( X[10], data, 40 ); |
GET_UINT32_LE( X[11], data, 44 ); |
GET_UINT32_LE( X[12], data, 48 ); |
GET_UINT32_LE( X[13], data, 52 ); |
GET_UINT32_LE( X[14], data, 56 ); |
GET_UINT32_LE( X[15], data, 60 ); |
A = Ap = ctx->state[0]; |
B = Bp = ctx->state[1]; |
C = Cp = ctx->state[2]; |
D = Dp = ctx->state[3]; |
E = Ep = ctx->state[4]; |
#define F1( x, y, z ) ( (x) ^ (y) ^ (z) ) |
#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) |
#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) ) |
#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) ) |
#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) ) |
#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) ) |
#define P( a, b, c, d, e, r, s, f, k ) \ |
do \ |
{ \ |
(a) += f( (b), (c), (d) ) + X[r] + (k); \ |
(a) = S( (a), (s) ) + (e); \ |
(c) = S( (c), 10 ); \ |
} while( 0 ) |
#define P2( a, b, c, d, e, r, s, rp, sp ) \ |
do \ |
{ \ |
P( (a), (b), (c), (d), (e), (r), (s), F, K ); \ |
P( a ## p, b ## p, c ## p, d ## p, e ## p, \ |
(rp), (sp), Fp, Kp ); \ |
} while( 0 ) |
#define F F1 |
#define K 0x00000000 |
#define Fp F5 |
#define Kp 0x50A28BE6 |
P2( A, B, C, D, E, 0, 11, 5, 8 ); |
P2( E, A, B, C, D, 1, 14, 14, 9 ); |
P2( D, E, A, B, C, 2, 15, 7, 9 ); |
P2( C, D, E, A, B, 3, 12, 0, 11 ); |
P2( B, C, D, E, A, 4, 5, 9, 13 ); |
P2( A, B, C, D, E, 5, 8, 2, 15 ); |
P2( E, A, B, C, D, 6, 7, 11, 15 ); |
P2( D, E, A, B, C, 7, 9, 4, 5 ); |
P2( C, D, E, A, B, 8, 11, 13, 7 ); |
P2( B, C, D, E, A, 9, 13, 6, 7 ); |
P2( A, B, C, D, E, 10, 14, 15, 8 ); |
P2( E, A, B, C, D, 11, 15, 8, 11 ); |
P2( D, E, A, B, C, 12, 6, 1, 14 ); |
P2( C, D, E, A, B, 13, 7, 10, 14 ); |
P2( B, C, D, E, A, 14, 9, 3, 12 ); |
P2( A, B, C, D, E, 15, 8, 12, 6 ); |
#undef F |
#undef K |
#undef Fp |
#undef Kp |
#define F F2 |
#define K 0x5A827999 |
#define Fp F4 |
#define Kp 0x5C4DD124 |
P2( E, A, B, C, D, 7, 7, 6, 9 ); |
P2( D, E, A, B, C, 4, 6, 11, 13 ); |
P2( C, D, E, A, B, 13, 8, 3, 15 ); |
P2( B, C, D, E, A, 1, 13, 7, 7 ); |
P2( A, B, C, D, E, 10, 11, 0, 12 ); |
P2( E, A, B, C, D, 6, 9, 13, 8 ); |
P2( D, E, A, B, C, 15, 7, 5, 9 ); |
P2( C, D, E, A, B, 3, 15, 10, 11 ); |
P2( B, C, D, E, A, 12, 7, 14, 7 ); |
P2( A, B, C, D, E, 0, 12, 15, 7 ); |
P2( E, A, B, C, D, 9, 15, 8, 12 ); |
P2( D, E, A, B, C, 5, 9, 12, 7 ); |
P2( C, D, E, A, B, 2, 11, 4, 6 ); |
P2( B, C, D, E, A, 14, 7, 9, 15 ); |
P2( A, B, C, D, E, 11, 13, 1, 13 ); |
P2( E, A, B, C, D, 8, 12, 2, 11 ); |
#undef F |
#undef K |
#undef Fp |
#undef Kp |
#define F F3 |
#define K 0x6ED9EBA1 |
#define Fp F3 |
#define Kp 0x6D703EF3 |
P2( D, E, A, B, C, 3, 11, 15, 9 ); |
P2( C, D, E, A, B, 10, 13, 5, 7 ); |
P2( B, C, D, E, A, 14, 6, 1, 15 ); |
P2( A, B, C, D, E, 4, 7, 3, 11 ); |
P2( E, A, B, C, D, 9, 14, 7, 8 ); |
P2( D, E, A, B, C, 15, 9, 14, 6 ); |
P2( C, D, E, A, B, 8, 13, 6, 6 ); |
P2( B, C, D, E, A, 1, 15, 9, 14 ); |
P2( A, B, C, D, E, 2, 14, 11, 12 ); |
P2( E, A, B, C, D, 7, 8, 8, 13 ); |
P2( D, E, A, B, C, 0, 13, 12, 5 ); |
P2( C, D, E, A, B, 6, 6, 2, 14 ); |
P2( B, C, D, E, A, 13, 5, 10, 13 ); |
P2( A, B, C, D, E, 11, 12, 0, 13 ); |
P2( E, A, B, C, D, 5, 7, 4, 7 ); |
P2( D, E, A, B, C, 12, 5, 13, 5 ); |
#undef F |
#undef K |
#undef Fp |
#undef Kp |
#define F F4 |
#define K 0x8F1BBCDC |
#define Fp F2 |
#define Kp 0x7A6D76E9 |
P2( C, D, E, A, B, 1, 11, 8, 15 ); |
P2( B, C, D, E, A, 9, 12, 6, 5 ); |
P2( A, B, C, D, E, 11, 14, 4, 8 ); |
P2( E, A, B, C, D, 10, 15, 1, 11 ); |
P2( D, E, A, B, C, 0, 14, 3, 14 ); |
P2( C, D, E, A, B, 8, 15, 11, 14 ); |
P2( B, C, D, E, A, 12, 9, 15, 6 ); |
P2( A, B, C, D, E, 4, 8, 0, 14 ); |
P2( E, A, B, C, D, 13, 9, 5, 6 ); |
P2( D, E, A, B, C, 3, 14, 12, 9 ); |
P2( C, D, E, A, B, 7, 5, 2, 12 ); |
P2( B, C, D, E, A, 15, 6, 13, 9 ); |
P2( A, B, C, D, E, 14, 8, 9, 12 ); |
P2( E, A, B, C, D, 5, 6, 7, 5 ); |
P2( D, E, A, B, C, 6, 5, 10, 15 ); |
P2( C, D, E, A, B, 2, 12, 14, 8 ); |
#undef F |
#undef K |
#undef Fp |
#undef Kp |
#define F F5 |
#define K 0xA953FD4E |
#define Fp F1 |
#define Kp 0x00000000 |
P2( B, C, D, E, A, 4, 9, 12, 8 ); |
P2( A, B, C, D, E, 0, 15, 15, 5 ); |
P2( E, A, B, C, D, 5, 5, 10, 12 ); |
P2( D, E, A, B, C, 9, 11, 4, 9 ); |
P2( C, D, E, A, B, 7, 6, 1, 12 ); |
P2( B, C, D, E, A, 12, 8, 5, 5 ); |
P2( A, B, C, D, E, 2, 13, 8, 14 ); |
P2( E, A, B, C, D, 10, 12, 7, 6 ); |
P2( D, E, A, B, C, 14, 5, 6, 8 ); |
P2( C, D, E, A, B, 1, 12, 2, 13 ); |
P2( B, C, D, E, A, 3, 13, 13, 6 ); |
P2( A, B, C, D, E, 8, 14, 14, 5 ); |
P2( E, A, B, C, D, 11, 11, 0, 15 ); |
P2( D, E, A, B, C, 6, 8, 3, 13 ); |
P2( C, D, E, A, B, 15, 5, 9, 11 ); |
P2( B, C, D, E, A, 13, 6, 11, 11 ); |
#undef F |
#undef K |
#undef Fp |
#undef Kp |
C = ctx->state[1] + C + Dp; |
ctx->state[1] = ctx->state[2] + D + Ep; |
ctx->state[2] = ctx->state[3] + E + Ap; |
ctx->state[3] = ctx->state[4] + A + Bp; |
ctx->state[4] = ctx->state[0] + B + Cp; |
ctx->state[0] = C; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, |
const unsigned char data[64] ) |
{ |
mbedtls_internal_ripemd160_process( ctx, data ); |
} |
#endif |
#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ |
/* |
* RIPEMD-160 process buffer |
*/ |
int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
uint32_t left; |
if( ilen == 0 ) |
return( 0 ); |
left = ctx->total[0] & 0x3F; |
fill = 64 - left; |
ctx->total[0] += (uint32_t) ilen; |
ctx->total[0] &= 0xFFFFFFFF; |
if( ctx->total[0] < (uint32_t) ilen ) |
ctx->total[1]++; |
if( left && ilen >= fill ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, fill ); |
if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
input += fill; |
ilen -= fill; |
left = 0; |
} |
while( ilen >= 64 ) |
{ |
if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 ) |
return( ret ); |
input += 64; |
ilen -= 64; |
} |
if( ilen > 0 ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, ilen ); |
} |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_ripemd160_update_ret( ctx, input, ilen ); |
} |
#endif |
static const unsigned char ripemd160_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 |
}; |
/* |
* RIPEMD-160 final digest |
*/ |
int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, |
unsigned char output[20] ) |
{ |
int ret; |
uint32_t last, padn; |
uint32_t high, low; |
unsigned char msglen[8]; |
high = ( ctx->total[0] >> 29 ) |
| ( ctx->total[1] << 3 ); |
low = ( ctx->total[0] << 3 ); |
PUT_UINT32_LE( low, msglen, 0 ); |
PUT_UINT32_LE( high, msglen, 4 ); |
last = ctx->total[0] & 0x3F; |
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); |
ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn ); |
if( ret != 0 ) |
return( ret ); |
ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 ); |
if( ret != 0 ) |
return( ret ); |
PUT_UINT32_LE( ctx->state[0], output, 0 ); |
PUT_UINT32_LE( ctx->state[1], output, 4 ); |
PUT_UINT32_LE( ctx->state[2], output, 8 ); |
PUT_UINT32_LE( ctx->state[3], output, 12 ); |
PUT_UINT32_LE( ctx->state[4], output, 16 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, |
unsigned char output[20] ) |
{ |
mbedtls_ripemd160_finish_ret( ctx, output ); |
} |
#endif |
#endif /* ! MBEDTLS_RIPEMD160_ALT */ |
/* |
* output = RIPEMD-160( input buffer ) |
*/ |
int mbedtls_ripemd160_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ) |
{ |
int ret; |
mbedtls_ripemd160_context ctx; |
mbedtls_ripemd160_init( &ctx ); |
if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_ripemd160_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_ripemd160( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ) |
{ |
mbedtls_ripemd160_ret( input, ilen, output ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* Test vectors from the RIPEMD-160 paper and |
* http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC |
*/ |
#define TESTS 8 |
static const unsigned char ripemd160_test_str[TESTS][81] = |
{ |
{ "" }, |
{ "a" }, |
{ "abc" }, |
{ "message digest" }, |
{ "abcdefghijklmnopqrstuvwxyz" }, |
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, |
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, |
{ "12345678901234567890123456789012345678901234567890123456789012" |
"345678901234567890" }, |
}; |
static const size_t ripemd160_test_strlen[TESTS] = |
{ |
0, 1, 3, 14, 26, 56, 62, 80 |
}; |
static const unsigned char ripemd160_test_md[TESTS][20] = |
{ |
{ 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, |
0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, |
{ 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, |
0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, |
{ 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, |
0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, |
{ 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, |
0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, |
{ 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, |
0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, |
{ 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, |
0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, |
{ 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, |
0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, |
{ 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, |
0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, |
}; |
/* |
* Checkup routine |
*/ |
int mbedtls_ripemd160_self_test( int verbose ) |
{ |
int i, ret = 0; |
unsigned char output[20]; |
memset( output, 0, sizeof output ); |
for( i = 0; i < TESTS; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); |
ret = mbedtls_ripemd160_ret( ripemd160_test_str[i], |
ripemd160_test_strlen[i], output ); |
if( ret != 0 ) |
goto fail; |
if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_RIPEMD160_C */ |
/programs/develop/libraries/kos_mbedtls/library/rsa.c |
---|
0,0 → 1,2731 |
/* |
* The RSA public-key cryptosystem |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The following sources were referenced in the design of this implementation |
* of the RSA algorithm: |
* |
* [1] A method for obtaining digital signatures and public-key cryptosystems |
* R Rivest, A Shamir, and L Adleman |
* http://people.csail.mit.edu/rivest/pubs.html#RSA78 |
* |
* [2] Handbook of Applied Cryptography - 1997, Chapter 8 |
* Menezes, van Oorschot and Vanstone |
* |
* [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks |
* Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and |
* Stefan Mangard |
* https://arxiv.org/abs/1702.08719v2 |
* |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_RSA_C) |
#include "mbedtls/rsa.h" |
#include "mbedtls/rsa_internal.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PKCS1_V21) |
#include "mbedtls/md.h" |
#endif |
#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) |
#include <stdlib.h> |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#if !defined(MBEDTLS_RSA_ALT) |
/* Parameter validation macros */ |
#define RSA_VALIDATE_RET( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) |
#define RSA_VALIDATE( cond ) \ |
MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if defined(MBEDTLS_PKCS1_V15) |
/* constant-time buffer comparison */ |
static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n ) |
{ |
size_t i; |
const unsigned char *A = (const unsigned char *) a; |
const unsigned char *B = (const unsigned char *) b; |
unsigned char diff = 0; |
for( i = 0; i < n; i++ ) |
diff |= A[i] ^ B[i]; |
return( diff ); |
} |
#endif /* MBEDTLS_PKCS1_V15 */ |
int mbedtls_rsa_import( mbedtls_rsa_context *ctx, |
const mbedtls_mpi *N, |
const mbedtls_mpi *P, const mbedtls_mpi *Q, |
const mbedtls_mpi *D, const mbedtls_mpi *E ) |
{ |
int ret; |
RSA_VALIDATE_RET( ctx != NULL ); |
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) || |
( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) || |
( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) || |
( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) || |
( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
if( N != NULL ) |
ctx->len = mbedtls_mpi_size( &ctx->N ); |
return( 0 ); |
} |
int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, |
unsigned char const *N, size_t N_len, |
unsigned char const *P, size_t P_len, |
unsigned char const *Q, size_t Q_len, |
unsigned char const *D, size_t D_len, |
unsigned char const *E, size_t E_len ) |
{ |
int ret = 0; |
RSA_VALIDATE_RET( ctx != NULL ); |
if( N != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) ); |
ctx->len = mbedtls_mpi_size( &ctx->N ); |
} |
if( P != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) ); |
if( Q != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) ); |
if( D != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) ); |
if( E != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) ); |
cleanup: |
if( ret != 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
return( 0 ); |
} |
/* |
* Checks whether the context fields are set in such a way |
* that the RSA primitives will be able to execute without error. |
* It does *not* make guarantees for consistency of the parameters. |
*/ |
static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv, |
int blinding_needed ) |
{ |
#if !defined(MBEDTLS_RSA_NO_CRT) |
/* blinding_needed is only used for NO_CRT to decide whether |
* P,Q need to be present or not. */ |
((void) blinding_needed); |
#endif |
if( ctx->len != mbedtls_mpi_size( &ctx->N ) || |
ctx->len > MBEDTLS_MPI_MAX_SIZE ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
/* |
* 1. Modular exponentiation needs positive, odd moduli. |
*/ |
/* Modular exponentiation wrt. N is always used for |
* RSA public key operations. */ |
if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 || |
mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
#if !defined(MBEDTLS_RSA_NO_CRT) |
/* Modular exponentiation for P and Q is only |
* used for private key operations and if CRT |
* is used. */ |
if( is_priv && |
( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || |
mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 || |
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 || |
mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
#endif /* !MBEDTLS_RSA_NO_CRT */ |
/* |
* 2. Exponents must be positive |
*/ |
/* Always need E for public key operations */ |
if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_RSA_NO_CRT) |
/* For private key operations, use D or DP & DQ |
* as (unblinded) exponents. */ |
if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
#else |
if( is_priv && |
( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 || |
mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
#endif /* MBEDTLS_RSA_NO_CRT */ |
/* Blinding shouldn't make exponents negative either, |
* so check that P, Q >= 1 if that hasn't yet been |
* done as part of 1. */ |
#if defined(MBEDTLS_RSA_NO_CRT) |
if( is_priv && blinding_needed && |
( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 || |
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
#endif |
/* It wouldn't lead to an error if it wasn't satisfied, |
* but check for QP >= 1 nonetheless. */ |
#if !defined(MBEDTLS_RSA_NO_CRT) |
if( is_priv && |
mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
#endif |
return( 0 ); |
} |
int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ) |
{ |
int ret = 0; |
int have_N, have_P, have_Q, have_D, have_E; |
#if !defined(MBEDTLS_RSA_NO_CRT) |
int have_DP, have_DQ, have_QP; |
#endif |
int n_missing, pq_missing, d_missing, is_pub, is_priv; |
RSA_VALIDATE_RET( ctx != NULL ); |
have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 ); |
have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 ); |
have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 ); |
have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 ); |
have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 ); |
#if !defined(MBEDTLS_RSA_NO_CRT) |
have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 ); |
have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 ); |
have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 ); |
#endif |
/* |
* Check whether provided parameters are enough |
* to deduce all others. The following incomplete |
* parameter sets for private keys are supported: |
* |
* (1) P, Q missing. |
* (2) D and potentially N missing. |
* |
*/ |
n_missing = have_P && have_Q && have_D && have_E; |
pq_missing = have_N && !have_P && !have_Q && have_D && have_E; |
d_missing = have_P && have_Q && !have_D && have_E; |
is_pub = have_N && !have_P && !have_Q && !have_D && have_E; |
/* These three alternatives are mutually exclusive */ |
is_priv = n_missing || pq_missing || d_missing; |
if( !is_priv && !is_pub ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* |
* Step 1: Deduce N if P, Q are provided. |
*/ |
if( !have_N && have_P && have_Q ) |
{ |
if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, |
&ctx->Q ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
ctx->len = mbedtls_mpi_size( &ctx->N ); |
} |
/* |
* Step 2: Deduce and verify all remaining core parameters. |
*/ |
if( pq_missing ) |
{ |
ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D, |
&ctx->P, &ctx->Q ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
else if( d_missing ) |
{ |
if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P, |
&ctx->Q, |
&ctx->E, |
&ctx->D ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
} |
/* |
* Step 3: Deduce all additional parameters specific |
* to our current RSA implementation. |
*/ |
#if !defined(MBEDTLS_RSA_NO_CRT) |
if( is_priv && ! ( have_DP && have_DQ && have_QP ) ) |
{ |
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, |
&ctx->DP, &ctx->DQ, &ctx->QP ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
#endif /* MBEDTLS_RSA_NO_CRT */ |
/* |
* Step 3: Basic sanity checks |
*/ |
return( rsa_check_context( ctx, is_priv, 1 ) ); |
} |
int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, |
unsigned char *N, size_t N_len, |
unsigned char *P, size_t P_len, |
unsigned char *Q, size_t Q_len, |
unsigned char *D, size_t D_len, |
unsigned char *E, size_t E_len ) |
{ |
int ret = 0; |
int is_priv; |
RSA_VALIDATE_RET( ctx != NULL ); |
/* Check if key is private or public */ |
is_priv = |
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; |
if( !is_priv ) |
{ |
/* If we're trying to export private parameters for a public key, |
* something must be wrong. */ |
if( P != NULL || Q != NULL || D != NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
if( N != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) ); |
if( P != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) ); |
if( Q != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) ); |
if( D != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) ); |
if( E != NULL ) |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) ); |
cleanup: |
return( ret ); |
} |
int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, |
mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, |
mbedtls_mpi *D, mbedtls_mpi *E ) |
{ |
int ret; |
int is_priv; |
RSA_VALIDATE_RET( ctx != NULL ); |
/* Check if key is private or public */ |
is_priv = |
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; |
if( !is_priv ) |
{ |
/* If we're trying to export private parameters for a public key, |
* something must be wrong. */ |
if( P != NULL || Q != NULL || D != NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
/* Export all requested core parameters. */ |
if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) || |
( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) || |
( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) || |
( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) || |
( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
/* |
* Export CRT parameters |
* This must also be implemented if CRT is not used, for being able to |
* write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt |
* can be used in this case. |
*/ |
int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, |
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ) |
{ |
int ret; |
int is_priv; |
RSA_VALIDATE_RET( ctx != NULL ); |
/* Check if key is private or public */ |
is_priv = |
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 && |
mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0; |
if( !is_priv ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
#if !defined(MBEDTLS_RSA_NO_CRT) |
/* Export all requested blinding parameters. */ |
if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) || |
( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) || |
( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
#else |
if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, |
DP, DQ, QP ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret ); |
} |
#endif |
return( 0 ); |
} |
/* |
* Initialize an RSA context |
*/ |
void mbedtls_rsa_init( mbedtls_rsa_context *ctx, |
int padding, |
int hash_id ) |
{ |
RSA_VALIDATE( ctx != NULL ); |
RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || |
padding == MBEDTLS_RSA_PKCS_V21 ); |
memset( ctx, 0, sizeof( mbedtls_rsa_context ) ); |
mbedtls_rsa_set_padding( ctx, padding, hash_id ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &ctx->mutex ); |
#endif |
} |
/* |
* Set padding for an existing RSA context |
*/ |
void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, |
int hash_id ) |
{ |
RSA_VALIDATE( ctx != NULL ); |
RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 || |
padding == MBEDTLS_RSA_PKCS_V21 ); |
ctx->padding = padding; |
ctx->hash_id = hash_id; |
} |
/* |
* Get length in bytes of RSA modulus |
*/ |
size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ) |
{ |
return( ctx->len ); |
} |
#if defined(MBEDTLS_GENPRIME) |
/* |
* Generate an RSA keypair |
* |
* This generation method follows the RSA key pair generation procedure of |
* FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072. |
*/ |
int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
unsigned int nbits, int exponent ) |
{ |
int ret; |
mbedtls_mpi H, G, L; |
int prime_quality = 0; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( f_rng != NULL ); |
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* |
* If the modulus is 1024 bit long or shorter, then the security strength of |
* the RSA algorithm is less than or equal to 80 bits and therefore an error |
* rate of 2^-80 is sufficient. |
*/ |
if( nbits > 1024 ) |
prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR; |
mbedtls_mpi_init( &H ); |
mbedtls_mpi_init( &G ); |
mbedtls_mpi_init( &L ); |
/* |
* find primes P and Q with Q < P so that: |
* 1. |P-Q| > 2^( nbits / 2 - 100 ) |
* 2. GCD( E, (P-1)*(Q-1) ) == 1 |
* 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 ) |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) ); |
do |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, |
prime_quality, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, |
prime_quality, f_rng, p_rng ) ); |
/* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) ); |
if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) ) |
continue; |
/* not required by any standards, but some users rely on the fact that P > Q */ |
if( H.s < 0 ) |
mbedtls_mpi_swap( &ctx->P, &ctx->Q ); |
/* Temporarily replace P,Q by P-1, Q-1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) ); |
/* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); |
if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) |
continue; |
/* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) ); |
if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a)) |
continue; |
break; |
} |
while( 1 ); |
/* Restore P,Q */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); |
ctx->len = mbedtls_mpi_size( &ctx->N ); |
#if !defined(MBEDTLS_RSA_NO_CRT) |
/* |
* DP = D mod (P - 1) |
* DQ = D mod (Q - 1) |
* QP = Q^-1 mod P |
*/ |
MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D, |
&ctx->DP, &ctx->DQ, &ctx->QP ) ); |
#endif /* MBEDTLS_RSA_NO_CRT */ |
/* Double-check */ |
MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) ); |
cleanup: |
mbedtls_mpi_free( &H ); |
mbedtls_mpi_free( &G ); |
mbedtls_mpi_free( &L ); |
if( ret != 0 ) |
{ |
mbedtls_rsa_free( ctx ); |
return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_GENPRIME */ |
/* |
* Check a public RSA key |
*/ |
int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) |
{ |
RSA_VALIDATE_RET( ctx != NULL ); |
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 ) |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 || |
mbedtls_mpi_bitlen( &ctx->E ) < 2 || |
mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
return( 0 ); |
} |
/* |
* Check for the consistency of all fields in an RSA private key context |
*/ |
int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) |
{ |
RSA_VALIDATE_RET( ctx != NULL ); |
if( mbedtls_rsa_check_pubkey( ctx ) != 0 || |
rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q, |
&ctx->D, &ctx->E, NULL, NULL ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
#if !defined(MBEDTLS_RSA_NO_CRT) |
else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D, |
&ctx->DP, &ctx->DQ, &ctx->QP ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
#endif |
return( 0 ); |
} |
/* |
* Check if contexts holding a public and private key match |
*/ |
int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, |
const mbedtls_rsa_context *prv ) |
{ |
RSA_VALIDATE_RET( pub != NULL ); |
RSA_VALIDATE_RET( prv != NULL ); |
if( mbedtls_rsa_check_pubkey( pub ) != 0 || |
mbedtls_rsa_check_privkey( prv ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 || |
mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); |
} |
return( 0 ); |
} |
/* |
* Do an RSA public key operation |
*/ |
int mbedtls_rsa_public( mbedtls_rsa_context *ctx, |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
size_t olen; |
mbedtls_mpi T; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
RSA_VALIDATE_RET( output != NULL ); |
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
mbedtls_mpi_init( &T ); |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); |
if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) |
{ |
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
goto cleanup; |
} |
olen = ctx->len; |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); |
cleanup: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
mbedtls_mpi_free( &T ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret ); |
return( 0 ); |
} |
/* |
* Generate or update blinding values, see section 10 of: |
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, |
* DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer |
* Berlin Heidelberg, 1996. p. 104-113. |
*/ |
static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) |
{ |
int ret, count = 0; |
if( ctx->Vf.p != NULL ) |
{ |
/* We already have blinding values, just update them by squaring */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); |
goto cleanup; |
} |
/* Unblinding value: Vf = random number, invertible mod N */ |
do { |
if( count++ > 10 ) |
return( MBEDTLS_ERR_RSA_RNG_FAILED ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); |
} while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); |
/* Blinding value: Vi = Vf^(-e) mod N */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); |
cleanup: |
return( ret ); |
} |
/* |
* Exponent blinding supposed to prevent side-channel attacks using multiple |
* traces of measurements to recover the RSA key. The more collisions are there, |
* the more bits of the key can be recovered. See [3]. |
* |
* Collecting n collisions with m bit long blinding value requires 2^(m-m/n) |
* observations on avarage. |
* |
* For example with 28 byte blinding to achieve 2 collisions the adversary has |
* to make 2^112 observations on avarage. |
* |
* (With the currently (as of 2017 April) known best algorithms breaking 2048 |
* bit RSA requires approximately as much time as trying out 2^112 random keys. |
* Thus in this sense with 28 byte blinding the security is not reduced by |
* side-channel attacks like the one in [3]) |
* |
* This countermeasure does not help if the key recovery is possible with a |
* single trace. |
*/ |
#define RSA_EXPONENT_BLINDING 28 |
/* |
* Do an RSA private key operation |
*/ |
int mbedtls_rsa_private( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
const unsigned char *input, |
unsigned char *output ) |
{ |
int ret; |
size_t olen; |
/* Temporary holding the result */ |
mbedtls_mpi T; |
/* Temporaries holding P-1, Q-1 and the |
* exponent blinding factor, respectively. */ |
mbedtls_mpi P1, Q1, R; |
#if !defined(MBEDTLS_RSA_NO_CRT) |
/* Temporaries holding the results mod p resp. mod q. */ |
mbedtls_mpi TP, TQ; |
/* Temporaries holding the blinded exponents for |
* the mod p resp. mod q computation (if used). */ |
mbedtls_mpi DP_blind, DQ_blind; |
/* Pointers to actual exponents to be used - either the unblinded |
* or the blinded ones, depending on the presence of a PRNG. */ |
mbedtls_mpi *DP = &ctx->DP; |
mbedtls_mpi *DQ = &ctx->DQ; |
#else |
/* Temporary holding the blinded exponent (if used). */ |
mbedtls_mpi D_blind; |
/* Pointer to actual exponent to be used - either the unblinded |
* or the blinded one, depending on the presence of a PRNG. */ |
mbedtls_mpi *D = &ctx->D; |
#endif /* MBEDTLS_RSA_NO_CRT */ |
/* Temporaries holding the initial input and the double |
* checked result; should be the same in the end. */ |
mbedtls_mpi I, C; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
RSA_VALIDATE_RET( output != NULL ); |
if( rsa_check_context( ctx, 1 /* private key checks */, |
f_rng != NULL /* blinding y/n */ ) != 0 ) |
{ |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
/* MPI Initialization */ |
mbedtls_mpi_init( &T ); |
mbedtls_mpi_init( &P1 ); |
mbedtls_mpi_init( &Q1 ); |
mbedtls_mpi_init( &R ); |
if( f_rng != NULL ) |
{ |
#if defined(MBEDTLS_RSA_NO_CRT) |
mbedtls_mpi_init( &D_blind ); |
#else |
mbedtls_mpi_init( &DP_blind ); |
mbedtls_mpi_init( &DQ_blind ); |
#endif |
} |
#if !defined(MBEDTLS_RSA_NO_CRT) |
mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ ); |
#endif |
mbedtls_mpi_init( &I ); |
mbedtls_mpi_init( &C ); |
/* End of MPI initialization */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); |
if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) |
{ |
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) ); |
if( f_rng != NULL ) |
{ |
/* |
* Blinding |
* T = T * Vi mod N |
*/ |
MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); |
/* |
* Exponent blinding |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); |
#if defined(MBEDTLS_RSA_NO_CRT) |
/* |
* D_blind = ( P - 1 ) * ( Q - 1 ) * R + D |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, |
f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) ); |
D = &D_blind; |
#else |
/* |
* DP_blind = ( P - 1 ) * R + DP |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, |
f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind, |
&ctx->DP ) ); |
DP = &DP_blind; |
/* |
* DQ_blind = ( Q - 1 ) * R + DQ |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, |
f_rng, p_rng ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind, |
&ctx->DQ ) ); |
DQ = &DQ_blind; |
#endif /* MBEDTLS_RSA_NO_CRT */ |
} |
#if defined(MBEDTLS_RSA_NO_CRT) |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) ); |
#else |
/* |
* Faster decryption using the CRT |
* |
* TP = input ^ dP mod P |
* TQ = input ^ dQ mod Q |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) ); |
/* |
* T = (TP - TQ) * (Q^-1 mod P) mod P |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) ); |
/* |
* T = TQ + T * Q |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) ); |
#endif /* MBEDTLS_RSA_NO_CRT */ |
if( f_rng != NULL ) |
{ |
/* |
* Unblind |
* T = T * Vf mod N |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); |
} |
/* Verify the result to prevent glitching attacks. */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E, |
&ctx->N, &ctx->RN ) ); |
if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; |
goto cleanup; |
} |
olen = ctx->len; |
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); |
cleanup: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
mbedtls_mpi_free( &P1 ); |
mbedtls_mpi_free( &Q1 ); |
mbedtls_mpi_free( &R ); |
if( f_rng != NULL ) |
{ |
#if defined(MBEDTLS_RSA_NO_CRT) |
mbedtls_mpi_free( &D_blind ); |
#else |
mbedtls_mpi_free( &DP_blind ); |
mbedtls_mpi_free( &DQ_blind ); |
#endif |
} |
mbedtls_mpi_free( &T ); |
#if !defined(MBEDTLS_RSA_NO_CRT) |
mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ ); |
#endif |
mbedtls_mpi_free( &C ); |
mbedtls_mpi_free( &I ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); |
return( 0 ); |
} |
#if defined(MBEDTLS_PKCS1_V21) |
/** |
* Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. |
* |
* \param dst buffer to mask |
* \param dlen length of destination buffer |
* \param src source of the mask generation |
* \param slen length of the source buffer |
* \param md_ctx message digest context to use |
*/ |
static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, |
size_t slen, mbedtls_md_context_t *md_ctx ) |
{ |
unsigned char mask[MBEDTLS_MD_MAX_SIZE]; |
unsigned char counter[4]; |
unsigned char *p; |
unsigned int hlen; |
size_t i, use_len; |
int ret = 0; |
memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); |
memset( counter, 0, 4 ); |
hlen = mbedtls_md_get_size( md_ctx->md_info ); |
/* Generate and apply dbMask */ |
p = dst; |
while( dlen > 0 ) |
{ |
use_len = hlen; |
if( dlen < hlen ) |
use_len = dlen; |
if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 ) |
goto exit; |
for( i = 0; i < use_len; ++i ) |
*p++ ^= mask[i]; |
counter[3]++; |
dlen -= use_len; |
} |
exit: |
mbedtls_platform_zeroize( mask, sizeof( mask ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS1_V21 */ |
#if defined(MBEDTLS_PKCS1_V21) |
/* |
* Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function |
*/ |
int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
const unsigned char *label, size_t label_len, |
size_t ilen, |
const unsigned char *input, |
unsigned char *output ) |
{ |
size_t olen; |
int ret; |
unsigned char *p = output; |
unsigned int hlen; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( output != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
RSA_VALIDATE_RET( label_len == 0 || label != NULL ); |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( f_rng == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
olen = ctx->len; |
hlen = mbedtls_md_get_size( md_info ); |
/* first comparison checks for overflow */ |
if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
memset( output, 0, olen ); |
*p++ = 0; |
/* Generate a random octet string seed */ |
if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) |
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); |
p += hlen; |
/* Construct DB */ |
if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 ) |
return( ret ); |
p += hlen; |
p += olen - 2 * hlen - 2 - ilen; |
*p++ = 1; |
memcpy( p, input, ilen ); |
mbedtls_md_init( &md_ctx ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) |
goto exit; |
/* maskedDB: Apply dbMask to DB */ |
if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, |
&md_ctx ) ) != 0 ) |
goto exit; |
/* maskedSeed: Apply seedMask to seed */ |
if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, |
&md_ctx ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_md_free( &md_ctx ); |
if( ret != 0 ) |
return( ret ); |
return( ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, output, output ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); |
} |
#endif /* MBEDTLS_PKCS1_V21 */ |
#if defined(MBEDTLS_PKCS1_V15) |
/* |
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function |
*/ |
int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t ilen, |
const unsigned char *input, |
unsigned char *output ) |
{ |
size_t nb_pad, olen; |
int ret; |
unsigned char *p = output; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( output != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
olen = ctx->len; |
/* first comparison checks for overflow */ |
if( ilen + 11 < ilen || olen < ilen + 11 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
nb_pad = olen - 3 - ilen; |
*p++ = 0; |
if( mode == MBEDTLS_RSA_PUBLIC ) |
{ |
if( f_rng == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
*p++ = MBEDTLS_RSA_CRYPT; |
while( nb_pad-- > 0 ) |
{ |
int rng_dl = 100; |
do { |
ret = f_rng( p_rng, p, 1 ); |
} while( *p == 0 && --rng_dl && ret == 0 ); |
/* Check if RNG failed to generate data */ |
if( rng_dl == 0 || ret != 0 ) |
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); |
p++; |
} |
} |
else |
{ |
*p++ = MBEDTLS_RSA_SIGN; |
while( nb_pad-- > 0 ) |
*p++ = 0xFF; |
} |
*p++ = 0; |
memcpy( p, input, ilen ); |
return( ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, output, output ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); |
} |
#endif /* MBEDTLS_PKCS1_V15 */ |
/* |
* Add the message padding, then do an RSA operation |
*/ |
int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t ilen, |
const unsigned char *input, |
unsigned char *output ) |
{ |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( output != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
switch( ctx->padding ) |
{ |
#if defined(MBEDTLS_PKCS1_V15) |
case MBEDTLS_RSA_PKCS_V15: |
return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen, |
input, output ); |
#endif |
#if defined(MBEDTLS_PKCS1_V21) |
case MBEDTLS_RSA_PKCS_V21: |
return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0, |
ilen, input, output ); |
#endif |
default: |
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); |
} |
} |
#if defined(MBEDTLS_PKCS1_V21) |
/* |
* Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function |
*/ |
int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
const unsigned char *label, size_t label_len, |
size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ) |
{ |
int ret; |
size_t ilen, i, pad_len; |
unsigned char *p, bad, pad_done; |
unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; |
unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; |
unsigned int hlen; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); |
RSA_VALIDATE_RET( label_len == 0 || label != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
RSA_VALIDATE_RET( olen != NULL ); |
/* |
* Parameters sanity checks |
*/ |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
ilen = ctx->len; |
if( ilen < 16 || ilen > sizeof( buf ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hlen = mbedtls_md_get_size( md_info ); |
// checking for integer underflow |
if( 2 * hlen + 2 > ilen ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* |
* RSA operation |
*/ |
ret = ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, input, buf ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); |
if( ret != 0 ) |
goto cleanup; |
/* |
* Unmask data and generate lHash |
*/ |
mbedtls_md_init( &md_ctx ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) |
{ |
mbedtls_md_free( &md_ctx ); |
goto cleanup; |
} |
/* seed: Apply seedMask to maskedSeed */ |
if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, |
&md_ctx ) ) != 0 || |
/* DB: Apply dbMask to maskedDB */ |
( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, |
&md_ctx ) ) != 0 ) |
{ |
mbedtls_md_free( &md_ctx ); |
goto cleanup; |
} |
mbedtls_md_free( &md_ctx ); |
/* Generate lHash */ |
if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 ) |
goto cleanup; |
/* |
* Check contents, in "constant-time" |
*/ |
p = buf; |
bad = 0; |
bad |= *p++; /* First byte must be 0 */ |
p += hlen; /* Skip seed */ |
/* Check lHash */ |
for( i = 0; i < hlen; i++ ) |
bad |= lhash[i] ^ *p++; |
/* Get zero-padding len, but always read till end of buffer |
* (minus one, for the 01 byte) */ |
pad_len = 0; |
pad_done = 0; |
for( i = 0; i < ilen - 2 * hlen - 2; i++ ) |
{ |
pad_done |= p[i]; |
pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; |
} |
p += pad_len; |
bad |= *p++ ^ 0x01; |
/* |
* The only information "leaked" is whether the padding was correct or not |
* (eg, no data is copied if it was not correct). This meets the |
* recommendations in PKCS#1 v2.2: an opponent cannot distinguish between |
* the different error conditions. |
*/ |
if( bad != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_INVALID_PADDING; |
goto cleanup; |
} |
if( ilen - ( p - buf ) > output_max_len ) |
{ |
ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; |
goto cleanup; |
} |
*olen = ilen - (p - buf); |
memcpy( output, p, *olen ); |
ret = 0; |
cleanup: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
mbedtls_platform_zeroize( lhash, sizeof( lhash ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS1_V21 */ |
#if defined(MBEDTLS_PKCS1_V15) |
/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches. |
* |
* \param value The value to analyze. |
* \return Zero if \p value is zero, otherwise all-bits-one. |
*/ |
static unsigned all_or_nothing_int( unsigned value ) |
{ |
/* MSVC has a warning about unary minus on unsigned, but this is |
* well-defined and precisely what we want to do here */ |
#if defined(_MSC_VER) |
#pragma warning( push ) |
#pragma warning( disable : 4146 ) |
#endif |
return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) ); |
#if defined(_MSC_VER) |
#pragma warning( pop ) |
#endif |
} |
/** Check whether a size is out of bounds, without branches. |
* |
* This is equivalent to `size > max`, but is likely to be compiled to |
* to code using bitwise operation rather than a branch. |
* |
* \param size Size to check. |
* \param max Maximum desired value for \p size. |
* \return \c 0 if `size <= max`. |
* \return \c 1 if `size > max`. |
*/ |
static unsigned size_greater_than( size_t size, size_t max ) |
{ |
/* Return the sign bit (1 for negative) of (max - size). */ |
return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) ); |
} |
/** Choose between two integer values, without branches. |
* |
* This is equivalent to `cond ? if1 : if0`, but is likely to be compiled |
* to code using bitwise operation rather than a branch. |
* |
* \param cond Condition to test. |
* \param if1 Value to use if \p cond is nonzero. |
* \param if0 Value to use if \p cond is zero. |
* \return \c if1 if \p cond is nonzero, otherwise \c if0. |
*/ |
static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 ) |
{ |
unsigned mask = all_or_nothing_int( cond ); |
return( ( mask & if1 ) | (~mask & if0 ) ); |
} |
/** Shift some data towards the left inside a buffer without leaking |
* the length of the data through side channels. |
* |
* `mem_move_to_left(start, total, offset)` is functionally equivalent to |
* ``` |
* memmove(start, start + offset, total - offset); |
* memset(start + offset, 0, total - offset); |
* ``` |
* but it strives to use a memory access pattern (and thus total timing) |
* that does not depend on \p offset. This timing independence comes at |
* the expense of performance. |
* |
* \param start Pointer to the start of the buffer. |
* \param total Total size of the buffer. |
* \param offset Offset from which to copy \p total - \p offset bytes. |
*/ |
static void mem_move_to_left( void *start, |
size_t total, |
size_t offset ) |
{ |
volatile unsigned char *buf = start; |
size_t i, n; |
if( total == 0 ) |
return; |
for( i = 0; i < total; i++ ) |
{ |
unsigned no_op = size_greater_than( total - offset, i ); |
/* The first `total - offset` passes are a no-op. The last |
* `offset` passes shift the data one byte to the left and |
* zero out the last byte. */ |
for( n = 0; n < total - 1; n++ ) |
{ |
unsigned char current = buf[n]; |
unsigned char next = buf[n+1]; |
buf[n] = if_int( no_op, current, next ); |
} |
buf[total-1] = if_int( no_op, buf[total-1], 0 ); |
} |
} |
/* |
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function |
*/ |
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len ) |
{ |
int ret; |
size_t ilen, i, plaintext_max_size; |
unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; |
/* The following variables take sensitive values: their value must |
* not leak into the observable behavior of the function other than |
* the designated outputs (output, olen, return value). Otherwise |
* this would open the execution of the function to |
* side-channel-based variants of the Bleichenbacher padding oracle |
* attack. Potential side channels include overall timing, memory |
* access patterns (especially visible to an adversary who has access |
* to a shared memory cache), and branches (especially visible to |
* an adversary who has access to a shared code cache or to a shared |
* branch predictor). */ |
size_t pad_count = 0; |
unsigned bad = 0; |
unsigned char pad_done = 0; |
size_t plaintext_size = 0; |
unsigned output_too_large; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
RSA_VALIDATE_RET( olen != NULL ); |
ilen = ctx->len; |
plaintext_max_size = ( output_max_len > ilen - 11 ? |
ilen - 11 : |
output_max_len ); |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( ilen < 16 || ilen > sizeof( buf ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
ret = ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, input, buf ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); |
if( ret != 0 ) |
goto cleanup; |
/* Check and get padding length in constant time and constant |
* memory trace. The first byte must be 0. */ |
bad |= buf[0]; |
if( mode == MBEDTLS_RSA_PRIVATE ) |
{ |
/* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00 |
* where PS must be at least 8 nonzero bytes. */ |
bad |= buf[1] ^ MBEDTLS_RSA_CRYPT; |
/* Read the whole buffer. Set pad_done to nonzero if we find |
* the 0x00 byte and remember the padding length in pad_count. */ |
for( i = 2; i < ilen; i++ ) |
{ |
pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1; |
pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; |
} |
} |
else |
{ |
/* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00 |
* where PS must be at least 8 bytes with the value 0xFF. */ |
bad |= buf[1] ^ MBEDTLS_RSA_SIGN; |
/* Read the whole buffer. Set pad_done to nonzero if we find |
* the 0x00 byte and remember the padding length in pad_count. |
* If there's a non-0xff byte in the padding, the padding is bad. */ |
for( i = 2; i < ilen; i++ ) |
{ |
pad_done |= if_int( buf[i], 0, 1 ); |
pad_count += if_int( pad_done, 0, 1 ); |
bad |= if_int( pad_done, 0, buf[i] ^ 0xFF ); |
} |
} |
/* If pad_done is still zero, there's no data, only unfinished padding. */ |
bad |= if_int( pad_done, 0, 1 ); |
/* There must be at least 8 bytes of padding. */ |
bad |= size_greater_than( 8, pad_count ); |
/* If the padding is valid, set plaintext_size to the number of |
* remaining bytes after stripping the padding. If the padding |
* is invalid, avoid leaking this fact through the size of the |
* output: use the maximum message size that fits in the output |
* buffer. Do it without branches to avoid leaking the padding |
* validity through timing. RSA keys are small enough that all the |
* size_t values involved fit in unsigned int. */ |
plaintext_size = if_int( bad, |
(unsigned) plaintext_max_size, |
(unsigned) ( ilen - pad_count - 3 ) ); |
/* Set output_too_large to 0 if the plaintext fits in the output |
* buffer and to 1 otherwise. */ |
output_too_large = size_greater_than( plaintext_size, |
plaintext_max_size ); |
/* Set ret without branches to avoid timing attacks. Return: |
* - INVALID_PADDING if the padding is bad (bad != 0). |
* - OUTPUT_TOO_LARGE if the padding is good but the decrypted |
* plaintext does not fit in the output buffer. |
* - 0 if the padding is correct. */ |
ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING, |
if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE, |
0 ) ); |
/* If the padding is bad or the plaintext is too large, zero the |
* data that we're about to copy to the output buffer. |
* We need to copy the same amount of data |
* from the same buffer whether the padding is good or not to |
* avoid leaking the padding validity through overall timing or |
* through memory or cache access patterns. */ |
bad = all_or_nothing_int( bad | output_too_large ); |
for( i = 11; i < ilen; i++ ) |
buf[i] &= ~bad; |
/* If the plaintext is too large, truncate it to the buffer size. |
* Copy anyway to avoid revealing the length through timing, because |
* revealing the length is as bad as revealing the padding validity |
* for a Bleichenbacher attack. */ |
plaintext_size = if_int( output_too_large, |
(unsigned) plaintext_max_size, |
(unsigned) plaintext_size ); |
/* Move the plaintext to the leftmost position where it can start in |
* the working buffer, i.e. make it start plaintext_max_size from |
* the end of the buffer. Do this with a memory access trace that |
* does not depend on the plaintext size. After this move, the |
* starting location of the plaintext is no longer sensitive |
* information. */ |
mem_move_to_left( buf + ilen - plaintext_max_size, |
plaintext_max_size, |
plaintext_max_size - plaintext_size ); |
/* Finally copy the decrypted plaintext plus trailing zeros |
* into the output buffer. */ |
memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size ); |
/* Report the amount of data we copied to the output buffer. In case |
* of errors (bad padding or output too large), the value of *olen |
* when this function returns is not specified. Making it equivalent |
* to the good case limits the risks of leaking the padding validity. */ |
*olen = plaintext_size; |
cleanup: |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS1_V15 */ |
/* |
* Do an RSA operation, then remove the message padding |
*/ |
int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, size_t *olen, |
const unsigned char *input, |
unsigned char *output, |
size_t output_max_len) |
{ |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL ); |
RSA_VALIDATE_RET( input != NULL ); |
RSA_VALIDATE_RET( olen != NULL ); |
switch( ctx->padding ) |
{ |
#if defined(MBEDTLS_PKCS1_V15) |
case MBEDTLS_RSA_PKCS_V15: |
return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen, |
input, output, output_max_len ); |
#endif |
#if defined(MBEDTLS_PKCS1_V21) |
case MBEDTLS_RSA_PKCS_V21: |
return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0, |
olen, input, output, |
output_max_len ); |
#endif |
default: |
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); |
} |
} |
#if defined(MBEDTLS_PKCS1_V21) |
/* |
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function |
*/ |
int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ) |
{ |
size_t olen; |
unsigned char *p = sig; |
unsigned char salt[MBEDTLS_MD_MAX_SIZE]; |
size_t slen, min_slen, hlen, offset = 0; |
int ret; |
size_t msb; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
RSA_VALIDATE_RET( sig != NULL ); |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( f_rng == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
olen = ctx->len; |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
/* Gather length of hash to sign */ |
md_info = mbedtls_md_info_from_type( md_alg ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hashlen = mbedtls_md_get_size( md_info ); |
} |
md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hlen = mbedtls_md_get_size( md_info ); |
/* Calculate the largest possible salt length. Normally this is the hash |
* length, which is the maximum length the salt can have. If there is not |
* enough room, use the maximum salt length that fits. The constraint is |
* that the hash length plus the salt length plus 2 bytes must be at most |
* the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 |
* (PKCS#1 v2.2) §9.1.1 step 3. */ |
min_slen = hlen - 2; |
if( olen < hlen + min_slen + 2 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
else if( olen >= hlen + hlen + 2 ) |
slen = hlen; |
else |
slen = olen - hlen - 2; |
memset( sig, 0, olen ); |
/* Generate salt of length slen */ |
if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) |
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); |
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */ |
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; |
p += olen - hlen - slen - 2; |
*p++ = 0x01; |
memcpy( p, salt, slen ); |
p += slen; |
mbedtls_md_init( &md_ctx ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) |
goto exit; |
/* Generate H = Hash( M' ) */ |
if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 ) |
goto exit; |
/* Compensate for boundary condition when applying mask */ |
if( msb % 8 == 0 ) |
offset = 1; |
/* maskedDB: Apply dbMask to DB */ |
if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, |
&md_ctx ) ) != 0 ) |
goto exit; |
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; |
sig[0] &= 0xFF >> ( olen * 8 - msb ); |
p += hlen; |
*p++ = 0xBC; |
mbedtls_platform_zeroize( salt, sizeof( salt ) ); |
exit: |
mbedtls_md_free( &md_ctx ); |
if( ret != 0 ) |
return( ret ); |
return( ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, sig, sig ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) ); |
} |
#endif /* MBEDTLS_PKCS1_V21 */ |
#if defined(MBEDTLS_PKCS1_V15) |
/* |
* Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function |
*/ |
/* Construct a PKCS v1.5 encoding of a hashed message |
* |
* This is used both for signature generation and verification. |
* |
* Parameters: |
* - md_alg: Identifies the hash algorithm used to generate the given hash; |
* MBEDTLS_MD_NONE if raw data is signed. |
* - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE. |
* - hash: Buffer containing the hashed message or the raw data. |
* - dst_len: Length of the encoded message. |
* - dst: Buffer to hold the encoded message. |
* |
* Assumptions: |
* - hash has size hashlen if md_alg == MBEDTLS_MD_NONE. |
* - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE. |
* - dst points to a buffer of size at least dst_len. |
* |
*/ |
static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
size_t dst_len, |
unsigned char *dst ) |
{ |
size_t oid_size = 0; |
size_t nb_pad = dst_len; |
unsigned char *p = dst; |
const char *oid = NULL; |
/* Are we signing hashed or raw data? */ |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hashlen = mbedtls_md_get_size( md_info ); |
/* Double-check that 8 + hashlen + oid_size can be used as a |
* 1-byte ASN.1 length encoding and that there's no overflow. */ |
if( 8 + hashlen + oid_size >= 0x80 || |
10 + hashlen < hashlen || |
10 + hashlen + oid_size < 10 + hashlen ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* |
* Static bounds check: |
* - Need 10 bytes for five tag-length pairs. |
* (Insist on 1-byte length encodings to protect against variants of |
* Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) |
* - Need hashlen bytes for hash |
* - Need oid_size bytes for hash alg OID. |
*/ |
if( nb_pad < 10 + hashlen + oid_size ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
nb_pad -= 10 + hashlen + oid_size; |
} |
else |
{ |
if( nb_pad < hashlen ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
nb_pad -= hashlen; |
} |
/* Need space for signature header and padding delimiter (3 bytes), |
* and 8 bytes for the minimal padding */ |
if( nb_pad < 3 + 8 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
nb_pad -= 3; |
/* Now nb_pad is the amount of memory to be filled |
* with padding, and at least 8 bytes long. */ |
/* Write signature header and padding */ |
*p++ = 0; |
*p++ = MBEDTLS_RSA_SIGN; |
memset( p, 0xFF, nb_pad ); |
p += nb_pad; |
*p++ = 0; |
/* Are we signing raw data? */ |
if( md_alg == MBEDTLS_MD_NONE ) |
{ |
memcpy( p, hash, hashlen ); |
return( 0 ); |
} |
/* Signing hashed data, add corresponding ASN.1 structure |
* |
* DigestInfo ::= SEQUENCE { |
* digestAlgorithm DigestAlgorithmIdentifier, |
* digest Digest } |
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier |
* Digest ::= OCTET STRING |
* |
* Schematic: |
* TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] |
* TAG-NULL + LEN [ NULL ] ] |
* TAG-OCTET + LEN [ HASH ] ] |
*/ |
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
*p++ = (unsigned char)( 0x08 + oid_size + hashlen ); |
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; |
*p++ = (unsigned char)( 0x04 + oid_size ); |
*p++ = MBEDTLS_ASN1_OID; |
*p++ = (unsigned char) oid_size; |
memcpy( p, oid, oid_size ); |
p += oid_size; |
*p++ = MBEDTLS_ASN1_NULL; |
*p++ = 0x00; |
*p++ = MBEDTLS_ASN1_OCTET_STRING; |
*p++ = (unsigned char) hashlen; |
memcpy( p, hash, hashlen ); |
p += hashlen; |
/* Just a sanity-check, should be automatic |
* after the initial bounds check. */ |
if( p != dst + dst_len ) |
{ |
mbedtls_platform_zeroize( dst, dst_len ); |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
} |
return( 0 ); |
} |
/* |
* Do an RSA operation to sign the message digest |
*/ |
int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ) |
{ |
int ret; |
unsigned char *sig_try = NULL, *verif = NULL; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
RSA_VALIDATE_RET( sig != NULL ); |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* |
* Prepare PKCS1-v1.5 encoding (padding and hash identifier) |
*/ |
if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, |
ctx->len, sig ) ) != 0 ) |
return( ret ); |
/* |
* Call respective RSA primitive |
*/ |
if( mode == MBEDTLS_RSA_PUBLIC ) |
{ |
/* Skip verification on a public key operation */ |
return( mbedtls_rsa_public( ctx, sig, sig ) ); |
} |
/* Private key operation |
* |
* In order to prevent Lenstra's attack, make the signature in a |
* temporary buffer and check it before returning it. |
*/ |
sig_try = mbedtls_calloc( 1, ctx->len ); |
if( sig_try == NULL ) |
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); |
verif = mbedtls_calloc( 1, ctx->len ); |
if( verif == NULL ) |
{ |
mbedtls_free( sig_try ); |
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); |
} |
MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) ); |
if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; |
goto cleanup; |
} |
memcpy( sig, sig_try, ctx->len ); |
cleanup: |
mbedtls_free( sig_try ); |
mbedtls_free( verif ); |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS1_V15 */ |
/* |
* Do an RSA operation to sign the message digest |
*/ |
int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
unsigned char *sig ) |
{ |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
RSA_VALIDATE_RET( sig != NULL ); |
switch( ctx->padding ) |
{ |
#if defined(MBEDTLS_PKCS1_V15) |
case MBEDTLS_RSA_PKCS_V15: |
return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg, |
hashlen, hash, sig ); |
#endif |
#if defined(MBEDTLS_PKCS1_V21) |
case MBEDTLS_RSA_PKCS_V21: |
return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg, |
hashlen, hash, sig ); |
#endif |
default: |
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); |
} |
} |
#if defined(MBEDTLS_PKCS1_V21) |
/* |
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function |
*/ |
int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
mbedtls_md_type_t mgf1_hash_id, |
int expected_salt_len, |
const unsigned char *sig ) |
{ |
int ret; |
size_t siglen; |
unsigned char *p; |
unsigned char *hash_start; |
unsigned char result[MBEDTLS_MD_MAX_SIZE]; |
unsigned char zeros[8]; |
unsigned int hlen; |
size_t observed_salt_len, msb; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( sig != NULL ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
siglen = ctx->len; |
if( siglen < 16 || siglen > sizeof( buf ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
ret = ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, sig, buf ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf ); |
if( ret != 0 ) |
return( ret ); |
p = buf; |
if( buf[siglen - 1] != 0xBC ) |
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
/* Gather length of hash to sign */ |
md_info = mbedtls_md_info_from_type( md_alg ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hashlen = mbedtls_md_get_size( md_info ); |
} |
md_info = mbedtls_md_info_from_type( mgf1_hash_id ); |
if( md_info == NULL ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hlen = mbedtls_md_get_size( md_info ); |
memset( zeros, 0, 8 ); |
/* |
* Note: EMSA-PSS verification is over the length of N - 1 bits |
*/ |
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; |
if( buf[0] >> ( 8 - siglen * 8 + msb ) ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* Compensate for boundary condition when applying mask */ |
if( msb % 8 == 0 ) |
{ |
p++; |
siglen -= 1; |
} |
if( siglen < hlen + 2 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
hash_start = p + siglen - hlen - 1; |
mbedtls_md_init( &md_ctx ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) |
goto exit; |
ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx ); |
if( ret != 0 ) |
goto exit; |
buf[0] &= 0xFF >> ( siglen * 8 - msb ); |
while( p < hash_start - 1 && *p == 0 ) |
p++; |
if( *p++ != 0x01 ) |
{ |
ret = MBEDTLS_ERR_RSA_INVALID_PADDING; |
goto exit; |
} |
observed_salt_len = hash_start - p; |
if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && |
observed_salt_len != (size_t) expected_salt_len ) |
{ |
ret = MBEDTLS_ERR_RSA_INVALID_PADDING; |
goto exit; |
} |
/* |
* Generate H = Hash( M' ) |
*/ |
ret = mbedtls_md_starts( &md_ctx ); |
if ( ret != 0 ) |
goto exit; |
ret = mbedtls_md_update( &md_ctx, zeros, 8 ); |
if ( ret != 0 ) |
goto exit; |
ret = mbedtls_md_update( &md_ctx, hash, hashlen ); |
if ( ret != 0 ) |
goto exit; |
ret = mbedtls_md_update( &md_ctx, p, observed_salt_len ); |
if ( ret != 0 ) |
goto exit; |
ret = mbedtls_md_finish( &md_ctx, result ); |
if ( ret != 0 ) |
goto exit; |
if( memcmp( hash_start, result, hlen ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; |
goto exit; |
} |
exit: |
mbedtls_md_free( &md_ctx ); |
return( ret ); |
} |
/* |
* Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function |
*/ |
int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
const unsigned char *sig ) |
{ |
mbedtls_md_type_t mgf1_hash_id; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( sig != NULL ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE ) |
? (mbedtls_md_type_t) ctx->hash_id |
: md_alg; |
return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, |
md_alg, hashlen, hash, |
mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY, |
sig ) ); |
} |
#endif /* MBEDTLS_PKCS1_V21 */ |
#if defined(MBEDTLS_PKCS1_V15) |
/* |
* Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function |
*/ |
int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
const unsigned char *sig ) |
{ |
int ret = 0; |
size_t sig_len; |
unsigned char *encoded = NULL, *encoded_expected = NULL; |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( sig != NULL ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
sig_len = ctx->len; |
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) |
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); |
/* |
* Prepare expected PKCS1 v1.5 encoding of hash. |
*/ |
if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL || |
( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL ) |
{ |
ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; |
goto cleanup; |
} |
if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len, |
encoded_expected ) ) != 0 ) |
goto cleanup; |
/* |
* Apply RSA primitive to get what should be PKCS1 encoded hash. |
*/ |
ret = ( mode == MBEDTLS_RSA_PUBLIC ) |
? mbedtls_rsa_public( ctx, sig, encoded ) |
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded ); |
if( ret != 0 ) |
goto cleanup; |
/* |
* Compare |
*/ |
if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected, |
sig_len ) ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; |
goto cleanup; |
} |
cleanup: |
if( encoded != NULL ) |
{ |
mbedtls_platform_zeroize( encoded, sig_len ); |
mbedtls_free( encoded ); |
} |
if( encoded_expected != NULL ) |
{ |
mbedtls_platform_zeroize( encoded_expected, sig_len ); |
mbedtls_free( encoded_expected ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_PKCS1_V15 */ |
/* |
* Do an RSA operation and check the message digest |
*/ |
int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng, |
int mode, |
mbedtls_md_type_t md_alg, |
unsigned int hashlen, |
const unsigned char *hash, |
const unsigned char *sig ) |
{ |
RSA_VALIDATE_RET( ctx != NULL ); |
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE || |
mode == MBEDTLS_RSA_PUBLIC ); |
RSA_VALIDATE_RET( sig != NULL ); |
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && |
hashlen == 0 ) || |
hash != NULL ); |
switch( ctx->padding ) |
{ |
#if defined(MBEDTLS_PKCS1_V15) |
case MBEDTLS_RSA_PKCS_V15: |
return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg, |
hashlen, hash, sig ); |
#endif |
#if defined(MBEDTLS_PKCS1_V21) |
case MBEDTLS_RSA_PKCS_V21: |
return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg, |
hashlen, hash, sig ); |
#endif |
default: |
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); |
} |
} |
/* |
* Copy the components of an RSA key |
*/ |
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) |
{ |
int ret; |
RSA_VALIDATE_RET( dst != NULL ); |
RSA_VALIDATE_RET( src != NULL ); |
dst->ver = src->ver; |
dst->len = src->len; |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) ); |
#if !defined(MBEDTLS_RSA_NO_CRT) |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) ); |
#endif |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) ); |
dst->padding = src->padding; |
dst->hash_id = src->hash_id; |
cleanup: |
if( ret != 0 ) |
mbedtls_rsa_free( dst ); |
return( ret ); |
} |
/* |
* Free the components of an RSA key |
*/ |
void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_mpi_free( &ctx->Vi ); |
mbedtls_mpi_free( &ctx->Vf ); |
mbedtls_mpi_free( &ctx->RN ); |
mbedtls_mpi_free( &ctx->D ); |
mbedtls_mpi_free( &ctx->Q ); |
mbedtls_mpi_free( &ctx->P ); |
mbedtls_mpi_free( &ctx->E ); |
mbedtls_mpi_free( &ctx->N ); |
#if !defined(MBEDTLS_RSA_NO_CRT) |
mbedtls_mpi_free( &ctx->RQ ); |
mbedtls_mpi_free( &ctx->RP ); |
mbedtls_mpi_free( &ctx->QP ); |
mbedtls_mpi_free( &ctx->DQ ); |
mbedtls_mpi_free( &ctx->DP ); |
#endif /* MBEDTLS_RSA_NO_CRT */ |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &ctx->mutex ); |
#endif |
} |
#endif /* !MBEDTLS_RSA_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
#include "mbedtls/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 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" |
#if defined(MBEDTLS_PKCS1_V15) |
static int myrand( void *rng_state, unsigned char *output, size_t len ) |
{ |
#if !defined(__OpenBSD__) |
size_t i; |
if( rng_state != NULL ) |
rng_state = NULL; |
for( i = 0; i < len; ++i ) |
output[i] = rand(); |
#else |
if( rng_state != NULL ) |
rng_state = NULL; |
arc4random_buf( output, len ); |
#endif /* !OpenBSD */ |
return( 0 ); |
} |
#endif /* MBEDTLS_PKCS1_V15 */ |
/* |
* Checkup routine |
*/ |
int mbedtls_rsa_self_test( int verbose ) |
{ |
int ret = 0; |
#if defined(MBEDTLS_PKCS1_V15) |
size_t len; |
mbedtls_rsa_context rsa; |
unsigned char rsa_plaintext[PT_LEN]; |
unsigned char rsa_decrypted[PT_LEN]; |
unsigned char rsa_ciphertext[KEY_LEN]; |
#if defined(MBEDTLS_SHA1_C) |
unsigned char sha1sum[20]; |
#endif |
mbedtls_mpi K; |
mbedtls_mpi_init( &K ); |
mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) ); |
MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) ); |
if( verbose != 0 ) |
mbedtls_printf( " RSA key validation: " ); |
if( mbedtls_rsa_check_pubkey( &rsa ) != 0 || |
mbedtls_rsa_check_privkey( &rsa ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n PKCS#1 encryption : " ); |
memcpy( rsa_plaintext, RSA_PT, PT_LEN ); |
if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, |
PT_LEN, rsa_plaintext, |
rsa_ciphertext ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n PKCS#1 decryption : " ); |
if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, |
&len, rsa_ciphertext, rsa_decrypted, |
sizeof(rsa_decrypted) ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
#if defined(MBEDTLS_SHA1_C) |
if( verbose != 0 ) |
mbedtls_printf( " PKCS#1 data sign : " ); |
if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
return( 1 ); |
} |
if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, |
MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, |
sha1sum, rsa_ciphertext ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n PKCS#1 sig. verify: " ); |
if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, |
MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, |
sha1sum, rsa_ciphertext ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
#endif /* MBEDTLS_SHA1_C */ |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
cleanup: |
mbedtls_mpi_free( &K ); |
mbedtls_rsa_free( &rsa ); |
#else /* MBEDTLS_PKCS1_V15 */ |
((void) verbose); |
#endif /* MBEDTLS_PKCS1_V15 */ |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_RSA_C */ |
/programs/develop/libraries/kos_mbedtls/library/rsa_internal.c |
---|
0,0 → 1,494 |
/* |
* Helper functions for the RSA module |
* |
* Copyright (C) 2006-2017, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
* |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_RSA_C) |
#include "mbedtls/rsa.h" |
#include "mbedtls/bignum.h" |
#include "mbedtls/rsa_internal.h" |
/* |
* Compute RSA prime factors from public and private exponents |
* |
* Summary of algorithm: |
* Setting F := lcm(P-1,Q-1), the idea is as follows: |
* |
* (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2) |
* is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the |
* square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four |
* possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1) |
* or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime |
* factors of N. |
* |
* (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same |
* construction still applies since (-)^K is the identity on the set of |
* roots of 1 in Z/NZ. |
* |
* The public and private key primitives (-)^E and (-)^D are mutually inverse |
* bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e. |
* if and only if DE - 1 is a multiple of F, say DE - 1 = F * L. |
* Splitting L = 2^t * K with K odd, we have |
* |
* DE - 1 = FL = (F/2) * (2^(t+1)) * K, |
* |
* so (F / 2) * K is among the numbers |
* |
* (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord |
* |
* where ord is the order of 2 in (DE - 1). |
* We can therefore iterate through these numbers apply the construction |
* of (a) and (b) above to attempt to factor N. |
* |
*/ |
int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, |
mbedtls_mpi const *E, mbedtls_mpi const *D, |
mbedtls_mpi *P, mbedtls_mpi *Q ) |
{ |
int ret = 0; |
uint16_t attempt; /* Number of current attempt */ |
uint16_t iter; /* Number of squares computed in the current attempt */ |
uint16_t order; /* Order of 2 in DE - 1 */ |
mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */ |
mbedtls_mpi K; /* Temporary holding the current candidate */ |
const unsigned char primes[] = { 2, |
3, 5, 7, 11, 13, 17, 19, 23, |
29, 31, 37, 41, 43, 47, 53, 59, |
61, 67, 71, 73, 79, 83, 89, 97, |
101, 103, 107, 109, 113, 127, 131, 137, |
139, 149, 151, 157, 163, 167, 173, 179, |
181, 191, 193, 197, 199, 211, 223, 227, |
229, 233, 239, 241, 251 |
}; |
const size_t num_primes = sizeof( primes ) / sizeof( *primes ); |
if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || |
mbedtls_mpi_cmp_int( D, 1 ) <= 0 || |
mbedtls_mpi_cmp_mpi( D, N ) >= 0 || |
mbedtls_mpi_cmp_int( E, 1 ) <= 0 || |
mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) |
{ |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
} |
/* |
* Initializations and temporary changes |
*/ |
mbedtls_mpi_init( &K ); |
mbedtls_mpi_init( &T ); |
/* T := DE - 1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D, E ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) ); |
if( ( order = (uint16_t) mbedtls_mpi_lsb( &T ) ) == 0 ) |
{ |
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
goto cleanup; |
} |
/* After this operation, T holds the largest odd divisor of DE - 1. */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) ); |
/* |
* Actual work |
*/ |
/* Skip trying 2 if N == 1 mod 8 */ |
attempt = 0; |
if( N->p[0] % 8 == 1 ) |
attempt = 1; |
for( ; attempt < num_primes; ++attempt ) |
{ |
mbedtls_mpi_lset( &K, primes[attempt] ); |
/* Check if gcd(K,N) = 1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); |
if( mbedtls_mpi_cmp_int( P, 1 ) != 0 ) |
continue; |
/* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ... |
* and check whether they have nontrivial GCD with N. */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N, |
Q /* temporarily use Q for storing Montgomery |
* multiplication helper values */ ) ); |
for( iter = 1; iter <= order; ++iter ) |
{ |
/* If we reach 1 prematurely, there's no point |
* in continuing to square K */ |
if( mbedtls_mpi_cmp_int( &K, 1 ) == 0 ) |
break; |
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) ); |
if( mbedtls_mpi_cmp_int( P, 1 ) == 1 && |
mbedtls_mpi_cmp_mpi( P, N ) == -1 ) |
{ |
/* |
* Have found a nontrivial divisor P of N. |
* Set Q := N / P. |
*/ |
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) ); |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) ); |
} |
/* |
* If we get here, then either we prematurely aborted the loop because |
* we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must |
* be 1 if D,E,N were consistent. |
* Check if that's the case and abort if not, to avoid very long, |
* yet eventually failing, computations if N,D,E were not sane. |
*/ |
if( mbedtls_mpi_cmp_int( &K, 1 ) != 0 ) |
{ |
break; |
} |
} |
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
cleanup: |
mbedtls_mpi_free( &K ); |
mbedtls_mpi_free( &T ); |
return( ret ); |
} |
/* |
* Given P, Q and the public exponent E, deduce D. |
* This is essentially a modular inversion. |
*/ |
int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P, |
mbedtls_mpi const *Q, |
mbedtls_mpi const *E, |
mbedtls_mpi *D ) |
{ |
int ret = 0; |
mbedtls_mpi K, L; |
if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 ) |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || |
mbedtls_mpi_cmp_int( Q, 1 ) <= 0 || |
mbedtls_mpi_cmp_int( E, 0 ) == 0 ) |
{ |
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); |
} |
mbedtls_mpi_init( &K ); |
mbedtls_mpi_init( &L ); |
/* Temporarily put K := P-1 and L := Q-1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); |
/* Temporarily put D := gcd(P-1, Q-1) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) ); |
/* K := LCM(P-1, Q-1) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) ); |
/* Compute modular inverse of E in LCM(P-1, Q-1) */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) ); |
cleanup: |
mbedtls_mpi_free( &K ); |
mbedtls_mpi_free( &L ); |
return( ret ); |
} |
/* |
* Check that RSA CRT parameters are in accordance with core parameters. |
*/ |
int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, |
const mbedtls_mpi *D, const mbedtls_mpi *DP, |
const mbedtls_mpi *DQ, const mbedtls_mpi *QP ) |
{ |
int ret = 0; |
mbedtls_mpi K, L; |
mbedtls_mpi_init( &K ); |
mbedtls_mpi_init( &L ); |
/* Check that DP - D == 0 mod P - 1 */ |
if( DP != NULL ) |
{ |
if( P == NULL ) |
{ |
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); |
if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
} |
/* Check that DQ - D == 0 mod Q - 1 */ |
if( DQ != NULL ) |
{ |
if( Q == NULL ) |
{ |
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) ); |
if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
} |
/* Check that QP * Q - 1 == 0 mod P */ |
if( QP != NULL ) |
{ |
if( P == NULL || Q == NULL ) |
{ |
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
goto cleanup; |
} |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) ); |
if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
} |
cleanup: |
/* Wrap MPI error codes by RSA check failure error code */ |
if( ret != 0 && |
ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED && |
ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA ) |
{ |
ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
} |
mbedtls_mpi_free( &K ); |
mbedtls_mpi_free( &L ); |
return( ret ); |
} |
/* |
* Check that core RSA parameters are sane. |
*/ |
int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P, |
const mbedtls_mpi *Q, const mbedtls_mpi *D, |
const mbedtls_mpi *E, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret = 0; |
mbedtls_mpi K, L; |
mbedtls_mpi_init( &K ); |
mbedtls_mpi_init( &L ); |
/* |
* Step 1: If PRNG provided, check that P and Q are prime |
*/ |
#if defined(MBEDTLS_GENPRIME) |
/* |
* When generating keys, the strongest security we support aims for an error |
* rate of at most 2^-100 and we are aiming for the same certainty here as |
* well. |
*/ |
if( f_rng != NULL && P != NULL && |
( ret = mbedtls_mpi_is_prime_ext( P, 50, f_rng, p_rng ) ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
if( f_rng != NULL && Q != NULL && |
( ret = mbedtls_mpi_is_prime_ext( Q, 50, f_rng, p_rng ) ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
#else |
((void) f_rng); |
((void) p_rng); |
#endif /* MBEDTLS_GENPRIME */ |
/* |
* Step 2: Check that 1 < N = P * Q |
*/ |
if( P != NULL && Q != NULL && N != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) ); |
if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 || |
mbedtls_mpi_cmp_mpi( &K, N ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
} |
/* |
* Step 3: Check and 1 < D, E < N if present. |
*/ |
if( N != NULL && D != NULL && E != NULL ) |
{ |
if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 || |
mbedtls_mpi_cmp_int( E, 1 ) <= 0 || |
mbedtls_mpi_cmp_mpi( D, N ) >= 0 || |
mbedtls_mpi_cmp_mpi( E, N ) >= 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
} |
/* |
* Step 4: Check that D, E are inverse modulo P-1 and Q-1 |
*/ |
if( P != NULL && Q != NULL && D != NULL && E != NULL ) |
{ |
if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 || |
mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
/* Compute DE-1 mod P-1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); |
if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
/* Compute DE-1 mod Q-1 */ |
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) ); |
if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 ) |
{ |
ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
goto cleanup; |
} |
} |
cleanup: |
mbedtls_mpi_free( &K ); |
mbedtls_mpi_free( &L ); |
/* Wrap MPI error codes by RSA check failure error code */ |
if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) |
{ |
ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
} |
return( ret ); |
} |
int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q, |
const mbedtls_mpi *D, mbedtls_mpi *DP, |
mbedtls_mpi *DQ, mbedtls_mpi *QP ) |
{ |
int ret = 0; |
mbedtls_mpi K; |
mbedtls_mpi_init( &K ); |
/* DP = D mod P-1 */ |
if( DP != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) ); |
} |
/* DQ = D mod Q-1 */ |
if( DQ != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) ); |
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) ); |
} |
/* QP = Q^{-1} mod P */ |
if( QP != NULL ) |
{ |
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) ); |
} |
cleanup: |
mbedtls_mpi_free( &K ); |
return( ret ); |
} |
#endif /* MBEDTLS_RSA_C */ |
/programs/develop/libraries/kos_mbedtls/library/sha1.c |
---|
0,0 → 1,575 |
/* |
* FIPS-180-1 compliant SHA-1 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The SHA-1 standard was published by NIST in 1993. |
* |
* http://www.itl.nist.gov/fipspubs/fip180-1.htm |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SHA1_C) |
#include "mbedtls/sha1.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#define SHA1_VALIDATE_RET(cond) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) |
#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if !defined(MBEDTLS_SHA1_ALT) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_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 |
void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) |
{ |
SHA1_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); |
} |
void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); |
} |
void mbedtls_sha1_clone( mbedtls_sha1_context *dst, |
const mbedtls_sha1_context *src ) |
{ |
SHA1_VALIDATE( dst != NULL ); |
SHA1_VALIDATE( src != NULL ); |
*dst = *src; |
} |
/* |
* SHA-1 context setup |
*/ |
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) |
{ |
SHA1_VALIDATE_RET( ctx != NULL ); |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) |
{ |
mbedtls_sha1_starts_ret( ctx ); |
} |
#endif |
#if !defined(MBEDTLS_SHA1_PROCESS_ALT) |
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, |
const unsigned char data[64] ) |
{ |
uint32_t temp, W[16], A, B, C, D, E; |
SHA1_VALIDATE_RET( ctx != NULL ); |
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); |
GET_UINT32_BE( W[ 0], data, 0 ); |
GET_UINT32_BE( W[ 1], data, 4 ); |
GET_UINT32_BE( W[ 2], data, 8 ); |
GET_UINT32_BE( W[ 3], data, 12 ); |
GET_UINT32_BE( W[ 4], data, 16 ); |
GET_UINT32_BE( W[ 5], data, 20 ); |
GET_UINT32_BE( W[ 6], data, 24 ); |
GET_UINT32_BE( W[ 7], data, 28 ); |
GET_UINT32_BE( W[ 8], data, 32 ); |
GET_UINT32_BE( W[ 9], data, 36 ); |
GET_UINT32_BE( W[10], data, 40 ); |
GET_UINT32_BE( W[11], data, 44 ); |
GET_UINT32_BE( W[12], data, 48 ); |
GET_UINT32_BE( W[13], data, 52 ); |
GET_UINT32_BE( W[14], data, 56 ); |
GET_UINT32_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) \ |
do \ |
{ \ |
(e) += S((a),5) + F((b),(c),(d)) + K + (x); \ |
(b) = S((b),30); \ |
} while( 0 ) |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, |
const unsigned char data[64] ) |
{ |
mbedtls_internal_sha1_process( ctx, data ); |
} |
#endif |
#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ |
/* |
* SHA-1 process buffer |
*/ |
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
uint32_t left; |
SHA1_VALIDATE_RET( ctx != NULL ); |
SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); |
if( ilen == 0 ) |
return( 0 ); |
left = ctx->total[0] & 0x3F; |
fill = 64 - left; |
ctx->total[0] += (uint32_t) ilen; |
ctx->total[0] &= 0xFFFFFFFF; |
if( ctx->total[0] < (uint32_t) ilen ) |
ctx->total[1]++; |
if( left && ilen >= fill ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, fill ); |
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
input += fill; |
ilen -= fill; |
left = 0; |
} |
while( ilen >= 64 ) |
{ |
if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) |
return( ret ); |
input += 64; |
ilen -= 64; |
} |
if( ilen > 0 ) |
memcpy( (void *) (ctx->buffer + left), input, ilen ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_sha1_update_ret( ctx, input, ilen ); |
} |
#endif |
/* |
* SHA-1 final digest |
*/ |
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, |
unsigned char output[20] ) |
{ |
int ret; |
uint32_t used; |
uint32_t high, low; |
SHA1_VALIDATE_RET( ctx != NULL ); |
SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); |
/* |
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length |
*/ |
used = ctx->total[0] & 0x3F; |
ctx->buffer[used++] = 0x80; |
if( used <= 56 ) |
{ |
/* Enough room for padding + length in current block */ |
memset( ctx->buffer + used, 0, 56 - used ); |
} |
else |
{ |
/* We'll need an extra block */ |
memset( ctx->buffer + used, 0, 64 - used ); |
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
memset( ctx->buffer, 0, 56 ); |
} |
/* |
* Add message length |
*/ |
high = ( ctx->total[0] >> 29 ) |
| ( ctx->total[1] << 3 ); |
low = ( ctx->total[0] << 3 ); |
PUT_UINT32_BE( high, ctx->buffer, 56 ); |
PUT_UINT32_BE( low, ctx->buffer, 60 ); |
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
/* |
* Output final state |
*/ |
PUT_UINT32_BE( ctx->state[0], output, 0 ); |
PUT_UINT32_BE( ctx->state[1], output, 4 ); |
PUT_UINT32_BE( ctx->state[2], output, 8 ); |
PUT_UINT32_BE( ctx->state[3], output, 12 ); |
PUT_UINT32_BE( ctx->state[4], output, 16 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, |
unsigned char output[20] ) |
{ |
mbedtls_sha1_finish_ret( ctx, output ); |
} |
#endif |
#endif /* !MBEDTLS_SHA1_ALT */ |
/* |
* output = SHA-1( input buffer ) |
*/ |
int mbedtls_sha1_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ) |
{ |
int ret; |
mbedtls_sha1_context ctx; |
SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); |
SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); |
mbedtls_sha1_init( &ctx ); |
if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_sha1_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha1( const unsigned char *input, |
size_t ilen, |
unsigned char output[20] ) |
{ |
mbedtls_sha1_ret( input, ilen, output ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* FIPS-180-1 test vectors |
*/ |
static const unsigned char sha1_test_buf[3][57] = |
{ |
{ "abc" }, |
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, |
{ "" } |
}; |
static const size_t 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 } |
}; |
/* |
* Checkup routine |
*/ |
int mbedtls_sha1_self_test( int verbose ) |
{ |
int i, j, buflen, ret = 0; |
unsigned char buf[1024]; |
unsigned char sha1sum[20]; |
mbedtls_sha1_context ctx; |
mbedtls_sha1_init( &ctx ); |
/* |
* SHA-1 |
*/ |
for( i = 0; i < 3; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); |
if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) |
goto fail; |
if( i == 2 ) |
{ |
memset( buf, 'a', buflen = 1000 ); |
for( j = 0; j < 1000; j++ ) |
{ |
ret = mbedtls_sha1_update_ret( &ctx, buf, buflen ); |
if( ret != 0 ) |
goto fail; |
} |
} |
else |
{ |
ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i], |
sha1_test_buflen[i] ); |
if( ret != 0 ) |
goto fail; |
} |
if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 ) |
goto fail; |
if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
goto exit; |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
exit: |
mbedtls_sha1_free( &ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_SHA1_C */ |
/programs/develop/libraries/kos_mbedtls/library/sha256.c |
---|
0,0 → 1,588 |
/* |
* FIPS-180-2 compliant SHA-256 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The SHA-256 Secure Hash Standard was published by NIST in 2002. |
* |
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SHA256_C) |
#include "mbedtls/sha256.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_printf printf |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#define SHA256_VALIDATE_RET(cond) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA ) |
#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if !defined(MBEDTLS_SHA256_ALT) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
do { \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} while( 0 ) |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_BE(n,b,i) \ |
do { \ |
(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) ); \ |
} while( 0 ) |
#endif |
void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) |
{ |
SHA256_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); |
} |
void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); |
} |
void mbedtls_sha256_clone( mbedtls_sha256_context *dst, |
const mbedtls_sha256_context *src ) |
{ |
SHA256_VALIDATE( dst != NULL ); |
SHA256_VALIDATE( src != NULL ); |
*dst = *src; |
} |
/* |
* SHA-256 context setup |
*/ |
int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) |
{ |
SHA256_VALIDATE_RET( ctx != NULL ); |
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, |
int is224 ) |
{ |
mbedtls_sha256_starts_ret( ctx, is224 ); |
} |
#endif |
#if !defined(MBEDTLS_SHA256_PROCESS_ALT) |
static const uint32_t K[] = |
{ |
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, |
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, |
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, |
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, |
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, |
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, |
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, |
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, |
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, |
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, |
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, |
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, |
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, |
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, |
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, |
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, |
}; |
#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) \ |
do \ |
{ \ |
temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ |
temp2 = S2(a) + F0((a),(b),(c)); \ |
(d) += temp1; (h) = temp1 + temp2; \ |
} while( 0 ) |
int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, |
const unsigned char data[64] ) |
{ |
uint32_t temp1, temp2, W[64]; |
uint32_t A[8]; |
unsigned int i; |
SHA256_VALIDATE_RET( ctx != NULL ); |
SHA256_VALIDATE_RET( (const unsigned char *)data != NULL ); |
for( i = 0; i < 8; i++ ) |
A[i] = ctx->state[i]; |
#if defined(MBEDTLS_SHA256_SMALLER) |
for( i = 0; i < 64; i++ ) |
{ |
if( i < 16 ) |
GET_UINT32_BE( W[i], data, 4 * i ); |
else |
R( i ); |
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); |
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; |
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; |
} |
#else /* MBEDTLS_SHA256_SMALLER */ |
for( i = 0; i < 16; i++ ) |
GET_UINT32_BE( W[i], data, 4 * i ); |
for( i = 0; i < 16; i += 8 ) |
{ |
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); |
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] ); |
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] ); |
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] ); |
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] ); |
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); |
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); |
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); |
} |
for( i = 16; i < 64; i += 8 ) |
{ |
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] ); |
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] ); |
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] ); |
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] ); |
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] ); |
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); |
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); |
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); |
} |
#endif /* MBEDTLS_SHA256_SMALLER */ |
for( i = 0; i < 8; i++ ) |
ctx->state[i] += A[i]; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, |
const unsigned char data[64] ) |
{ |
mbedtls_internal_sha256_process( ctx, data ); |
} |
#endif |
#endif /* !MBEDTLS_SHA256_PROCESS_ALT */ |
/* |
* SHA-256 process buffer |
*/ |
int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
uint32_t left; |
SHA256_VALIDATE_RET( ctx != NULL ); |
SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); |
if( ilen == 0 ) |
return( 0 ); |
left = ctx->total[0] & 0x3F; |
fill = 64 - left; |
ctx->total[0] += (uint32_t) ilen; |
ctx->total[0] &= 0xFFFFFFFF; |
if( ctx->total[0] < (uint32_t) ilen ) |
ctx->total[1]++; |
if( left && ilen >= fill ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, fill ); |
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
input += fill; |
ilen -= fill; |
left = 0; |
} |
while( ilen >= 64 ) |
{ |
if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) |
return( ret ); |
input += 64; |
ilen -= 64; |
} |
if( ilen > 0 ) |
memcpy( (void *) (ctx->buffer + left), input, ilen ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_sha256_update_ret( ctx, input, ilen ); |
} |
#endif |
/* |
* SHA-256 final digest |
*/ |
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, |
unsigned char output[32] ) |
{ |
int ret; |
uint32_t used; |
uint32_t high, low; |
SHA256_VALIDATE_RET( ctx != NULL ); |
SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); |
/* |
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length |
*/ |
used = ctx->total[0] & 0x3F; |
ctx->buffer[used++] = 0x80; |
if( used <= 56 ) |
{ |
/* Enough room for padding + length in current block */ |
memset( ctx->buffer + used, 0, 56 - used ); |
} |
else |
{ |
/* We'll need an extra block */ |
memset( ctx->buffer + used, 0, 64 - used ); |
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
memset( ctx->buffer, 0, 56 ); |
} |
/* |
* Add message length |
*/ |
high = ( ctx->total[0] >> 29 ) |
| ( ctx->total[1] << 3 ); |
low = ( ctx->total[0] << 3 ); |
PUT_UINT32_BE( high, ctx->buffer, 56 ); |
PUT_UINT32_BE( low, ctx->buffer, 60 ); |
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
/* |
* Output final state |
*/ |
PUT_UINT32_BE( ctx->state[0], output, 0 ); |
PUT_UINT32_BE( ctx->state[1], output, 4 ); |
PUT_UINT32_BE( ctx->state[2], output, 8 ); |
PUT_UINT32_BE( ctx->state[3], output, 12 ); |
PUT_UINT32_BE( ctx->state[4], output, 16 ); |
PUT_UINT32_BE( ctx->state[5], output, 20 ); |
PUT_UINT32_BE( ctx->state[6], output, 24 ); |
if( ctx->is224 == 0 ) |
PUT_UINT32_BE( ctx->state[7], output, 28 ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, |
unsigned char output[32] ) |
{ |
mbedtls_sha256_finish_ret( ctx, output ); |
} |
#endif |
#endif /* !MBEDTLS_SHA256_ALT */ |
/* |
* output = SHA-256( input buffer ) |
*/ |
int mbedtls_sha256_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[32], |
int is224 ) |
{ |
int ret; |
mbedtls_sha256_context ctx; |
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 ); |
SHA256_VALIDATE_RET( ilen == 0 || input != NULL ); |
SHA256_VALIDATE_RET( (unsigned char *)output != NULL ); |
mbedtls_sha256_init( &ctx ); |
if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_sha256_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha256( const unsigned char *input, |
size_t ilen, |
unsigned char output[32], |
int is224 ) |
{ |
mbedtls_sha256_ret( input, ilen, output, is224 ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* FIPS-180-2 test vectors |
*/ |
static const unsigned char sha256_test_buf[3][57] = |
{ |
{ "abc" }, |
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, |
{ "" } |
}; |
static const size_t sha256_test_buflen[3] = |
{ |
3, 56, 1000 |
}; |
static const unsigned char sha256_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 } |
}; |
/* |
* Checkup routine |
*/ |
int mbedtls_sha256_self_test( int verbose ) |
{ |
int i, j, k, buflen, ret = 0; |
unsigned char *buf; |
unsigned char sha256sum[32]; |
mbedtls_sha256_context ctx; |
buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); |
if( NULL == buf ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "Buffer allocation failed\n" ); |
return( 1 ); |
} |
mbedtls_sha256_init( &ctx ); |
for( i = 0; i < 6; i++ ) |
{ |
j = i % 3; |
k = i < 3; |
if( verbose != 0 ) |
mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); |
if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 ) |
goto fail; |
if( j == 2 ) |
{ |
memset( buf, 'a', buflen = 1000 ); |
for( j = 0; j < 1000; j++ ) |
{ |
ret = mbedtls_sha256_update_ret( &ctx, buf, buflen ); |
if( ret != 0 ) |
goto fail; |
} |
} |
else |
{ |
ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j], |
sha256_test_buflen[j] ); |
if( ret != 0 ) |
goto fail; |
} |
if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 ) |
goto fail; |
if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
goto exit; |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
exit: |
mbedtls_sha256_free( &ctx ); |
mbedtls_free( buf ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_SHA256_C */ |
/programs/develop/libraries/kos_mbedtls/library/sha512.c |
---|
0,0 → 1,638 |
/* |
* FIPS-180-2 compliant SHA-384/512 implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The SHA-512 Secure Hash Standard was published by NIST in 2002. |
* |
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SHA512_C) |
#include "mbedtls/sha512.h" |
#include "mbedtls/platform_util.h" |
#if defined(_MSC_VER) || defined(__WATCOMC__) |
#define UL64(x) x##ui64 |
#else |
#define UL64(x) x##ULL |
#endif |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_printf printf |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#define SHA512_VALIDATE_RET(cond) \ |
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA ) |
#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) |
#if !defined(MBEDTLS_SHA512_ALT) |
/* |
* 64-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT64_BE |
#define GET_UINT64_BE(n,b,i) \ |
{ \ |
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \ |
| ( (uint64_t) (b)[(i) + 1] << 48 ) \ |
| ( (uint64_t) (b)[(i) + 2] << 40 ) \ |
| ( (uint64_t) (b)[(i) + 3] << 32 ) \ |
| ( (uint64_t) (b)[(i) + 4] << 24 ) \ |
| ( (uint64_t) (b)[(i) + 5] << 16 ) \ |
| ( (uint64_t) (b)[(i) + 6] << 8 ) \ |
| ( (uint64_t) (b)[(i) + 7] ); \ |
} |
#endif /* GET_UINT64_BE */ |
#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 /* PUT_UINT64_BE */ |
void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) |
{ |
SHA512_VALIDATE( ctx != NULL ); |
memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); |
} |
void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); |
} |
void mbedtls_sha512_clone( mbedtls_sha512_context *dst, |
const mbedtls_sha512_context *src ) |
{ |
SHA512_VALIDATE( dst != NULL ); |
SHA512_VALIDATE( src != NULL ); |
*dst = *src; |
} |
/* |
* SHA-512 context setup |
*/ |
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) |
{ |
SHA512_VALIDATE_RET( ctx != NULL ); |
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, |
int is384 ) |
{ |
mbedtls_sha512_starts_ret( ctx, is384 ); |
} |
#endif |
#if !defined(MBEDTLS_SHA512_PROCESS_ALT) |
/* |
* Round constants |
*/ |
static const uint64_t 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) |
}; |
int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, |
const unsigned char data[128] ) |
{ |
int i; |
uint64_t temp1, temp2, W[80]; |
uint64_t A, B, C, D, E, F, G, H; |
SHA512_VALIDATE_RET( ctx != NULL ); |
SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); |
#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) \ |
do \ |
{ \ |
temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ |
temp2 = S2(a) + F0((a),(b),(c)); \ |
(d) += temp1; (h) = temp1 + temp2; \ |
} while( 0 ) |
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; |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha512_process( mbedtls_sha512_context *ctx, |
const unsigned char data[128] ) |
{ |
mbedtls_internal_sha512_process( ctx, data ); |
} |
#endif |
#endif /* !MBEDTLS_SHA512_PROCESS_ALT */ |
/* |
* SHA-512 process buffer |
*/ |
int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
int ret; |
size_t fill; |
unsigned int left; |
SHA512_VALIDATE_RET( ctx != NULL ); |
SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); |
if( ilen == 0 ) |
return( 0 ); |
left = (unsigned int) (ctx->total[0] & 0x7F); |
fill = 128 - left; |
ctx->total[0] += (uint64_t) ilen; |
if( ctx->total[0] < (uint64_t) ilen ) |
ctx->total[1]++; |
if( left && ilen >= fill ) |
{ |
memcpy( (void *) (ctx->buffer + left), input, fill ); |
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
input += fill; |
ilen -= fill; |
left = 0; |
} |
while( ilen >= 128 ) |
{ |
if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) |
return( ret ); |
input += 128; |
ilen -= 128; |
} |
if( ilen > 0 ) |
memcpy( (void *) (ctx->buffer + left), input, ilen ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha512_update( mbedtls_sha512_context *ctx, |
const unsigned char *input, |
size_t ilen ) |
{ |
mbedtls_sha512_update_ret( ctx, input, ilen ); |
} |
#endif |
/* |
* SHA-512 final digest |
*/ |
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, |
unsigned char output[64] ) |
{ |
int ret; |
unsigned used; |
uint64_t high, low; |
SHA512_VALIDATE_RET( ctx != NULL ); |
SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); |
/* |
* Add padding: 0x80 then 0x00 until 16 bytes remain for the length |
*/ |
used = ctx->total[0] & 0x7F; |
ctx->buffer[used++] = 0x80; |
if( used <= 112 ) |
{ |
/* Enough room for padding + length in current block */ |
memset( ctx->buffer + used, 0, 112 - used ); |
} |
else |
{ |
/* We'll need an extra block */ |
memset( ctx->buffer + used, 0, 128 - used ); |
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
memset( ctx->buffer, 0, 112 ); |
} |
/* |
* Add message length |
*/ |
high = ( ctx->total[0] >> 61 ) |
| ( ctx->total[1] << 3 ); |
low = ( ctx->total[0] << 3 ); |
PUT_UINT64_BE( high, ctx->buffer, 112 ); |
PUT_UINT64_BE( low, ctx->buffer, 120 ); |
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) |
return( ret ); |
/* |
* Output final state |
*/ |
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 ); |
} |
return( 0 ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, |
unsigned char output[64] ) |
{ |
mbedtls_sha512_finish_ret( ctx, output ); |
} |
#endif |
#endif /* !MBEDTLS_SHA512_ALT */ |
/* |
* output = SHA-512( input buffer ) |
*/ |
int mbedtls_sha512_ret( const unsigned char *input, |
size_t ilen, |
unsigned char output[64], |
int is384 ) |
{ |
int ret; |
mbedtls_sha512_context ctx; |
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 ); |
SHA512_VALIDATE_RET( ilen == 0 || input != NULL ); |
SHA512_VALIDATE_RET( (unsigned char *)output != NULL ); |
mbedtls_sha512_init( &ctx ); |
if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 ) |
goto exit; |
exit: |
mbedtls_sha512_free( &ctx ); |
return( ret ); |
} |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
void mbedtls_sha512( const unsigned char *input, |
size_t ilen, |
unsigned char output[64], |
int is384 ) |
{ |
mbedtls_sha512_ret( input, ilen, output, is384 ); |
} |
#endif |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* FIPS-180-2 test vectors |
*/ |
static const unsigned char sha512_test_buf[3][113] = |
{ |
{ "abc" }, |
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" |
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, |
{ "" } |
}; |
static const size_t sha512_test_buflen[3] = |
{ |
3, 112, 1000 |
}; |
static const unsigned char sha512_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 } |
}; |
/* |
* Checkup routine |
*/ |
int mbedtls_sha512_self_test( int verbose ) |
{ |
int i, j, k, buflen, ret = 0; |
unsigned char *buf; |
unsigned char sha512sum[64]; |
mbedtls_sha512_context ctx; |
buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); |
if( NULL == buf ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "Buffer allocation failed\n" ); |
return( 1 ); |
} |
mbedtls_sha512_init( &ctx ); |
for( i = 0; i < 6; i++ ) |
{ |
j = i % 3; |
k = i < 3; |
if( verbose != 0 ) |
mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); |
if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 ) |
goto fail; |
if( j == 2 ) |
{ |
memset( buf, 'a', buflen = 1000 ); |
for( j = 0; j < 1000; j++ ) |
{ |
ret = mbedtls_sha512_update_ret( &ctx, buf, buflen ); |
if( ret != 0 ) |
goto fail; |
} |
} |
else |
{ |
ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j], |
sha512_test_buflen[j] ); |
if( ret != 0 ) |
goto fail; |
} |
if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 ) |
goto fail; |
if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) |
{ |
ret = 1; |
goto fail; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
goto exit; |
fail: |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
exit: |
mbedtls_sha512_free( &ctx ); |
mbedtls_free( buf ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_SHA512_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_cache.c |
---|
0,0 → 1,329 |
/* |
* SSL session cache implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* These session callbacks use a simple chained list |
* to store and retrieve the session information. |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_CACHE_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/ssl_cache.h" |
#include <string.h> |
void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) |
{ |
memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); |
cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT; |
cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES; |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &cache->mutex ); |
#endif |
} |
int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) |
{ |
int ret = 1; |
#if defined(MBEDTLS_HAVE_TIME) |
mbedtls_time_t t = mbedtls_time( NULL ); |
#endif |
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; |
mbedtls_ssl_cache_entry *cur, *entry; |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) |
return( 1 ); |
#endif |
cur = cache->chain; |
entry = NULL; |
while( cur != NULL ) |
{ |
entry = cur; |
cur = cur->next; |
#if defined(MBEDTLS_HAVE_TIME) |
if( cache->timeout != 0 && |
(int) ( t - entry->timestamp ) > cache->timeout ) |
continue; |
#endif |
if( session->ciphersuite != entry->session.ciphersuite || |
session->compression != entry->session.compression || |
session->id_len != entry->session.id_len ) |
continue; |
if( memcmp( session->id, entry->session.id, |
entry->session.id_len ) != 0 ) |
continue; |
memcpy( session->master, entry->session.master, 48 ); |
session->verify_result = entry->session.verify_result; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/* |
* Restore peer certificate (without rest of the original chain) |
*/ |
if( entry->peer_cert.p != NULL ) |
{ |
if( ( session->peer_cert = mbedtls_calloc( 1, |
sizeof(mbedtls_x509_crt) ) ) == NULL ) |
{ |
ret = 1; |
goto exit; |
} |
mbedtls_x509_crt_init( session->peer_cert ); |
if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, |
entry->peer_cert.len ) != 0 ) |
{ |
mbedtls_free( session->peer_cert ); |
session->peer_cert = NULL; |
ret = 1; |
goto exit; |
} |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
ret = 0; |
goto exit; |
} |
exit: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) |
ret = 1; |
#endif |
return( ret ); |
} |
int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) |
{ |
int ret = 1; |
#if defined(MBEDTLS_HAVE_TIME) |
mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0; |
mbedtls_ssl_cache_entry *old = NULL; |
#endif |
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; |
mbedtls_ssl_cache_entry *cur, *prv; |
int count = 0; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 ) |
return( ret ); |
#endif |
cur = cache->chain; |
prv = NULL; |
while( cur != NULL ) |
{ |
count++; |
#if defined(MBEDTLS_HAVE_TIME) |
if( cache->timeout != 0 && |
(int) ( t - cur->timestamp ) > cache->timeout ) |
{ |
cur->timestamp = t; |
break; /* expired, reuse this slot, update timestamp */ |
} |
#endif |
if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 ) |
break; /* client reconnected, keep timestamp for session id */ |
#if defined(MBEDTLS_HAVE_TIME) |
if( oldest == 0 || cur->timestamp < oldest ) |
{ |
oldest = cur->timestamp; |
old = cur; |
} |
#endif |
prv = cur; |
cur = cur->next; |
} |
if( cur == NULL ) |
{ |
#if defined(MBEDTLS_HAVE_TIME) |
/* |
* Reuse oldest entry if max_entries reached |
*/ |
if( count >= cache->max_entries ) |
{ |
if( old == NULL ) |
{ |
ret = 1; |
goto exit; |
} |
cur = old; |
} |
#else /* MBEDTLS_HAVE_TIME */ |
/* |
* Reuse first entry in chain if max_entries reached, |
* but move to last place |
*/ |
if( count >= cache->max_entries ) |
{ |
if( cache->chain == NULL ) |
{ |
ret = 1; |
goto exit; |
} |
cur = cache->chain; |
cache->chain = cur->next; |
cur->next = NULL; |
prv->next = cur; |
} |
#endif /* MBEDTLS_HAVE_TIME */ |
else |
{ |
/* |
* max_entries not reached, create new entry |
*/ |
cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) ); |
if( cur == NULL ) |
{ |
ret = 1; |
goto exit; |
} |
if( prv == NULL ) |
cache->chain = cur; |
else |
prv->next = cur; |
} |
#if defined(MBEDTLS_HAVE_TIME) |
cur->timestamp = t; |
#endif |
} |
memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/* |
* If we're reusing an entry, free its certificate first |
*/ |
if( cur->peer_cert.p != NULL ) |
{ |
mbedtls_free( cur->peer_cert.p ); |
memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) ); |
} |
/* |
* Store peer certificate |
*/ |
if( session->peer_cert != NULL ) |
{ |
cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len ); |
if( cur->peer_cert.p == NULL ) |
{ |
ret = 1; |
goto exit; |
} |
memcpy( cur->peer_cert.p, session->peer_cert->raw.p, |
session->peer_cert->raw.len ); |
cur->peer_cert.len = session->peer_cert->raw.len; |
cur->session.peer_cert = NULL; |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
ret = 0; |
exit: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) |
ret = 1; |
#endif |
return( ret ); |
} |
#if defined(MBEDTLS_HAVE_TIME) |
void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ) |
{ |
if( timeout < 0 ) timeout = 0; |
cache->timeout = timeout; |
} |
#endif /* MBEDTLS_HAVE_TIME */ |
void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ) |
{ |
if( max < 0 ) max = 0; |
cache->max_entries = max; |
} |
void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ) |
{ |
mbedtls_ssl_cache_entry *cur, *prv; |
cur = cache->chain; |
while( cur != NULL ) |
{ |
prv = cur; |
cur = cur->next; |
mbedtls_ssl_session_free( &prv->session ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
mbedtls_free( prv->peer_cert.p ); |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
mbedtls_free( prv ); |
} |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &cache->mutex ); |
#endif |
cache->chain = NULL; |
} |
#endif /* MBEDTLS_SSL_CACHE_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_ciphersuites.c |
---|
0,0 → 1,2375 |
/** |
* \file ssl_ciphersuites.c |
* |
* \brief SSL ciphersuites for mbed TLS |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#endif |
#include "mbedtls/ssl_ciphersuites.h" |
#include "mbedtls/ssl.h" |
#include <string.h> |
/* |
* Ordered from most preferred to least preferred in terms of security. |
* |
* Current rule (except RC4 and 3DES, weak and null which come last): |
* 1. By key exchange: |
* Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK |
* 2. By key length and cipher: |
* ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 |
* 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 |
* 4. By hash function used when relevant |
* 5. By key exchange/auth again: EC > non-EC |
*/ |
static const int ciphersuite_preference[] = |
{ |
#if defined(MBEDTLS_SSL_CIPHERSUITES) |
MBEDTLS_SSL_CIPHERSUITES, |
#else |
/* Chacha-Poly ephemeral suites */ |
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
/* All AES-256 ephemeral suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, |
/* All CAMELLIA-256 ephemeral suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, |
/* All ARIA-256 ephemeral suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, |
/* All AES-128 ephemeral suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, |
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, |
/* All CAMELLIA-128 ephemeral suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, |
/* All ARIA-128 ephemeral suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, |
/* The PSK ephemeral suites */ |
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, |
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, |
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, |
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, |
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, |
/* The ECJPAKE suite */ |
MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, |
/* All AES-256 suites */ |
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_RSA_WITH_AES_256_CCM, |
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, |
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, |
/* All CAMELLIA-256 suites */ |
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, |
MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, |
/* All ARIA-256 suites */ |
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, |
/* All AES-128 suites */ |
MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_RSA_WITH_AES_128_CCM, |
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, |
/* All CAMELLIA-128 suites */ |
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, |
MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, |
/* All ARIA-128 suites */ |
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, |
MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, |
MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, |
/* The RSA PSK suites */ |
MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, |
/* The PSK suites */ |
MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, |
MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, |
MBEDTLS_TLS_PSK_WITH_AES_256_CCM, |
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, |
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, |
MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, |
MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, |
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, |
MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, |
MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384, |
MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_PSK_WITH_AES_128_CCM, |
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, |
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, |
MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, |
MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, |
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, |
MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, |
MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, |
/* 3DES suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, |
MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, |
/* RC4 suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, |
MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, |
MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, |
MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, |
MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, |
MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, |
MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, |
MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, |
/* Weak suites */ |
MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, |
MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, |
/* NULL suites */ |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, |
MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, |
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, |
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, |
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, |
MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, |
MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, |
MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, |
MBEDTLS_TLS_RSA_WITH_NULL_SHA256, |
MBEDTLS_TLS_RSA_WITH_NULL_SHA, |
MBEDTLS_TLS_RSA_WITH_NULL_MD5, |
MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, |
MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, |
MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, |
MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, |
MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, |
MBEDTLS_TLS_PSK_WITH_NULL_SHA384, |
MBEDTLS_TLS_PSK_WITH_NULL_SHA256, |
MBEDTLS_TLS_PSK_WITH_NULL_SHA, |
#endif /* MBEDTLS_SSL_CIPHERSUITES */ |
0 |
}; |
static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = |
{ |
#if defined(MBEDTLS_CHACHAPOLY_C) && \ |
defined(MBEDTLS_SHA256_C) && \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
{ MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
{ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-PSK-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
{ MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
{ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, |
"TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256", |
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, |
MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_CHACHAPOLY_C && |
MBEDTLS_SHA256_C && |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_SHA1_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_SHA1_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_SHA256_C) |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_SHA256_C) |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
{ MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_MD5_C) |
{ MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif |
#endif /* MBEDTLS_ARC4_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_SHA1_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_SHA1_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
{ MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", |
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", |
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", |
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", |
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", |
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_GCM_C) |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_GCM_C */ |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA", |
MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_ARC4_C) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA", |
MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_NODTLS }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_ARC4_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
#if defined(MBEDTLS_AES_C) |
#if defined(MBEDTLS_CCM_C) |
{ MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8", |
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_SHORT_TAG }, |
#endif /* MBEDTLS_CCM_C */ |
#endif /* MBEDTLS_AES_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
#if defined(MBEDTLS_MD5_C) |
{ MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#if defined(MBEDTLS_SHA512_C) |
{ MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", |
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
#if defined(MBEDTLS_DES_C) |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA", |
MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
#if defined(MBEDTLS_SHA1_C) |
{ MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA", |
MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_CIPHERSUITE_WEAK }, |
#endif /* MBEDTLS_SHA1_C */ |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* MBEDTLS_DES_C */ |
#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ |
#if defined(MBEDTLS_ARIA_C) |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, |
"TLS-RSA-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, |
"TLS-RSA-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, |
"TLS-RSA-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, |
"TLS-RSA-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, |
"TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, |
"TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, |
"TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, |
"TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, |
"TLS-PSK-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384, |
"TLS-PSK-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, |
"TLS-PSK-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, |
"TLS-PSK-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, |
"TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, |
"TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, |
"TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, |
"TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, |
"TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, |
"TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, |
"TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, |
"TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, |
"TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, |
"TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, |
"TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, |
"TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, |
"TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, |
"TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, |
"TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, |
"TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, |
"TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, |
"TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, |
"TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, |
"TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, |
"TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, |
"TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, |
"TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384", |
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) |
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, |
"TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384", |
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, |
"TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256", |
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) |
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, |
"TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256", |
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, |
0 }, |
#endif |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#endif /* MBEDTLS_ARIA_C */ |
{ 0, "", |
MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, |
0, 0, 0, 0, 0 } |
}; |
#if defined(MBEDTLS_SSL_CIPHERSUITES) |
const int *mbedtls_ssl_list_ciphersuites( void ) |
{ |
return( ciphersuite_preference ); |
} |
#else |
#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \ |
sizeof( ciphersuite_definitions[0] ) |
static int supported_ciphersuites[MAX_CIPHERSUITES]; |
static int supported_init = 0; |
static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info ) |
{ |
(void)cs_info; |
#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) |
if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) |
return( 1 ); |
#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ |
#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) |
if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB || |
cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC ) |
{ |
return( 1 ); |
} |
#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ |
return( 0 ); |
} |
const int *mbedtls_ssl_list_ciphersuites( void ) |
{ |
/* |
* On initial call filter out all ciphersuites not supported by current |
* build based on presence in the ciphersuite_definitions. |
*/ |
if( supported_init == 0 ) |
{ |
const int *p; |
int *q; |
for( p = ciphersuite_preference, q = supported_ciphersuites; |
*p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; |
p++ ) |
{ |
const mbedtls_ssl_ciphersuite_t *cs_info; |
if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL && |
!ciphersuite_is_removed( cs_info ) ) |
{ |
*(q++) = *p; |
} |
} |
*q = 0; |
supported_init = 1; |
} |
return( supported_ciphersuites ); |
} |
#endif /* MBEDTLS_SSL_CIPHERSUITES */ |
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( |
const char *ciphersuite_name ) |
{ |
const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; |
if( NULL == ciphersuite_name ) |
return( NULL ); |
while( cur->id != 0 ) |
{ |
if( 0 == strcmp( cur->name, ciphersuite_name ) ) |
return( cur ); |
cur++; |
} |
return( NULL ); |
} |
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite ) |
{ |
const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; |
while( cur->id != 0 ) |
{ |
if( cur->id == ciphersuite ) |
return( cur ); |
cur++; |
} |
return( NULL ); |
} |
const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ) |
{ |
const mbedtls_ssl_ciphersuite_t *cur; |
cur = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id ); |
if( cur == NULL ) |
return( "unknown" ); |
return( cur->name ); |
} |
int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ) |
{ |
const mbedtls_ssl_ciphersuite_t *cur; |
cur = mbedtls_ssl_ciphersuite_from_string( ciphersuite_name ); |
if( cur == NULL ) |
return( 0 ); |
return( cur->id ); |
} |
#if defined(MBEDTLS_PK_C) |
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_RSA: |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_RSA_PSK: |
return( MBEDTLS_PK_RSA ); |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
return( MBEDTLS_PK_ECDSA ); |
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: |
return( MBEDTLS_PK_ECKEY ); |
default: |
return( MBEDTLS_PK_NONE ); |
} |
} |
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_RSA: |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
return( MBEDTLS_PK_RSA ); |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
return( MBEDTLS_PK_ECDSA ); |
default: |
return( MBEDTLS_PK_NONE ); |
} |
} |
#endif /* MBEDTLS_PK_C */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: |
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: |
case MBEDTLS_KEY_EXCHANGE_ECJPAKE: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ) |
{ |
switch( info->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_PSK: |
case MBEDTLS_KEY_EXCHANGE_RSA_PSK: |
case MBEDTLS_KEY_EXCHANGE_DHE_PSK: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: |
return( 1 ); |
default: |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#endif /* MBEDTLS_SSL_TLS_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_cli.c |
---|
0,0 → 1,3650 |
/* |
* SSLv3/TLSv1 client-side functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_CLI_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/debug.h" |
#include "mbedtls/ssl.h" |
#include "mbedtls/ssl_internal.h" |
#include <string.h> |
#include <stdint.h> |
#if defined(MBEDTLS_HAVE_TIME) |
#include "mbedtls/platform_time.h" |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
#include "mbedtls/platform_util.h" |
#endif |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
size_t hostname_len; |
*olen = 0; |
if( ssl->hostname == NULL ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", |
ssl->hostname ) ); |
hostname_len = strlen( ssl->hostname ); |
if( end < p || (size_t)( end - p ) < hostname_len + 9 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
/* |
* Sect. 3, RFC 6066 (TLS Extensions Definitions) |
* |
* In order to provide any of the server names, clients MAY include an |
* extension of type "server_name" in the (extended) client hello. The |
* "extension_data" field of this extension SHALL contain |
* "ServerNameList" where: |
* |
* struct { |
* NameType name_type; |
* select (name_type) { |
* case host_name: HostName; |
* } name; |
* } ServerName; |
* |
* enum { |
* host_name(0), (255) |
* } NameType; |
* |
* opaque HostName<1..2^16-1>; |
* |
* struct { |
* ServerName server_name_list<1..2^16-1> |
* } ServerNameList; |
* |
*/ |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF ); |
*p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF ); |
*p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF ); |
*p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( hostname_len ) & 0xFF ); |
memcpy( p, ssl->hostname, hostname_len ); |
*olen = hostname_len + 9; |
} |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
*olen = 0; |
/* We're always including an TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the |
* initial ClientHello, in which case also adding the renegotiation |
* info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ |
if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); |
if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
/* |
* Secure renegotiation |
*/ |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); |
*p++ = 0x00; |
*p++ = ( ssl->verify_data_len + 1 ) & 0xFF; |
*p++ = ssl->verify_data_len & 0xFF; |
memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); |
*olen = 5 + ssl->verify_data_len; |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/* |
* Only if we handle at least one key exchange that needs signatures. |
*/ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
size_t sig_alg_len = 0; |
const int *md; |
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) |
unsigned char *sig_alg_list = buf + 6; |
#endif |
*olen = 0; |
if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); |
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) |
{ |
#if defined(MBEDTLS_ECDSA_C) |
sig_alg_len += 2; |
#endif |
#if defined(MBEDTLS_RSA_C) |
sig_alg_len += 2; |
#endif |
} |
if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
/* |
* Prepare signature_algorithms extension (TLS 1.2) |
*/ |
sig_alg_len = 0; |
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) |
{ |
#if defined(MBEDTLS_ECDSA_C) |
sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); |
sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; |
#endif |
#if defined(MBEDTLS_RSA_C) |
sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); |
sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; |
#endif |
} |
/* |
* enum { |
* none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), |
* sha512(6), (255) |
* } HashAlgorithm; |
* |
* enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } |
* SignatureAlgorithm; |
* |
* struct { |
* HashAlgorithm hash; |
* SignatureAlgorithm signature; |
* } SignatureAndHashAlgorithm; |
* |
* SignatureAndHashAlgorithm |
* supported_signature_algorithms<2..2^16-2>; |
*/ |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF ); |
*p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF ); |
*p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); |
*olen = 6 + sig_alg_len; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
unsigned char *elliptic_curve_list = p + 6; |
size_t elliptic_curve_len = 0; |
const mbedtls_ecp_curve_info *info; |
#if defined(MBEDTLS_ECP_C) |
const mbedtls_ecp_group_id *grp_id; |
#else |
((void) ssl); |
#endif |
*olen = 0; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); |
#if defined(MBEDTLS_ECP_C) |
for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) |
#else |
for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) |
#endif |
{ |
#if defined(MBEDTLS_ECP_C) |
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); |
#endif |
if( info == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) ); |
return; |
} |
elliptic_curve_len += 2; |
} |
if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
elliptic_curve_len = 0; |
#if defined(MBEDTLS_ECP_C) |
for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) |
#else |
for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) |
#endif |
{ |
#if defined(MBEDTLS_ECP_C) |
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); |
#endif |
elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; |
elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; |
} |
if( elliptic_curve_len == 0 ) |
return; |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF ); |
*p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); |
*p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); |
*olen = 6 + elliptic_curve_len; |
} |
static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
*olen = 0; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); |
if( end < p || (size_t)( end - p ) < 6 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 2; |
*p++ = 1; |
*p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; |
*olen = 6; |
} |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || |
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
int ret; |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
size_t kkpp_len; |
*olen = 0; |
/* Skip costly extension if we can't use EC J-PAKE anyway */ |
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) ); |
if( end - p < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); |
/* |
* We may need to send ClientHello multiple times for Hello verification. |
* We don't want to compute fresh values every time (both for performance |
* and consistency reasons), so cache the extension content. |
*/ |
if( ssl->handshake->ecjpake_cache == NULL || |
ssl->handshake->ecjpake_cache_len == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); |
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, |
p + 2, end - p - 2, &kkpp_len, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); |
return; |
} |
ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len ); |
if( ssl->handshake->ecjpake_cache == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) ); |
return; |
} |
memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); |
ssl->handshake->ecjpake_cache_len = kkpp_len; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) ); |
kkpp_len = ssl->handshake->ecjpake_cache_len; |
if( (size_t)( end - p - 2 ) < kkpp_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); |
} |
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); |
*olen = kkpp_len + 4; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
*olen = 0; |
if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); |
if( end < p || (size_t)( end - p ) < 5 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 1; |
*p++ = ssl->conf->mfl_code; |
*olen = 5; |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
*olen = 0; |
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) |
{ |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); |
if( end < p || (size_t)( end - p ) < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
*olen = 0; |
if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || |
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " |
"extension" ) ); |
if( end < p || (size_t)( end - p ) < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
*olen = 0; |
if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || |
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " |
"extension" ) ); |
if( end < p || (size_t)( end - p ) < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
size_t tlen = ssl->session_negotiate->ticket_len; |
*olen = 0; |
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) |
{ |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); |
if( end < p || (size_t)( end - p ) < 4 + tlen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); |
*p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( tlen ) & 0xFF ); |
*olen = 4; |
if( ssl->session_negotiate->ticket == NULL || tlen == 0 ) |
{ |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) ); |
memcpy( p, ssl->session_negotiate->ticket, tlen ); |
*olen += tlen; |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_SSL_ALPN) |
static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, size_t *olen ) |
{ |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
size_t alpnlen = 0; |
const char **cur; |
*olen = 0; |
if( ssl->conf->alpn_list == NULL ) |
{ |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); |
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) |
alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1; |
if( end < p || (size_t)( end - p ) < 6 + alpnlen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); |
/* |
* opaque ProtocolName<1..2^8-1>; |
* |
* struct { |
* ProtocolName protocol_name_list<2..2^16-1> |
* } ProtocolNameList; |
*/ |
/* Skip writing extension and list length for now */ |
p += 4; |
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) |
{ |
*p = (unsigned char)( strlen( *cur ) & 0xFF ); |
memcpy( p + 1, *cur, *p ); |
p += 1 + *p; |
} |
*olen = p - buf; |
/* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ |
buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); |
buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); |
/* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ |
buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); |
buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); |
} |
#endif /* MBEDTLS_SSL_ALPN */ |
/* |
* Generate random bytes for ClientHello |
*/ |
static int ssl_generate_random( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned char *p = ssl->handshake->randbytes; |
#if defined(MBEDTLS_HAVE_TIME) |
mbedtls_time_t t; |
#endif |
/* |
* When responding to a verify request, MUST reuse random (RFC 6347 4.2.1) |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake->verify_cookie != NULL ) |
{ |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_HAVE_TIME) |
t = mbedtls_time( NULL ); |
*p++ = (unsigned char)( t >> 24 ); |
*p++ = (unsigned char)( t >> 16 ); |
*p++ = (unsigned char)( t >> 8 ); |
*p++ = (unsigned char)( t ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); |
#else |
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) |
return( ret ); |
p += 4; |
#endif /* MBEDTLS_HAVE_TIME */ |
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
/** |
* \brief Validate cipher suite against config in SSL context. |
* |
* \param suite_info cipher suite to validate |
* \param ssl SSL context |
* \param min_minor_ver Minimal minor version to accept a cipher suite |
* \param max_minor_ver Maximal minor version to accept a cipher suite |
* |
* \return 0 if valid, else 1 |
*/ |
static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info, |
const mbedtls_ssl_context * ssl, |
int min_minor_ver, int max_minor_ver ) |
{ |
(void) ssl; |
if( suite_info == NULL ) |
return( 1 ); |
if( suite_info->min_minor_ver > max_minor_ver || |
suite_info->max_minor_ver < min_minor_ver ) |
return( 1 ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) |
return( 1 ); |
#endif |
#if defined(MBEDTLS_ARC4_C) |
if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && |
suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) |
return( 1 ); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && |
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) |
return( 1 ); |
#endif |
return( 0 ); |
} |
static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
size_t i, n, olen, ext_len = 0; |
unsigned char *buf; |
unsigned char *p, *q; |
unsigned char offer_compress; |
const int *ciphersuites; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
int uses_ec = 0; |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); |
if( ssl->conf->f_rng == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); |
return( MBEDTLS_ERR_SSL_NO_RNG ); |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
#endif |
{ |
ssl->major_ver = ssl->conf->min_major_ver; |
ssl->minor_ver = ssl->conf->min_minor_ver; |
} |
if( ssl->conf->max_major_ver == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, " |
"consider using mbedtls_ssl_config_defaults()" ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
/* |
* 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; |
mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, |
ssl->conf->transport, p ); |
p += 2; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", |
buf[4], buf[5] ) ); |
if( ( ret = ssl_generate_random( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret ); |
return( ret ); |
} |
memcpy( p, ssl->handshake->randbytes, 32 ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 ); |
p += 32; |
/* |
* 38 . 38 session id length |
* 39 . 39+n session id |
* 39+n . 39+n DTLS only: cookie length (1 byte) |
* 40+n . .. DTSL only: cookie |
* .. . .. ciphersuitelist length (2 bytes) |
* .. . .. ciphersuitelist |
* .. . .. compression methods length (1 byte) |
* .. . .. compression methods |
* .. . .. extensions length (2 bytes) |
* .. . .. extensions |
*/ |
n = ssl->session_negotiate->id_len; |
if( n < 16 || n > 32 || |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || |
#endif |
ssl->handshake->resume == 0 ) |
{ |
n = 0; |
} |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
/* |
* RFC 5077 section 3.4: "When presenting a ticket, the client MAY |
* generate and include a Session ID in the TLS ClientHello." |
*/ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
#endif |
{ |
if( ssl->session_negotiate->ticket != NULL && |
ssl->session_negotiate->ticket_len != 0 ) |
{ |
ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); |
if( ret != 0 ) |
return( ret ); |
ssl->session_negotiate->id_len = n = 32; |
} |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
*p++ = (unsigned char) n; |
for( i = 0; i < n; i++ ) |
*p++ = ssl->session_negotiate->id[i]; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); |
/* |
* DTLS cookie |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
if( ssl->handshake->verify_cookie == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) ); |
*p++ = 0; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", |
ssl->handshake->verify_cookie, |
ssl->handshake->verify_cookie_len ); |
*p++ = ssl->handshake->verify_cookie_len; |
memcpy( p, ssl->handshake->verify_cookie, |
ssl->handshake->verify_cookie_len ); |
p += ssl->handshake->verify_cookie_len; |
} |
} |
#endif |
/* |
* Ciphersuite list |
*/ |
ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; |
/* Skip writing ciphersuite length for now */ |
n = 0; |
q = p; |
p += 2; |
for( i = 0; ciphersuites[i] != 0; i++ ) |
{ |
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); |
if( ssl_validate_ciphersuite( ciphersuite_info, ssl, |
ssl->conf->min_minor_ver, |
ssl->conf->max_minor_ver ) != 0 ) |
continue; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x", |
ciphersuites[i] ) ); |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info ); |
#endif |
n++; |
*p++ = (unsigned char)( ciphersuites[i] >> 8 ); |
*p++ = (unsigned char)( ciphersuites[i] ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); |
/* |
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV |
*/ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
#endif |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); |
*p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); |
*p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); |
n++; |
} |
/* Some versions of OpenSSL don't handle it correctly if not at end */ |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) |
if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) ); |
*p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ); |
*p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); |
n++; |
} |
#endif |
*q++ = (unsigned char)( n >> 7 ); |
*q++ = (unsigned char)( n << 1 ); |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
offer_compress = 1; |
#else |
offer_compress = 0; |
#endif |
/* |
* We don't support compression with DTLS right now: if many records come |
* in the same datagram, uncompressing one could overwrite the next one. |
* We don't want to add complexity for handling that case unless there is |
* an actual need for it. |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
offer_compress = 0; |
#endif |
if( offer_compress ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d", |
MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) ); |
*p++ = 2; |
*p++ = MBEDTLS_SSL_COMPRESS_DEFLATE; |
*p++ = MBEDTLS_SSL_COMPRESS_NULL; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", |
MBEDTLS_SSL_COMPRESS_NULL ) ); |
*p++ = 1; |
*p++ = MBEDTLS_SSL_COMPRESS_NULL; |
} |
// First write extensions, then the total length |
// |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
/* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added |
* even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( uses_ec ) |
{ |
ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
} |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_ALPN) |
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
/* olen unused if all extensions are disabled */ |
((void) olen); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", |
ext_len ) ); |
if( ext_len > 0 ) |
{ |
*p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( ext_len ) & 0xFF ); |
p += ext_len; |
} |
ssl->out_msglen = p - buf; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO; |
ssl->state++; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
mbedtls_ssl_send_flight_completed( ssl ); |
#endif |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); |
return( 0 ); |
} |
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
{ |
/* Check verify-data in constant-time. The length OTOH is no secret */ |
if( len != 1 + ssl->verify_data_len * 2 || |
buf[0] != ssl->verify_data_len * 2 || |
mbedtls_ssl_safer_memcmp( buf + 1, |
ssl->own_verify_data, ssl->verify_data_len ) != 0 || |
mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len, |
ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
{ |
if( len != 1 || buf[0] != 0x00 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; |
} |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
/* |
* server should use the extension only if we did, |
* and if so the server's value should match ours (and len is always 1) |
*/ |
if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || |
len != 1 || |
buf[0] != ssl->conf->mfl_code ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || |
len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
((void) buf); |
ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || |
len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
((void) buf); |
ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || |
len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
((void) buf); |
ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || |
len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
((void) buf); |
ssl->handshake->new_session_ticket = 1; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
size_t list_size; |
const unsigned char *p; |
if( len == 0 || (size_t)( buf[0] + 1 ) != len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
list_size = buf[0]; |
p = buf + 1; |
while( list_size > 0 ) |
{ |
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || |
p[0] == MBEDTLS_ECP_PF_COMPRESSED ) |
{ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) |
ssl->handshake->ecdh_ctx.point_format = p[0]; |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
ssl->handshake->ecjpake_ctx.point_format = p[0]; |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); |
return( 0 ); |
} |
list_size--; |
p++; |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || |
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
int ret; |
if( ssl->transform_negotiate->ciphersuite_info->key_exchange != |
MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); |
return( 0 ); |
} |
/* If we got here, we no longer need our cached extension */ |
mbedtls_free( ssl->handshake->ecjpake_cache ); |
ssl->handshake->ecjpake_cache = NULL; |
ssl->handshake->ecjpake_cache_len = 0; |
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, |
buf, len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_ALPN) |
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
size_t list_len, name_len; |
const char **p; |
/* If we didn't send it, the server shouldn't send it */ |
if( ssl->conf->alpn_list == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
/* |
* opaque ProtocolName<1..2^8-1>; |
* |
* struct { |
* ProtocolName protocol_name_list<2..2^16-1> |
* } ProtocolNameList; |
* |
* the "ProtocolNameList" MUST contain exactly one "ProtocolName" |
*/ |
/* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ |
if( len < 4 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
list_len = ( buf[0] << 8 ) | buf[1]; |
if( list_len != len - 2 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
name_len = buf[2]; |
if( name_len != list_len - 1 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
/* Check that the server chosen protocol was in our list and save it */ |
for( p = ssl->conf->alpn_list; *p != NULL; p++ ) |
{ |
if( name_len == strlen( *p ) && |
memcmp( buf + 3, *p, name_len ) == 0 ) |
{ |
ssl->alpn_chosen = *p; |
return( 0 ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
#endif /* MBEDTLS_SSL_ALPN */ |
/* |
* Parse HelloVerifyRequest. Only called after verifying the HS type. |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) |
{ |
const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); |
int major_ver, minor_ver; |
unsigned char cookie_len; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); |
/* Check that there is enough room for: |
* - 2 bytes of version |
* - 1 byte of cookie_len |
*/ |
if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, |
( "incoming HelloVerifyRequest message is too short" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
/* |
* struct { |
* ProtocolVersion server_version; |
* opaque cookie<0..2^8-1>; |
* } HelloVerifyRequest; |
*/ |
MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); |
mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p ); |
p += 2; |
/* |
* Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1) |
* even is lower than our min version. |
*/ |
if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || |
minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 || |
major_ver > ssl->conf->max_major_ver || |
minor_ver > ssl->conf->max_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); |
return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); |
} |
cookie_len = *p++; |
if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, |
( "cookie length does not match incoming message size" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); |
mbedtls_free( ssl->handshake->verify_cookie ); |
ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len ); |
if( ssl->handshake->verify_cookie == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
memcpy( ssl->handshake->verify_cookie, p, cookie_len ); |
ssl->handshake->verify_cookie_len = cookie_len; |
/* Start over at ClientHello */ |
ssl->state = MBEDTLS_SSL_CLIENT_HELLO; |
mbedtls_ssl_reset_checksum( ssl ); |
mbedtls_ssl_recv_flight_completed( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) |
{ |
int ret, i; |
size_t n; |
size_t ext_len; |
unsigned char *buf, *ext; |
unsigned char comp; |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
int accept_comp; |
#endif |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
int renegotiation_info_seen = 0; |
#endif |
int handshake_failure = 0; |
const mbedtls_ssl_ciphersuite_t *suite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); |
buf = ssl->in_msg; |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
/* No alert on a read error. */ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
ssl->renego_records_seen++; |
if( ssl->conf->renego_max_records >= 0 && |
ssl->renego_records_seen > ssl->conf->renego_max_records ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " |
"but not honored by server" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) ); |
ssl->keep_current_message = 1; |
return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); |
return( ssl_parse_hello_verify_request( ssl ) ); |
} |
else |
{ |
/* We made it through the verification process */ |
mbedtls_free( ssl->handshake->verify_cookie ); |
ssl->handshake->verify_cookie = NULL; |
ssl->handshake->verify_cookie_len = 0; |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) || |
buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
/* |
* 0 . 1 server_version |
* 2 . 33 random (maybe including 4 bytes of Unix time) |
* 34 . 34 session_id length = n |
* 35 . 34+n session_id |
* 35+n . 36+n cipher_suite |
* 37+n . 37+n compression_method |
* |
* 38+n . 39+n extensions length (optional) |
* 40+n . .. extensions |
*/ |
buf += mbedtls_ssl_hs_hdr_len( ssl ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 ); |
mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, |
ssl->conf->transport, buf + 0 ); |
if( ssl->major_ver < ssl->conf->min_major_ver || |
ssl->minor_ver < ssl->conf->min_minor_ver || |
ssl->major_ver > ssl->conf->max_major_ver || |
ssl->minor_ver > ssl->conf->max_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - " |
" min: [%d:%d], server: [%d:%d], max: [%d:%d]", |
ssl->conf->min_major_ver, ssl->conf->min_minor_ver, |
ssl->major_ver, ssl->minor_ver, |
ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); |
return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", |
( (uint32_t) buf[2] << 24 ) | |
( (uint32_t) buf[3] << 16 ) | |
( (uint32_t) buf[4] << 8 ) | |
( (uint32_t) buf[5] ) ) ); |
memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); |
n = buf[34]; |
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 ); |
if( n > 32 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n ) |
{ |
ext_len = ( ( buf[38 + n] << 8 ) |
| ( buf[39 + n] ) ); |
if( ( ext_len > 0 && ext_len < 4 ) || |
ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
} |
else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n ) |
{ |
ext_len = 0; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
/* ciphersuite (used later) */ |
i = ( buf[35 + n] << 8 ) | buf[36 + n]; |
/* |
* Read and check compression |
*/ |
comp = buf[37 + n]; |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
/* See comments in ssl_write_client_hello() */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
accept_comp = 0; |
else |
#endif |
accept_comp = 1; |
if( comp != MBEDTLS_SSL_COMPRESS_NULL && |
( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) ) |
#else /* MBEDTLS_ZLIB_SUPPORT */ |
if( comp != MBEDTLS_SSL_COMPRESS_NULL ) |
#endif/* MBEDTLS_ZLIB_SUPPORT */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
} |
/* |
* Initialize update checksum functions |
*/ |
ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i ); |
if( ssl->transform_negotiate->ciphersuite_info == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n ); |
/* |
* Check if the session can be resumed |
*/ |
if( ssl->handshake->resume == 0 || n == 0 || |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || |
#endif |
ssl->session_negotiate->ciphersuite != i || |
ssl->session_negotiate->compression != comp || |
ssl->session_negotiate->id_len != n || |
memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) |
{ |
ssl->state++; |
ssl->handshake->resume = 0; |
#if defined(MBEDTLS_HAVE_TIME) |
ssl->session_negotiate->start = mbedtls_time( NULL ); |
#endif |
ssl->session_negotiate->ciphersuite = i; |
ssl->session_negotiate->compression = comp; |
ssl->session_negotiate->id_len = n; |
memcpy( ssl->session_negotiate->id, buf + 35, n ); |
} |
else |
{ |
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; |
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( ret ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", |
ssl->handshake->resume ? "a" : "no" ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); |
/* |
* Perform cipher suite validation in same way as in ssl_write_client_hello. |
*/ |
i = 0; |
while( 1 ) |
{ |
if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] == |
ssl->session_negotiate->ciphersuite ) |
{ |
break; |
} |
} |
suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); |
if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
ssl->handshake->ecrs_enabled = 1; |
} |
#endif |
if( comp != MBEDTLS_SSL_COMPRESS_NULL |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
&& comp != MBEDTLS_SSL_COMPRESS_DEFLATE |
#endif |
) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
ssl->session_negotiate->compression = comp; |
ext = buf + 40 + n; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) ); |
while( ext_len ) |
{ |
unsigned int ext_id = ( ( ext[0] << 8 ) |
| ( ext[1] ) ); |
unsigned int ext_size = ( ( ext[2] << 8 ) |
| ( ext[3] ) ); |
if( ext_size + 4 > ext_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
switch( ext_id ) |
{ |
case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
renegotiation_info_seen = 1; |
#endif |
if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, |
ext_size ) ) != 0 ) |
return( ret ); |
break; |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) ); |
if( ( ret = ssl_parse_max_fragment_length_ext( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) ); |
if( ( ret = ssl_parse_truncated_hmac_ext( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) ); |
if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) ); |
if( ( ret = ssl_parse_extended_ms_ext( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
case MBEDTLS_TLS_EXT_SESSION_TICKET: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) ); |
if( ( ret = ssl_parse_session_ticket_ext( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); |
if( ( ret = ssl_parse_supported_point_formats_ext( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || |
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) ); |
if( ( ret = ssl_parse_ecjpake_kkpp( ssl, |
ext + 4, ext_size ) ) != 0 ) |
{ |
return( ret ); |
} |
break; |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_ALPN) |
case MBEDTLS_TLS_EXT_ALPN: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); |
if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_ALPN */ |
default: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", |
ext_id ) ); |
} |
ext_len -= 4 + ext_size; |
ext += 4 + ext_size; |
if( ext_len > 0 && ext_len < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
} |
/* |
* Renegotiation security checks |
*/ |
if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); |
handshake_failure = 1; |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && |
renegotiation_info_seen == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); |
handshake_failure = 1; |
} |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); |
handshake_failure = 1; |
} |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
renegotiation_info_seen == 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); |
handshake_failure = 1; |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
if( handshake_failure == 1 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p, |
unsigned char *end ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
/* |
* 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 = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret ); |
return( ret ); |
} |
if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d", |
ssl->handshake->dhm_ctx.len * 8, |
ssl->conf->dhm_min_bitlen ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); |
return( ret ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ecp_curve_info *curve_info; |
mbedtls_ecp_group_id grp_id; |
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
grp_id = ssl->handshake->ecdh_ctx.grp.id; |
#else |
grp_id = ssl->handshake->ecdh_ctx.grp_id; |
#endif |
curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); |
if( curve_info == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); |
#if defined(MBEDTLS_ECP_C) |
if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 ) |
#else |
if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || |
ssl->handshake->ecdh_ctx.grp.nbits > 521 ) |
#endif |
return( -1 ); |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_QP ); |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, |
unsigned char **p, |
unsigned char *end ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
/* |
* Ephemeral ECDH parameters: |
* |
* struct { |
* ECParameters curve_params; |
* ECPoint public; |
* } ServerECDHParams; |
*/ |
if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx, |
(const unsigned char **) p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; |
#endif |
return( ret ); |
} |
if( ssl_check_server_ecdh_params( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, |
unsigned char **p, |
unsigned char *end ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
size_t len; |
((void) ssl); |
/* |
* PSK parameters: |
* |
* opaque psk_identity_hint<0..2^16-1>; |
*/ |
if( end - (*p) < 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " |
"(psk_identity_hint length)" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
len = (*p)[0] << 8 | (*p)[1]; |
*p += 2; |
if( end - (*p) < (int) len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " |
"(psk_identity_hint length)" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
/* |
* Note: we currently ignore the PKS identity hint, as we only allow one |
* PSK to be provisionned on the client. This could be changed later if |
* someone needs that feature. |
*/ |
*p += len; |
ret = 0; |
return( ret ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
/* |
* Generate a pre-master secret and encrypt it with the server's RSA key |
*/ |
static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, |
size_t offset, size_t *olen, |
size_t pms_offset ) |
{ |
int ret; |
size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; |
unsigned char *p = ssl->handshake->premaster + pms_offset; |
if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
} |
/* |
* Generate (part of) the pre-master as |
* struct { |
* ProtocolVersion client_version; |
* opaque random[46]; |
* } PreMasterSecret; |
*/ |
mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, |
ssl->conf->transport, p ); |
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); |
return( ret ); |
} |
ssl->handshake->pmslen = 48; |
if( ssl->session_negotiate->peer_cert == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
/* |
* Now write it out, encrypted |
*/ |
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, |
MBEDTLS_PK_RSA ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); |
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); |
} |
if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk, |
p, ssl->handshake->pmslen, |
ssl->out_msg + offset + len_bytes, olen, |
MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( len_bytes == 2 ) |
{ |
ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 ); |
ssl->out_msg[offset+1] = (unsigned char)( *olen ); |
*olen += 2; |
} |
#endif |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, |
unsigned char **p, |
unsigned char *end, |
mbedtls_md_type_t *md_alg, |
mbedtls_pk_type_t *pk_alg ) |
{ |
((void) ssl); |
*md_alg = MBEDTLS_MD_NONE; |
*pk_alg = MBEDTLS_PK_NONE; |
/* Only in TLS 1.2 */ |
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
return( 0 ); |
} |
if( (*p) + 2 > end ) |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
/* |
* Get hash algorithm |
*/ |
if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported " |
"HashAlgorithm %d", *(p)[0] ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
/* |
* Get signature algorithm |
*/ |
if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported " |
"SignatureAlgorithm %d", (*p)[1] ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
/* |
* Check if the hash is acceptable |
*/ |
if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered", |
*(p)[0] ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) ); |
*p += 2; |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
const mbedtls_ecp_keypair *peer_key; |
if( ssl->session_negotiate->peer_cert == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, |
MBEDTLS_PK_ECKEY ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); |
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); |
} |
peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk ); |
if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, |
MBEDTLS_ECDH_THEIRS ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); |
return( ret ); |
} |
if( ssl_check_server_ecdh_params( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
unsigned char *p = NULL, *end = NULL; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); |
ssl->state++; |
return( 0 ); |
} |
((void) p); |
((void) end); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) |
{ |
if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); |
ssl->state++; |
return( 0 ); |
} |
((void) p); |
((void) end); |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled && |
ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing ) |
{ |
goto start_processing; |
} |
#endif |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
/* |
* ServerKeyExchange may be skipped with PSK and RSA-PSK when the server |
* doesn't use a psk_identity_hint |
*/ |
if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) |
{ |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) |
{ |
/* Current message is probably either |
* CertificateRequest or ServerHelloDone */ |
ssl->keep_current_message = 1; |
goto exit; |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must " |
"not be skipped" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled ) |
ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing; |
start_processing: |
#endif |
p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); |
end = ssl->in_msg + ssl->in_hslen; |
MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) |
{ |
if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
} /* FALLTROUGH */ |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) |
; /* nothing more to do */ |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || |
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) |
{ |
if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) |
{ |
if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, |
p, end - p ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) |
{ |
size_t sig_len, hashlen; |
unsigned char hash[64]; |
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; |
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; |
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); |
size_t params_len = p - params; |
void *rs_ctx = NULL; |
/* |
* Handle the digitally-signed structure |
*/ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
if( ssl_parse_signature_algorithm( ssl, &p, end, |
&md_alg, &pk_alg ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); |
/* Default hash for ECDSA is SHA-1 */ |
if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE ) |
md_alg = MBEDTLS_MD_SHA1; |
} |
else |
#endif |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* |
* Read signature |
*/ |
if( p > end - 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
sig_len = ( p[0] << 8 ) | p[1]; |
p += 2; |
if( p != end - sig_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len ); |
/* |
* Compute the hash that has been signed |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( md_alg == MBEDTLS_MD_NONE ) |
{ |
hashlen = 36; |
ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, params, |
params_len ); |
if( ret != 0 ) |
return( ret ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, |
params, params_len, |
md_alg ); |
if( ret != 0 ) |
return( ret ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); |
if( ssl->session_negotiate->peer_cert == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
/* |
* Verify signature |
*/ |
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); |
} |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled ) |
rs_ctx = &ssl->handshake->ecrs_ctx.pk; |
#endif |
if( ( ret = mbedtls_pk_verify_restartable( |
&ssl->session_negotiate->peer_cert->pk, |
md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 ) |
{ |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) |
#endif |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; |
#endif |
return( ret ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ |
exit: |
ssl->state++; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); |
return( 0 ); |
} |
#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) |
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); |
if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); |
ssl->state++; |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ |
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned char *buf; |
size_t n = 0; |
size_t cert_type_len = 0, dn_len = 0; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); |
if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); |
ssl->state++; |
return( 0 ); |
} |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
ssl->state++; |
ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", |
ssl->client_auth ? "a" : "no" ) ); |
if( ssl->client_auth == 0 ) |
{ |
/* Current message is probably the ServerHelloDone */ |
ssl->keep_current_message = 1; |
goto exit; |
} |
/* |
* struct { |
* ClientCertificateType certificate_types<1..2^8-1>; |
* SignatureAndHashAlgorithm |
* supported_signature_algorithms<2^16-1>; -- TLS 1.2 only |
* DistinguishedName certificate_authorities<0..2^16-1>; |
* } CertificateRequest; |
* |
* Since we only support a single certificate on clients, let's just |
* ignore all the information that's supposed to help us pick a |
* certificate. |
* |
* We could check that our certificate matches the request, and bail out |
* if it doesn't, but it's simpler to just send the certificate anyway, |
* and give the server the opportunity to decide if it should terminate |
* the connection when it doesn't like our certificate. |
* |
* Same goes for the hash in TLS 1.2's signature_algorithms: at this |
* point we only have one hash available (see comments in |
* write_certificate_verify), so let's just use what we have. |
* |
* However, we still minimally parse the message to check it is at least |
* superficially sane. |
*/ |
buf = ssl->in_msg; |
/* certificate_types */ |
if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); |
} |
cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; |
n = cert_type_len; |
/* |
* In the subsequent code there are two paths that read from buf: |
* * the length of the signature algorithms field (if minor version of |
* SSL is 3), |
* * distinguished name length otherwise. |
* Both reach at most the index: |
* ...hdr_len + 2 + n, |
* therefore the buffer length at this point must be greater than that |
* regardless of the actual code path. |
*/ |
if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); |
} |
/* supported_signature_algorithms */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) |
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); |
#if defined(MBEDTLS_DEBUG_C) |
unsigned char* sig_alg; |
size_t i; |
#endif |
/* |
* The furthest access in buf is in the loop few lines below: |
* sig_alg[i + 1], |
* where: |
* sig_alg = buf + ...hdr_len + 3 + n, |
* max(i) = sig_alg_len - 1. |
* Therefore the furthest access is: |
* buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1], |
* which reduces to: |
* buf[...hdr_len + 3 + n + sig_alg_len], |
* which is one less than we need the buf to be. |
*/ |
if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); |
} |
#if defined(MBEDTLS_DEBUG_C) |
sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; |
for( i = 0; i < sig_alg_len; i += 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d" |
",%d", sig_alg[i], sig_alg[i + 1] ) ); |
} |
#endif |
n += 2 + sig_alg_len; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
/* certificate_authorities */ |
dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) |
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); |
n += dn_len; |
if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); |
} |
exit: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ |
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) || |
ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); |
} |
ssl->state++; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
mbedtls_ssl_recv_flight_completed( ssl ); |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); |
return( 0 ); |
} |
static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
size_t i, n; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) |
{ |
/* |
* DHM key exchange -- send G^X mod P |
*/ |
n = ssl->handshake->dhm_ctx.len; |
ssl->out_msg[4] = (unsigned char)( n >> 8 ); |
ssl->out_msg[5] = (unsigned char)( n ); |
i = 6; |
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, |
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), |
&ssl->out_msg[i], n, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); |
if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, |
ssl->handshake->premaster, |
MBEDTLS_PREMASTER_SIZE, |
&ssl->handshake->pmslen, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) |
{ |
/* |
* ECDH key exchange -- send client public value |
*/ |
i = 4; |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled ) |
{ |
if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret ) |
goto ecdh_calc_secret; |
mbedtls_ecdh_enable_restart( &ssl->handshake->ecdh_ctx ); |
} |
#endif |
ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, |
&n, |
&ssl->out_msg[i], 1000, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; |
#endif |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_Q ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled ) |
{ |
ssl->handshake->ecrs_n = n; |
ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; |
} |
ecdh_calc_secret: |
if( ssl->handshake->ecrs_enabled ) |
n = ssl->handshake->ecrs_n; |
#endif |
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, |
&ssl->handshake->pmslen, |
ssl->handshake->premaster, |
MBEDTLS_MPI_MAX_SIZE, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; |
#endif |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_Z ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) |
{ |
/* |
* opaque psk_identity<0..2^16-1>; |
*/ |
if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) ); |
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); |
} |
i = 4; |
n = ssl->conf->psk_identity_len; |
if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " |
"SSL buffer too short" ) ); |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
} |
ssl->out_msg[i++] = (unsigned char)( n >> 8 ); |
ssl->out_msg[i++] = (unsigned char)( n ); |
memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len ); |
i += ssl->conf->psk_identity_len; |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) |
{ |
n = 0; |
} |
else |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) |
{ |
if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 ) |
return( ret ); |
} |
else |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) |
{ |
/* |
* ClientDiffieHellmanPublic public (DHM send G^X mod P) |
*/ |
n = ssl->handshake->dhm_ctx.len; |
if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" |
" or SSL buffer too short" ) ); |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
} |
ssl->out_msg[i++] = (unsigned char)( n >> 8 ); |
ssl->out_msg[i++] = (unsigned char)( n ); |
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, |
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), |
&ssl->out_msg[i], n, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) |
{ |
/* |
* ClientECDiffieHellmanPublic public; |
*/ |
ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, |
&ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_Q ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, |
ciphersuite_info->key_exchange ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) |
{ |
i = 4; |
if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 ) |
return( ret ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
i = 4; |
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, |
ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); |
return( ret ); |
} |
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, |
ssl->handshake->premaster, 32, &ssl->handshake->pmslen, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
{ |
((void) ciphersuite_info); |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->out_msglen = i + n; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; |
ssl->state++; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); |
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); |
return( ret ); |
} |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); |
ssl->state++; |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#else |
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
size_t n = 0, offset = 0; |
unsigned char hash[48]; |
unsigned char *hash_start = hash; |
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; |
unsigned int hashlen; |
void *rs_ctx = NULL; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled && |
ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign ) |
{ |
goto sign; |
} |
#endif |
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); |
return( ret ); |
} |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); |
ssl->state++; |
return( 0 ); |
} |
if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); |
ssl->state++; |
return( 0 ); |
} |
if( mbedtls_ssl_own_key( ssl ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) ); |
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); |
} |
/* |
* Make a signature of the handshake digests |
*/ |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled ) |
ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; |
sign: |
#endif |
ssl->handshake->calc_verify( ssl, hash ); |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
/* |
* digitally-signed struct { |
* opaque md5_hash[16]; |
* opaque sha_hash[20]; |
* }; |
* |
* md5_hash |
* MD5(handshake_messages); |
* |
* sha_hash |
* SHA(handshake_messages); |
*/ |
hashlen = 36; |
md_alg = MBEDTLS_MD_NONE; |
/* |
* For ECDSA, default hash is SHA-1 only |
*/ |
if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) ) |
{ |
hash_start += 16; |
hashlen -= 16; |
md_alg = MBEDTLS_MD_SHA1; |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
/* |
* digitally-signed struct { |
* opaque handshake_messages[handshake_messages_length]; |
* }; |
* |
* Taking shortcut here. We assume that the server always allows the |
* PRF Hash function and has sent it in the allowed signature |
* algorithms list received in the Certificate Request message. |
* |
* Until we encounter a server that does not, we will take this |
* shortcut. |
* |
* Reason: Otherwise we should have running hashes for SHA512 and SHA224 |
* in order to satisfy 'weird' needs from the server side. |
*/ |
if( ssl->transform_negotiate->ciphersuite_info->mac == |
MBEDTLS_MD_SHA384 ) |
{ |
md_alg = MBEDTLS_MD_SHA384; |
ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; |
} |
else |
{ |
md_alg = MBEDTLS_MD_SHA256; |
ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; |
} |
ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); |
/* Info from md_alg will be used instead */ |
hashlen = 0; |
offset = 2; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled ) |
rs_ctx = &ssl->handshake->ecrs_ctx.pk; |
#endif |
if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ), |
md_alg, hash_start, hashlen, |
ssl->out_msg + 6 + offset, &n, |
ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; |
#endif |
return( ret ); |
} |
ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); |
ssl->out_msg[5 + offset] = (unsigned char)( n ); |
ssl->out_msglen = 6 + n + offset; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; |
ssl->state++; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) ); |
return( ret ); |
} |
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
uint32_t lifetime; |
size_t ticket_len; |
unsigned char *ticket; |
const unsigned char *msg; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
/* |
* struct { |
* uint32 ticket_lifetime_hint; |
* opaque ticket<0..2^16-1>; |
* } NewSessionTicket; |
* |
* 0 . 3 ticket_lifetime_hint |
* 4 . 5 ticket_len (n) |
* 6 . 5+n ticket content |
*/ |
if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || |
ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); |
} |
msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); |
lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) | |
( msg[2] << 8 ) | ( msg[3] ); |
ticket_len = ( msg[4] << 8 ) | ( msg[5] ); |
if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) ); |
/* We're not waiting for a NewSessionTicket message any more */ |
ssl->handshake->new_session_ticket = 0; |
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; |
/* |
* Zero-length ticket means the server changed his mind and doesn't want |
* to send a ticket after all, so just forget it |
*/ |
if( ticket_len == 0 ) |
return( 0 ); |
mbedtls_platform_zeroize( ssl->session_negotiate->ticket, |
ssl->session_negotiate->ticket_len ); |
mbedtls_free( ssl->session_negotiate->ticket ); |
ssl->session_negotiate->ticket = NULL; |
ssl->session_negotiate->ticket_len = 0; |
if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
memcpy( ticket, msg + 6, ticket_len ); |
ssl->session_negotiate->ticket = ticket; |
ssl->session_negotiate->ticket_len = ticket_len; |
ssl->session_negotiate->ticket_lifetime = lifetime; |
/* |
* RFC 5077 section 3.4: |
* "If the client receives a session ticket from the server, then it |
* discards any Session ID that was sent in the ServerHello." |
*/ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) ); |
ssl->session_negotiate->id_len = 0; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
/* |
* SSL handshake -- client side -- single step |
*/ |
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) |
{ |
int ret = 0; |
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
return( ret ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) |
{ |
if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* Change state now, so that it is right in mbedtls_ssl_read_record(), used |
* by DTLS for dropping out-of-sequence ChangeCipherSpec records */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && |
ssl->handshake->new_session_ticket != 0 ) |
{ |
ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET; |
} |
#endif |
switch( ssl->state ) |
{ |
case MBEDTLS_SSL_HELLO_REQUEST: |
ssl->state = MBEDTLS_SSL_CLIENT_HELLO; |
break; |
/* |
* ==> ClientHello |
*/ |
case MBEDTLS_SSL_CLIENT_HELLO: |
ret = ssl_write_client_hello( ssl ); |
break; |
/* |
* <== ServerHello |
* Certificate |
* ( ServerKeyExchange ) |
* ( CertificateRequest ) |
* ServerHelloDone |
*/ |
case MBEDTLS_SSL_SERVER_HELLO: |
ret = ssl_parse_server_hello( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_CERTIFICATE: |
ret = mbedtls_ssl_parse_certificate( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: |
ret = ssl_parse_server_key_exchange( ssl ); |
break; |
case MBEDTLS_SSL_CERTIFICATE_REQUEST: |
ret = ssl_parse_certificate_request( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_HELLO_DONE: |
ret = ssl_parse_server_hello_done( ssl ); |
break; |
/* |
* ==> ( Certificate/Alert ) |
* ClientKeyExchange |
* ( CertificateVerify ) |
* ChangeCipherSpec |
* Finished |
*/ |
case MBEDTLS_SSL_CLIENT_CERTIFICATE: |
ret = mbedtls_ssl_write_certificate( ssl ); |
break; |
case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: |
ret = ssl_write_client_key_exchange( ssl ); |
break; |
case MBEDTLS_SSL_CERTIFICATE_VERIFY: |
ret = ssl_write_certificate_verify( ssl ); |
break; |
case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: |
ret = mbedtls_ssl_write_change_cipher_spec( ssl ); |
break; |
case MBEDTLS_SSL_CLIENT_FINISHED: |
ret = mbedtls_ssl_write_finished( ssl ); |
break; |
/* |
* <== ( NewSessionTicket ) |
* ChangeCipherSpec |
* Finished |
*/ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: |
ret = ssl_parse_new_session_ticket( ssl ); |
break; |
#endif |
case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: |
ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_FINISHED: |
ret = mbedtls_ssl_parse_finished( ssl ); |
break; |
case MBEDTLS_SSL_FLUSH_BUFFERS: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); |
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; |
break; |
case MBEDTLS_SSL_HANDSHAKE_WRAPUP: |
mbedtls_ssl_handshake_wrapup( ssl ); |
break; |
default: |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_cookie.c |
---|
0,0 → 1,258 |
/* |
* DTLS cookie callbacks implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* These session callbacks use a simple chained list |
* to store and retrieve the session information. |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_COOKIE_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/ssl_cookie.h" |
#include "mbedtls/ssl_internal.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
/* |
* If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is |
* available. Try SHA-256 first, 512 wastes resources since we need to stay |
* with max 32 bytes of cookie for DTLS 1.0 |
*/ |
#if defined(MBEDTLS_SHA256_C) |
#define COOKIE_MD MBEDTLS_MD_SHA224 |
#define COOKIE_MD_OUTLEN 32 |
#define COOKIE_HMAC_LEN 28 |
#elif defined(MBEDTLS_SHA512_C) |
#define COOKIE_MD MBEDTLS_MD_SHA384 |
#define COOKIE_MD_OUTLEN 48 |
#define COOKIE_HMAC_LEN 28 |
#elif defined(MBEDTLS_SHA1_C) |
#define COOKIE_MD MBEDTLS_MD_SHA1 |
#define COOKIE_MD_OUTLEN 20 |
#define COOKIE_HMAC_LEN 20 |
#else |
#error "DTLS hello verify needs SHA-1 or SHA-2" |
#endif |
/* |
* Cookies are formed of a 4-bytes timestamp (or serial number) and |
* an HMAC of timestemp and client ID. |
*/ |
#define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN ) |
void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ) |
{ |
mbedtls_md_init( &ctx->hmac_ctx ); |
#if !defined(MBEDTLS_HAVE_TIME) |
ctx->serial = 0; |
#endif |
ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &ctx->mutex ); |
#endif |
} |
void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ) |
{ |
ctx->timeout = delay; |
} |
void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) |
{ |
mbedtls_md_free( &ctx->hmac_ctx ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &ctx->mutex ); |
#endif |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); |
} |
int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
unsigned char key[COOKIE_MD_OUTLEN]; |
if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) |
return( ret ); |
ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 ); |
if( ret != 0 ) |
return( ret ); |
ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); |
if( ret != 0 ) |
return( ret ); |
mbedtls_platform_zeroize( key, sizeof( key ) ); |
return( 0 ); |
} |
/* |
* Generate the HMAC part of a cookie |
*/ |
static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, |
const unsigned char time[4], |
unsigned char **p, unsigned char *end, |
const unsigned char *cli_id, size_t cli_id_len ) |
{ |
unsigned char hmac_out[COOKIE_MD_OUTLEN]; |
if( (size_t)( end - *p ) < COOKIE_HMAC_LEN ) |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || |
mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || |
mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 || |
mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 ) |
{ |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
memcpy( *p, hmac_out, COOKIE_HMAC_LEN ); |
*p += COOKIE_HMAC_LEN; |
return( 0 ); |
} |
/* |
* Generate cookie for DTLS ClientHello verification |
*/ |
int mbedtls_ssl_cookie_write( void *p_ctx, |
unsigned char **p, unsigned char *end, |
const unsigned char *cli_id, size_t cli_id_len ) |
{ |
int ret; |
mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; |
unsigned long t; |
if( ctx == NULL || cli_id == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( (size_t)( end - *p ) < COOKIE_LEN ) |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
#if defined(MBEDTLS_HAVE_TIME) |
t = (unsigned long) mbedtls_time( NULL ); |
#else |
t = ctx->serial++; |
#endif |
(*p)[0] = (unsigned char)( t >> 24 ); |
(*p)[1] = (unsigned char)( t >> 16 ); |
(*p)[2] = (unsigned char)( t >> 8 ); |
(*p)[3] = (unsigned char)( t ); |
*p += 4; |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); |
#endif |
ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4, |
p, end, cli_id, cli_id_len ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + |
MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
/* |
* Check a cookie |
*/ |
int mbedtls_ssl_cookie_check( void *p_ctx, |
const unsigned char *cookie, size_t cookie_len, |
const unsigned char *cli_id, size_t cli_id_len ) |
{ |
unsigned char ref_hmac[COOKIE_HMAC_LEN]; |
int ret = 0; |
unsigned char *p = ref_hmac; |
mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; |
unsigned long cur_time, cookie_time; |
if( ctx == NULL || cli_id == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( cookie_len != COOKIE_LEN ) |
return( -1 ); |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); |
#endif |
if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie, |
&p, p + sizeof( ref_hmac ), |
cli_id, cli_id_len ) != 0 ) |
ret = -1; |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + |
MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
if( ret != 0 ) |
return( ret ); |
if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 ) |
return( -1 ); |
#if defined(MBEDTLS_HAVE_TIME) |
cur_time = (unsigned long) mbedtls_time( NULL ); |
#else |
cur_time = ctx->serial; |
#endif |
cookie_time = ( (unsigned long) cookie[0] << 24 ) | |
( (unsigned long) cookie[1] << 16 ) | |
( (unsigned long) cookie[2] << 8 ) | |
( (unsigned long) cookie[3] ); |
if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout ) |
return( -1 ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_COOKIE_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_srv.c |
---|
0,0 → 1,4381 |
/* |
* SSLv3/TLSv1 server-side functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/debug.h" |
#include "mbedtls/ssl.h" |
#include "mbedtls/ssl_internal.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_ECP_C) |
#include "mbedtls/ecp.h" |
#endif |
#if defined(MBEDTLS_HAVE_TIME) |
#include "mbedtls/platform_time.h" |
#endif |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) |
int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, |
const unsigned char *info, |
size_t ilen ) |
{ |
if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
mbedtls_free( ssl->cli_id ); |
if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
memcpy( ssl->cli_id, info, ilen ); |
ssl->cli_id_len = ilen; |
return( 0 ); |
} |
void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, |
mbedtls_ssl_cookie_write_t *f_cookie_write, |
mbedtls_ssl_cookie_check_t *f_cookie_check, |
void *p_cookie ) |
{ |
conf->f_cookie_write = f_cookie_write; |
conf->f_cookie_check = f_cookie_check; |
conf->p_cookie = p_cookie; |
} |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
int ret; |
size_t servername_list_size, hostname_len; |
const unsigned char *p; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); |
if( len < 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); |
if( servername_list_size + 2 != len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
p = buf + 2; |
while( servername_list_size > 2 ) |
{ |
hostname_len = ( ( p[1] << 8 ) | p[2] ); |
if( hostname_len + 3 > servername_list_size ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) |
{ |
ret = ssl->conf->f_sni( ssl->conf->p_sni, |
ssl, p + 3, hostname_len ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
return( 0 ); |
} |
servername_list_size -= hostname_len + 3; |
p += hostname_len + 3; |
} |
if( servername_list_size != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
{ |
/* Check verify-data in constant-time. The length OTOH is no secret */ |
if( len != 1 + ssl->verify_data_len || |
buf[0] != ssl->verify_data_len || |
mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data, |
ssl->verify_data_len ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
{ |
if( len != 1 || buf[0] != 0x0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; |
} |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* |
* Status of the implementation of signature-algorithms extension: |
* |
* Currently, we are only considering the signature-algorithm extension |
* to pick a ciphersuite which allows us to send the ServerKeyExchange |
* message with a signature-hash combination that the user allows. |
* |
* We do *not* check whether all certificates in our certificate |
* chain are signed with an allowed signature-hash pair. |
* This needs to be done at a later stage. |
* |
*/ |
static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
size_t sig_alg_list_size; |
const unsigned char *p; |
const unsigned char *end = buf + len; |
mbedtls_md_type_t md_cur; |
mbedtls_pk_type_t sig_cur; |
if ( len < 2 ) { |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); |
if( sig_alg_list_size + 2 != len || |
sig_alg_list_size % 2 != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* Currently we only guarantee signing the ServerKeyExchange message according |
* to the constraints specified in this extension (see above), so it suffices |
* to remember only one suitable hash for each possible signature algorithm. |
* |
* This will change when we also consider certificate signatures, |
* in which case we will need to remember the whole signature-hash |
* pair list from the extension. |
*/ |
for( p = buf + 2; p < end; p += 2 ) |
{ |
/* Silently ignore unknown signature or hash algorithms. */ |
if( ( sig_cur = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext" |
" unknown sig alg encoding %d", p[1] ) ); |
continue; |
} |
/* Check if we support the hash the user proposes */ |
md_cur = mbedtls_ssl_md_alg_from_hash( p[0] ); |
if( md_cur == MBEDTLS_MD_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" |
" unknown hash alg encoding %d", p[0] ) ); |
continue; |
} |
if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 ) |
{ |
mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" |
" match sig %d and hash %d", |
sig_cur, md_cur ) ); |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: " |
"hash alg %d not supported", md_cur ) ); |
} |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
size_t list_size, our_size; |
const unsigned char *p; |
const mbedtls_ecp_curve_info *curve_info, **curves; |
if ( len < 2 ) { |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); |
if( list_size + 2 != len || |
list_size % 2 != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* Should never happen unless client duplicates the extension */ |
if( ssl->handshake->curves != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* Don't allow our peer to make us allocate too much memory, |
* and leave room for a final 0 */ |
our_size = list_size / 2 + 1; |
if( our_size > MBEDTLS_ECP_DP_MAX ) |
our_size = MBEDTLS_ECP_DP_MAX; |
if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
ssl->handshake->curves = curves; |
p = buf + 2; |
while( list_size > 0 && our_size > 1 ) |
{ |
curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] ); |
if( curve_info != NULL ) |
{ |
*curves++ = curve_info; |
our_size--; |
} |
list_size -= 2; |
p += 2; |
} |
return( 0 ); |
} |
static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
size_t list_size; |
const unsigned char *p; |
if( len == 0 || (size_t)( buf[0] + 1 ) != len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
list_size = buf[0]; |
p = buf + 1; |
while( list_size > 0 ) |
{ |
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || |
p[0] == MBEDTLS_ECP_PF_COMPRESSED ) |
{ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) |
ssl->handshake->ecdh_ctx.point_format = p[0]; |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
ssl->handshake->ecjpake_ctx.point_format = p[0]; |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); |
return( 0 ); |
} |
list_size--; |
p++; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || |
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
int ret; |
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); |
return( 0 ); |
} |
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, |
buf, len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( ret ); |
} |
/* Only mark the extension as OK when we're sure it is */ |
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ssl->session_negotiate->mfl_code = buf[0]; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
((void) buf); |
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) |
ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
((void) buf); |
if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED && |
ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, |
size_t len ) |
{ |
if( len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
((void) buf); |
if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED && |
ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t len ) |
{ |
int ret; |
mbedtls_ssl_session session; |
mbedtls_ssl_session_init( &session ); |
if( ssl->conf->f_ticket_parse == NULL || |
ssl->conf->f_ticket_write == NULL ) |
{ |
return( 0 ); |
} |
/* Remember the client asked us to send a new ticket */ |
ssl->handshake->new_session_ticket = 1; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) ); |
if( len == 0 ) |
return( 0 ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/* |
* Failures are ok: just ignore the ticket and proceed. |
*/ |
if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session, |
buf, len ) ) != 0 ) |
{ |
mbedtls_ssl_session_free( &session ); |
if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) ); |
else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED ) |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) ); |
else |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret ); |
return( 0 ); |
} |
/* |
* Keep the session ID sent by the client, since we MUST send it back to |
* inform them we're accepting the ticket (RFC 5077 section 3.4) |
*/ |
session.id_len = ssl->session_negotiate->id_len; |
memcpy( &session.id, ssl->session_negotiate->id, session.id_len ); |
mbedtls_ssl_session_free( ssl->session_negotiate ); |
memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); |
/* Zeroize instead of free as we copied the content */ |
mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); |
ssl->handshake->resume = 1; |
/* Don't send a new ticket after all, this one is OK */ |
ssl->handshake->new_session_ticket = 0; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_SSL_ALPN) |
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
size_t list_len, cur_len, ours_len; |
const unsigned char *theirs, *start, *end; |
const char **ours; |
/* If ALPN not configured, just ignore the extension */ |
if( ssl->conf->alpn_list == NULL ) |
return( 0 ); |
/* |
* opaque ProtocolName<1..2^8-1>; |
* |
* struct { |
* ProtocolName protocol_name_list<2..2^16-1> |
* } ProtocolNameList; |
*/ |
/* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ |
if( len < 4 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
list_len = ( buf[0] << 8 ) | buf[1]; |
if( list_len != len - 2 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* |
* Validate peer's list (lengths) |
*/ |
start = buf + 2; |
end = buf + len; |
for( theirs = start; theirs != end; theirs += cur_len ) |
{ |
cur_len = *theirs++; |
/* Current identifier must fit in list */ |
if( cur_len > (size_t)( end - theirs ) ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* Empty strings MUST NOT be included */ |
if( cur_len == 0 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
} |
/* |
* Use our order of preference |
*/ |
for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ ) |
{ |
ours_len = strlen( *ours ); |
for( theirs = start; theirs != end; theirs += cur_len ) |
{ |
cur_len = *theirs++; |
if( cur_len == ours_len && |
memcmp( theirs, *ours, cur_len ) == 0 ) |
{ |
ssl->alpn_chosen = *ours; |
return( 0 ); |
} |
} |
} |
/* If we get there, no match was found */ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
#endif /* MBEDTLS_SSL_ALPN */ |
/* |
* Auxiliary functions for ServerHello parsing and related actions |
*/ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/* |
* Return 0 if the given key uses one of the acceptable curves, -1 otherwise |
*/ |
#if defined(MBEDTLS_ECDSA_C) |
static int ssl_check_key_curve( mbedtls_pk_context *pk, |
const mbedtls_ecp_curve_info **curves ) |
{ |
const mbedtls_ecp_curve_info **crv = curves; |
mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id; |
while( *crv != NULL ) |
{ |
if( (*crv)->grp_id == grp_id ) |
return( 0 ); |
crv++; |
} |
return( -1 ); |
} |
#endif /* MBEDTLS_ECDSA_C */ |
/* |
* Try picking a certificate for this ciphersuite, |
* return 0 on success and -1 on failure. |
*/ |
static int ssl_pick_cert( mbedtls_ssl_context *ssl, |
const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) |
{ |
mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; |
mbedtls_pk_type_t pk_alg = |
mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); |
uint32_t flags; |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
if( ssl->handshake->sni_key_cert != NULL ) |
list = ssl->handshake->sni_key_cert; |
else |
#endif |
list = ssl->conf->key_cert; |
if( pk_alg == MBEDTLS_PK_NONE ) |
return( 0 ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) ); |
if( list == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) ); |
return( -1 ); |
} |
for( cur = list; cur != NULL; cur = cur->next ) |
{ |
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", |
cur->cert ); |
if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); |
continue; |
} |
/* |
* This avoids sending the client a cert it'll reject based on |
* keyUsage or other extensions. |
* |
* It also allows the user to provision different certificates for |
* different uses based on keyUsage, eg if they want to avoid signing |
* and decrypting with the same RSA key. |
*/ |
if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info, |
MBEDTLS_SSL_IS_SERVER, &flags ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: " |
"(extended) key usage extension" ) ); |
continue; |
} |
#if defined(MBEDTLS_ECDSA_C) |
if( pk_alg == MBEDTLS_PK_ECDSA && |
ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); |
continue; |
} |
#endif |
/* |
* Try to select a SHA-1 certificate for pre-1.2 clients, but still |
* present them a SHA-higher cert rather than failing if it's the only |
* one we got that satisfies the other conditions. |
*/ |
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 && |
cur->cert->sig_md != MBEDTLS_MD_SHA1 ) |
{ |
if( fallback == NULL ) |
fallback = cur; |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: " |
"sha-2 with pre-TLS 1.2 client" ) ); |
continue; |
} |
} |
/* If we get there, we got a winner */ |
break; |
} |
if( cur == NULL ) |
cur = fallback; |
/* Do not update ssl->handshake->key_cert unless there is a match */ |
if( cur != NULL ) |
{ |
ssl->handshake->key_cert = cur; |
MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate", |
ssl->handshake->key_cert->cert ); |
return( 0 ); |
} |
return( -1 ); |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
/* |
* Check if a given ciphersuite is suitable for use with our config/keys/etc |
* Sets ciphersuite_info only if the suite matches. |
*/ |
static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, |
const mbedtls_ssl_ciphersuite_t **ciphersuite_info ) |
{ |
const mbedtls_ssl_ciphersuite_t *suite_info; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
mbedtls_pk_type_t sig_type; |
#endif |
suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); |
if( suite_info == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) ); |
if( suite_info->min_minor_ver > ssl->minor_ver || |
suite_info->max_minor_ver < ssl->minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) |
return( 0 ); |
#endif |
#if defined(MBEDTLS_ARC4_C) |
if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && |
suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) ); |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && |
( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake " |
"not configured or ext missing" ) ); |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) |
if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && |
( ssl->handshake->curves == NULL || |
ssl->handshake->curves[0] == NULL ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " |
"no common elliptic curve" ) ); |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
/* If the ciphersuite requires a pre-shared key and we don't |
* have one, skip it now rather than failing later */ |
if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && |
ssl->conf->f_psk == NULL && |
( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || |
ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) ); |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* If the ciphersuite requires signing, check whether |
* a suitable hash algorithm is present. */ |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info ); |
if( sig_type != MBEDTLS_PK_NONE && |
mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm " |
"for signature algorithm %d", sig_type ) ); |
return( 0 ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
/* |
* Final check: if ciphersuite requires us to have a |
* certificate/key of a particular type: |
* - select the appropriate certificate if we have one, or |
* - try the next ciphersuite if we don't |
* This must be done last since we modify the key_cert list. |
*/ |
if( ssl_pick_cert( ssl, suite_info ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " |
"no suitable certificate" ) ); |
return( 0 ); |
} |
#endif |
*ciphersuite_info = suite_info; |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) |
static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) |
{ |
int ret, got_common_suite; |
unsigned int i, j; |
size_t n; |
unsigned int ciph_len, sess_len, chal_len; |
unsigned char *buf, *p; |
const int *ciphersuites; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
buf = ssl->in_hdr; |
MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, 5 ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d", |
buf[2] ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d", |
( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) ); |
MBEDTLS_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] != MBEDTLS_SSL_HS_CLIENT_HELLO || |
buf[3] != MBEDTLS_SSL_MAJOR_VERSION_3 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; |
if( n < 17 || n > 512 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; |
ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver ) |
? buf[4] : ssl->conf->max_minor_ver; |
if( ssl->minor_ver < ssl->conf->min_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" |
" [%d:%d] < [%d:%d]", |
ssl->major_ver, ssl->minor_ver, |
ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); |
return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); |
} |
ssl->handshake->max_major_ver = buf[3]; |
ssl->handshake->max_minor_ver = buf[4]; |
if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); |
return( ret ); |
} |
ssl->handshake->update_checksum( ssl, buf + 2, n ); |
buf = ssl->in_msg; |
n = ssl->in_left - 5; |
/* |
* 0 . 1 ciphersuitelist length |
* 2 . 3 session id length |
* 4 . 5 challenge length |
* 6 . .. ciphersuitelist |
* .. . .. session id |
* .. . .. challenge |
*/ |
MBEDTLS_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]; |
MBEDTLS_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 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
if( sess_len > 32 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
if( chal_len < 8 || chal_len > 32 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
if( n != 6 + ciph_len + sess_len + chal_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", |
buf + 6, ciph_len ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", |
buf + 6 + ciph_len, sess_len ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, challenge", |
buf + 6 + ciph_len + sess_len, chal_len ); |
p = buf + 6 + ciph_len; |
ssl->session_negotiate->id_len = sess_len; |
memset( ssl->session_negotiate->id, 0, |
sizeof( ssl->session_negotiate->id ) ); |
memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); |
p += sess_len; |
memset( ssl->handshake->randbytes, 0, 64 ); |
memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); |
/* |
* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV |
*/ |
for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) |
{ |
if( p[0] == 0 && p[1] == 0 && p[2] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " |
"during renegotiation" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; |
break; |
} |
} |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) |
for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) |
{ |
if( p[0] == 0 && |
p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && |
p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); |
if( ssl->minor_ver < ssl->conf->max_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
break; |
} |
} |
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ |
got_common_suite = 0; |
ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; |
ciphersuite_info = NULL; |
#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) |
for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) |
for( i = 0; ciphersuites[i] != 0; i++ ) |
#else |
for( i = 0; ciphersuites[i] != 0; i++ ) |
for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) |
#endif |
{ |
if( p[0] != 0 || |
p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || |
p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) |
continue; |
got_common_suite = 1; |
if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], |
&ciphersuite_info ) ) != 0 ) |
return( ret ); |
if( ciphersuite_info != NULL ) |
goto have_ciphersuite_v2; |
} |
if( got_common_suite ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " |
"but none of them usable" ) ); |
return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); |
return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); |
} |
have_ciphersuite_v2: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); |
ssl->session_negotiate->ciphersuite = ciphersuites[i]; |
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; |
/* |
* SSLv2 Client Hello relevant renegotiation security checks |
*/ |
if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ssl->in_left = 0; |
ssl->state++; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ |
/* This function doesn't alert on errors that happen early during |
ClientHello parsing because they might indicate that the client is |
not talking SSL/TLS at all and would not understand our alert. */ |
static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) |
{ |
int ret, got_common_suite; |
size_t i, j; |
size_t ciph_offset, comp_offset, ext_offset; |
size_t msg_len, ciph_len, sess_len, comp_len, ext_len; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
size_t cookie_offset, cookie_len; |
#endif |
unsigned char *buf, *p, *ext; |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
int renegotiation_info_seen = 0; |
#endif |
int handshake_failure = 0; |
const int *ciphersuites; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; |
int major, minor; |
/* If there is no signature-algorithm extension present, |
* we need to fall back to the default values for allowed |
* signature-hash pairs. */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
int sig_hash_alg_ext_present = 0; |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
read_record_header: |
#endif |
/* |
* If renegotiating, then the input was read with mbedtls_ssl_read_record(), |
* otherwise read it ourselves manually in order to support SSLv2 |
* ClientHello, which doesn't use the same record layer format. |
*/ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
#endif |
{ |
if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) |
{ |
/* No alert on a read error. */ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); |
return( ret ); |
} |
} |
buf = ssl->in_hdr; |
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) |
#endif |
if( ( buf[0] & 0x80 ) != 0 ) |
return( ssl_parse_client_hello_v2( ssl ) ); |
#endif |
MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); |
/* |
* SSLv3/TLS Client Hello |
* |
* Record layer: |
* 0 . 0 message type |
* 1 . 2 protocol version |
* 3 . 11 DTLS: epoch + record sequence number |
* 3 . 4 message length |
*/ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", |
buf[0] ) ); |
if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", |
( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]", |
buf[1], buf[2] ) ); |
mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 ); |
/* According to RFC 5246 Appendix E.1, the version here is typically |
* "{03,00}, the lowest version number supported by the client, [or] the |
* value of ClientHello.client_version", so the only meaningful check here |
* is the major version shouldn't be less than 3 */ |
if( major < MBEDTLS_SSL_MAJOR_VERSION_3 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* For DTLS if this is the initial handshake, remember the client sequence |
* number to use it in our next message (RFC 6347 4.2.1) */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
&& ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE |
#endif |
) |
{ |
/* Epoch should be 0 for initial handshakes */ |
if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 ); |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record, discarding" ) ); |
ssl->next_record_offset = 0; |
ssl->in_left = 0; |
goto read_record_header; |
} |
/* No MAC to check yet, so we can update right now */ |
mbedtls_ssl_dtls_replay_update( ssl ); |
#endif |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
{ |
/* Set by mbedtls_ssl_read_record() */ |
msg_len = ssl->in_hslen; |
} |
else |
#endif |
{ |
if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
if( ( ret = mbedtls_ssl_fetch_input( ssl, |
mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); |
return( ret ); |
} |
/* Done reading this record, get ready for the next one */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); |
else |
#endif |
ssl->in_left = 0; |
} |
buf = ssl->in_msg; |
MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len ); |
ssl->handshake->update_checksum( ssl, buf, msg_len ); |
/* |
* Handshake layer: |
* 0 . 0 handshake type |
* 1 . 3 handshake length |
* 4 . 5 DTLS only: message seqence number |
* 6 . 8 DTLS only: fragment offset |
* 9 . 11 DTLS only: fragment length |
*/ |
if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) ); |
if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", |
( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); |
/* We don't support fragmentation of ClientHello (yet?) */ |
if( buf[1] != 0 || |
msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
/* |
* Copy the client's handshake message_seq on initial handshakes, |
* check sequence number on renego. |
*/ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
/* This couldn't be done in ssl_prepare_handshake_record() */ |
unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | |
ssl->in_msg[5]; |
if( cli_msg_seq != ssl->handshake->in_msg_seq ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: " |
"%d (expected %d)", cli_msg_seq, |
ssl->handshake->in_msg_seq ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ssl->handshake->in_msg_seq++; |
} |
else |
#endif |
{ |
unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | |
ssl->in_msg[5]; |
ssl->handshake->out_msg_seq = cli_msg_seq; |
ssl->handshake->in_msg_seq = cli_msg_seq + 1; |
} |
/* |
* For now we don't support fragmentation, so make sure |
* fragment_offset == 0 and fragment_length == length |
*/ |
if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || |
memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
buf += mbedtls_ssl_hs_hdr_len( ssl ); |
msg_len -= mbedtls_ssl_hs_hdr_len( ssl ); |
/* |
* ClientHello layer: |
* 0 . 1 protocol version |
* 2 . 33 random bytes (starting with 4 bytes of Unix time) |
* 34 . 35 session id length (1 byte) |
* 35 . 34+x session id |
* 35+x . 35+x DTLS only: cookie length (1 byte) |
* 36+x . .. DTLS only: cookie |
* .. . .. ciphersuite list length (2 bytes) |
* .. . .. ciphersuite list |
* .. . .. compression alg. list length (1 byte) |
* .. . .. compression alg. list |
* .. . .. extensions length (2 bytes, optional) |
* .. . .. extensions (optional) |
*/ |
/* |
* Minimal length (with everything empty and extensions omitted) is |
* 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can |
* read at least up to session id length without worrying. |
*/ |
if( msg_len < 38 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* |
* Check and save the protocol version |
*/ |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 ); |
mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, |
ssl->conf->transport, buf ); |
ssl->handshake->max_major_ver = ssl->major_ver; |
ssl->handshake->max_minor_ver = ssl->minor_ver; |
if( ssl->major_ver < ssl->conf->min_major_ver || |
ssl->minor_ver < ssl->conf->min_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" |
" [%d:%d] < [%d:%d]", |
ssl->major_ver, ssl->minor_ver, |
ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); |
return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); |
} |
if( ssl->major_ver > ssl->conf->max_major_ver ) |
{ |
ssl->major_ver = ssl->conf->max_major_ver; |
ssl->minor_ver = ssl->conf->max_minor_ver; |
} |
else if( ssl->minor_ver > ssl->conf->max_minor_ver ) |
ssl->minor_ver = ssl->conf->max_minor_ver; |
/* |
* Save client random (inc. Unix time) |
*/ |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 ); |
memcpy( ssl->handshake->randbytes, buf + 2, 32 ); |
/* |
* Check the session ID length and save session ID |
*/ |
sess_len = buf[34]; |
if( sess_len > sizeof( ssl->session_negotiate->id ) || |
sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len ); |
ssl->session_negotiate->id_len = sess_len; |
memset( ssl->session_negotiate->id, 0, |
sizeof( ssl->session_negotiate->id ) ); |
memcpy( ssl->session_negotiate->id, buf + 35, |
ssl->session_negotiate->id_len ); |
/* |
* Check the cookie length and content |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
cookie_offset = 35 + sess_len; |
cookie_len = buf[cookie_offset]; |
if( cookie_offset + 1 + cookie_len + 2 > msg_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", |
buf + cookie_offset + 1, cookie_len ); |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) |
if( ssl->conf->f_cookie_check != NULL |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
&& ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE |
#endif |
) |
{ |
if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, |
buf + cookie_offset + 1, cookie_len, |
ssl->cli_id, ssl->cli_id_len ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) ); |
ssl->handshake->verify_cookie_len = 1; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) ); |
ssl->handshake->verify_cookie_len = 0; |
} |
} |
else |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ |
{ |
/* We know we didn't send a cookie, so it should be empty */ |
if( cookie_len != 0 ) |
{ |
/* This may be an attacker's probe, so don't send an alert */ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) ); |
} |
/* |
* Check the ciphersuitelist length (will be parsed later) |
*/ |
ciph_offset = cookie_offset + 1 + cookie_len; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
ciph_offset = 35 + sess_len; |
ciph_len = ( buf[ciph_offset + 0] << 8 ) |
| ( buf[ciph_offset + 1] ); |
if( ciph_len < 2 || |
ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ |
( ciph_len % 2 ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", |
buf + ciph_offset + 2, ciph_len ); |
/* |
* Check the compression algorithms length and pick one |
*/ |
comp_offset = ciph_offset + 2 + ciph_len; |
comp_len = buf[comp_offset]; |
if( comp_len < 1 || |
comp_len > 16 || |
comp_len + comp_offset + 1 > msg_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression", |
buf + comp_offset + 1, comp_len ); |
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
for( i = 0; i < comp_len; ++i ) |
{ |
if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE ) |
{ |
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE; |
break; |
} |
} |
#endif |
/* See comments in ssl_write_client_hello() */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; |
#endif |
/* Do not parse the extensions if the protocol is SSLv3 */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) |
{ |
#endif |
/* |
* Check the extension length |
*/ |
ext_offset = comp_offset + 1 + comp_len; |
if( msg_len > ext_offset ) |
{ |
if( msg_len < ext_offset + 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ext_len = ( buf[ext_offset + 0] << 8 ) |
| ( buf[ext_offset + 1] ); |
if( ( ext_len > 0 && ext_len < 4 ) || |
msg_len != ext_offset + 2 + ext_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
} |
else |
ext_len = 0; |
ext = buf + ext_offset + 2; |
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); |
while( ext_len != 0 ) |
{ |
unsigned int ext_id; |
unsigned int ext_size; |
if ( ext_len < 4 ) { |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) ); |
ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) ); |
if( ext_size + 4 > ext_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
switch( ext_id ) |
{ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
case MBEDTLS_TLS_EXT_SERVERNAME: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); |
if( ssl->conf->f_sni == NULL ) |
break; |
ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
renegotiation_info_seen = 1; |
#endif |
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
case MBEDTLS_TLS_EXT_SIG_ALG: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); |
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
sig_hash_alg_ext_present = 1; |
break; |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); |
ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); |
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; |
ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || |
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) ); |
ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); |
ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); |
ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); |
ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); |
ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
case MBEDTLS_TLS_EXT_SESSION_TICKET: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); |
ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_SSL_ALPN) |
case MBEDTLS_TLS_EXT_ALPN: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); |
ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); |
if( ret != 0 ) |
return( ret ); |
break; |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
default: |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", |
ext_id ) ); |
} |
ext_len -= 4 + ext_size; |
ext += 4 + ext_size; |
if( ext_len > 0 && ext_len < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
} |
#endif |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) |
for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) |
{ |
if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && |
p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) ); |
if( ssl->minor_ver < ssl->conf->max_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
break; |
} |
} |
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* |
* Try to fall back to default hash SHA1 if the client |
* hasn't provided any preferred signature-hash combinations. |
*/ |
if( sig_hash_alg_ext_present == 0 ) |
{ |
mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1; |
if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 ) |
md_default = MBEDTLS_MD_NONE; |
mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
/* |
* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV |
*/ |
for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) |
{ |
if( p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " |
"during renegotiation" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
#endif |
ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; |
break; |
} |
} |
/* |
* Renegotiation security checks |
*/ |
if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && |
ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); |
handshake_failure = 1; |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && |
renegotiation_info_seen == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); |
handshake_failure = 1; |
} |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); |
handshake_failure = 1; |
} |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
renegotiation_info_seen == 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); |
handshake_failure = 1; |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
if( handshake_failure == 1 ) |
{ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
/* |
* Search for a matching ciphersuite |
* (At the end because we need information from the EC-based extensions |
* and certificate from the SNI callback triggered by the SNI extension.) |
*/ |
got_common_suite = 0; |
ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; |
ciphersuite_info = NULL; |
#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) |
for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) |
for( i = 0; ciphersuites[i] != 0; i++ ) |
#else |
for( i = 0; ciphersuites[i] != 0; i++ ) |
for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) |
#endif |
{ |
if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || |
p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) |
continue; |
got_common_suite = 1; |
if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], |
&ciphersuite_info ) ) != 0 ) |
return( ret ); |
if( ciphersuite_info != NULL ) |
goto have_ciphersuite; |
} |
if( got_common_suite ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " |
"but none of them usable" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); |
return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); |
} |
have_ciphersuite: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); |
ssl->session_negotiate->ciphersuite = ciphersuites[i]; |
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; |
ssl->state++; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
mbedtls_ssl_recv_flight_completed( ssl ); |
#endif |
/* Debugging-only output for testsuite */ |
#if defined(MBEDTLS_DEBUG_C) && \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info ); |
if( sig_alg != MBEDTLS_PK_NONE ) |
{ |
mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, |
sig_alg ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", |
mbedtls_ssl_hash_from_md_alg( md_alg ) ) ); |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm " |
"%d - should not happen", sig_alg ) ); |
} |
} |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
const mbedtls_ssl_ciphersuite_t *suite = NULL; |
const mbedtls_cipher_info_t *cipher = NULL; |
if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
*olen = 0; |
return; |
} |
/* |
* RFC 7366: "If a server receives an encrypt-then-MAC request extension |
* from a client and then selects a stream or Authenticated Encryption |
* with Associated Data (AEAD) ciphersuite, it MUST NOT send an |
* encrypt-then-MAC response extension back to the client." |
*/ |
if( ( suite = mbedtls_ssl_ciphersuite_from_id( |
ssl->session_negotiate->ciphersuite ) ) == NULL || |
( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL || |
cipher->mode != MBEDTLS_MODE_CBC ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret " |
"extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
if( ssl->handshake->new_session_ticket == 0 ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 0x00; |
*olen = 4; |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) |
{ |
*p++ = 0x00; |
*p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; |
*p++ = ssl->verify_data_len * 2 & 0xFF; |
memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); |
p += ssl->verify_data_len; |
memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); |
p += ssl->verify_data_len; |
} |
else |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
{ |
*p++ = 0x00; |
*p++ = 0x01; |
*p++ = 0x00; |
} |
*olen = p - buf; |
} |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
if( ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 1; |
*p++ = ssl->session_negotiate->mfl_code; |
*olen = 5; |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
((void) ssl); |
if( ( ssl->handshake->cli_exts & |
MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); |
*p++ = 0x00; |
*p++ = 2; |
*p++ = 1; |
*p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; |
*olen = 6; |
} |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, |
size_t *olen ) |
{ |
int ret; |
unsigned char *p = buf; |
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
size_t kkpp_len; |
*olen = 0; |
/* Skip costly computation if not needed */ |
if( ssl->transform_negotiate->ciphersuite_info->key_exchange != |
MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) ); |
if( end - p < 4 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); |
return; |
} |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); |
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, |
p + 2, end - p - 2, &kkpp_len, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); |
return; |
} |
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); |
*olen = kkpp_len + 4; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_SSL_ALPN ) |
static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, |
unsigned char *buf, size_t *olen ) |
{ |
if( ssl->alpn_chosen == NULL ) |
{ |
*olen = 0; |
return; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) ); |
/* |
* 0 . 1 ext identifier |
* 2 . 3 ext length |
* 4 . 5 protocol list length |
* 6 . 6 protocol name length |
* 7 . 7+n protocol name |
*/ |
buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); |
buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); |
*olen = 7 + strlen( ssl->alpn_chosen ); |
buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); |
buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); |
buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); |
buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); |
buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); |
memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); |
} |
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) |
static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned char *p = ssl->out_msg + 4; |
unsigned char *cookie_len_byte; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) ); |
/* |
* struct { |
* ProtocolVersion server_version; |
* opaque cookie<0..2^8-1>; |
* } HelloVerifyRequest; |
*/ |
/* The RFC is not clear on this point, but sending the actual negotiated |
* version looks like the most interoperable thing to do. */ |
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, |
ssl->conf->transport, p ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); |
p += 2; |
/* If we get here, f_cookie_check is not null */ |
if( ssl->conf->f_cookie_write == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* Skip length byte until we know the length */ |
cookie_len_byte = p++; |
if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, |
&p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, |
ssl->cli_id, ssl->cli_id_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); |
return( ret ); |
} |
*cookie_len_byte = (unsigned char)( p - ( cookie_len_byte + 1 ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte ); |
ssl->out_msglen = p - ssl->out_msg; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; |
ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ |
static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) |
{ |
#if defined(MBEDTLS_HAVE_TIME) |
mbedtls_time_t t; |
#endif |
int ret; |
size_t olen, ext_len = 0, n; |
unsigned char *buf, *p; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake->verify_cookie_len != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); |
return( ssl_write_hello_verify_request( ssl ) ); |
} |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ |
if( ssl->conf->f_rng == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); |
return( MBEDTLS_ERR_SSL_NO_RNG ); |
} |
/* |
* 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; |
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, |
ssl->conf->transport, p ); |
p += 2; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", |
buf[4], buf[5] ) ); |
#if defined(MBEDTLS_HAVE_TIME) |
t = mbedtls_time( NULL ); |
*p++ = (unsigned char)( t >> 24 ); |
*p++ = (unsigned char)( t >> 16 ); |
*p++ = (unsigned char)( t >> 8 ); |
*p++ = (unsigned char)( t ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); |
#else |
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) |
return( ret ); |
p += 4; |
#endif /* MBEDTLS_HAVE_TIME */ |
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) |
return( ret ); |
p += 28; |
memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); |
/* |
* Resume is 0 by default, see ssl_handshake_init(). |
* It may be already set to 1 by ssl_parse_session_ticket_ext(). |
* If not, try looking up session ID in our cache. |
*/ |
if( ssl->handshake->resume == 0 && |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && |
#endif |
ssl->session_negotiate->id_len != 0 && |
ssl->conf->f_get_cache != NULL && |
ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); |
ssl->handshake->resume = 1; |
} |
if( ssl->handshake->resume == 0 ) |
{ |
/* |
* New session, create a new session id, |
* unless we're about to issue a session ticket |
*/ |
ssl->state++; |
#if defined(MBEDTLS_HAVE_TIME) |
ssl->session_negotiate->start = mbedtls_time( NULL ); |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
if( ssl->handshake->new_session_ticket != 0 ) |
{ |
ssl->session_negotiate->id_len = n = 0; |
memset( ssl->session_negotiate->id, 0, 32 ); |
} |
else |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
{ |
ssl->session_negotiate->id_len = n = 32; |
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, |
n ) ) != 0 ) |
return( ret ); |
} |
} |
else |
{ |
/* |
* Resuming a session |
*/ |
n = ssl->session_negotiate->id_len; |
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; |
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); |
return( ret ); |
} |
} |
/* |
* 38 . 38 session id length |
* 39 . 38+n session id |
* 39+n . 40+n chosen ciphersuite |
* 41+n . 41+n chosen compression alg. |
* 42+n . 43+n extensions length |
* 44+n . 43+n+m extensions |
*/ |
*p++ = (unsigned char) ssl->session_negotiate->id_len; |
memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len ); |
p += ssl->session_negotiate->id_len; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", |
ssl->handshake->resume ? "a" : "no" ) ); |
*p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); |
*p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); |
*p++ = (unsigned char)( ssl->session_negotiate->compression ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", |
mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", |
ssl->session_negotiate->compression ) ); |
/* Do not write the extensions if the protocol is SSLv3 */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) |
{ |
#endif |
/* |
* First write extensions, then the total length |
*/ |
ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if ( mbedtls_ssl_ciphersuite_uses_ec( |
mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) ) |
{ |
ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
} |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
#if defined(MBEDTLS_SSL_ALPN) |
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); |
ext_len += olen; |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); |
if( ext_len > 0 ) |
{ |
*p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( ext_len ) & 0xFF ); |
p += ext_len; |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
} |
#endif |
ssl->out_msglen = p - buf; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; |
ret = mbedtls_ssl_write_handshake_msg( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); |
return( ret ); |
} |
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); |
ssl->state++; |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#else |
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
size_t dn_size, total_dn_size; /* excluding length bytes */ |
size_t ct_len, sa_len; /* including length bytes */ |
unsigned char *buf, *p; |
const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; |
const mbedtls_x509_crt *crt; |
int authmode; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); |
ssl->state++; |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) |
authmode = ssl->handshake->sni_authmode; |
else |
#endif |
authmode = ssl->conf->authmode; |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || |
authmode == MBEDTLS_SSL_VERIFY_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); |
return( 0 ); |
} |
/* |
* 0 . 0 handshake type |
* 1 . 3 handshake length |
* 4 . 4 cert type count |
* 5 .. m-1 cert types |
* m .. m+1 sig alg length (TLS 1.2 only) |
* m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) |
* 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; |
/* |
* Supported certificate types |
* |
* ClientCertificateType certificate_types<1..2^8-1>; |
* enum { (255) } ClientCertificateType; |
*/ |
ct_len = 0; |
#if defined(MBEDTLS_RSA_C) |
p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; |
#endif |
p[0] = (unsigned char) ct_len++; |
p += ct_len; |
sa_len = 0; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
/* |
* Add signature_algorithms for verify (TLS 1.2) |
* |
* SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; |
* |
* struct { |
* HashAlgorithm hash; |
* SignatureAlgorithm signature; |
* } SignatureAndHashAlgorithm; |
* |
* enum { (255) } HashAlgorithm; |
* enum { (255) } SignatureAlgorithm; |
*/ |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
const int *cur; |
/* |
* Supported signature algorithms |
*/ |
for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) |
{ |
unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); |
if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) |
continue; |
#if defined(MBEDTLS_RSA_C) |
p[2 + sa_len++] = hash; |
p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
p[2 + sa_len++] = hash; |
p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; |
#endif |
} |
p[0] = (unsigned char)( sa_len >> 8 ); |
p[1] = (unsigned char)( sa_len ); |
sa_len += 2; |
p += sa_len; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
/* |
* DistinguishedName certificate_authorities<0..2^16-1>; |
* opaque DistinguishedName<1..2^16-1>; |
*/ |
p += 2; |
total_dn_size = 0; |
if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) |
{ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
if( ssl->handshake->sni_ca_chain != NULL ) |
crt = ssl->handshake->sni_ca_chain; |
else |
#endif |
crt = ssl->conf->ca_chain; |
while( crt != NULL && crt->version != 0 ) |
{ |
dn_size = crt->subject_raw.len; |
if( end < p || |
(size_t)( end - p ) < dn_size || |
(size_t)( end - p ) < 2 + dn_size ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); |
break; |
} |
*p++ = (unsigned char)( dn_size >> 8 ); |
*p++ = (unsigned char)( dn_size ); |
memcpy( p, crt->subject_raw.p, dn_size ); |
p += dn_size; |
MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); |
total_dn_size += 2 + dn_size; |
crt = crt->next; |
} |
} |
ssl->out_msglen = p - buf; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; |
ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); |
ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); |
ret = mbedtls_ssl_write_handshake_msg( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); |
return( ret ); |
} |
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); |
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); |
} |
if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, |
mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ), |
MBEDTLS_ECDH_OURS ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ |
defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, |
size_t *signature_len ) |
{ |
/* Append the signature to ssl->out_msg, leaving 2 bytes for the |
* signature length which will be added in ssl_write_server_key_exchange |
* after the call to ssl_prepare_server_key_exchange. |
* ssl_write_server_key_exchange also takes care of incrementing |
* ssl->out_msglen. */ |
unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; |
size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN |
- sig_start ); |
int ret = ssl->conf->f_async_resume( ssl, |
sig_start, signature_len, sig_max_len ); |
if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) |
{ |
ssl->handshake->async_in_progress = 0; |
mbedtls_ssl_set_async_operation_data( ssl, NULL ); |
} |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); |
return( ret ); |
} |
#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && |
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ |
/* Prepare the ServerKeyExchange message, up to and including |
* calculating the signature if any, but excluding formatting the |
* signature and sending the message. */ |
static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, |
size_t *signature_len ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
unsigned char *dig_signed = NULL; |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ |
(void) ciphersuite_info; /* unused in some configurations */ |
#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
(void) signature_len; |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ |
ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ |
/* |
* |
* Part 1: Provide key exchange parameters for chosen ciphersuite. |
* |
*/ |
/* |
* - ECJPAKE key exchanges |
*/ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
int ret; |
size_t len = 0; |
ret = mbedtls_ecjpake_write_round_two( |
&ssl->handshake->ecjpake_ctx, |
ssl->out_msg + ssl->out_msglen, |
MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); |
return( ret ); |
} |
ssl->out_msglen += len; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
/* |
* For (EC)DHE key exchanges with PSK, parameters are prefixed by support |
* identity hint (RFC 4279, Sec. 3). Until someone needs this feature, |
* we use empty support identity hints here. |
**/ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) |
{ |
ssl->out_msg[ssl->out_msglen++] = 0x00; |
ssl->out_msg[ssl->out_msglen++] = 0x00; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
/* |
* - DHE key exchanges |
*/ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) |
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) |
{ |
int ret; |
size_t len = 0; |
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
/* |
* 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 = mbedtls_dhm_set_group( &ssl->handshake->dhm_ctx, |
&ssl->conf->dhm_P, |
&ssl->conf->dhm_G ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_set_group", ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_dhm_make_params( |
&ssl->handshake->dhm_ctx, |
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), |
ssl->out_msg + ssl->out_msglen, &len, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
dig_signed = ssl->out_msg + ssl->out_msglen; |
#endif |
ssl->out_msglen += len; |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */ |
/* |
* - ECDHE key exchanges |
*/ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) |
if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) ) |
{ |
/* |
* Ephemeral ECDH parameters: |
* |
* struct { |
* ECParameters curve_params; |
* ECPoint public; |
* } ServerECDHParams; |
*/ |
const mbedtls_ecp_curve_info **curve = NULL; |
const mbedtls_ecp_group_id *gid; |
int ret; |
size_t len = 0; |
/* Match our preference list against the offered curves */ |
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) |
for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) |
if( (*curve)->grp_id == *gid ) |
goto curve_matching_done; |
curve_matching_done: |
if( curve == NULL || *curve == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); |
return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); |
if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx, |
(*curve)->grp_id ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_ecdh_make_params( |
&ssl->handshake->ecdh_ctx, &len, |
ssl->out_msg + ssl->out_msglen, |
MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
dig_signed = ssl->out_msg + ssl->out_msglen; |
#endif |
ssl->out_msglen += len; |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_Q ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ |
/* |
* |
* Part 2: For key exchanges involving the server signing the |
* exchange parameters, compute and add the signature here. |
* |
*/ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) |
{ |
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed; |
size_t hashlen = 0; |
unsigned char hash[MBEDTLS_MD_MAX_SIZE]; |
int ret; |
/* |
* 2.1: Choose hash algorithm: |
* A: For TLS 1.2, obey signature-hash-algorithm extension |
* to choose appropriate hash. |
* B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 |
* (RFC 4492, Sec. 5.4) |
* C: Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3) |
*/ |
mbedtls_md_type_t md_alg; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
mbedtls_pk_type_t sig_alg = |
mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
/* A: For TLS 1.2, obey signature-hash-algorithm extension |
* (RFC 5246, Sec. 7.4.1.4.1). */ |
if( sig_alg == MBEDTLS_PK_NONE || |
( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, |
sig_alg ) ) == MBEDTLS_MD_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
/* (... because we choose a cipher suite |
* only if there is a matching hash.) */ |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) |
{ |
/* B: Default hash SHA1 */ |
md_alg = MBEDTLS_MD_SHA1; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
{ |
/* C: MD5 + SHA1 */ |
md_alg = MBEDTLS_MD_NONE; |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); |
/* |
* 2.2: Compute the hash to be signed |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( md_alg == MBEDTLS_MD_NONE ) |
{ |
hashlen = 36; |
ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, |
dig_signed, |
dig_signed_len ); |
if( ret != 0 ) |
return( ret ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( md_alg != MBEDTLS_MD_NONE ) |
{ |
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, |
dig_signed, |
dig_signed_len, |
md_alg ); |
if( ret != 0 ) |
return( ret ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); |
/* |
* 2.3: Compute and add the signature |
*/ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
/* |
* For TLS 1.2, we need to specify signature and hash algorithm |
* explicitly through a prefix to the signature. |
* |
* struct { |
* HashAlgorithm hash; |
* SignatureAlgorithm signature; |
* } SignatureAndHashAlgorithm; |
* |
* struct { |
* SignatureAndHashAlgorithm algorithm; |
* opaque signature<0..2^16-1>; |
* } DigitallySigned; |
* |
*/ |
ssl->out_msg[ssl->out_msglen++] = |
mbedtls_ssl_hash_from_md_alg( md_alg ); |
ssl->out_msg[ssl->out_msglen++] = |
mbedtls_ssl_sig_from_pk_alg( sig_alg ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
if( ssl->conf->f_async_sign_start != NULL ) |
{ |
ret = ssl->conf->f_async_sign_start( ssl, |
mbedtls_ssl_own_cert( ssl ), |
md_alg, hash, hashlen ); |
switch( ret ) |
{ |
case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: |
/* act as if f_async_sign was null */ |
break; |
case 0: |
ssl->handshake->async_in_progress = 1; |
return( ssl_resume_server_key_exchange( ssl, signature_len ) ); |
case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: |
ssl->handshake->async_in_progress = 1; |
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); |
default: |
MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
if( mbedtls_ssl_own_key( ssl ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); |
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); |
} |
/* Append the signature to ssl->out_msg, leaving 2 bytes for the |
* signature length which will be added in ssl_write_server_key_exchange |
* after the call to ssl_prepare_server_key_exchange. |
* ssl_write_server_key_exchange also takes care of incrementing |
* ssl->out_msglen. */ |
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), |
md_alg, hash, hashlen, |
ssl->out_msg + ssl->out_msglen + 2, |
signature_len, |
ssl->conf->f_rng, |
ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ |
return( 0 ); |
} |
/* Prepare the ServerKeyExchange message and send it. For ciphersuites |
* that do not include a ServerKeyExchange message, do nothing. Either |
* way, if successful, move on to the next step in the SSL state |
* machine. */ |
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
size_t signature_len = 0; |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) |
/* Extract static ECDH parameters and abort if ServerKeyExchange |
* is not needed. */ |
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) |
{ |
/* For suites involving ECDH, extract DH parameters |
* from certificate at this point. */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) |
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) |
{ |
ssl_get_ecdh_params_from_cert( ssl ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ |
/* Key exchanges not involving ephemeral keys don't use |
* ServerKeyExchange, so end here. */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); |
ssl->state++; |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ |
defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
/* If we have already prepared the message and there is an ongoing |
* signature operation, resume signing. */ |
if( ssl->handshake->async_in_progress != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); |
ret = ssl_resume_server_key_exchange( ssl, &signature_len ); |
} |
else |
#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && |
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ |
{ |
/* ServerKeyExchange is needed. Prepare the message. */ |
ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); |
} |
if( ret != 0 ) |
{ |
/* If we're starting to write a new message, set ssl->out_msglen |
* to 0. But if we're resuming after an asynchronous message, |
* out_msglen is the amount of data written so far and mst be |
* preserved. */ |
if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) ); |
else |
ssl->out_msglen = 0; |
return( ret ); |
} |
/* If there is a signature, write its length. |
* ssl_prepare_server_key_exchange already wrote the signature |
* itself at its proper place in the output buffer. */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) |
if( signature_len != 0 ) |
{ |
ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 ); |
ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", |
ssl->out_msg + ssl->out_msglen, |
signature_len ); |
/* Skip over the already-written signature */ |
ssl->out_msglen += signature_len; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ |
/* Add header and send. */ |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; |
ssl->state++; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); |
return( 0 ); |
} |
static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) ); |
ssl->out_msglen = 4; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; |
ssl->state++; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
mbedtls_ssl_send_flight_completed( ssl ); |
#endif |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p, |
const unsigned char *end ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
size_t n; |
/* |
* Receive G^Y mod P, premaster = (G^Y)^X mod P |
*/ |
if( *p + 2 > end ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
n = ( (*p)[0] << 8 ) | (*p)[1]; |
*p += 2; |
if( *p + n > end ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); |
} |
*p += n; |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); |
return( ret ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl, |
unsigned char *peer_pms, |
size_t *peer_pmslen, |
size_t peer_pmssize ) |
{ |
int ret = ssl->conf->f_async_resume( ssl, |
peer_pms, peer_pmslen, peer_pmssize ); |
if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) |
{ |
ssl->handshake->async_in_progress = 0; |
mbedtls_ssl_set_async_operation_data( ssl, NULL ); |
} |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, |
const unsigned char *p, |
const unsigned char *end, |
unsigned char *peer_pms, |
size_t *peer_pmslen, |
size_t peer_pmssize ) |
{ |
int ret; |
mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); |
mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; |
size_t len = mbedtls_pk_get_len( public_key ); |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
/* If we have already started decoding the message and there is an ongoing |
* decryption operation, resume signing. */ |
if( ssl->handshake->async_in_progress != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) ); |
return( ssl_resume_decrypt_pms( ssl, |
peer_pms, peer_pmslen, peer_pmssize ) ); |
} |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
/* |
* Prepare to decrypt the premaster using own private RSA key |
*/ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
if ( p + 2 > end ) { |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( *p++ != ( ( len >> 8 ) & 0xFF ) || |
*p++ != ( ( len ) & 0xFF ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
} |
#endif |
if( p + len != end ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
/* |
* Decrypt the premaster secret |
*/ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
if( ssl->conf->f_async_decrypt_start != NULL ) |
{ |
ret = ssl->conf->f_async_decrypt_start( ssl, |
mbedtls_ssl_own_cert( ssl ), |
p, len ); |
switch( ret ) |
{ |
case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: |
/* act as if f_async_decrypt_start was null */ |
break; |
case 0: |
ssl->handshake->async_in_progress = 1; |
return( ssl_resume_decrypt_pms( ssl, |
peer_pms, |
peer_pmslen, |
peer_pmssize ) ); |
case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: |
ssl->handshake->async_in_progress = 1; |
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); |
default: |
MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); |
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); |
} |
ret = mbedtls_pk_decrypt( private_key, p, len, |
peer_pms, peer_pmslen, peer_pmssize, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
return( ret ); |
} |
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, |
const unsigned char *p, |
const unsigned char *end, |
size_t pms_offset ) |
{ |
int ret; |
unsigned char *pms = ssl->handshake->premaster + pms_offset; |
unsigned char ver[2]; |
unsigned char fake_pms[48], peer_pms[48]; |
unsigned char mask; |
size_t i, peer_pmslen; |
unsigned int diff; |
/* In case of a failure in decryption, the decryption may write less than |
* 2 bytes of output, but we always read the first two bytes. It doesn't |
* matter in the end because diff will be nonzero in that case due to |
* peer_pmslen being less than 48, and we only care whether diff is 0. |
* But do initialize peer_pms for robustness anyway. This also makes |
* memory analyzers happy (don't access uninitialized memory, even |
* if it's an unsigned char). */ |
peer_pms[0] = peer_pms[1] = ~0; |
ret = ssl_decrypt_encrypted_pms( ssl, p, end, |
peer_pms, |
&peer_pmslen, |
sizeof( peer_pms ) ); |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) |
return( ret ); |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
mbedtls_ssl_write_version( ssl->handshake->max_major_ver, |
ssl->handshake->max_minor_ver, |
ssl->conf->transport, ver ); |
/* Avoid data-dependent branches while checking for invalid |
* padding, to protect against timing-based Bleichenbacher-type |
* attacks. */ |
diff = (unsigned int) ret; |
diff |= peer_pmslen ^ 48; |
diff |= peer_pms[0] ^ ver[0]; |
diff |= peer_pms[1] ^ ver[1]; |
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ |
/* MSVC has a warning about unary minus on unsigned, but this is |
* well-defined and precisely what we want to do here */ |
#if defined(_MSC_VER) |
#pragma warning( push ) |
#pragma warning( disable : 4146 ) |
#endif |
mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); |
#if defined(_MSC_VER) |
#pragma warning( pop ) |
#endif |
/* |
* 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. |
* To protect against timing-based variants of the attack, we must |
* not have any branch that depends on whether the decryption was |
* successful. In particular, always generate the fake premaster secret, |
* regardless of whether it will ultimately influence the output or not. |
*/ |
ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); |
if( ret != 0 ) |
{ |
/* It's ok to abort on an RNG failure, since this does not reveal |
* anything about the RSA decryption. */ |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
if( diff != 0 ) |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
#endif |
if( sizeof( ssl->handshake->premaster ) < pms_offset || |
sizeof( ssl->handshake->premaster ) - pms_offset < 48 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->handshake->pmslen = 48; |
/* Set pms to either the true or the fake PMS, without |
* data-dependent branches. */ |
for( i = 0; i < ssl->handshake->pmslen; i++ ) |
pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p, |
const unsigned char *end ) |
{ |
int ret = 0; |
size_t n; |
if( ssl->conf->f_psk == NULL && |
( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || |
ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); |
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); |
} |
/* |
* Receive client pre-shared key identity name |
*/ |
if( end - *p < 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
n = ( (*p)[0] << 8 ) | (*p)[1]; |
*p += 2; |
if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( ssl->conf->f_psk != NULL ) |
{ |
if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 ) |
ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; |
} |
else |
{ |
/* Identity is not a big secret since clients send it in the clear, |
* but treat it carefully anyway, just in case */ |
if( n != ssl->conf->psk_identity_len || |
mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) |
{ |
ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; |
} |
} |
if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ) |
{ |
MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ); |
return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ); |
} |
*p += n; |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; |
unsigned char *p, *end; |
ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \ |
( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) ) |
if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) && |
( ssl->handshake->async_in_progress != 0 ) ) |
{ |
/* We've already read a record and there is an asynchronous |
* operation in progress to decrypt it. So skip reading the |
* record. */ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) ); |
} |
else |
#endif |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); |
end = ssl->in_msg + ssl->in_hslen; |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) |
{ |
if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); |
return( ret ); |
} |
if( p != end ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, |
ssl->handshake->premaster, |
MBEDTLS_PREMASTER_SIZE, |
&ssl->handshake->pmslen, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); |
} |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) |
{ |
if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, |
p, end - p) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); |
} |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_QP ); |
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, |
&ssl->handshake->pmslen, |
ssl->handshake->premaster, |
MBEDTLS_MPI_MAX_SIZE, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); |
} |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_Z ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || |
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) |
{ |
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); |
return( ret ); |
} |
if( p != end ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, |
ciphersuite_info->key_exchange ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) |
{ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
if ( ssl->handshake->async_in_progress != 0 ) |
{ |
/* There is an asynchronous operation in progress to |
* decrypt the encrypted premaster secret, so skip |
* directly to resuming this operation. */ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) ); |
/* Update p to skip the PSK identity. ssl_parse_encrypted_pms |
* won't actually use it, but maintain p anyway for robustness. */ |
p += ssl->conf->psk_identity_len + 2; |
} |
else |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); |
return( ret ); |
} |
if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, |
ciphersuite_info->key_exchange ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) |
{ |
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); |
return( ret ); |
} |
if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); |
return( ret ); |
} |
if( p != end ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); |
} |
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, |
ciphersuite_info->key_exchange ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) |
{ |
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, |
p, end - p ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); |
} |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_QP ); |
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, |
ciphersuite_info->key_exchange ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) |
{ |
if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, |
p, end - p ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); |
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); |
} |
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, |
ssl->handshake->premaster, 32, &ssl->handshake->pmslen, |
ssl->conf->f_rng, ssl->conf->p_rng ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); |
return( ret ); |
} |
ssl->state++; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) ); |
return( 0 ); |
} |
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); |
ssl->state++; |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#else |
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
size_t i, sig_len; |
unsigned char hash[48]; |
unsigned char *hash_start = hash; |
size_t hashlen; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
mbedtls_pk_type_t pk_alg; |
#endif |
mbedtls_md_type_t md_alg; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || |
ssl->session_negotiate->peer_cert == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); |
ssl->state++; |
return( 0 ); |
} |
/* Read the message without adding it to the checksum */ |
ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ ); |
if( 0 != ret ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret ); |
return( ret ); |
} |
ssl->state++; |
/* Process the message contents */ |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || |
ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
i = mbedtls_ssl_hs_hdr_len( ssl ); |
/* |
* struct { |
* SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only |
* opaque signature<0..2^16-1>; |
* } DigitallySigned; |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
md_alg = MBEDTLS_MD_NONE; |
hashlen = 36; |
/* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ |
if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, |
MBEDTLS_PK_ECDSA ) ) |
{ |
hash_start += 16; |
hashlen -= 16; |
md_alg = MBEDTLS_MD_SHA1; |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
if( i + 2 > ssl->in_hslen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
/* |
* Hash |
*/ |
md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); |
if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" |
" for verify message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
#if !defined(MBEDTLS_MD_SHA1) |
if( MBEDTLS_MD_SHA1 == md_alg ) |
hash_start += 16; |
#endif |
/* Info from md_alg will be used instead */ |
hashlen = 0; |
i++; |
/* |
* Signature |
*/ |
if( ( pk_alg = mbedtls_ssl_pk_alg_from_sig( ssl->in_msg[i] ) ) |
== MBEDTLS_PK_NONE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" |
" for verify message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
/* |
* Check the certificate's key type matches the signature alg |
*/ |
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
i++; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
if( i + 2 > ssl->in_hslen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1]; |
i += 2; |
if( i + sig_len != ssl->in_hslen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); |
} |
/* Calculate hash and verify signature */ |
ssl->handshake->calc_verify( ssl, hash ); |
if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, |
md_alg, hash_start, hashlen, |
ssl->in_msg + i, sig_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); |
return( ret ); |
} |
mbedtls_ssl_update_handshake_status( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); |
return( ret ); |
} |
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && |
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
size_t tlen; |
uint32_t lifetime; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) ); |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET; |
/* |
* struct { |
* uint32 ticket_lifetime_hint; |
* opaque ticket<0..2^16-1>; |
* } NewSessionTicket; |
* |
* 4 . 7 ticket_lifetime_hint (0 = unspecified) |
* 8 . 9 ticket_len (n) |
* 10 . 9+n ticket content |
*/ |
if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, |
ssl->session_negotiate, |
ssl->out_msg + 10, |
ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, |
&tlen, &lifetime ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); |
tlen = 0; |
} |
ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; |
ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; |
ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; |
ssl->out_msg[7] = ( lifetime ) & 0xFF; |
ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); |
ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); |
ssl->out_msglen = 10 + tlen; |
/* |
* Morally equivalent to updating ssl->state, but NewSessionTicket and |
* ChangeCipherSpec share the same state. |
*/ |
ssl->handshake->new_session_ticket = 0; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
/* |
* SSL handshake -- server side -- single step |
*/ |
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) |
{ |
int ret = 0; |
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) ); |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
return( ret ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) |
{ |
if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
switch( ssl->state ) |
{ |
case MBEDTLS_SSL_HELLO_REQUEST: |
ssl->state = MBEDTLS_SSL_CLIENT_HELLO; |
break; |
/* |
* <== ClientHello |
*/ |
case MBEDTLS_SSL_CLIENT_HELLO: |
ret = ssl_parse_client_hello( ssl ); |
break; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: |
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); |
#endif |
/* |
* ==> ServerHello |
* Certificate |
* ( ServerKeyExchange ) |
* ( CertificateRequest ) |
* ServerHelloDone |
*/ |
case MBEDTLS_SSL_SERVER_HELLO: |
ret = ssl_write_server_hello( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_CERTIFICATE: |
ret = mbedtls_ssl_write_certificate( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: |
ret = ssl_write_server_key_exchange( ssl ); |
break; |
case MBEDTLS_SSL_CERTIFICATE_REQUEST: |
ret = ssl_write_certificate_request( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_HELLO_DONE: |
ret = ssl_write_server_hello_done( ssl ); |
break; |
/* |
* <== ( Certificate/Alert ) |
* ClientKeyExchange |
* ( CertificateVerify ) |
* ChangeCipherSpec |
* Finished |
*/ |
case MBEDTLS_SSL_CLIENT_CERTIFICATE: |
ret = mbedtls_ssl_parse_certificate( ssl ); |
break; |
case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: |
ret = ssl_parse_client_key_exchange( ssl ); |
break; |
case MBEDTLS_SSL_CERTIFICATE_VERIFY: |
ret = ssl_parse_certificate_verify( ssl ); |
break; |
case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: |
ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); |
break; |
case MBEDTLS_SSL_CLIENT_FINISHED: |
ret = mbedtls_ssl_parse_finished( ssl ); |
break; |
/* |
* ==> ( NewSessionTicket ) |
* ChangeCipherSpec |
* Finished |
*/ |
case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
if( ssl->handshake->new_session_ticket != 0 ) |
ret = ssl_write_new_session_ticket( ssl ); |
else |
#endif |
ret = mbedtls_ssl_write_change_cipher_spec( ssl ); |
break; |
case MBEDTLS_SSL_SERVER_FINISHED: |
ret = mbedtls_ssl_write_finished( ssl ); |
break; |
case MBEDTLS_SSL_FLUSH_BUFFERS: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); |
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; |
break; |
case MBEDTLS_SSL_HANDSHAKE_WRAPUP: |
mbedtls_ssl_handshake_wrapup( ssl ); |
break; |
default: |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_SRV_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_ticket.c |
---|
0,0 → 1,487 |
/* |
* TLS server tickets callbacks implementation |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_TICKET_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/ssl_ticket.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
/* |
* Initialze context |
*/ |
void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_ssl_ticket_context ) ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_init( &ctx->mutex ); |
#endif |
} |
#define MAX_KEY_BYTES 32 /* 256 bits */ |
/* |
* Generate/update a key |
*/ |
static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, |
unsigned char index ) |
{ |
int ret; |
unsigned char buf[MAX_KEY_BYTES]; |
mbedtls_ssl_ticket_key *key = ctx->keys + index; |
#if defined(MBEDTLS_HAVE_TIME) |
key->generation_time = (uint32_t) mbedtls_time( NULL ); |
#endif |
if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) |
return( ret ); |
if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 ) |
return( ret ); |
/* With GCM and CCM, same context can encrypt & decrypt */ |
ret = mbedtls_cipher_setkey( &key->ctx, buf, |
mbedtls_cipher_get_key_bitlen( &key->ctx ), |
MBEDTLS_ENCRYPT ); |
mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
return( ret ); |
} |
/* |
* Rotate/generate keys if necessary |
*/ |
static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) |
{ |
#if !defined(MBEDTLS_HAVE_TIME) |
((void) ctx); |
#else |
if( ctx->ticket_lifetime != 0 ) |
{ |
uint32_t current_time = (uint32_t) mbedtls_time( NULL ); |
uint32_t key_time = ctx->keys[ctx->active].generation_time; |
if( current_time >= key_time && |
current_time - key_time < ctx->ticket_lifetime ) |
{ |
return( 0 ); |
} |
ctx->active = 1 - ctx->active; |
return( ssl_ticket_gen_key( ctx, ctx->active ) ); |
} |
else |
#endif /* MBEDTLS_HAVE_TIME */ |
return( 0 ); |
} |
/* |
* Setup context for actual use |
*/ |
int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, |
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, |
mbedtls_cipher_type_t cipher, |
uint32_t lifetime ) |
{ |
int ret; |
const mbedtls_cipher_info_t *cipher_info; |
ctx->f_rng = f_rng; |
ctx->p_rng = p_rng; |
ctx->ticket_lifetime = lifetime; |
cipher_info = mbedtls_cipher_info_from_type( cipher); |
if( cipher_info == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( cipher_info->mode != MBEDTLS_MODE_GCM && |
cipher_info->mode != MBEDTLS_MODE_CCM ) |
{ |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 || |
( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 || |
( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
/* |
* Serialize a session in the following format: |
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) |
* n . n+2 peer_cert length = m (0 if no certificate) |
* n+3 . n+2+m peer cert ASN.1 |
*/ |
static int ssl_save_session( const mbedtls_ssl_session *session, |
unsigned char *buf, size_t buf_len, |
size_t *olen ) |
{ |
unsigned char *p = buf; |
size_t left = buf_len; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
size_t cert_len; |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
if( left < sizeof( mbedtls_ssl_session ) ) |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
memcpy( p, session, sizeof( mbedtls_ssl_session ) ); |
p += sizeof( mbedtls_ssl_session ); |
left -= sizeof( mbedtls_ssl_session ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
if( session->peer_cert == NULL ) |
cert_len = 0; |
else |
cert_len = session->peer_cert->raw.len; |
if( left < 3 + cert_len ) |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
*p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF ); |
*p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF ); |
*p++ = (unsigned char)( ( cert_len ) & 0xFF ); |
if( session->peer_cert != NULL ) |
memcpy( p, session->peer_cert->raw.p, cert_len ); |
p += cert_len; |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
*olen = p - buf; |
return( 0 ); |
} |
/* |
* Unserialise session, see ssl_save_session() |
*/ |
static int ssl_load_session( mbedtls_ssl_session *session, |
const unsigned char *buf, size_t len ) |
{ |
const unsigned char *p = buf; |
const unsigned char * const end = buf + len; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
size_t cert_len; |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
memcpy( session, p, sizeof( mbedtls_ssl_session ) ); |
p += sizeof( mbedtls_ssl_session ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
if( 3 > (size_t)( end - p ) ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2]; |
p += 3; |
if( cert_len == 0 ) |
{ |
session->peer_cert = NULL; |
} |
else |
{ |
int ret; |
if( cert_len > (size_t)( end - p ) ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); |
if( session->peer_cert == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
mbedtls_x509_crt_init( session->peer_cert ); |
if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert, |
p, cert_len ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( session->peer_cert ); |
mbedtls_free( session->peer_cert ); |
session->peer_cert = NULL; |
return( ret ); |
} |
p += cert_len; |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
if( p != end ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
return( 0 ); |
} |
/* |
* Create session ticket, with the following structure: |
* |
* struct { |
* opaque key_name[4]; |
* opaque iv[12]; |
* opaque encrypted_state<0..2^16-1>; |
* opaque tag[16]; |
* } ticket; |
* |
* The key_name, iv, and length of encrypted_state are the additional |
* authenticated data. |
*/ |
int mbedtls_ssl_ticket_write( void *p_ticket, |
const mbedtls_ssl_session *session, |
unsigned char *start, |
const unsigned char *end, |
size_t *tlen, |
uint32_t *ticket_lifetime ) |
{ |
int ret; |
mbedtls_ssl_ticket_context *ctx = p_ticket; |
mbedtls_ssl_ticket_key *key; |
unsigned char *key_name = start; |
unsigned char *iv = start + 4; |
unsigned char *state_len_bytes = iv + 12; |
unsigned char *state = state_len_bytes + 2; |
unsigned char *tag; |
size_t clear_len, ciph_len; |
*tlen = 0; |
if( ctx == NULL || ctx->f_rng == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
/* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag, |
* in addition to session itself, that will be checked when writing it. */ |
if( end - start < 4 + 12 + 2 + 16 ) |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) |
goto cleanup; |
key = &ctx->keys[ctx->active]; |
*ticket_lifetime = ctx->ticket_lifetime; |
memcpy( key_name, key->name, 4 ); |
if( ( ret = ctx->f_rng( ctx->p_rng, iv, 12 ) ) != 0 ) |
goto cleanup; |
/* Dump session state */ |
if( ( ret = ssl_save_session( session, |
state, end - state, &clear_len ) ) != 0 || |
(unsigned long) clear_len > 65535 ) |
{ |
goto cleanup; |
} |
state_len_bytes[0] = ( clear_len >> 8 ) & 0xff; |
state_len_bytes[1] = ( clear_len ) & 0xff; |
/* Encrypt and authenticate */ |
tag = state + clear_len; |
if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx, |
iv, 12, key_name, 4 + 12 + 2, |
state, clear_len, state, &ciph_len, tag, 16 ) ) != 0 ) |
{ |
goto cleanup; |
} |
if( ciph_len != clear_len ) |
{ |
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; |
goto cleanup; |
} |
*tlen = 4 + 12 + 2 + 16 + ciph_len; |
cleanup: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
/* |
* Select key based on name |
*/ |
static mbedtls_ssl_ticket_key *ssl_ticket_select_key( |
mbedtls_ssl_ticket_context *ctx, |
const unsigned char name[4] ) |
{ |
unsigned char i; |
for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ ) |
if( memcmp( name, ctx->keys[i].name, 4 ) == 0 ) |
return( &ctx->keys[i] ); |
return( NULL ); |
} |
/* |
* Load session ticket (see mbedtls_ssl_ticket_write for structure) |
*/ |
int mbedtls_ssl_ticket_parse( void *p_ticket, |
mbedtls_ssl_session *session, |
unsigned char *buf, |
size_t len ) |
{ |
int ret; |
mbedtls_ssl_ticket_context *ctx = p_ticket; |
mbedtls_ssl_ticket_key *key; |
unsigned char *key_name = buf; |
unsigned char *iv = buf + 4; |
unsigned char *enc_len_p = iv + 12; |
unsigned char *ticket = enc_len_p + 2; |
unsigned char *tag; |
size_t enc_len, clear_len; |
if( ctx == NULL || ctx->f_rng == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
/* See mbedtls_ssl_ticket_write() */ |
if( len < 4 + 12 + 2 + 16 ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) |
return( ret ); |
#endif |
if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) |
goto cleanup; |
enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1]; |
tag = ticket + enc_len; |
if( len != 4 + 12 + 2 + enc_len + 16 ) |
{ |
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; |
goto cleanup; |
} |
/* Select key */ |
if( ( key = ssl_ticket_select_key( ctx, key_name ) ) == NULL ) |
{ |
/* We can't know for sure but this is a likely option unless we're |
* under attack - this is only informative anyway */ |
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; |
goto cleanup; |
} |
/* Decrypt and authenticate */ |
if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, iv, 12, |
key_name, 4 + 12 + 2, ticket, enc_len, |
ticket, &clear_len, tag, 16 ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) |
ret = MBEDTLS_ERR_SSL_INVALID_MAC; |
goto cleanup; |
} |
if( clear_len != enc_len ) |
{ |
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; |
goto cleanup; |
} |
/* Actually load session */ |
if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 ) |
goto cleanup; |
#if defined(MBEDTLS_HAVE_TIME) |
{ |
/* Check for expiration */ |
mbedtls_time_t current_time = mbedtls_time( NULL ); |
if( current_time < session->start || |
(uint32_t)( current_time - session->start ) > ctx->ticket_lifetime ) |
{ |
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; |
goto cleanup; |
} |
} |
#endif |
cleanup: |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
#endif |
return( ret ); |
} |
/* |
* Free context |
*/ |
void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ) |
{ |
mbedtls_cipher_free( &ctx->keys[0].ctx ); |
mbedtls_cipher_free( &ctx->keys[1].ctx ); |
#if defined(MBEDTLS_THREADING_C) |
mbedtls_mutex_free( &ctx->mutex ); |
#endif |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) ); |
} |
#endif /* MBEDTLS_SSL_TICKET_C */ |
/programs/develop/libraries/kos_mbedtls/library/ssl_tls.c |
---|
0,0 → 1,9807 |
/* |
* SSLv3/TLSv1 shared functions |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The SSL 3.0 specification was drafted by Netscape in 1996, |
* and became an IETF standard in 1999. |
* |
* http://wp.netscape.com/eng/ssl3/ |
* http://www.ietf.org/rfc/rfc2246.txt |
* http://www.ietf.org/rfc/rfc4346.txt |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SSL_TLS_C) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#define mbedtls_calloc calloc |
#define mbedtls_free free |
#endif |
#include "mbedtls/debug.h" |
#include "mbedtls/ssl.h" |
#include "mbedtls/ssl_internal.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
#include "mbedtls/oid.h" |
#endif |
static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ); |
static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ); |
/* Length of the "epoch" field in the record header */ |
static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
return( 2 ); |
#else |
((void) ssl); |
#endif |
return( 0 ); |
} |
/* |
* Start a timer. |
* Passing millisecs = 0 cancels a running timer. |
*/ |
static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) |
{ |
if( ssl->f_set_timer == NULL ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) ); |
ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs ); |
} |
/* |
* Return -1 is timer is expired, 0 if it isn't. |
*/ |
static int ssl_check_timer( mbedtls_ssl_context *ssl ) |
{ |
if( ssl->f_get_timer == NULL ) |
return( 0 ); |
if( ssl->f_get_timer( ssl->p_timer ) == 2 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) ); |
return( -1 ); |
} |
return( 0 ); |
} |
static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, |
mbedtls_ssl_transform *transform ); |
static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, |
mbedtls_ssl_transform *transform ); |
#define SSL_DONT_FORCE_FLUSH 0 |
#define SSL_FORCE_FLUSH 1 |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* Forward declarations for functions related to message buffering. */ |
static void ssl_buffering_free( mbedtls_ssl_context *ssl ); |
static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, |
uint8_t slot ); |
static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ); |
static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ); |
static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ); |
static int ssl_buffer_message( mbedtls_ssl_context *ssl ); |
static int ssl_buffer_future_record( mbedtls_ssl_context *ssl ); |
static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ); |
static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ); |
static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl ) |
{ |
size_t mtu = ssl_get_current_mtu( ssl ); |
if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN ) |
return( mtu ); |
return( MBEDTLS_SSL_OUT_BUFFER_LEN ); |
} |
static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl ) |
{ |
size_t const bytes_written = ssl->out_left; |
size_t const mtu = ssl_get_maximum_datagram_size( ssl ); |
/* Double-check that the write-index hasn't gone |
* past what we can transmit in a single datagram. */ |
if( bytes_written > mtu ) |
{ |
/* Should never happen... */ |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
return( (int) ( mtu - bytes_written ) ); |
} |
static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl ) |
{ |
int ret; |
size_t remaining, expansion; |
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); |
if( max_len > mfl ) |
max_len = mfl; |
/* By the standard (RFC 6066 Sect. 4), the MFL extension |
* only limits the maximum record payload size, so in theory |
* we would be allowed to pack multiple records of payload size |
* MFL into a single datagram. However, this would mean that there's |
* no way to explicitly communicate MTU restrictions to the peer. |
* |
* The following reduction of max_len makes sure that we never |
* write datagrams larger than MFL + Record Expansion Overhead. |
*/ |
if( max_len <= ssl->out_left ) |
return( 0 ); |
max_len -= ssl->out_left; |
#endif |
ret = ssl_get_remaining_space_in_datagram( ssl ); |
if( ret < 0 ) |
return( ret ); |
remaining = (size_t) ret; |
ret = mbedtls_ssl_get_record_expansion( ssl ); |
if( ret < 0 ) |
return( ret ); |
expansion = (size_t) ret; |
if( remaining <= expansion ) |
return( 0 ); |
remaining -= expansion; |
if( remaining >= max_len ) |
remaining = max_len; |
return( (int) remaining ); |
} |
/* |
* Double the retransmit timeout value, within the allowed range, |
* returning -1 if the maximum value has already been reached. |
*/ |
static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) |
{ |
uint32_t new_timeout; |
if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) |
return( -1 ); |
/* Implement the final paragraph of RFC 6347 section 4.1.1.1 |
* in the following way: after the initial transmission and a first |
* retransmission, back off to a temporary estimated MTU of 508 bytes. |
* This value is guaranteed to be deliverable (if not guaranteed to be |
* delivered) of any compliant IPv4 (and IPv6) network, and should work |
* on most non-IP stacks too. */ |
if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) |
{ |
ssl->handshake->mtu = 508; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); |
} |
new_timeout = 2 * ssl->handshake->retransmit_timeout; |
/* Avoid arithmetic overflow and range overflow */ |
if( new_timeout < ssl->handshake->retransmit_timeout || |
new_timeout > ssl->conf->hs_timeout_max ) |
{ |
new_timeout = ssl->conf->hs_timeout_max; |
} |
ssl->handshake->retransmit_timeout = new_timeout; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", |
ssl->handshake->retransmit_timeout ) ); |
return( 0 ); |
} |
static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) |
{ |
ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", |
ssl->handshake->retransmit_timeout ) ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
/* |
* Convert max_fragment_length codes to length. |
* RFC 6066 says: |
* enum{ |
* 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) |
* } MaxFragmentLength; |
* and we add 0 -> extension unused |
*/ |
static unsigned int ssl_mfl_code_to_length( int mfl ) |
{ |
switch( mfl ) |
{ |
case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: |
return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); |
case MBEDTLS_SSL_MAX_FRAG_LEN_512: |
return 512; |
case MBEDTLS_SSL_MAX_FRAG_LEN_1024: |
return 1024; |
case MBEDTLS_SSL_MAX_FRAG_LEN_2048: |
return 2048; |
case MBEDTLS_SSL_MAX_FRAG_LEN_4096: |
return 4096; |
default: |
return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); |
} |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_CLI_C) |
static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src ) |
{ |
mbedtls_ssl_session_free( dst ); |
memcpy( dst, src, sizeof( mbedtls_ssl_session ) ); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
if( src->peer_cert != NULL ) |
{ |
int ret; |
dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) ); |
if( dst->peer_cert == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
mbedtls_x509_crt_init( dst->peer_cert ); |
if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p, |
src->peer_cert->raw.len ) ) != 0 ) |
{ |
mbedtls_free( dst->peer_cert ); |
dst->peer_cert = NULL; |
return( ret ); |
} |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) |
if( src->ticket != NULL ) |
{ |
dst->ticket = mbedtls_calloc( 1, src->ticket_len ); |
if( dst->ticket == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
memcpy( dst->ticket, src->ticket, src->ticket_len ); |
} |
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, |
const unsigned char *key_enc, const unsigned char *key_dec, |
size_t keylen, |
const unsigned char *iv_enc, const unsigned char *iv_dec, |
size_t ivlen, |
const unsigned char *mac_enc, const unsigned char *mac_dec, |
size_t maclen ) = NULL; |
int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL; |
int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL; |
int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL; |
int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL; |
int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
/* |
* Key material generation |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
static int ssl3_prf( const unsigned char *secret, size_t slen, |
const char *label, |
const unsigned char *random, size_t rlen, |
unsigned char *dstbuf, size_t dlen ) |
{ |
int ret = 0; |
size_t i; |
mbedtls_md5_context md5; |
mbedtls_sha1_context sha1; |
unsigned char padding[16]; |
unsigned char sha1sum[20]; |
((void)label); |
mbedtls_md5_init( &md5 ); |
mbedtls_sha1_init( &sha1 ); |
/* |
* SSLv3: |
* block = |
* MD5( secret + SHA1( 'A' + secret + random ) ) + |
* MD5( secret + SHA1( 'BB' + secret + random ) ) + |
* MD5( secret + SHA1( 'CCC' + secret + random ) ) + |
* ... |
*/ |
for( i = 0; i < dlen / 16; i++ ) |
{ |
memset( padding, (unsigned char) ('A' + i), 1 + i ); |
if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 ) |
goto exit; |
if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 ) |
goto exit; |
} |
exit: |
mbedtls_md5_free( &md5 ); |
mbedtls_sha1_free( &sha1 ); |
mbedtls_platform_zeroize( padding, sizeof( padding ) ); |
mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) |
static int tls1_prf( const unsigned char *secret, size_t slen, |
const char *label, |
const unsigned char *random, size_t rlen, |
unsigned char *dstbuf, size_t dlen ) |
{ |
size_t nb, hs; |
size_t i, j, k; |
const unsigned char *S1, *S2; |
unsigned char tmp[128]; |
unsigned char h_i[20]; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
int ret; |
mbedtls_md_init( &md_ctx ); |
if( sizeof( tmp ) < 20 + strlen( label ) + rlen ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
hs = ( slen + 1 ) / 2; |
S1 = secret; |
S2 = secret + slen - hs; |
nb = strlen( label ); |
memcpy( tmp + 20, label, nb ); |
memcpy( tmp + 20 + nb, random, rlen ); |
nb += rlen; |
/* |
* First compute P_md5(secret,label+random)[0..dlen] |
*/ |
if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) |
return( ret ); |
mbedtls_md_hmac_starts( &md_ctx, S1, hs ); |
mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); |
mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); |
for( i = 0; i < dlen; i += 16 ) |
{ |
mbedtls_md_hmac_reset ( &md_ctx ); |
mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb ); |
mbedtls_md_hmac_finish( &md_ctx, h_i ); |
mbedtls_md_hmac_reset ( &md_ctx ); |
mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 ); |
mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); |
k = ( i + 16 > dlen ) ? dlen % 16 : 16; |
for( j = 0; j < k; j++ ) |
dstbuf[i + j] = h_i[j]; |
} |
mbedtls_md_free( &md_ctx ); |
/* |
* XOR out with P_sha1(secret,label+random)[0..dlen] |
*/ |
if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) |
return( ret ); |
mbedtls_md_hmac_starts( &md_ctx, S2, hs ); |
mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); |
mbedtls_md_hmac_finish( &md_ctx, tmp ); |
for( i = 0; i < dlen; i += 20 ) |
{ |
mbedtls_md_hmac_reset ( &md_ctx ); |
mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb ); |
mbedtls_md_hmac_finish( &md_ctx, h_i ); |
mbedtls_md_hmac_reset ( &md_ctx ); |
mbedtls_md_hmac_update( &md_ctx, tmp, 20 ); |
mbedtls_md_hmac_finish( &md_ctx, tmp ); |
k = ( i + 20 > dlen ) ? dlen % 20 : 20; |
for( j = 0; j < k; j++ ) |
dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); |
} |
mbedtls_md_free( &md_ctx ); |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
static int tls_prf_generic( mbedtls_md_type_t md_type, |
const unsigned char *secret, size_t slen, |
const char *label, |
const unsigned char *random, size_t rlen, |
unsigned char *dstbuf, size_t dlen ) |
{ |
size_t nb; |
size_t i, j, k, md_len; |
unsigned char tmp[128]; |
unsigned char h_i[MBEDTLS_MD_MAX_SIZE]; |
const mbedtls_md_info_t *md_info; |
mbedtls_md_context_t md_ctx; |
int ret; |
mbedtls_md_init( &md_ctx ); |
if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL ) |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
md_len = mbedtls_md_get_size( md_info ); |
if( sizeof( tmp ) < md_len + strlen( label ) + rlen ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
nb = strlen( label ); |
memcpy( tmp + md_len, label, nb ); |
memcpy( tmp + md_len + nb, random, rlen ); |
nb += rlen; |
/* |
* Compute P_<hash>(secret, label + random)[0..dlen] |
*/ |
if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) |
return( ret ); |
mbedtls_md_hmac_starts( &md_ctx, secret, slen ); |
mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ); |
mbedtls_md_hmac_finish( &md_ctx, tmp ); |
for( i = 0; i < dlen; i += md_len ) |
{ |
mbedtls_md_hmac_reset ( &md_ctx ); |
mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ); |
mbedtls_md_hmac_finish( &md_ctx, h_i ); |
mbedtls_md_hmac_reset ( &md_ctx ); |
mbedtls_md_hmac_update( &md_ctx, tmp, md_len ); |
mbedtls_md_hmac_finish( &md_ctx, tmp ); |
k = ( i + md_len > dlen ) ? dlen % md_len : md_len; |
for( j = 0; j < k; j++ ) |
dstbuf[i + j] = h_i[j]; |
} |
mbedtls_md_free( &md_ctx ); |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SHA256_C) |
static int tls_prf_sha256( const unsigned char *secret, size_t slen, |
const char *label, |
const unsigned char *random, size_t rlen, |
unsigned char *dstbuf, size_t dlen ) |
{ |
return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen, |
label, random, rlen, dstbuf, dlen ) ); |
} |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
static int tls_prf_sha384( const unsigned char *secret, size_t slen, |
const char *label, |
const unsigned char *random, size_t rlen, |
unsigned char *dstbuf, size_t dlen ) |
{ |
return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen, |
label, random, rlen, dstbuf, dlen ) ); |
} |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t ); |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * ); |
static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) |
static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * ); |
static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); |
static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * ); |
static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); |
static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * ); |
static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) |
{ |
int ret = 0; |
unsigned char tmp[64]; |
unsigned char keyblk[256]; |
unsigned char *key1; |
unsigned char *key2; |
unsigned char *mac_enc; |
unsigned char *mac_dec; |
size_t mac_key_len; |
size_t iv_copy_len; |
const mbedtls_cipher_info_t *cipher_info; |
const mbedtls_md_info_t *md_info; |
mbedtls_ssl_session *session = ssl->session_negotiate; |
mbedtls_ssl_transform *transform = ssl->transform_negotiate; |
mbedtls_ssl_handshake_params *handshake = ssl->handshake; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); |
cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher ); |
if( cipher_info == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found", |
transform->ciphersuite_info->cipher ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac ); |
if( md_info == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found", |
transform->ciphersuite_info->mac ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
/* |
* Set appropriate PRF function and other SSL / TLS / TLS1.2 functions |
*/ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
handshake->tls_prf = ssl3_prf; |
handshake->calc_verify = ssl_calc_verify_ssl; |
handshake->calc_finished = ssl_calc_finished_ssl; |
} |
else |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
handshake->tls_prf = tls1_prf; |
handshake->calc_verify = ssl_calc_verify_tls; |
handshake->calc_finished = ssl_calc_finished_tls; |
} |
else |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA512_C) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && |
transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) |
{ |
handshake->tls_prf = tls_prf_sha384; |
handshake->calc_verify = ssl_calc_verify_tls_sha384; |
handshake->calc_finished = ssl_calc_finished_tls_sha384; |
} |
else |
#endif |
#if defined(MBEDTLS_SHA256_C) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
handshake->tls_prf = tls_prf_sha256; |
handshake->calc_verify = ssl_calc_verify_tls_sha256; |
handshake->calc_finished = ssl_calc_finished_tls_sha256; |
} |
else |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* |
* SSLv3: |
* master = |
* MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + |
* MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + |
* MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) |
* |
* TLSv1+: |
* master = PRF( premaster, "master secret", randbytes )[0..47] |
*/ |
if( handshake->resume == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, |
handshake->pmslen ); |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) |
{ |
unsigned char session_hash[48]; |
size_t hash_len; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) ); |
ssl->handshake->calc_verify( ssl, session_hash ); |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
#if defined(MBEDTLS_SHA512_C) |
if( ssl->transform_negotiate->ciphersuite_info->mac == |
MBEDTLS_MD_SHA384 ) |
{ |
hash_len = 48; |
} |
else |
#endif |
hash_len = 32; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
hash_len = 36; |
MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len ); |
ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, |
"extended master secret", |
session_hash, hash_len, |
session->master, 48 ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); |
return( ret ); |
} |
} |
else |
#endif |
ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, |
"master secret", |
handshake->randbytes, 64, |
session->master, 48 ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); |
return( ret ); |
} |
mbedtls_platform_zeroize( handshake->premaster, |
sizeof(handshake->premaster) ); |
} |
else |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); |
/* |
* Swap the client and server random values. |
*/ |
memcpy( tmp, handshake->randbytes, 64 ); |
memcpy( handshake->randbytes, tmp + 32, 32 ); |
memcpy( handshake->randbytes + 32, tmp, 32 ); |
mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); |
/* |
* SSLv3: |
* key block = |
* MD5( master + SHA1( 'A' + master + randbytes ) ) + |
* MD5( master + SHA1( 'BB' + master + randbytes ) ) + |
* MD5( master + SHA1( 'CCC' + master + randbytes ) ) + |
* MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + |
* ... |
* |
* TLSv1: |
* key block = PRF( master, "key expansion", randbytes ) |
*/ |
ret = handshake->tls_prf( session->master, 48, "key expansion", |
handshake->randbytes, 64, keyblk, 256 ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", |
mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); |
mbedtls_platform_zeroize( handshake->randbytes, |
sizeof( handshake->randbytes ) ); |
/* |
* Determine the appropriate key, IV and MAC length. |
*/ |
transform->keylen = cipher_info->key_bitlen / 8; |
if( cipher_info->mode == MBEDTLS_MODE_GCM || |
cipher_info->mode == MBEDTLS_MODE_CCM || |
cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) |
{ |
size_t taglen, explicit_ivlen; |
transform->maclen = 0; |
mac_key_len = 0; |
/* All modes haves 96-bit IVs; |
* GCM and CCM has 4 implicit and 8 explicit bytes |
* ChachaPoly has all 12 bytes implicit |
*/ |
transform->ivlen = 12; |
if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) |
transform->fixed_ivlen = 12; |
else |
transform->fixed_ivlen = 4; |
/* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */ |
taglen = transform->ciphersuite_info->flags & |
MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; |
/* Minimum length of encrypted record */ |
explicit_ivlen = transform->ivlen - transform->fixed_ivlen; |
transform->minlen = explicit_ivlen + taglen; |
} |
else |
{ |
/* Initialize HMAC contexts */ |
if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 || |
( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); |
return( ret ); |
} |
/* Get MAC length */ |
mac_key_len = mbedtls_md_get_size( md_info ); |
transform->maclen = mac_key_len; |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
/* |
* If HMAC is to be truncated, we shall keep the leftmost bytes, |
* (rfc 6066 page 13 or rfc 2104 section 4), |
* so we only need to adjust the length here. |
*/ |
if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) |
{ |
transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN; |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) |
/* Fall back to old, non-compliant version of the truncated |
* HMAC implementation which also truncates the key |
* (Mbed TLS versions from 1.3 to 2.6.0) */ |
mac_key_len = transform->maclen; |
#endif |
} |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
/* IV length */ |
transform->ivlen = cipher_info->iv_size; |
/* Minimum length */ |
if( cipher_info->mode == MBEDTLS_MODE_STREAM ) |
transform->minlen = transform->maclen; |
else |
{ |
/* |
* GenericBlockCipher: |
* 1. if EtM is in use: one block plus MAC |
* otherwise: * first multiple of blocklen greater than maclen |
* 2. IV except for SSL3 and TLS 1.0 |
*/ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) |
{ |
transform->minlen = transform->maclen |
+ cipher_info->block_size; |
} |
else |
#endif |
{ |
transform->minlen = transform->maclen |
+ cipher_info->block_size |
- transform->maclen % cipher_info->block_size; |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 ) |
; /* No need to adjust minlen */ |
else |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 || |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) |
{ |
transform->minlen += transform->ivlen; |
} |
else |
#endif |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", |
transform->keylen, transform->minlen, transform->ivlen, |
transform->maclen ) ); |
/* |
* Finally setup the cipher contexts, IVs and MAC secrets. |
*/ |
#if defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
{ |
key1 = keyblk + mac_key_len * 2; |
key2 = keyblk + mac_key_len * 2 + transform->keylen; |
mac_enc = keyblk; |
mac_dec = keyblk + mac_key_len; |
/* |
* This is not used in TLS v1.1. |
*/ |
iv_copy_len = ( transform->fixed_ivlen ) ? |
transform->fixed_ivlen : transform->ivlen; |
memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len ); |
memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len, |
iv_copy_len ); |
} |
else |
#endif /* MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
{ |
key1 = keyblk + mac_key_len * 2 + transform->keylen; |
key2 = keyblk + mac_key_len * 2; |
mac_enc = keyblk + mac_key_len; |
mac_dec = keyblk; |
/* |
* This is not used in TLS v1.1. |
*/ |
iv_copy_len = ( transform->fixed_ivlen ) ? |
transform->fixed_ivlen : transform->ivlen; |
memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len ); |
memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len, |
iv_copy_len ); |
} |
else |
#endif /* MBEDTLS_SSL_SRV_C */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
if( mac_key_len > sizeof transform->mac_enc ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
memcpy( transform->mac_enc, mac_enc, mac_key_len ); |
memcpy( transform->mac_dec, mac_dec, mac_key_len ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) |
{ |
/* For HMAC-based ciphersuites, initialize the HMAC transforms. |
For AEAD-based ciphersuites, there is nothing to do here. */ |
if( mac_key_len != 0 ) |
{ |
mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len ); |
mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len ); |
} |
} |
else |
#endif |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_init != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); |
if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, |
transform->iv_enc, transform->iv_dec, |
iv_copy_len, |
mac_enc, mac_dec, |
mac_key_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
} |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
#if defined(MBEDTLS_SSL_EXPORT_KEYS) |
if( ssl->conf->f_export_keys != NULL ) |
{ |
ssl->conf->f_export_keys( ssl->conf->p_export_keys, |
session->master, keyblk, |
mac_key_len, transform->keylen, |
iv_copy_len ); |
} |
#endif |
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, |
cipher_info ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, |
cipher_info ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1, |
cipher_info->key_bitlen, |
MBEDTLS_ENCRYPT ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2, |
cipher_info->key_bitlen, |
MBEDTLS_DECRYPT ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
if( cipher_info->mode == MBEDTLS_MODE_CBC ) |
{ |
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc, |
MBEDTLS_PADDING_NONE ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); |
return( ret ); |
} |
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec, |
MBEDTLS_PADDING_NONE ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) ); |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
// Initialize compression |
// |
if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) |
{ |
if( ssl->compress_buf == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); |
ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); |
if( ssl->compress_buf == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", |
MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) ); |
memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); |
memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); |
if( deflateInit( &transform->ctx_deflate, |
Z_DEFAULT_COMPRESSION ) != Z_OK || |
inflateInit( &transform->ctx_inflate ) != Z_OK ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) ); |
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); |
} |
} |
#endif /* MBEDTLS_ZLIB_SUPPORT */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] ) |
{ |
mbedtls_md5_context md5; |
mbedtls_sha1_context sha1; |
unsigned char pad_1[48]; |
unsigned char pad_2[48]; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); |
mbedtls_md5_init( &md5 ); |
mbedtls_sha1_init( &sha1 ); |
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); |
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); |
memset( pad_1, 0x36, 48 ); |
memset( pad_2, 0x5C, 48 ); |
mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); |
mbedtls_md5_update_ret( &md5, pad_1, 48 ); |
mbedtls_md5_finish_ret( &md5, hash ); |
mbedtls_md5_starts_ret( &md5 ); |
mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); |
mbedtls_md5_update_ret( &md5, pad_2, 48 ); |
mbedtls_md5_update_ret( &md5, hash, 16 ); |
mbedtls_md5_finish_ret( &md5, hash ); |
mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); |
mbedtls_sha1_update_ret( &sha1, pad_1, 40 ); |
mbedtls_sha1_finish_ret( &sha1, hash + 16 ); |
mbedtls_sha1_starts_ret( &sha1 ); |
mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); |
mbedtls_sha1_update_ret( &sha1, pad_2, 40 ); |
mbedtls_sha1_update_ret( &sha1, hash + 16, 20 ); |
mbedtls_sha1_finish_ret( &sha1, hash + 16 ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); |
mbedtls_md5_free( &md5 ); |
mbedtls_sha1_free( &sha1 ); |
return; |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) |
void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] ) |
{ |
mbedtls_md5_context md5; |
mbedtls_sha1_context sha1; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); |
mbedtls_md5_init( &md5 ); |
mbedtls_sha1_init( &sha1 ); |
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); |
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); |
mbedtls_md5_finish_ret( &md5, hash ); |
mbedtls_sha1_finish_ret( &sha1, hash + 16 ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); |
mbedtls_md5_free( &md5 ); |
mbedtls_sha1_free( &sha1 ); |
return; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] ) |
{ |
mbedtls_sha256_context sha256; |
mbedtls_sha256_init( &sha256 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); |
mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); |
mbedtls_sha256_finish_ret( &sha256, hash ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); |
mbedtls_sha256_free( &sha256 ); |
return; |
} |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] ) |
{ |
mbedtls_sha512_context sha512; |
mbedtls_sha512_init( &sha512 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); |
mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); |
mbedtls_sha512_finish_ret( &sha512, hash ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); |
mbedtls_sha512_free( &sha512 ); |
return; |
} |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ) |
{ |
unsigned char *p = ssl->handshake->premaster; |
unsigned char *end = p + sizeof( ssl->handshake->premaster ); |
const unsigned char *psk = ssl->conf->psk; |
size_t psk_len = ssl->conf->psk_len; |
/* If the psk callback was called, use its result */ |
if( ssl->handshake->psk != NULL ) |
{ |
psk = ssl->handshake->psk; |
psk_len = ssl->handshake->psk_len; |
} |
/* |
* PMS = struct { |
* opaque other_secret<0..2^16-1>; |
* opaque psk<0..2^16-1>; |
* }; |
* with "other_secret" depending on the particular key exchange |
*/ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK ) |
{ |
if( end - p < 2 ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
*(p++) = (unsigned char)( psk_len >> 8 ); |
*(p++) = (unsigned char)( psk_len ); |
if( end < p || (size_t)( end - p ) < psk_len ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
memset( p, 0, psk_len ); |
p += psk_len; |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) |
{ |
/* |
* other_secret already set by the ClientKeyExchange message, |
* and is 48 bytes long |
*/ |
if( end - p < 2 ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
*p++ = 0; |
*p++ = 48; |
p += 48; |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) |
{ |
int ret; |
size_t len; |
/* Write length only when we know the actual value */ |
if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, |
p + 2, end - ( p + 2 ), &len, |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); |
return( ret ); |
} |
*(p++) = (unsigned char)( len >> 8 ); |
*(p++) = (unsigned char)( len ); |
p += len; |
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) |
{ |
int ret; |
size_t zlen; |
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, |
p + 2, end - ( p + 2 ), |
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); |
return( ret ); |
} |
*(p++) = (unsigned char)( zlen >> 8 ); |
*(p++) = (unsigned char)( zlen ); |
p += zlen; |
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, |
MBEDTLS_DEBUG_ECDH_Z ); |
} |
else |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* opaque psk<0..2^16-1>; */ |
if( end - p < 2 ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
*(p++) = (unsigned char)( psk_len >> 8 ); |
*(p++) = (unsigned char)( psk_len ); |
if( end < p || (size_t)( end - p ) < psk_len ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
memcpy( p, psk, psk_len ); |
p += psk_len; |
ssl->handshake->pmslen = p - ssl->handshake->premaster; |
return( 0 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
/* |
* SSLv3.0 MAC functions |
*/ |
#define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */ |
static void ssl_mac( mbedtls_md_context_t *md_ctx, |
const unsigned char *secret, |
const unsigned char *buf, size_t len, |
const unsigned char *ctr, int type, |
unsigned char out[SSL_MAC_MAX_BYTES] ) |
{ |
unsigned char header[11]; |
unsigned char padding[48]; |
int padlen; |
int md_size = mbedtls_md_get_size( md_ctx->md_info ); |
int md_type = mbedtls_md_get_type( md_ctx->md_info ); |
/* Only MD5 and SHA-1 supported */ |
if( md_type == MBEDTLS_MD_MD5 ) |
padlen = 48; |
else |
padlen = 40; |
memcpy( header, ctr, 8 ); |
header[ 8] = (unsigned char) type; |
header[ 9] = (unsigned char)( len >> 8 ); |
header[10] = (unsigned char)( len ); |
memset( padding, 0x36, padlen ); |
mbedtls_md_starts( md_ctx ); |
mbedtls_md_update( md_ctx, secret, md_size ); |
mbedtls_md_update( md_ctx, padding, padlen ); |
mbedtls_md_update( md_ctx, header, 11 ); |
mbedtls_md_update( md_ctx, buf, len ); |
mbedtls_md_finish( md_ctx, out ); |
memset( padding, 0x5C, padlen ); |
mbedtls_md_starts( md_ctx ); |
mbedtls_md_update( md_ctx, secret, md_size ); |
mbedtls_md_update( md_ctx, padding, padlen ); |
mbedtls_md_update( md_ctx, out, md_size ); |
mbedtls_md_finish( md_ctx, out ); |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ |
( defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) ) |
#define SSL_SOME_MODES_USE_MAC |
#endif |
/* The function below is only used in the Lucky 13 counter-measure in |
* ssl_decrypt_buf(). These are the defines that guard the call site. */ |
#if defined(SSL_SOME_MODES_USE_MAC) && \ |
( defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) ) |
/* This function makes sure every byte in the memory region is accessed |
* (in ascending addresses order) */ |
static void ssl_read_memory( unsigned char *p, size_t len ) |
{ |
unsigned char acc = 0; |
volatile unsigned char force; |
for( ; len != 0; p++, len-- ) |
acc ^= *p; |
force = acc; |
(void) force; |
} |
#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */ |
/* |
* Encryption/decryption functions |
*/ |
static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_cipher_mode_t mode; |
int auth_done = 0; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); |
if( ssl->session_out == NULL || ssl->transform_out == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", |
ssl->out_msg, ssl->out_msglen ); |
/* |
* Add MAC before if needed |
*/ |
#if defined(SSL_SOME_MODES_USE_MAC) |
if( mode == MBEDTLS_MODE_STREAM || |
( mode == MBEDTLS_MODE_CBC |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
&& ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED |
#endif |
) ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
unsigned char mac[SSL_MAC_MAX_BYTES]; |
ssl_mac( &ssl->transform_out->md_ctx_enc, |
ssl->transform_out->mac_enc, |
ssl->out_msg, ssl->out_msglen, |
ssl->out_ctr, ssl->out_msgtype, |
mac ); |
memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); |
} |
else |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) |
{ |
unsigned char mac[MBEDTLS_SSL_MAC_ADD]; |
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 ); |
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 ); |
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 ); |
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, |
ssl->out_msg, ssl->out_msglen ); |
mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); |
mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); |
memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); |
} |
else |
#endif |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", |
ssl->out_msg + ssl->out_msglen, |
ssl->transform_out->maclen ); |
ssl->out_msglen += ssl->transform_out->maclen; |
auth_done++; |
} |
#endif /* AEAD not the only option */ |
/* |
* Encrypt |
*/ |
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) |
if( mode == MBEDTLS_MODE_STREAM ) |
{ |
int ret; |
size_t olen = 0; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " |
"including %d bytes of padding", |
ssl->out_msglen, 0 ) ); |
if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, |
ssl->transform_out->iv_enc, |
ssl->transform_out->ivlen, |
ssl->out_msg, ssl->out_msglen, |
ssl->out_msg, &olen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); |
return( ret ); |
} |
if( ssl->out_msglen != olen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
else |
#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ |
#if defined(MBEDTLS_GCM_C) || \ |
defined(MBEDTLS_CCM_C) || \ |
defined(MBEDTLS_CHACHAPOLY_C) |
if( mode == MBEDTLS_MODE_GCM || |
mode == MBEDTLS_MODE_CCM || |
mode == MBEDTLS_MODE_CHACHAPOLY ) |
{ |
int ret; |
size_t enc_msglen, olen; |
unsigned char *enc_msg; |
unsigned char add_data[13]; |
unsigned char iv[12]; |
mbedtls_ssl_transform *transform = ssl->transform_out; |
unsigned char taglen = transform->ciphersuite_info->flags & |
MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; |
size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen; |
/* |
* Prepare additional authenticated data |
*/ |
memcpy( add_data, ssl->out_ctr, 8 ); |
add_data[8] = ssl->out_msgtype; |
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, |
ssl->conf->transport, add_data + 9 ); |
add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; |
add_data[12] = ssl->out_msglen & 0xFF; |
MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); |
/* |
* Generate IV |
*/ |
if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) |
{ |
/* GCM and CCM: fixed || explicit (=seqnum) */ |
memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); |
memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 ); |
memcpy( ssl->out_iv, ssl->out_ctr, 8 ); |
} |
else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) |
{ |
/* ChachaPoly: fixed XOR sequence number */ |
unsigned char i; |
memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); |
for( i = 0; i < 8; i++ ) |
iv[i+4] ^= ssl->out_ctr[i]; |
} |
else |
{ |
/* Reminder if we ever add an AEAD mode with a different size */ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", |
iv, transform->ivlen ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", |
ssl->out_iv, explicit_ivlen ); |
/* |
* Fix message length with added IV |
*/ |
enc_msg = ssl->out_msg; |
enc_msglen = ssl->out_msglen; |
ssl->out_msglen += explicit_ivlen; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " |
"including 0 bytes of padding", |
ssl->out_msglen ) ); |
/* |
* Encrypt and authenticate |
*/ |
if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, |
iv, transform->ivlen, |
add_data, 13, |
enc_msg, enc_msglen, |
enc_msg, &olen, |
enc_msg + enc_msglen, taglen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); |
return( ret ); |
} |
if( olen != enc_msglen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->out_msglen += taglen; |
auth_done++; |
MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); |
} |
else |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) |
if( mode == MBEDTLS_MODE_CBC ) |
{ |
int ret; |
unsigned char *enc_msg; |
size_t enc_msglen, padlen, olen = 0, i; |
padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) % |
ssl->transform_out->ivlen; |
if( padlen == ssl->transform_out->ivlen ) |
padlen = 0; |
for( i = 0; i <= padlen; i++ ) |
ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; |
ssl->out_msglen += padlen + 1; |
enc_msglen = ssl->out_msglen; |
enc_msg = ssl->out_msg; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) |
/* |
* Prepend per-record IV for block cipher in TLS v1.1 and up as per |
* Method 1 (6.2.3.2. in RFC4346 and RFC5246) |
*/ |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) |
{ |
/* |
* Generate IV |
*/ |
ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc, |
ssl->transform_out->ivlen ); |
if( ret != 0 ) |
return( ret ); |
memcpy( ssl->out_iv, ssl->transform_out->iv_enc, |
ssl->transform_out->ivlen ); |
/* |
* Fix pointer positions and message length with added IV |
*/ |
enc_msg = ssl->out_msg; |
enc_msglen = ssl->out_msglen; |
ssl->out_msglen += ssl->transform_out->ivlen; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " |
"including %d bytes of IV and %d bytes of padding", |
ssl->out_msglen, ssl->transform_out->ivlen, |
padlen + 1 ) ); |
if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, |
ssl->transform_out->iv_enc, |
ssl->transform_out->ivlen, |
enc_msg, enc_msglen, |
enc_msg, &olen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); |
return( ret ); |
} |
if( enc_msglen != olen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) |
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) |
{ |
/* |
* Save IV in SSL3 and TLS1 |
*/ |
memcpy( ssl->transform_out->iv_enc, |
ssl->transform_out->cipher_ctx_enc.iv, |
ssl->transform_out->ivlen ); |
} |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
if( auth_done == 0 ) |
{ |
unsigned char mac[MBEDTLS_SSL_MAC_ADD]; |
/* |
* MAC(MAC_write_key, seq_num + |
* TLSCipherText.type + |
* TLSCipherText.version + |
* length_of( (IV +) ENC(...) ) + |
* IV + // except for TLS 1.0 |
* ENC(content + padding + padding_length)); |
*/ |
unsigned char pseudo_hdr[13]; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); |
memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 ); |
memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 ); |
pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF ); |
pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); |
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 ); |
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, |
ssl->out_iv, ssl->out_msglen ); |
mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); |
mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); |
memcpy( ssl->out_iv + ssl->out_msglen, mac, |
ssl->transform_out->maclen ); |
ssl->out_msglen += ssl->transform_out->maclen; |
auth_done++; |
} |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
} |
else |
#endif /* MBEDTLS_CIPHER_MODE_CBC && |
( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* Make extra sure authentication was performed, exactly once */ |
if( auth_done != 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); |
return( 0 ); |
} |
static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_cipher_mode_t mode; |
int auth_done = 0; |
#if defined(SSL_SOME_MODES_USE_MAC) |
size_t padlen = 0, correct = 1; |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); |
if( ssl->session_in == NULL || ssl->transform_in == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec ); |
if( ssl->in_msglen < ssl->transform_in->minlen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)", |
ssl->in_msglen, ssl->transform_in->minlen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) |
if( mode == MBEDTLS_MODE_STREAM ) |
{ |
int ret; |
size_t olen = 0; |
padlen = 0; |
if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, |
ssl->transform_in->iv_dec, |
ssl->transform_in->ivlen, |
ssl->in_msg, ssl->in_msglen, |
ssl->in_msg, &olen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); |
return( ret ); |
} |
if( ssl->in_msglen != olen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
else |
#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ |
#if defined(MBEDTLS_GCM_C) || \ |
defined(MBEDTLS_CCM_C) || \ |
defined(MBEDTLS_CHACHAPOLY_C) |
if( mode == MBEDTLS_MODE_GCM || |
mode == MBEDTLS_MODE_CCM || |
mode == MBEDTLS_MODE_CHACHAPOLY ) |
{ |
int ret; |
size_t dec_msglen, olen; |
unsigned char *dec_msg; |
unsigned char *dec_msg_result; |
unsigned char add_data[13]; |
unsigned char iv[12]; |
mbedtls_ssl_transform *transform = ssl->transform_in; |
unsigned char taglen = transform->ciphersuite_info->flags & |
MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; |
size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; |
/* |
* Compute and update sizes |
*/ |
if( ssl->in_msglen < explicit_iv_len + taglen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " |
"+ taglen (%d)", ssl->in_msglen, |
explicit_iv_len, taglen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; |
dec_msg = ssl->in_msg; |
dec_msg_result = ssl->in_msg; |
ssl->in_msglen = dec_msglen; |
/* |
* Prepare additional authenticated data |
*/ |
memcpy( add_data, ssl->in_ctr, 8 ); |
add_data[8] = ssl->in_msgtype; |
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, |
ssl->conf->transport, add_data + 9 ); |
add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; |
add_data[12] = ssl->in_msglen & 0xFF; |
MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); |
/* |
* Prepare IV |
*/ |
if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) |
{ |
/* GCM and CCM: fixed || explicit (transmitted) */ |
memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); |
memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 ); |
} |
else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) |
{ |
/* ChachaPoly: fixed XOR sequence number */ |
unsigned char i; |
memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); |
for( i = 0; i < 8; i++ ) |
iv[i+4] ^= ssl->in_ctr[i]; |
} |
else |
{ |
/* Reminder if we ever add an AEAD mode with a different size */ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); |
/* |
* Decrypt and authenticate |
*/ |
if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, |
iv, transform->ivlen, |
add_data, 13, |
dec_msg, dec_msglen, |
dec_msg_result, &olen, |
dec_msg + dec_msglen, taglen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); |
if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
return( ret ); |
} |
auth_done++; |
if( olen != dec_msglen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
else |
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ |
( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) |
if( mode == MBEDTLS_MODE_CBC ) |
{ |
/* |
* Decrypt and check the padding |
*/ |
int ret; |
unsigned char *dec_msg; |
unsigned char *dec_msg_result; |
size_t dec_msglen; |
size_t minlen = 0; |
size_t olen = 0; |
/* |
* Check immediate ciphertext sanity |
*/ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) |
minlen += ssl->transform_in->ivlen; |
#endif |
if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || |
ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " |
"+ 1 ) ( + expl IV )", ssl->in_msglen, |
ssl->transform_in->ivlen, |
ssl->transform_in->maclen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
dec_msglen = ssl->in_msglen; |
dec_msg = ssl->in_msg; |
dec_msg_result = ssl->in_msg; |
/* |
* Authenticate before decrypt if enabled |
*/ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) |
{ |
unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; |
unsigned char pseudo_hdr[13]; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); |
dec_msglen -= ssl->transform_in->maclen; |
ssl->in_msglen -= ssl->transform_in->maclen; |
memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 ); |
memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 ); |
pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF ); |
pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); |
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 ); |
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, |
ssl->in_iv, ssl->in_msglen ); |
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); |
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen, |
ssl->transform_in->maclen ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, |
ssl->transform_in->maclen ); |
if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect, |
ssl->transform_in->maclen ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
auth_done++; |
} |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
/* |
* Check length sanity |
*/ |
if( ssl->in_msglen % ssl->transform_in->ivlen != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0", |
ssl->in_msglen, ssl->transform_in->ivlen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) |
/* |
* Initialize for prepended IV for block cipher in TLS v1.1 and up |
*/ |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) |
{ |
unsigned char i; |
dec_msglen -= ssl->transform_in->ivlen; |
ssl->in_msglen -= ssl->transform_in->ivlen; |
for( i = 0; i < ssl->transform_in->ivlen; i++ ) |
ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ |
if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, |
ssl->transform_in->iv_dec, |
ssl->transform_in->ivlen, |
dec_msg, dec_msglen, |
dec_msg_result, &olen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); |
return( ret ); |
} |
if( dec_msglen != olen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) |
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) |
{ |
/* |
* Save IV in SSL3 and TLS1 |
*/ |
memcpy( ssl->transform_in->iv_dec, |
ssl->transform_in->cipher_ctx_dec.iv, |
ssl->transform_in->ivlen ); |
} |
#endif |
padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; |
if( ssl->in_msglen < ssl->transform_in->maclen + padlen && |
auth_done == 0 ) |
{ |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", |
ssl->in_msglen, ssl->transform_in->maclen, padlen ) ); |
#endif |
padlen = 0; |
correct = 0; |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
if( padlen > ssl->transform_in->ivlen ) |
{ |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, " |
"should be no more than %d", |
padlen, ssl->transform_in->ivlen ) ); |
#endif |
correct = 0; |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
/* |
* TLSv1+: always check the padding up to the first failure |
* and fake check up to 256 bytes of padding |
*/ |
size_t pad_count = 0, real_count = 1; |
size_t padding_idx = ssl->in_msglen - padlen; |
size_t i; |
/* |
* Padding is guaranteed to be incorrect if: |
* 1. padlen > ssl->in_msglen |
* |
* 2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN + |
* ssl->transform_in->maclen |
* |
* In both cases we reset padding_idx to a safe value (0) to |
* prevent out-of-buffer reads. |
*/ |
correct &= ( padlen <= ssl->in_msglen ); |
correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN + |
ssl->transform_in->maclen ); |
padding_idx *= correct; |
for( i = 0; i < 256; i++ ) |
{ |
real_count &= ( i < padlen ); |
pad_count += real_count * |
( ssl->in_msg[padding_idx + i] == padlen - 1 ); |
} |
correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
if( padlen > 0 && correct == 0 ) |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); |
#endif |
padlen &= correct * 0x1FF; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->in_msglen -= padlen; |
} |
else |
#endif /* MBEDTLS_CIPHER_MODE_CBC && |
( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", |
ssl->in_msg, ssl->in_msglen ); |
#endif |
/* |
* Authenticate if not done yet. |
* Compute the MAC regardless of the padding result (RFC4346, CBCTIME). |
*/ |
#if defined(SSL_SOME_MODES_USE_MAC) |
if( auth_done == 0 ) |
{ |
unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; |
ssl->in_msglen -= ssl->transform_in->maclen; |
ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); |
ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
ssl_mac( &ssl->transform_in->md_ctx_dec, |
ssl->transform_in->mac_dec, |
ssl->in_msg, ssl->in_msglen, |
ssl->in_ctr, ssl->in_msgtype, |
mac_expect ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
/* |
* Process MAC and always update for padlen afterwards to make |
* total time independent of padlen. |
* |
* Known timing attacks: |
* - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) |
* |
* To compensate for different timings for the MAC calculation |
* depending on how much padding was removed (which is determined |
* by padlen), process extra_run more blocks through the hash |
* function. |
* |
* The formula in the paper is |
* extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 ) |
* where L1 is the size of the header plus the decrypted message |
* plus CBC padding and L2 is the size of the header plus the |
* decrypted message. This is for an underlying hash function |
* with 64-byte blocks. |
* We use ( (Lx+8) / 64 ) to handle 'negative Lx' values |
* correctly. We round down instead of up, so -56 is the correct |
* value for our calculations instead of -55. |
* |
* Repeat the formula rather than defining a block_size variable. |
* This avoids requiring division by a variable at runtime |
* (which would be marginally less efficient and would require |
* linking an extra division function in some builds). |
*/ |
size_t j, extra_run = 0; |
/* |
* The next two sizes are the minimum and maximum values of |
* in_msglen over all padlen values. |
* |
* They're independent of padlen, since we previously did |
* in_msglen -= padlen. |
* |
* Note that max_len + maclen is never more than the buffer |
* length, as we previously did in_msglen -= maclen too. |
*/ |
const size_t max_len = ssl->in_msglen + padlen; |
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; |
switch( ssl->transform_in->ciphersuite_info->mac ) |
{ |
#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \ |
defined(MBEDTLS_SHA256_C) |
case MBEDTLS_MD_MD5: |
case MBEDTLS_MD_SHA1: |
case MBEDTLS_MD_SHA256: |
/* 8 bytes of message size, 64-byte compression blocks */ |
extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - |
( 13 + ssl->in_msglen + 8 ) / 64; |
break; |
#endif |
#if defined(MBEDTLS_SHA512_C) |
case MBEDTLS_MD_SHA384: |
/* 16 bytes of message size, 128-byte compression blocks */ |
extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 - |
( 13 + ssl->in_msglen + 16 ) / 128; |
break; |
#endif |
default: |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
extra_run &= correct * 0xFF; |
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 ); |
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 ); |
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); |
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, |
ssl->in_msglen ); |
/* Make sure we access everything even when padlen > 0. This |
* makes the synchronisation requirements for just-in-time |
* Prime+Probe attacks much tighter and hopefully impractical. */ |
ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen ); |
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); |
/* Call mbedtls_md_process at least once due to cache attacks |
* that observe whether md_process() was called of not */ |
for( j = 0; j < extra_run + 1; j++ ) |
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); |
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); |
/* Make sure we access all the memory that could contain the MAC, |
* before we check it in the next code block. This makes the |
* synchronisation requirements for just-in-time Prime+Probe |
* attacks much tighter and hopefully impractical. */ |
ssl_read_memory( ssl->in_msg + min_len, |
max_len - min_len + ssl->transform_in->maclen ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen, |
ssl->transform_in->maclen ); |
#endif |
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect, |
ssl->transform_in->maclen ) != 0 ) |
{ |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); |
#endif |
correct = 0; |
} |
auth_done++; |
} |
/* |
* Finally check the correct flag |
*/ |
if( correct == 0 ) |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
#endif /* SSL_SOME_MODES_USE_MAC */ |
/* Make extra sure authentication was performed, exactly once */ |
if( auth_done != 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
if( ssl->in_msglen == 0 ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 |
&& ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) |
{ |
/* TLS v1.2 explicitly disallows zero-length messages which are not application data */ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
ssl->nb_zero++; |
/* |
* Three or more empty messages may be a DoS attack |
* (excessive CPU consumption). |
*/ |
if( ssl->nb_zero > 3 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " |
"messages, possible DoS attack" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
} |
else |
ssl->nb_zero = 0; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
; /* in_ctr read from peer, not maintained internally */ |
} |
else |
#endif |
{ |
unsigned char i; |
for( i = 8; i > ssl_ep_len( ssl ); i-- ) |
if( ++ssl->in_ctr[i - 1] != 0 ) |
break; |
/* The loop goes to its end iff the counter is wrapping */ |
if( i == ssl_ep_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); |
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); |
return( 0 ); |
} |
#undef MAC_NONE |
#undef MAC_PLAINTEXT |
#undef MAC_CIPHERTEXT |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
/* |
* Compression/decompression functions |
*/ |
static int ssl_compress_buf( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned char *msg_post = ssl->out_msg; |
ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf; |
size_t len_pre = ssl->out_msglen; |
unsigned char *msg_pre = ssl->compress_buf; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); |
if( len_pre == 0 ) |
return( 0 ); |
memcpy( msg_pre, ssl->out_msg, len_pre ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ", |
ssl->out_msglen ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload", |
ssl->out_msg, ssl->out_msglen ); |
ssl->transform_out->ctx_deflate.next_in = msg_pre; |
ssl->transform_out->ctx_deflate.avail_in = len_pre; |
ssl->transform_out->ctx_deflate.next_out = msg_post; |
ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written; |
ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); |
if( ret != Z_OK ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); |
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); |
} |
ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN - |
ssl->transform_out->ctx_deflate.avail_out - bytes_written; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", |
ssl->out_msglen ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload", |
ssl->out_msg, ssl->out_msglen ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); |
return( 0 ); |
} |
static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned char *msg_post = ssl->in_msg; |
ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf; |
size_t len_pre = ssl->in_msglen; |
unsigned char *msg_pre = ssl->compress_buf; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); |
if( len_pre == 0 ) |
return( 0 ); |
memcpy( msg_pre, ssl->in_msg, len_pre ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ", |
ssl->in_msglen ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload", |
ssl->in_msg, ssl->in_msglen ); |
ssl->transform_in->ctx_inflate.next_in = msg_pre; |
ssl->transform_in->ctx_inflate.avail_in = len_pre; |
ssl->transform_in->ctx_inflate.next_out = msg_post; |
ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN - |
header_bytes; |
ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); |
if( ret != Z_OK ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); |
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); |
} |
ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN - |
ssl->transform_in->ctx_inflate.avail_out - header_bytes; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", |
ssl->in_msglen ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload", |
ssl->in_msg, ssl->in_msglen ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_ZLIB_SUPPORT */ |
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) |
static int ssl_write_hello_request( mbedtls_ssl_context *ssl ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) |
{ |
/* If renegotiation is not enforced, retransmit until we would reach max |
* timeout if we were using the usual handshake doubling scheme */ |
if( ssl->conf->renego_max_records < 0 ) |
{ |
uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; |
unsigned char doublings = 1; |
while( ratio != 0 ) |
{ |
++doublings; |
ratio >>= 1; |
} |
if( ++ssl->renego_records_seen > doublings ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) ); |
return( 0 ); |
} |
} |
return( ssl_write_hello_request( ssl ) ); |
} |
#endif |
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ |
/* |
* Fill the input message buffer by appending data to it. |
* The amount of data already fetched is in ssl->in_left. |
* |
* If we return 0, is it guaranteed that (at least) nb_want bytes are |
* available (from this read and/or a previous one). Otherwise, an error code |
* is returned (possibly EOF or WANT_READ). |
* |
* With stream transport (TLS) on success ssl->in_left == nb_want, but |
* with datagram transport (DTLS) on success ssl->in_left >= nb_want, |
* since we always read a whole datagram at once. |
* |
* For DTLS, it is up to the caller to set ssl->next_record_offset when |
* they're done reading a record. |
*/ |
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) |
{ |
int ret; |
size_t len; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); |
if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " |
"or mbedtls_ssl_set_bio()" ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
uint32_t timeout; |
/* Just to be sure */ |
if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " |
"mbedtls_ssl_set_timer_cb() for DTLS" ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
/* |
* The point is, we need to always read a full datagram at once, so we |
* sometimes read more then requested, and handle the additional data. |
* It could be the rest of the current record (while fetching the |
* header) and/or some other records in the same datagram. |
*/ |
/* |
* Move to the next record in the already read datagram if applicable |
*/ |
if( ssl->next_record_offset != 0 ) |
{ |
if( ssl->in_left < ssl->next_record_offset ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->in_left -= ssl->next_record_offset; |
if( ssl->in_left != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d", |
ssl->next_record_offset ) ); |
memmove( ssl->in_hdr, |
ssl->in_hdr + ssl->next_record_offset, |
ssl->in_left ); |
} |
ssl->next_record_offset = 0; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", |
ssl->in_left, nb_want ) ); |
/* |
* Done if we already have enough data. |
*/ |
if( nb_want <= ssl->in_left) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); |
return( 0 ); |
} |
/* |
* A record can't be split across datagrams. If we need to read but |
* are not at the beginning of a new record, the caller did something |
* wrong. |
*/ |
if( ssl->in_left != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* |
* Don't even try to read if time's out already. |
* This avoids by-passing the timer when repeatedly receiving messages |
* that will end up being dropped. |
*/ |
if( ssl_check_timer( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) ); |
ret = MBEDTLS_ERR_SSL_TIMEOUT; |
} |
else |
{ |
len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
timeout = ssl->handshake->retransmit_timeout; |
else |
timeout = ssl->conf->read_timeout; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); |
if( ssl->f_recv_timeout != NULL ) |
ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, |
timeout ); |
else |
ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); |
if( ret == 0 ) |
return( MBEDTLS_ERR_SSL_CONN_EOF ); |
} |
if( ret == MBEDTLS_ERR_SSL_TIMEOUT ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); |
ssl_set_timer( ssl, 0 ); |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
{ |
if( ssl_double_retransmit_timeout( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) ); |
return( MBEDTLS_ERR_SSL_TIMEOUT ); |
} |
if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); |
return( ret ); |
} |
return( MBEDTLS_ERR_SSL_WANT_READ ); |
} |
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) |
else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) |
{ |
if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); |
return( ret ); |
} |
return( MBEDTLS_ERR_SSL_WANT_READ ); |
} |
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ |
} |
if( ret < 0 ) |
return( ret ); |
ssl->in_left = ret; |
} |
else |
#endif |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", |
ssl->in_left, nb_want ) ); |
while( ssl->in_left < nb_want ) |
{ |
len = nb_want - ssl->in_left; |
if( ssl_check_timer( ssl ) != 0 ) |
ret = MBEDTLS_ERR_SSL_TIMEOUT; |
else |
{ |
if( ssl->f_recv_timeout != NULL ) |
{ |
ret = ssl->f_recv_timeout( ssl->p_bio, |
ssl->in_hdr + ssl->in_left, len, |
ssl->conf->read_timeout ); |
} |
else |
{ |
ret = ssl->f_recv( ssl->p_bio, |
ssl->in_hdr + ssl->in_left, len ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", |
ssl->in_left, nb_want ) ); |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); |
if( ret == 0 ) |
return( MBEDTLS_ERR_SSL_CONN_EOF ); |
if( ret < 0 ) |
return( ret ); |
if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, |
( "f_recv returned %d bytes but only %lu were requested", |
ret, (unsigned long)len ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->in_left += ret; |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); |
return( 0 ); |
} |
/* |
* Flush any data not yet written |
*/ |
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned char *buf; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); |
if( ssl->f_send == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " |
"or mbedtls_ssl_set_bio()" ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
/* Avoid incrementing counter if data is flushed */ |
if( ssl->out_left == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); |
return( 0 ); |
} |
while( ssl->out_left > 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", |
mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); |
buf = ssl->out_hdr - ssl->out_left; |
ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); |
if( ret <= 0 ) |
return( ret ); |
if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, |
( "f_send returned %d bytes but only %lu bytes were sent", |
ret, (unsigned long)ssl->out_left ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
ssl->out_left -= ret; |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ssl->out_hdr = ssl->out_buf; |
} |
else |
#endif |
{ |
ssl->out_hdr = ssl->out_buf + 8; |
} |
ssl_update_out_pointers( ssl, ssl->transform_out ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); |
return( 0 ); |
} |
/* |
* Functions to handle the DTLS retransmission state machine |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* |
* Append current handshake message to current outgoing flight |
*/ |
static int ssl_flight_append( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_flight_item *msg; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight", |
ssl->out_msg, ssl->out_msglen ); |
/* Allocate space for current message */ |
if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", |
sizeof( mbedtls_ssl_flight_item ) ) ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) ); |
mbedtls_free( msg ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
/* Copy current handshake message with headers */ |
memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); |
msg->len = ssl->out_msglen; |
msg->type = ssl->out_msgtype; |
msg->next = NULL; |
/* Append to the current flight */ |
if( ssl->handshake->flight == NULL ) |
ssl->handshake->flight = msg; |
else |
{ |
mbedtls_ssl_flight_item *cur = ssl->handshake->flight; |
while( cur->next != NULL ) |
cur = cur->next; |
cur->next = msg; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) ); |
return( 0 ); |
} |
/* |
* Free the current flight of handshake messages |
*/ |
static void ssl_flight_free( mbedtls_ssl_flight_item *flight ) |
{ |
mbedtls_ssl_flight_item *cur = flight; |
mbedtls_ssl_flight_item *next; |
while( cur != NULL ) |
{ |
next = cur->next; |
mbedtls_free( cur->p ); |
mbedtls_free( cur ); |
cur = next; |
} |
} |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); |
#endif |
/* |
* Swap transform_out and out_ctr with the alternative ones |
*/ |
static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_transform *tmp_transform; |
unsigned char tmp_out_ctr[8]; |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
int ret; |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
if( ssl->transform_out == ssl->handshake->alt_transform_out ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); |
/* Swap transforms */ |
tmp_transform = ssl->transform_out; |
ssl->transform_out = ssl->handshake->alt_transform_out; |
ssl->handshake->alt_transform_out = tmp_transform; |
/* Swap epoch + sequence_number */ |
memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 ); |
memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 ); |
memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); |
/* Adjust to the newly activated transform */ |
ssl_update_out_pointers( ssl, ssl->transform_out ); |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_activate != NULL ) |
{ |
if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
} |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
return( 0 ); |
} |
/* |
* Retransmit the current flight of messages. |
*/ |
int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) |
{ |
int ret = 0; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); |
ret = mbedtls_ssl_flight_transmit( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); |
return( ret ); |
} |
/* |
* Transmit or retransmit the current flight of messages. |
* |
* Need to remember the current message in case flush_output returns |
* WANT_WRITE, causing us to exit this function and come back later. |
* This function must be called until state is no longer SENDING. |
*/ |
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); |
if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) ); |
ssl->handshake->cur_msg = ssl->handshake->flight; |
ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; |
if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) |
return( ret ); |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; |
} |
while( ssl->handshake->cur_msg != NULL ) |
{ |
size_t max_frag_len; |
const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; |
int const is_finished = |
( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && |
cur->p[0] == MBEDTLS_SSL_HS_FINISHED ); |
uint8_t const force_flush = ssl->disable_datagram_packing == 1 ? |
SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; |
/* Swap epochs before sending Finished: we can't do it after |
* sending ChangeCipherSpec, in case write returns WANT_READ. |
* Must be done before copying, may change out_msg pointer */ |
if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); |
if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) |
return( ret ); |
} |
ret = ssl_get_remaining_payload_in_datagram( ssl ); |
if( ret < 0 ) |
return( ret ); |
max_frag_len = (size_t) ret; |
/* CCS is copied as is, while HS messages may need fragmentation */ |
if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) |
{ |
if( max_frag_len == 0 ) |
{ |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
return( ret ); |
continue; |
} |
memcpy( ssl->out_msg, cur->p, cur->len ); |
ssl->out_msglen = cur->len; |
ssl->out_msgtype = cur->type; |
/* Update position inside current message */ |
ssl->handshake->cur_msg_p += cur->len; |
} |
else |
{ |
const unsigned char * const p = ssl->handshake->cur_msg_p; |
const size_t hs_len = cur->len - 12; |
const size_t frag_off = p - ( cur->p + 12 ); |
const size_t rem_len = hs_len - frag_off; |
size_t cur_hs_frag_len, max_hs_frag_len; |
if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) |
{ |
if( is_finished ) |
{ |
if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) |
return( ret ); |
} |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
return( ret ); |
continue; |
} |
max_hs_frag_len = max_frag_len - 12; |
cur_hs_frag_len = rem_len > max_hs_frag_len ? |
max_hs_frag_len : rem_len; |
if( frag_off == 0 && cur_hs_frag_len != hs_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", |
(unsigned) cur_hs_frag_len, |
(unsigned) max_hs_frag_len ) ); |
} |
/* Messages are stored with handshake headers as if not fragmented, |
* copy beginning of headers then fill fragmentation fields. |
* Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ |
memcpy( ssl->out_msg, cur->p, 6 ); |
ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff ); |
ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff ); |
ssl->out_msg[8] = ( ( frag_off ) & 0xff ); |
ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff ); |
ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff ); |
ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); |
/* Copy the handshake message content and set records fields */ |
memcpy( ssl->out_msg + 12, p, cur_hs_frag_len ); |
ssl->out_msglen = cur_hs_frag_len + 12; |
ssl->out_msgtype = cur->type; |
/* Update position inside current message */ |
ssl->handshake->cur_msg_p += cur_hs_frag_len; |
} |
/* If done with the current message move to the next one if any */ |
if( ssl->handshake->cur_msg_p >= cur->p + cur->len ) |
{ |
if( cur->next != NULL ) |
{ |
ssl->handshake->cur_msg = cur->next; |
ssl->handshake->cur_msg_p = cur->next->p + 12; |
} |
else |
{ |
ssl->handshake->cur_msg = NULL; |
ssl->handshake->cur_msg_p = NULL; |
} |
} |
/* Actually send the message out */ |
if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); |
return( ret ); |
} |
} |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
return( ret ); |
/* Update state and set timer */ |
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; |
else |
{ |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; |
ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) ); |
return( 0 ); |
} |
/* |
* To be called when the last message of an incoming flight is received. |
*/ |
void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) |
{ |
/* We won't need to resend that one any more */ |
ssl_flight_free( ssl->handshake->flight ); |
ssl->handshake->flight = NULL; |
ssl->handshake->cur_msg = NULL; |
/* The next incoming flight will start with this msg_seq */ |
ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; |
/* We don't want to remember CCS's across flight boundaries. */ |
ssl->handshake->buffering.seen_ccs = 0; |
/* Clear future message buffering structure. */ |
ssl_buffering_free( ssl ); |
/* Cancel timer */ |
ssl_set_timer( ssl, 0 ); |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) |
{ |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; |
} |
else |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; |
} |
/* |
* To be called when the last message of an outgoing flight is send. |
*/ |
void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) |
{ |
ssl_reset_retransmit_timeout( ssl ); |
ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) |
{ |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; |
} |
else |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* |
* Handshake layer functions |
*/ |
/* |
* Write (DTLS: or queue) current handshake (including CCS) message. |
* |
* - fill in handshake headers |
* - update handshake checksum |
* - DTLS: save message for resending |
* - then pass to the record layer |
* |
* DTLS: except for HelloRequest, messages are only queued, and will only be |
* actually sent when calling flight_transmit() or resend(). |
* |
* Inputs: |
* - ssl->out_msglen: 4 + actual handshake message len |
* (4 is the size of handshake headers for TLS) |
* - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) |
* - ssl->out_msg + 4: the handshake message body |
* |
* Outputs, ie state before passing to flight_append() or write_record(): |
* - ssl->out_msglen: the length of the record contents |
* (including handshake headers but excluding record headers) |
* - ssl->out_msg: the record contents (handshake headers + content) |
*/ |
int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
const size_t hs_len = ssl->out_msglen - 4; |
const unsigned char hs_type = ssl->out_msg[0]; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) ); |
/* |
* Sanity checks |
*/ |
if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && |
ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) |
{ |
/* In SSLv3, the client might send a NoCertificate alert. */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) |
if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && |
ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && |
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ) |
#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
/* Whenever we send anything different from a |
* HelloRequest we should be in a handshake - double check. */ |
if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) && |
ssl->handshake == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake != NULL && |
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#endif |
/* Double-check that we did not exceed the bounds |
* of the outgoing record buffer. |
* This should never fail as the various message |
* writing functions must obey the bounds of the |
* outgoing record buffer, but better be safe. |
* |
* Note: We deliberately do not check for the MTU or MFL here. |
*/ |
if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: " |
"size %u, maximum %u", |
(unsigned) ssl->out_msglen, |
(unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* |
* Fill handshake headers |
*/ |
if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
ssl->out_msg[1] = (unsigned char)( hs_len >> 16 ); |
ssl->out_msg[2] = (unsigned char)( hs_len >> 8 ); |
ssl->out_msg[3] = (unsigned char)( hs_len ); |
/* |
* DTLS has additional fields in the Handshake layer, |
* between the length field and the actual payload: |
* uint16 message_seq; |
* uint24 fragment_offset; |
* uint24 fragment_length; |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
/* Make room for the additional DTLS fields */ |
if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " |
"size %u, maximum %u", |
(unsigned) ( hs_len ), |
(unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len ); |
ssl->out_msglen += 8; |
/* Write message_seq and update it, except for HelloRequest */ |
if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) |
{ |
ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; |
ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; |
++( ssl->handshake->out_msg_seq ); |
} |
else |
{ |
ssl->out_msg[4] = 0; |
ssl->out_msg[5] = 0; |
} |
/* Handshake hashes are computed without fragmentation, |
* so set frag_offset = 0 and frag_len = hs_len for now */ |
memset( ssl->out_msg + 6, 0x00, 3 ); |
memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* Update running hashes of handshake messages seen */ |
if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) |
ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); |
} |
/* Either send now, or just save to be sent (and resent) later */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) ) |
{ |
if( ( ret = ssl_flight_append( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret ); |
return( ret ); |
} |
} |
else |
#endif |
{ |
if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); |
return( ret ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) ); |
return( 0 ); |
} |
/* |
* Record layer functions |
*/ |
/* |
* Write current record. |
* |
* Uses: |
* - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) |
* - ssl->out_msglen: length of the record content (excl headers) |
* - ssl->out_msg: record content |
*/ |
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) |
{ |
int ret, done = 0; |
size_t len = ssl->out_msglen; |
uint8_t flush = force_flush; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
if( ssl->transform_out != NULL && |
ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) |
{ |
if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); |
return( ret ); |
} |
len = ssl->out_msglen; |
} |
#endif /*MBEDTLS_ZLIB_SUPPORT */ |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_write != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) ); |
ret = mbedtls_ssl_hw_record_write( ssl ); |
if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
if( ret == 0 ) |
done = 1; |
} |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
if( !done ) |
{ |
unsigned i; |
size_t protected_record_size; |
ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; |
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, |
ssl->conf->transport, ssl->out_hdr + 1 ); |
memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 ); |
ssl->out_len[0] = (unsigned char)( len >> 8 ); |
ssl->out_len[1] = (unsigned char)( len ); |
if( ssl->transform_out != NULL ) |
{ |
if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); |
return( ret ); |
} |
len = ssl->out_msglen; |
ssl->out_len[0] = (unsigned char)( len >> 8 ); |
ssl->out_len[1] = (unsigned char)( len ); |
} |
protected_record_size = len + mbedtls_ssl_hdr_len( ssl ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* In case of DTLS, double-check that we don't exceed |
* the remaining space in the datagram. */ |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ret = ssl_get_remaining_space_in_datagram( ssl ); |
if( ret < 0 ) |
return( ret ); |
if( protected_record_size > (size_t) ret ) |
{ |
/* Should never happen */ |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " |
"version = [%d:%d], msglen = %d", |
ssl->out_hdr[0], ssl->out_hdr[1], |
ssl->out_hdr[2], len ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", |
ssl->out_hdr, protected_record_size ); |
ssl->out_left += protected_record_size; |
ssl->out_hdr += protected_record_size; |
ssl_update_out_pointers( ssl, ssl->transform_out ); |
for( i = 8; i > ssl_ep_len( ssl ); i-- ) |
if( ++ssl->cur_out_ctr[i - 1] != 0 ) |
break; |
/* The loop goes to its end iff the counter is wrapping */ |
if( i == ssl_ep_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); |
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); |
} |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
flush == SSL_DONT_FORCE_FLUSH ) |
{ |
size_t remaining; |
ret = ssl_get_remaining_payload_in_datagram( ssl ); |
if( ret < 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram", |
ret ); |
return( ret ); |
} |
remaining = (size_t) ret; |
if( remaining == 0 ) |
{ |
flush = SSL_FORCE_FLUSH; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
if( ( flush == SSL_FORCE_FLUSH ) && |
( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) |
{ |
if( ssl->in_msglen < ssl->in_hslen || |
memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || |
memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) |
{ |
return( 1 ); |
} |
return( 0 ); |
} |
static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl ) |
{ |
return( ( ssl->in_msg[9] << 16 ) | |
( ssl->in_msg[10] << 8 ) | |
ssl->in_msg[11] ); |
} |
static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl ) |
{ |
return( ( ssl->in_msg[6] << 16 ) | |
( ssl->in_msg[7] << 8 ) | |
ssl->in_msg[8] ); |
} |
static int ssl_check_hs_header( mbedtls_ssl_context const *ssl ) |
{ |
uint32_t msg_len, frag_off, frag_len; |
msg_len = ssl_get_hs_total_len( ssl ); |
frag_off = ssl_get_hs_frag_off( ssl ); |
frag_len = ssl_get_hs_frag_len( ssl ); |
if( frag_off > msg_len ) |
return( -1 ); |
if( frag_len > msg_len - frag_off ) |
return( -1 ); |
if( frag_len + 12 > ssl->in_msglen ) |
return( -1 ); |
return( 0 ); |
} |
/* |
* Mark bits in bitmask (used for DTLS HS reassembly) |
*/ |
static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) |
{ |
unsigned int start_bits, end_bits; |
start_bits = 8 - ( offset % 8 ); |
if( start_bits != 8 ) |
{ |
size_t first_byte_idx = offset / 8; |
/* Special case */ |
if( len <= start_bits ) |
{ |
for( ; len != 0; len-- ) |
mask[first_byte_idx] |= 1 << ( start_bits - len ); |
/* Avoid potential issues with offset or len becoming invalid */ |
return; |
} |
offset += start_bits; /* Now offset % 8 == 0 */ |
len -= start_bits; |
for( ; start_bits != 0; start_bits-- ) |
mask[first_byte_idx] |= 1 << ( start_bits - 1 ); |
} |
end_bits = len % 8; |
if( end_bits != 0 ) |
{ |
size_t last_byte_idx = ( offset + len ) / 8; |
len -= end_bits; /* Now len % 8 == 0 */ |
for( ; end_bits != 0; end_bits-- ) |
mask[last_byte_idx] |= 1 << ( 8 - end_bits ); |
} |
memset( mask + offset / 8, 0xFF, len / 8 ); |
} |
/* |
* Check that bitmask is full |
*/ |
static int ssl_bitmask_check( unsigned char *mask, size_t len ) |
{ |
size_t i; |
for( i = 0; i < len / 8; i++ ) |
if( mask[i] != 0xFF ) |
return( -1 ); |
for( i = 0; i < len % 8; i++ ) |
if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) |
return( -1 ); |
return( 0 ); |
} |
/* msg_len does not include the handshake header */ |
static size_t ssl_get_reassembly_buffer_size( size_t msg_len, |
unsigned add_bitmap ) |
{ |
size_t alloc_len; |
alloc_len = 12; /* Handshake header */ |
alloc_len += msg_len; /* Content buffer */ |
if( add_bitmap ) |
alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */ |
return( alloc_len ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ) |
{ |
return( ( ssl->in_msg[1] << 16 ) | |
( ssl->in_msg[2] << 8 ) | |
ssl->in_msg[3] ); |
} |
int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) |
{ |
if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d", |
ssl->in_msglen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" |
" %d, type = %d, hslen = %d", |
ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
int ret; |
unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; |
if( ssl_check_hs_header( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
if( ssl->handshake != NULL && |
( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && |
recv_msg_seq != ssl->handshake->in_msg_seq ) || |
( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && |
ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) |
{ |
if( recv_msg_seq > ssl->handshake->in_msg_seq ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)", |
recv_msg_seq, |
ssl->handshake->in_msg_seq ) ); |
return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); |
} |
/* Retransmit only on last message from previous flight, to avoid |
* too many retransmissions. |
* Besides, No sane server ever retransmits HelloVerifyRequest */ |
if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && |
ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, " |
"message_seq = %d, start_of_flight = %d", |
recv_msg_seq, |
ssl->handshake->in_flight_start_seq ) ); |
if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); |
return( ret ); |
} |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: " |
"message_seq = %d, expected = %d", |
recv_msg_seq, |
ssl->handshake->in_msg_seq ) ); |
} |
return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); |
} |
/* Wait until message completion to increment in_msg_seq */ |
/* Message reassembly is handled alongside buffering of future |
* messages; the commonality is that both handshake fragments and |
* future messages cannot be forwarded immediately to the |
* handshake logic layer. */ |
if( ssl_hs_is_proper_fragment( ssl ) == 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); |
return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* With TLS we don't handle fragmentation (for now) */ |
if( ssl->in_msglen < ssl->in_hslen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
} |
return( 0 ); |
} |
void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) |
{ |
ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); |
} |
/* Handshake message is complete, increment counter */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake != NULL ) |
{ |
unsigned offset; |
mbedtls_ssl_hs_buffer *hs_buf; |
/* Increment handshake sequence number */ |
hs->in_msg_seq++; |
/* |
* Clear up handshake buffering and reassembly structure. |
*/ |
/* Free first entry */ |
ssl_buffering_free_slot( ssl, 0 ); |
/* Shift all other entries */ |
for( offset = 0, hs_buf = &hs->buffering.hs[0]; |
offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; |
offset++, hs_buf++ ) |
{ |
*hs_buf = *(hs_buf + 1); |
} |
/* Create a fresh last entry */ |
memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); |
} |
#endif |
} |
/* |
* DTLS anti-replay: RFC 6347 4.1.2.6 |
* |
* in_window is a field of bits numbered from 0 (lsb) to 63 (msb). |
* Bit n is set iff record number in_window_top - n has been seen. |
* |
* Usually, in_window_top is the last record number seen and the lsb of |
* in_window is set. The only exception is the initial state (record number 0 |
* not seen yet). |
*/ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ) |
{ |
ssl->in_window_top = 0; |
ssl->in_window = 0; |
} |
static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) |
{ |
return( ( (uint64_t) buf[0] << 40 ) | |
( (uint64_t) buf[1] << 32 ) | |
( (uint64_t) buf[2] << 24 ) | |
( (uint64_t) buf[3] << 16 ) | |
( (uint64_t) buf[4] << 8 ) | |
( (uint64_t) buf[5] ) ); |
} |
/* |
* Return 0 if sequence number is acceptable, -1 otherwise |
*/ |
int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) |
{ |
uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); |
uint64_t bit; |
if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) |
return( 0 ); |
if( rec_seqnum > ssl->in_window_top ) |
return( 0 ); |
bit = ssl->in_window_top - rec_seqnum; |
if( bit >= 64 ) |
return( -1 ); |
if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 ) |
return( -1 ); |
return( 0 ); |
} |
/* |
* Update replay window on new validated record |
*/ |
void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) |
{ |
uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); |
if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) |
return; |
if( rec_seqnum > ssl->in_window_top ) |
{ |
/* Update window_top and the contents of the window */ |
uint64_t shift = rec_seqnum - ssl->in_window_top; |
if( shift >= 64 ) |
ssl->in_window = 1; |
else |
{ |
ssl->in_window <<= shift; |
ssl->in_window |= 1; |
} |
ssl->in_window_top = rec_seqnum; |
} |
else |
{ |
/* Mark that number as seen in the current window */ |
uint64_t bit = ssl->in_window_top - rec_seqnum; |
if( bit < 64 ) /* Always true, but be extra sure */ |
ssl->in_window |= (uint64_t) 1 << bit; |
} |
} |
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ |
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) |
/* Forward declaration */ |
static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); |
/* |
* Without any SSL context, check if a datagram looks like a ClientHello with |
* a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. |
* Both input and output include full DTLS headers. |
* |
* - if cookie is valid, return 0 |
* - if ClientHello looks superficially valid but cookie is not, |
* fill obuf and set olen, then |
* return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED |
* - otherwise return a specific error code |
*/ |
static int ssl_check_dtls_clihlo_cookie( |
mbedtls_ssl_cookie_write_t *f_cookie_write, |
mbedtls_ssl_cookie_check_t *f_cookie_check, |
void *p_cookie, |
const unsigned char *cli_id, size_t cli_id_len, |
const unsigned char *in, size_t in_len, |
unsigned char *obuf, size_t buf_len, size_t *olen ) |
{ |
size_t sid_len, cookie_len; |
unsigned char *p; |
if( f_cookie_write == NULL || f_cookie_check == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
/* |
* Structure of ClientHello with record and handshake headers, |
* and expected values. We don't need to check a lot, more checks will be |
* done when actually parsing the ClientHello - skipping those checks |
* avoids code duplication and does not make cookie forging any easier. |
* |
* 0-0 ContentType type; copied, must be handshake |
* 1-2 ProtocolVersion version; copied |
* 3-4 uint16 epoch; copied, must be 0 |
* 5-10 uint48 sequence_number; copied |
* 11-12 uint16 length; (ignored) |
* |
* 13-13 HandshakeType msg_type; (ignored) |
* 14-16 uint24 length; (ignored) |
* 17-18 uint16 message_seq; copied |
* 19-21 uint24 fragment_offset; copied, must be 0 |
* 22-24 uint24 fragment_length; (ignored) |
* |
* 25-26 ProtocolVersion client_version; (ignored) |
* 27-58 Random random; (ignored) |
* 59-xx SessionID session_id; 1 byte len + sid_len content |
* 60+ opaque cookie<0..2^8-1>; 1 byte len + content |
* ... |
* |
* Minimum length is 61 bytes. |
*/ |
if( in_len < 61 || |
in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || |
in[3] != 0 || in[4] != 0 || |
in[19] != 0 || in[20] != 0 || in[21] != 0 ) |
{ |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
} |
sid_len = in[59]; |
if( sid_len > in_len - 61 ) |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
cookie_len = in[60 + sid_len]; |
if( cookie_len > in_len - 60 ) |
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); |
if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len, |
cli_id, cli_id_len ) == 0 ) |
{ |
/* Valid cookie */ |
return( 0 ); |
} |
/* |
* If we get here, we've got an invalid cookie, let's prepare HVR. |
* |
* 0-0 ContentType type; copied |
* 1-2 ProtocolVersion version; copied |
* 3-4 uint16 epoch; copied |
* 5-10 uint48 sequence_number; copied |
* 11-12 uint16 length; olen - 13 |
* |
* 13-13 HandshakeType msg_type; hello_verify_request |
* 14-16 uint24 length; olen - 25 |
* 17-18 uint16 message_seq; copied |
* 19-21 uint24 fragment_offset; copied |
* 22-24 uint24 fragment_length; olen - 25 |
* |
* 25-26 ProtocolVersion server_version; 0xfe 0xff |
* 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie |
* |
* Minimum length is 28. |
*/ |
if( buf_len < 28 ) |
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); |
/* Copy most fields and adapt others */ |
memcpy( obuf, in, 25 ); |
obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; |
obuf[25] = 0xfe; |
obuf[26] = 0xff; |
/* Generate and write actual cookie */ |
p = obuf + 28; |
if( f_cookie_write( p_cookie, |
&p, obuf + buf_len, cli_id, cli_id_len ) != 0 ) |
{ |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
*olen = p - obuf; |
/* Go back and fill length fields */ |
obuf[27] = (unsigned char)( *olen - 28 ); |
obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); |
obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); |
obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); |
obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); |
obuf[12] = (unsigned char)( ( *olen - 13 ) ); |
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); |
} |
/* |
* Handle possible client reconnect with the same UDP quadruplet |
* (RFC 6347 Section 4.2.8). |
* |
* Called by ssl_parse_record_header() in case we receive an epoch 0 record |
* that looks like a ClientHello. |
* |
* - if the input looks like a ClientHello without cookies, |
* send back HelloVerifyRequest, then |
* return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED |
* - if the input looks like a ClientHello with a valid cookie, |
* reset the session of the current context, and |
* return MBEDTLS_ERR_SSL_CLIENT_RECONNECT |
* - if anything goes wrong, return a specific error code |
* |
* mbedtls_ssl_read_record() will ignore the record if anything else than |
* MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function |
* cannot not return 0. |
*/ |
static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
size_t len; |
ret = ssl_check_dtls_clihlo_cookie( |
ssl->conf->f_cookie_write, |
ssl->conf->f_cookie_check, |
ssl->conf->p_cookie, |
ssl->cli_id, ssl->cli_id_len, |
ssl->in_buf, ssl->in_left, |
ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); |
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) |
{ |
int send_ret; |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", |
ssl->out_buf, len ); |
/* Don't check write errors as we can't do anything here. |
* If the error is permanent we'll catch it later, |
* if it's not, then hopefully it'll work next time. */ |
send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len ); |
MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret ); |
(void) send_ret; |
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); |
} |
if( ret == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); |
if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); |
return( ret ); |
} |
return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); |
} |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ |
/* |
* ContentType type; |
* ProtocolVersion version; |
* uint16 epoch; // DTLS only |
* uint48 sequence_number; // DTLS only |
* uint16 length; |
* |
* Return 0 if header looks sane (and, for DTLS, the record is expected) |
* MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, |
* MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. |
* |
* With DTLS, mbedtls_ssl_read_record() will: |
* 1. proceed with the record if this function returns 0 |
* 2. drop only the current record if this function returns UNEXPECTED_RECORD |
* 3. return CLIENT_RECONNECT if this function return that value |
* 4. drop the whole datagram if this function returns anything else. |
* Point 2 is needed when the peer is resending, and we have already received |
* the first record from a datagram but are still waiting for the others. |
*/ |
static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) |
{ |
int major_ver, minor_ver; |
MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); |
ssl->in_msgtype = ssl->in_hdr[0]; |
ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; |
mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " |
"version = [%d:%d], msglen = %d", |
ssl->in_msgtype, |
major_ver, minor_ver, ssl->in_msglen ) ); |
/* Check record type */ |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && |
ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT && |
ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && |
ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* Silently ignore invalid DTLS records as recommended by RFC 6347 |
* Section 4.1.2.7 */ |
if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
/* Check version */ |
if( major_ver != ssl->major_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
if( minor_ver > ssl->conf->max_minor_ver ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
/* Check length against the size of our buffer */ |
if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN |
- (size_t)( ssl->in_msg - ssl->in_buf ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
/* |
* DTLS-related tests. |
* Check epoch before checking length constraint because |
* the latter varies with the epoch. E.g., if a ChangeCipherSpec |
* message gets duplicated before the corresponding Finished message, |
* the second ChangeCipherSpec should be discarded because it belongs |
* to an old epoch, but not because its length is shorter than |
* the minimum record length for packets using the new record transform. |
* Note that these two kinds of failures are handled differently, |
* as an unexpected record is silently skipped but an invalid |
* record leads to the entire datagram being dropped. |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; |
/* Check epoch (and sequence number) with DTLS */ |
if( rec_epoch != ssl->in_epoch ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " |
"expected %d, received %d", |
ssl->in_epoch, rec_epoch ) ); |
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) |
/* |
* Check for an epoch 0 ClientHello. We can't use in_msg here to |
* access the first byte of record content (handshake type), as we |
* have an active transform (possibly iv_len != 0), so use the |
* fact that the record header len is 13 instead. |
*/ |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && |
rec_epoch == 0 && |
ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
ssl->in_left > 13 && |
ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " |
"from the same port" ) ); |
return( ssl_handle_possible_reconnect( ssl ) ); |
} |
else |
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ |
{ |
/* Consider buffering the record. */ |
if( rec_epoch == (unsigned int) ssl->in_epoch + 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) ); |
return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); |
} |
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); |
} |
} |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
/* Replay detection only works for the current epoch */ |
if( rec_epoch == ssl->in_epoch && |
mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); |
} |
#endif |
/* Drop unexpected ApplicationData records, |
* except at the beginning of renegotiations */ |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && |
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && |
ssl->state == MBEDTLS_SSL_SERVER_HELLO ) |
#endif |
) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* Check length against bounds of the current transform and version */ |
if( ssl->transform_in == NULL ) |
{ |
if( ssl->in_msglen < 1 || |
ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
} |
else |
{ |
if( ssl->in_msglen < ssl->transform_in->minlen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && |
ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
/* |
* TLS encrypted messages can have up to 256 bytes of padding |
*/ |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 && |
ssl->in_msglen > ssl->transform_in->minlen + |
MBEDTLS_SSL_IN_CONTENT_LEN + 256 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
#endif |
} |
return( 0 ); |
} |
/* |
* If applicable, decrypt (and decompress) record content |
*/ |
static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) |
{ |
int ret, done = 0; |
MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", |
ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ); |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_read != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) ); |
ret = mbedtls_ssl_hw_record_read( ssl ); |
if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
if( ret == 0 ) |
done = 1; |
} |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
if( !done && ssl->transform_in != NULL ) |
{ |
if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", |
ssl->in_msg, ssl->in_msglen ); |
if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
} |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
if( ssl->transform_in != NULL && |
ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) |
{ |
if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_ZLIB_SUPPORT */ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
mbedtls_ssl_dtls_replay_update( ssl ); |
} |
#endif |
return( 0 ); |
} |
static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ); |
/* |
* Read a record. |
* |
* Silently ignore non-fatal alert (and for DTLS, invalid records as well, |
* RFC 6347 4.1.2.7) and continue reading until a valid record is found. |
* |
*/ |
/* Helper functions for mbedtls_ssl_read_record(). */ |
static int ssl_consume_current_message( mbedtls_ssl_context *ssl ); |
static int ssl_get_next_record( mbedtls_ssl_context *ssl ); |
static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ); |
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, |
unsigned update_hs_digest ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); |
if( ssl->keep_current_message == 0 ) |
{ |
do { |
ret = ssl_consume_current_message( ssl ); |
if( ret != 0 ) |
return( ret ); |
if( ssl_record_is_in_progress( ssl ) == 0 ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
int have_buffered = 0; |
/* We only check for buffered messages if the |
* current datagram is fully consumed. */ |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl_next_record_is_in_datagram( ssl ) == 0 ) |
{ |
if( ssl_load_buffered_message( ssl ) == 0 ) |
have_buffered = 1; |
} |
if( have_buffered == 0 ) |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
{ |
ret = ssl_get_next_record( ssl ); |
if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) |
continue; |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret ); |
return( ret ); |
} |
} |
} |
ret = mbedtls_ssl_handle_message_type( ssl ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) |
{ |
/* Buffer future message */ |
ret = ssl_buffer_message( ssl ); |
if( ret != 0 ) |
return( ret ); |
ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
} while( MBEDTLS_ERR_SSL_NON_FATAL == ret || |
MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret ); |
if( 0 != ret ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); |
return( ret ); |
} |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
update_hs_digest == 1 ) |
{ |
mbedtls_ssl_update_handshake_status( ssl ); |
} |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) ); |
ssl->keep_current_message = 0; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ) |
{ |
if( ssl->in_left > ssl->next_record_offset ) |
return( 1 ); |
return( 0 ); |
} |
static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
mbedtls_ssl_hs_buffer * hs_buf; |
int ret = 0; |
if( hs == NULL ) |
return( -1 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); |
if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || |
ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) |
{ |
/* Check if we have seen a ChangeCipherSpec before. |
* If yes, synthesize a CCS record. */ |
if( !hs->buffering.seen_ccs ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) ); |
ret = -1; |
goto exit; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) ); |
ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; |
ssl->in_msglen = 1; |
ssl->in_msg[0] = 1; |
/* As long as they are equal, the exact value doesn't matter. */ |
ssl->in_left = 0; |
ssl->next_record_offset = 0; |
hs->buffering.seen_ccs = 0; |
goto exit; |
} |
#if defined(MBEDTLS_DEBUG_C) |
/* Debug only */ |
{ |
unsigned offset; |
for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) |
{ |
hs_buf = &hs->buffering.hs[offset]; |
if( hs_buf->is_valid == 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.", |
hs->in_msg_seq + offset, |
hs_buf->is_complete ? "fully" : "partially" ) ); |
} |
} |
} |
#endif /* MBEDTLS_DEBUG_C */ |
/* Check if we have buffered and/or fully reassembled the |
* next handshake message. */ |
hs_buf = &hs->buffering.hs[0]; |
if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) ) |
{ |
/* Synthesize a record containing the buffered HS message. */ |
size_t msg_len = ( hs_buf->data[1] << 16 ) | |
( hs_buf->data[2] << 8 ) | |
hs_buf->data[3]; |
/* Double-check that we haven't accidentally buffered |
* a message that doesn't fit into the input buffer. */ |
if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)", |
hs_buf->data, msg_len + 12 ); |
ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->in_hslen = msg_len + 12; |
ssl->in_msglen = msg_len + 12; |
memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen ); |
ret = 0; |
goto exit; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered", |
hs->in_msg_seq ) ); |
} |
ret = -1; |
exit: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) ); |
return( ret ); |
} |
static int ssl_buffer_make_space( mbedtls_ssl_context *ssl, |
size_t desired ) |
{ |
int offset; |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available", |
(unsigned) desired ) ); |
/* Get rid of future records epoch first, if such exist. */ |
ssl_free_buffered_record( ssl ); |
/* Check if we have enough space available now. */ |
if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - |
hs->buffering.total_bytes_buffered ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) ); |
return( 0 ); |
} |
/* We don't have enough space to buffer the next expected handshake |
* message. Remove buffers used for future messages to gain space, |
* starting with the most distant one. */ |
for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; |
offset >= 0; offset-- ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message", |
offset ) ); |
ssl_buffering_free_slot( ssl, (uint8_t) offset ); |
/* Check if we have enough space available now. */ |
if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - |
hs->buffering.total_bytes_buffered ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) ); |
return( 0 ); |
} |
} |
return( -1 ); |
} |
static int ssl_buffer_message( mbedtls_ssl_context *ssl ) |
{ |
int ret = 0; |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
if( hs == NULL ) |
return( 0 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) ); |
switch( ssl->in_msgtype ) |
{ |
case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) ); |
hs->buffering.seen_ccs = 1; |
break; |
case MBEDTLS_SSL_MSG_HANDSHAKE: |
{ |
unsigned recv_msg_seq_offset; |
unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; |
mbedtls_ssl_hs_buffer *hs_buf; |
size_t msg_len = ssl->in_hslen - 12; |
/* We should never receive an old handshake |
* message - double-check nonetheless. */ |
if( recv_msg_seq < ssl->handshake->in_msg_seq ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; |
if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS ) |
{ |
/* Silently ignore -- message too far in the future */ |
MBEDTLS_SSL_DEBUG_MSG( 2, |
( "Ignore future HS message with sequence number %u, " |
"buffering window %u - %u", |
recv_msg_seq, ssl->handshake->in_msg_seq, |
ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) ); |
goto exit; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ", |
recv_msg_seq, recv_msg_seq_offset ) ); |
hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ]; |
/* Check if the buffering for this seq nr has already commenced. */ |
if( !hs_buf->is_valid ) |
{ |
size_t reassembly_buf_sz; |
hs_buf->is_fragmented = |
( ssl_hs_is_proper_fragment( ssl ) == 1 ); |
/* We copy the message back into the input buffer |
* after reassembly, so check that it's not too large. |
* This is an implementation-specific limitation |
* and not one from the standard, hence it is not |
* checked in ssl_check_hs_header(). */ |
if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) |
{ |
/* Ignore message */ |
goto exit; |
} |
/* Check if we have enough space to buffer the message. */ |
if( hs->buffering.total_bytes_buffered > |
MBEDTLS_SSL_DTLS_MAX_BUFFERING ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len, |
hs_buf->is_fragmented ); |
if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - |
hs->buffering.total_bytes_buffered ) ) |
{ |
if( recv_msg_seq_offset > 0 ) |
{ |
/* If we can't buffer a future message because |
* of space limitations -- ignore. */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", |
(unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, |
(unsigned) hs->buffering.total_bytes_buffered ) ); |
goto exit; |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n", |
(unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, |
(unsigned) hs->buffering.total_bytes_buffered ) ); |
} |
if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n", |
(unsigned) msg_len, |
(unsigned) reassembly_buf_sz, |
MBEDTLS_SSL_DTLS_MAX_BUFFERING, |
(unsigned) hs->buffering.total_bytes_buffered ) ); |
ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; |
goto exit; |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", |
msg_len ) ); |
hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz ); |
if( hs_buf->data == NULL ) |
{ |
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; |
goto exit; |
} |
hs_buf->data_len = reassembly_buf_sz; |
/* Prepare final header: copy msg_type, length and message_seq, |
* then add standardised fragment_offset and fragment_length */ |
memcpy( hs_buf->data, ssl->in_msg, 6 ); |
memset( hs_buf->data + 6, 0, 3 ); |
memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ); |
hs_buf->is_valid = 1; |
hs->buffering.total_bytes_buffered += reassembly_buf_sz; |
} |
else |
{ |
/* Make sure msg_type and length are consistent */ |
if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) ); |
/* Ignore */ |
goto exit; |
} |
} |
if( !hs_buf->is_complete ) |
{ |
size_t frag_len, frag_off; |
unsigned char * const msg = hs_buf->data + 12; |
/* |
* Check and copy current fragment |
*/ |
/* Validation of header fields already done in |
* mbedtls_ssl_prepare_handshake_record(). */ |
frag_off = ssl_get_hs_frag_off( ssl ); |
frag_len = ssl_get_hs_frag_len( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d", |
frag_off, frag_len ) ); |
memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); |
if( hs_buf->is_fragmented ) |
{ |
unsigned char * const bitmask = msg + msg_len; |
ssl_bitmask_set( bitmask, frag_off, frag_len ); |
hs_buf->is_complete = ( ssl_bitmask_check( bitmask, |
msg_len ) == 0 ); |
} |
else |
{ |
hs_buf->is_complete = 1; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete", |
hs_buf->is_complete ? "" : "not yet " ) ); |
} |
break; |
} |
default: |
/* We don't buffer other types of messages. */ |
break; |
} |
exit: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) |
{ |
/* |
* Consume last content-layer message and potentially |
* update in_msglen which keeps track of the contents' |
* consumption state. |
* |
* (1) Handshake messages: |
* Remove last handshake message, move content |
* and adapt in_msglen. |
* |
* (2) Alert messages: |
* Consume whole record content, in_msglen = 0. |
* |
* (3) Change cipher spec: |
* Consume whole record content, in_msglen = 0. |
* |
* (4) Application data: |
* Don't do anything - the record layer provides |
* the application data as a stream transport |
* and consumes through mbedtls_ssl_read only. |
* |
*/ |
/* Case (1): Handshake messages */ |
if( ssl->in_hslen != 0 ) |
{ |
/* Hard assertion to be sure that no application data |
* is in flight, as corrupting ssl->in_msglen during |
* ssl->in_offt != NULL is fatal. */ |
if( ssl->in_offt != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
/* |
* Get next Handshake message in the current record |
*/ |
/* Notes: |
* (1) in_hslen is not necessarily the size of the |
* current handshake content: If DTLS handshake |
* fragmentation is used, that's the fragment |
* size instead. Using the total handshake message |
* size here is faulty and should be changed at |
* some point. |
* (2) While it doesn't seem to cause problems, one |
* has to be very careful not to assume that in_hslen |
* is always <= in_msglen in a sensible communication. |
* Again, it's wrong for DTLS handshake fragmentation. |
* The following check is therefore mandatory, and |
* should not be treated as a silently corrected assertion. |
* Additionally, ssl->in_hslen might be arbitrarily out of |
* bounds after handling a DTLS message with an unexpected |
* sequence number, see mbedtls_ssl_prepare_handshake_record. |
*/ |
if( ssl->in_hslen < ssl->in_msglen ) |
{ |
ssl->in_msglen -= ssl->in_hslen; |
memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, |
ssl->in_msglen ); |
MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", |
ssl->in_msg, ssl->in_msglen ); |
} |
else |
{ |
ssl->in_msglen = 0; |
} |
ssl->in_hslen = 0; |
} |
/* Case (4): Application data */ |
else if( ssl->in_offt != NULL ) |
{ |
return( 0 ); |
} |
/* Everything else (CCS & Alerts) */ |
else |
{ |
ssl->in_msglen = 0; |
} |
return( 0 ); |
} |
static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ) |
{ |
if( ssl->in_msglen > 0 ) |
return( 1 ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
if( hs == NULL ) |
return; |
if( hs->buffering.future_record.data != NULL ) |
{ |
hs->buffering.total_bytes_buffered -= |
hs->buffering.future_record.len; |
mbedtls_free( hs->buffering.future_record.data ); |
hs->buffering.future_record.data = NULL; |
} |
} |
static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
unsigned char * rec; |
size_t rec_len; |
unsigned rec_epoch; |
if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
return( 0 ); |
if( hs == NULL ) |
return( 0 ); |
rec = hs->buffering.future_record.data; |
rec_len = hs->buffering.future_record.len; |
rec_epoch = hs->buffering.future_record.epoch; |
if( rec == NULL ) |
return( 0 ); |
/* Only consider loading future records if the |
* input buffer is empty. */ |
if( ssl_next_record_is_in_datagram( ssl ) == 1 ) |
return( 0 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) ); |
if( rec_epoch != ssl->in_epoch ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) ); |
goto exit; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) ); |
/* Double-check that the record is not too large */ |
if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN - |
(size_t)( ssl->in_hdr - ssl->in_buf ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
memcpy( ssl->in_hdr, rec, rec_len ); |
ssl->in_left = rec_len; |
ssl->next_record_offset = 0; |
ssl_free_buffered_record( ssl ); |
exit: |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) ); |
return( 0 ); |
} |
static int ssl_buffer_future_record( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
size_t const rec_hdr_len = 13; |
size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen; |
/* Don't buffer future records outside handshakes. */ |
if( hs == NULL ) |
return( 0 ); |
/* Only buffer handshake records (we are only interested |
* in Finished messages). */ |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
return( 0 ); |
/* Don't buffer more than one future epoch record. */ |
if( hs->buffering.future_record.data != NULL ) |
return( 0 ); |
/* Don't buffer record if there's not enough buffering space remaining. */ |
if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - |
hs->buffering.total_bytes_buffered ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", |
(unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING, |
(unsigned) hs->buffering.total_bytes_buffered ) ); |
return( 0 ); |
} |
/* Buffer record */ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u", |
ssl->in_epoch + 1 ) ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr, |
rec_hdr_len + ssl->in_msglen ); |
/* ssl_parse_record_header() only considers records |
* of the next epoch as candidates for buffering. */ |
hs->buffering.future_record.epoch = ssl->in_epoch + 1; |
hs->buffering.future_record.len = total_buf_sz; |
hs->buffering.future_record.data = |
mbedtls_calloc( 1, hs->buffering.future_record.len ); |
if( hs->buffering.future_record.data == NULL ) |
{ |
/* If we run out of RAM trying to buffer a |
* record from the next epoch, just ignore. */ |
return( 0 ); |
} |
memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz ); |
hs->buffering.total_bytes_buffered += total_buf_sz; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
static int ssl_get_next_record( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* We might have buffered a future record; if so, |
* and if the epoch matches now, load it. |
* On success, this call will set ssl->in_left to |
* the length of the buffered record, so that |
* the calls to ssl_fetch_input() below will |
* essentially be no-ops. */ |
ret = ssl_load_buffered_record( ssl ); |
if( ret != 0 ) |
return( ret ); |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); |
return( ret ); |
} |
if( ( ret = ssl_parse_record_header( ssl ) ) != 0 ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) |
{ |
if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) |
{ |
ret = ssl_buffer_future_record( ssl ); |
if( ret != 0 ) |
return( ret ); |
/* Fall through to handling of unexpected records */ |
ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; |
} |
if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) |
{ |
/* Skip unexpected record (but not whole datagram) */ |
ssl->next_record_offset = ssl->in_msglen |
+ mbedtls_ssl_hdr_len( ssl ); |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " |
"(header)" ) ); |
} |
else |
{ |
/* Skip invalid record and the rest of the datagram */ |
ssl->next_record_offset = 0; |
ssl->in_left = 0; |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record " |
"(header)" ) ); |
} |
/* Get next record */ |
return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); |
} |
#endif |
return( ret ); |
} |
/* |
* Read and optionally decrypt the message contents |
*/ |
if( ( ret = mbedtls_ssl_fetch_input( ssl, |
mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); |
return( ret ); |
} |
/* Done reading this record, get ready for the next one */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl ); |
if( ssl->next_record_offset < ssl->in_left ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); |
} |
} |
else |
#endif |
ssl->in_left = 0; |
if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
/* Silently discard invalid records */ |
if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD || |
ret == MBEDTLS_ERR_SSL_INVALID_MAC ) |
{ |
/* Except when waiting for Finished as a bad mac here |
* probably means something went wrong in the handshake |
* (eg wrong psk used, mitm downgrade attempt, etc.) */ |
if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || |
ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) |
{ |
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) |
if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) |
{ |
mbedtls_ssl_send_alert_message( ssl, |
MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); |
} |
#endif |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) |
if( ssl->conf->badmac_limit != 0 && |
++ssl->badmac_seen >= ssl->conf->badmac_limit ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); |
return( MBEDTLS_ERR_SSL_INVALID_MAC ); |
} |
#endif |
/* As above, invalid records cause |
* dismissal of the whole datagram. */ |
ssl->next_record_offset = 0; |
ssl->in_left = 0; |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); |
return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); |
} |
return( ret ); |
} |
else |
#endif |
{ |
/* Error out (and send alert) on invalid records */ |
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) |
if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) |
{ |
mbedtls_ssl_send_alert_message( ssl, |
MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); |
} |
#endif |
return( ret ); |
} |
} |
return( 0 ); |
} |
int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
/* |
* Handle particular types of records |
*/ |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) |
{ |
return( ret ); |
} |
} |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) |
{ |
if( ssl->in_msglen != 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d", |
ssl->in_msglen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
if( ssl->in_msg[0] != 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x", |
ssl->in_msg[0] ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && |
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) |
{ |
if( ssl->handshake == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) ); |
return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); |
} |
#endif |
} |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) |
{ |
if( ssl->in_msglen != 2 ) |
{ |
/* Note: Standard allows for more than one 2 byte alert |
to be packed in a single message, but Mbed TLS doesn't |
currently support this. */ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d", |
ssl->in_msglen ) ); |
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]", |
ssl->in_msg[0], ssl->in_msg[1] ) ); |
/* |
* Ignore non-fatal alerts, except close_notify and no_renegotiation |
*/ |
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", |
ssl->in_msg[1] ) ); |
return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE ); |
} |
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && |
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); |
return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) |
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && |
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) ); |
/* Will be handled when trying to parse ServerHello */ |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && |
ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && |
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); |
/* Will be handled in mbedtls_ssl_parse_certificate() */ |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ |
/* Silently ignore: fetch new message */ |
return MBEDTLS_ERR_SSL_NON_FATAL; |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake != NULL && |
ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) |
{ |
ssl_handshake_wrapup_free_hs_transform( ssl ); |
} |
#endif |
return( 0 ); |
} |
int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
if( ( ret = mbedtls_ssl_send_alert_message( ssl, |
MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, |
unsigned char level, |
unsigned char message ) |
{ |
int ret; |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message )); |
ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; |
ssl->out_msglen = 2; |
ssl->out_msg[0] = level; |
ssl->out_msg[1] = message; |
if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); |
return( 0 ); |
} |
/* |
* Handshake functions |
*/ |
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ |
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
/* No certificate support -> dummy functions */ |
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) |
{ |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
#else |
/* Some certificate support -> implement write and parse */ |
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
size_t i, n; |
const mbedtls_x509_crt *crt; |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
{ |
if( ssl->client_auth == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
/* |
* If using SSLv3 and got no cert, send an Alert message |
* (otherwise an empty Certificate message will be sent). |
*/ |
if( mbedtls_ssl_own_cert( ssl ) == NULL && |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
ssl->out_msglen = 2; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; |
ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING; |
ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) ); |
goto write_msg; |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
{ |
if( mbedtls_ssl_own_cert( ssl ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) ); |
return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED ); |
} |
} |
#endif |
MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) ); |
/* |
* 0 . 0 handshake type |
* 1 . 3 handshake length |
* 4 . 6 length of all certs |
* 7 . 9 length of cert. 1 |
* 10 . n-1 peer certificate |
* n . n+2 length of cert. 2 |
* n+3 . ... upper level cert, etc. |
*/ |
i = 7; |
crt = mbedtls_ssl_own_cert( ssl ); |
while( crt != NULL ) |
{ |
n = crt->raw.len; |
if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", |
i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) ); |
return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE ); |
} |
ssl->out_msg[i ] = (unsigned char)( n >> 16 ); |
ssl->out_msg[i + 1] = (unsigned char)( n >> 8 ); |
ssl->out_msg[i + 2] = (unsigned char)( n ); |
i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n ); |
i += n; crt = crt->next; |
} |
ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 ); |
ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 ); |
ssl->out_msg[6] = (unsigned char)( ( i - 7 ) ); |
ssl->out_msglen = i; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE; |
#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) |
write_msg: |
#endif |
ssl->state++; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) ); |
return( ret ); |
} |
/* |
* Once the certificate message is read, parse it into a cert chain and |
* perform basic checks, but leave actual verification to the caller |
*/ |
static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
size_t i, n; |
uint8_t alert; |
#if defined(MBEDTLS_SSL_SRV_C) |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
/* |
* Check if the client sent an empty certificate |
*/ |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
if( ssl->in_msglen == 2 && |
ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT && |
ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && |
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); |
/* The client was asked for a certificate but didn't send |
one. The client should know what's going on, so we |
don't send an alert. */ |
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; |
return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) && |
ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && |
ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && |
memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); |
/* The client was asked for a certificate but didn't send |
one. The client should know what's going on, so we |
don't send an alert. */ |
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; |
return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
#endif /* MBEDTLS_SSL_SRV_C */ |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE || |
ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
i = mbedtls_ssl_hs_hdr_len( ssl ); |
/* |
* Same message structure as in mbedtls_ssl_write_certificate() |
*/ |
n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2]; |
if( ssl->in_msg[i] != 0 || |
ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
/* In case we tried to reuse a session but it failed */ |
if( ssl->session_negotiate->peer_cert != NULL ) |
{ |
mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert ); |
mbedtls_free( ssl->session_negotiate->peer_cert ); |
} |
if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1, |
sizeof( mbedtls_x509_crt ) ) ) == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", |
sizeof( mbedtls_x509_crt ) ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert ); |
i += 3; |
while( i < ssl->in_hslen ) |
{ |
if ( i + 3 > ssl->in_hslen ) { |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
if( ssl->in_msg[i] != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
n = ( (unsigned int) ssl->in_msg[i + 1] << 8 ) |
| (unsigned int) ssl->in_msg[i + 2]; |
i += 3; |
if( n < 128 || i + n > ssl->in_hslen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, |
ssl->in_msg + i, n ); |
switch( ret ) |
{ |
case 0: /*ok*/ |
case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: |
/* Ignore certificate with an unknown algorithm: maybe a |
prior certificate was already trusted. */ |
break; |
case MBEDTLS_ERR_X509_ALLOC_FAILED: |
alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; |
goto crt_parse_der_failed; |
case MBEDTLS_ERR_X509_UNKNOWN_VERSION: |
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; |
goto crt_parse_der_failed; |
default: |
alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; |
crt_parse_der_failed: |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert ); |
MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); |
return( ret ); |
} |
i += n; |
} |
MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); |
/* |
* On client, make sure the server cert doesn't change during renego to |
* avoid "triple handshake" attack: https://secure-resumption.com/ |
*/ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && |
ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
if( ssl->session->peer_cert == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
if( ssl->session->peer_cert->raw.len != |
ssl->session_negotiate->peer_cert->raw.len || |
memcmp( ssl->session->peer_cert->raw.p, |
ssl->session_negotiate->peer_cert->raw.p, |
ssl->session->peer_cert->raw.len ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); |
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); |
} |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ |
return( 0 ); |
} |
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
const mbedtls_ssl_ciphersuite_t * const ciphersuite_info = |
ssl->transform_negotiate->ciphersuite_info; |
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET |
? ssl->handshake->sni_authmode |
: ssl->conf->authmode; |
#else |
const int authmode = ssl->conf->authmode; |
#endif |
void *rs_ctx = NULL; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); |
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
authmode == MBEDTLS_SSL_VERIFY_NONE ) |
{ |
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); |
ssl->state++; |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled && |
ssl->handshake->ecrs_state == ssl_ecrs_crt_verify ) |
{ |
goto crt_verify; |
} |
#endif |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
/* mbedtls_ssl_read_record may have sent an alert already. We |
let it decide whether to alert. */ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ( ret = ssl_parse_certificate_chain( ssl ) ) != 0 ) |
{ |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ret == MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE && |
authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) |
{ |
ret = 0; |
} |
#endif |
ssl->state++; |
return( ret ); |
} |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ssl->handshake->ecrs_enabled) |
ssl->handshake->ecrs_state = ssl_ecrs_crt_verify; |
crt_verify: |
if( ssl->handshake->ecrs_enabled) |
rs_ctx = &ssl->handshake->ecrs_ctx; |
#endif |
if( authmode != MBEDTLS_SSL_VERIFY_NONE ) |
{ |
mbedtls_x509_crt *ca_chain; |
mbedtls_x509_crl *ca_crl; |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
if( ssl->handshake->sni_ca_chain != NULL ) |
{ |
ca_chain = ssl->handshake->sni_ca_chain; |
ca_crl = ssl->handshake->sni_ca_crl; |
} |
else |
#endif |
{ |
ca_chain = ssl->conf->ca_chain; |
ca_crl = ssl->conf->ca_crl; |
} |
/* |
* Main check: verify certificate |
*/ |
ret = mbedtls_x509_crt_verify_restartable( |
ssl->session_negotiate->peer_cert, |
ca_chain, ca_crl, |
ssl->conf->cert_profile, |
ssl->hostname, |
&ssl->session_negotiate->verify_result, |
ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx ); |
if( ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); |
} |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ); |
#endif |
/* |
* Secondary checks: always done, but change 'ret' only if it was 0 |
*/ |
#if defined(MBEDTLS_ECP_C) |
{ |
const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk; |
/* If certificate uses an EC key, make sure the curve is OK */ |
if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && |
mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) |
{ |
ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); |
if( ret == 0 ) |
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; |
} |
} |
#endif /* MBEDTLS_ECP_C */ |
if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert, |
ciphersuite_info, |
! ssl->conf->endpoint, |
&ssl->session_negotiate->verify_result ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); |
if( ret == 0 ) |
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; |
} |
/* mbedtls_x509_crt_verify_with_profile is supposed to report a |
* verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED, |
* with details encoded in the verification flags. All other kinds |
* of error codes, including those from the user provided f_vrfy |
* functions, are treated as fatal and lead to a failure of |
* ssl_parse_certificate even if verification was optional. */ |
if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && |
( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || |
ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) |
{ |
ret = 0; |
} |
if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); |
ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; |
} |
if( ret != 0 ) |
{ |
uint8_t alert; |
/* The certificate may have been rejected for several reasons. |
Pick one and send the corresponding alert. Which alert to send |
may be a subject of debate in some cases. */ |
if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER ) |
alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH ) |
alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE ) |
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE ) |
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE ) |
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK ) |
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY ) |
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED ) |
alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED ) |
alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; |
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) |
alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; |
else |
alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
alert ); |
} |
#if defined(MBEDTLS_DEBUG_C) |
if( ssl->session_negotiate->verify_result != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", |
ssl->session_negotiate->verify_result ) ); |
} |
else |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); |
} |
#endif /* MBEDTLS_DEBUG_C */ |
} |
ssl->state++; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); |
return( ret ); |
} |
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED |
!MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED |
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED |
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED |
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED |
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED |
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); |
ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; |
ssl->out_msglen = 1; |
ssl->out_msg[0] = 1; |
ssl->state++; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); |
return( 0 ); |
} |
int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
/* CCS records are only accepted if they have length 1 and content '1', |
* so we don't need to check this here. */ |
/* |
* Switch to our negotiated transform and session parameters for inbound |
* data. |
*/ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); |
ssl->transform_in = ssl->transform_negotiate; |
ssl->session_in = ssl->session_negotiate; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
ssl_dtls_replay_reset( ssl ); |
#endif |
/* Increment epoch */ |
if( ++ssl->in_epoch == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); |
/* This is highly unlikely to happen for legitimate reasons, so |
treat it as an attack and don't send an alert. */ |
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
memset( ssl->in_ctr, 0, 8 ); |
ssl_update_in_pointers( ssl, ssl->transform_negotiate ); |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_activate != NULL ) |
{ |
if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
} |
#endif |
ssl->state++; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); |
return( 0 ); |
} |
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, |
const mbedtls_ssl_ciphersuite_t *ciphersuite_info ) |
{ |
((void) ciphersuite_info); |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) |
ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; |
else |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA512_C) |
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) |
ssl->handshake->update_checksum = ssl_update_checksum_sha384; |
else |
#endif |
#if defined(MBEDTLS_SHA256_C) |
if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 ) |
ssl->handshake->update_checksum = ssl_update_checksum_sha256; |
else |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return; |
} |
} |
void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); |
mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 ); |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
} |
static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); |
mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); |
mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); |
} |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); |
} |
#endif |
#if defined(MBEDTLS_SHA512_C) |
static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); |
} |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
static void ssl_calc_finished_ssl( |
mbedtls_ssl_context *ssl, unsigned char *buf, int from ) |
{ |
const char *sender; |
mbedtls_md5_context md5; |
mbedtls_sha1_context sha1; |
unsigned char padbuf[48]; |
unsigned char md5sum[16]; |
unsigned char sha1sum[20]; |
mbedtls_ssl_session *session = ssl->session_negotiate; |
if( !session ) |
session = ssl->session; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); |
mbedtls_md5_init( &md5 ); |
mbedtls_sha1_init( &sha1 ); |
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); |
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); |
/* |
* SSLv3: |
* hash = |
* MD5( master + pad2 + |
* MD5( handshake + sender + master + pad1 ) ) |
* + SHA1( master + pad2 + |
* SHA1( handshake + sender + master + pad1 ) ) |
*/ |
#if !defined(MBEDTLS_MD5_ALT) |
MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) |
md5.state, sizeof( md5.state ) ); |
#endif |
#if !defined(MBEDTLS_SHA1_ALT) |
MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) |
sha1.state, sizeof( sha1.state ) ); |
#endif |
sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" |
: "SRVR"; |
memset( padbuf, 0x36, 48 ); |
mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); |
mbedtls_md5_update_ret( &md5, session->master, 48 ); |
mbedtls_md5_update_ret( &md5, padbuf, 48 ); |
mbedtls_md5_finish_ret( &md5, md5sum ); |
mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); |
mbedtls_sha1_update_ret( &sha1, session->master, 48 ); |
mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); |
mbedtls_sha1_finish_ret( &sha1, sha1sum ); |
memset( padbuf, 0x5C, 48 ); |
mbedtls_md5_starts_ret( &md5 ); |
mbedtls_md5_update_ret( &md5, session->master, 48 ); |
mbedtls_md5_update_ret( &md5, padbuf, 48 ); |
mbedtls_md5_update_ret( &md5, md5sum, 16 ); |
mbedtls_md5_finish_ret( &md5, buf ); |
mbedtls_sha1_starts_ret( &sha1 ); |
mbedtls_sha1_update_ret( &sha1, session->master, 48 ); |
mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); |
mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); |
mbedtls_sha1_finish_ret( &sha1, buf + 16 ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); |
mbedtls_md5_free( &md5 ); |
mbedtls_sha1_free( &sha1 ); |
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); |
mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) ); |
mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) |
static void ssl_calc_finished_tls( |
mbedtls_ssl_context *ssl, unsigned char *buf, int from ) |
{ |
int len = 12; |
const char *sender; |
mbedtls_md5_context md5; |
mbedtls_sha1_context sha1; |
unsigned char padbuf[36]; |
mbedtls_ssl_session *session = ssl->session_negotiate; |
if( !session ) |
session = ssl->session; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); |
mbedtls_md5_init( &md5 ); |
mbedtls_sha1_init( &sha1 ); |
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); |
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); |
/* |
* TLSv1: |
* hash = PRF( master, finished_label, |
* MD5( handshake ) + SHA1( handshake ) )[0..11] |
*/ |
#if !defined(MBEDTLS_MD5_ALT) |
MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) |
md5.state, sizeof( md5.state ) ); |
#endif |
#if !defined(MBEDTLS_SHA1_ALT) |
MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) |
sha1.state, sizeof( sha1.state ) ); |
#endif |
sender = ( from == MBEDTLS_SSL_IS_CLIENT ) |
? "client finished" |
: "server finished"; |
mbedtls_md5_finish_ret( &md5, padbuf ); |
mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); |
ssl->handshake->tls_prf( session->master, 48, sender, |
padbuf, 36, buf, len ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); |
mbedtls_md5_free( &md5 ); |
mbedtls_sha1_free( &sha1 ); |
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
static void ssl_calc_finished_tls_sha256( |
mbedtls_ssl_context *ssl, unsigned char *buf, int from ) |
{ |
int len = 12; |
const char *sender; |
mbedtls_sha256_context sha256; |
unsigned char padbuf[32]; |
mbedtls_ssl_session *session = ssl->session_negotiate; |
if( !session ) |
session = ssl->session; |
mbedtls_sha256_init( &sha256 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); |
mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); |
/* |
* TLSv1.2: |
* hash = PRF( master, finished_label, |
* Hash( handshake ) )[0.11] |
*/ |
#if !defined(MBEDTLS_SHA256_ALT) |
MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) |
sha256.state, sizeof( sha256.state ) ); |
#endif |
sender = ( from == MBEDTLS_SSL_IS_CLIENT ) |
? "client finished" |
: "server finished"; |
mbedtls_sha256_finish_ret( &sha256, padbuf ); |
ssl->handshake->tls_prf( session->master, 48, sender, |
padbuf, 32, buf, len ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); |
mbedtls_sha256_free( &sha256 ); |
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); |
} |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
static void ssl_calc_finished_tls_sha384( |
mbedtls_ssl_context *ssl, unsigned char *buf, int from ) |
{ |
int len = 12; |
const char *sender; |
mbedtls_sha512_context sha512; |
unsigned char padbuf[48]; |
mbedtls_ssl_session *session = ssl->session_negotiate; |
if( !session ) |
session = ssl->session; |
mbedtls_sha512_init( &sha512 ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); |
mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); |
/* |
* TLSv1.2: |
* hash = PRF( master, finished_label, |
* Hash( handshake ) )[0.11] |
*/ |
#if !defined(MBEDTLS_SHA512_ALT) |
MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) |
sha512.state, sizeof( sha512.state ) ); |
#endif |
sender = ( from == MBEDTLS_SSL_IS_CLIENT ) |
? "client finished" |
: "server finished"; |
mbedtls_sha512_finish_ret( &sha512, padbuf ); |
ssl->handshake->tls_prf( session->master, 48, sender, |
padbuf, 48, buf, len ); |
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); |
mbedtls_sha512_free( &sha512 ); |
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); |
} |
#endif /* MBEDTLS_SHA512_C */ |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) ); |
/* |
* Free our handshake params |
*/ |
mbedtls_ssl_handshake_free( ssl ); |
mbedtls_free( ssl->handshake ); |
ssl->handshake = NULL; |
/* |
* Free the previous transform and swith in the current one |
*/ |
if( ssl->transform ) |
{ |
mbedtls_ssl_transform_free( ssl->transform ); |
mbedtls_free( ssl->transform ); |
} |
ssl->transform = ssl->transform_negotiate; |
ssl->transform_negotiate = NULL; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) ); |
} |
void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) |
{ |
int resume = ssl->handshake->resume; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE; |
ssl->renego_records_seen = 0; |
} |
#endif |
/* |
* Free the previous session and switch in the current one |
*/ |
if( ssl->session ) |
{ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
/* RFC 7366 3.1: keep the EtM state */ |
ssl->session_negotiate->encrypt_then_mac = |
ssl->session->encrypt_then_mac; |
#endif |
mbedtls_ssl_session_free( ssl->session ); |
mbedtls_free( ssl->session ); |
} |
ssl->session = ssl->session_negotiate; |
ssl->session_negotiate = NULL; |
/* |
* Add cache entry |
*/ |
if( ssl->conf->f_set_cache != NULL && |
ssl->session->id_len != 0 && |
resume == 0 ) |
{ |
if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->handshake->flight != NULL ) |
{ |
/* Cancel handshake timer */ |
ssl_set_timer( ssl, 0 ); |
/* Keep last flight around in case we need to resend it: |
* we need the handshake and transform structures for that */ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) ); |
} |
else |
#endif |
ssl_handshake_wrapup_free_hs_transform( ssl ); |
ssl->state++; |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); |
} |
int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) |
{ |
int ret, hash_len; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); |
ssl_update_out_pointers( ssl, ssl->transform_negotiate ); |
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); |
/* |
* RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites |
* may define some other value. Currently (early 2016), no defined |
* ciphersuite does this (and this is unlikely to change as activity has |
* moved to TLS 1.3 now) so we can keep the hardcoded 12 here. |
*/ |
hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl->verify_data_len = hash_len; |
memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); |
#endif |
ssl->out_msglen = 4 + hash_len; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; |
/* |
* In case of session resuming, invert the client and server |
* ChangeCipherSpec messages order. |
*/ |
if( ssl->handshake->resume != 0 ) |
{ |
#if defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; |
#endif |
} |
else |
ssl->state++; |
/* |
* Switch to our negotiated transform and session parameters for outbound |
* data. |
*/ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
unsigned char i; |
/* Remember current epoch settings for resending */ |
ssl->handshake->alt_transform_out = ssl->transform_out; |
memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 ); |
/* Set sequence_number to zero */ |
memset( ssl->cur_out_ctr + 2, 0, 6 ); |
/* Increment epoch */ |
for( i = 2; i > 0; i-- ) |
if( ++ssl->cur_out_ctr[i - 1] != 0 ) |
break; |
/* The loop goes to its end iff the counter is wrapping */ |
if( i == 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); |
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
memset( ssl->cur_out_ctr, 0, 8 ); |
ssl->transform_out = ssl->transform_negotiate; |
ssl->session_out = ssl->session_negotiate; |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_activate != NULL ) |
{ |
if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
} |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
mbedtls_ssl_send_flight_completed( ssl ); |
#endif |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); |
return( ret ); |
} |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) ); |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
#define SSL_MAX_HASH_LEN 36 |
#else |
#define SSL_MAX_HASH_LEN 12 |
#endif |
int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
unsigned int hash_len; |
unsigned char buf[SSL_MAX_HASH_LEN]; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); |
ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 ); |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
/* There is currently no ciphersuite using another length with TLS 1.2 */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
hash_len = 36; |
else |
#endif |
hash_len = 12; |
if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED || |
ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); |
} |
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), |
buf, hash_len ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); |
return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl->verify_data_len = hash_len; |
memcpy( ssl->peer_verify_data, buf, hash_len ); |
#endif |
if( ssl->handshake->resume != 0 ) |
{ |
#if defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; |
#endif |
} |
else |
ssl->state++; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
mbedtls_ssl_recv_flight_completed( ssl ); |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) ); |
return( 0 ); |
} |
static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) |
{ |
memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) ); |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
mbedtls_md5_init( &handshake->fin_md5 ); |
mbedtls_sha1_init( &handshake->fin_sha1 ); |
mbedtls_md5_starts_ret( &handshake->fin_md5 ); |
mbedtls_sha1_starts_ret( &handshake->fin_sha1 ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
mbedtls_sha256_init( &handshake->fin_sha256 ); |
mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
mbedtls_sha512_init( &handshake->fin_sha512 ); |
mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 ); |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
handshake->update_checksum = ssl_update_checksum_start; |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); |
#endif |
#if defined(MBEDTLS_DHM_C) |
mbedtls_dhm_init( &handshake->dhm_ctx ); |
#endif |
#if defined(MBEDTLS_ECDH_C) |
mbedtls_ecdh_init( &handshake->ecdh_ctx ); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
mbedtls_ecjpake_init( &handshake->ecjpake_ctx ); |
#if defined(MBEDTLS_SSL_CLI_C) |
handshake->ecjpake_cache = NULL; |
handshake->ecjpake_cache_len = 0; |
#endif |
#endif |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx ); |
#endif |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; |
#endif |
} |
static void ssl_transform_init( mbedtls_ssl_transform *transform ) |
{ |
memset( transform, 0, sizeof(mbedtls_ssl_transform) ); |
mbedtls_cipher_init( &transform->cipher_ctx_enc ); |
mbedtls_cipher_init( &transform->cipher_ctx_dec ); |
mbedtls_md_init( &transform->md_ctx_enc ); |
mbedtls_md_init( &transform->md_ctx_dec ); |
} |
void mbedtls_ssl_session_init( mbedtls_ssl_session *session ) |
{ |
memset( session, 0, sizeof(mbedtls_ssl_session) ); |
} |
static int ssl_handshake_init( mbedtls_ssl_context *ssl ) |
{ |
/* Clear old handshake information if present */ |
if( ssl->transform_negotiate ) |
mbedtls_ssl_transform_free( ssl->transform_negotiate ); |
if( ssl->session_negotiate ) |
mbedtls_ssl_session_free( ssl->session_negotiate ); |
if( ssl->handshake ) |
mbedtls_ssl_handshake_free( ssl ); |
/* |
* Either the pointers are now NULL or cleared properly and can be freed. |
* Now allocate missing structures. |
*/ |
if( ssl->transform_negotiate == NULL ) |
{ |
ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) ); |
} |
if( ssl->session_negotiate == NULL ) |
{ |
ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) ); |
} |
if( ssl->handshake == NULL ) |
{ |
ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) ); |
} |
/* All pointers should exist and can be directly freed without issue */ |
if( ssl->handshake == NULL || |
ssl->transform_negotiate == NULL || |
ssl->session_negotiate == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) ); |
mbedtls_free( ssl->handshake ); |
mbedtls_free( ssl->transform_negotiate ); |
mbedtls_free( ssl->session_negotiate ); |
ssl->handshake = NULL; |
ssl->transform_negotiate = NULL; |
ssl->session_negotiate = NULL; |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
/* Initialize structures */ |
mbedtls_ssl_session_init( ssl->session_negotiate ); |
ssl_transform_init( ssl->transform_negotiate ); |
ssl_handshake_params_init( ssl->handshake ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ssl->handshake->alt_transform_out = ssl->transform_out; |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; |
else |
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; |
ssl_set_timer( ssl, 0 ); |
} |
#endif |
return( 0 ); |
} |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
/* Dummy cookie callbacks for defaults */ |
static int ssl_cookie_write_dummy( void *ctx, |
unsigned char **p, unsigned char *end, |
const unsigned char *cli_id, size_t cli_id_len ) |
{ |
((void) ctx); |
((void) p); |
((void) end); |
((void) cli_id); |
((void) cli_id_len); |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
} |
static int ssl_cookie_check_dummy( void *ctx, |
const unsigned char *cookie, size_t cookie_len, |
const unsigned char *cli_id, size_t cli_id_len ) |
{ |
((void) ctx); |
((void) cookie); |
((void) cookie_len); |
((void) cli_id); |
((void) cli_id_len); |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
} |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ |
/* Once ssl->out_hdr as the address of the beginning of the |
* next outgoing record is set, deduce the other pointers. |
* |
* Note: For TLS, we save the implicit record sequence number |
* (entering MAC computation) in the 8 bytes before ssl->out_hdr, |
* and the caller has to make sure there's space for this. |
*/ |
static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, |
mbedtls_ssl_transform *transform ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ssl->out_ctr = ssl->out_hdr + 3; |
ssl->out_len = ssl->out_hdr + 11; |
ssl->out_iv = ssl->out_hdr + 13; |
} |
else |
#endif |
{ |
ssl->out_ctr = ssl->out_hdr - 8; |
ssl->out_len = ssl->out_hdr + 3; |
ssl->out_iv = ssl->out_hdr + 5; |
} |
/* Adjust out_msg to make space for explicit IV, if used. */ |
if( transform != NULL && |
ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) |
{ |
ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen; |
} |
else |
ssl->out_msg = ssl->out_iv; |
} |
/* Once ssl->in_hdr as the address of the beginning of the |
* next incoming record is set, deduce the other pointers. |
* |
* Note: For TLS, we save the implicit record sequence number |
* (entering MAC computation) in the 8 bytes before ssl->in_hdr, |
* and the caller has to make sure there's space for this. |
*/ |
static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, |
mbedtls_ssl_transform *transform ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ssl->in_ctr = ssl->in_hdr + 3; |
ssl->in_len = ssl->in_hdr + 11; |
ssl->in_iv = ssl->in_hdr + 13; |
} |
else |
#endif |
{ |
ssl->in_ctr = ssl->in_hdr - 8; |
ssl->in_len = ssl->in_hdr + 3; |
ssl->in_iv = ssl->in_hdr + 5; |
} |
/* Offset in_msg from in_iv to allow space for explicit IV, if used. */ |
if( transform != NULL && |
ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) |
{ |
ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen; |
} |
else |
ssl->in_msg = ssl->in_iv; |
} |
/* |
* Initialize an SSL context |
*/ |
void mbedtls_ssl_init( mbedtls_ssl_context *ssl ) |
{ |
memset( ssl, 0, sizeof( mbedtls_ssl_context ) ); |
} |
/* |
* Setup an SSL context |
*/ |
static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) |
{ |
/* Set the incoming and outgoing record pointers. */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
ssl->out_hdr = ssl->out_buf; |
ssl->in_hdr = ssl->in_buf; |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
{ |
ssl->out_hdr = ssl->out_buf + 8; |
ssl->in_hdr = ssl->in_buf + 8; |
} |
/* Derive other internal pointers. */ |
ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); |
ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ ); |
} |
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, |
const mbedtls_ssl_config *conf ) |
{ |
int ret; |
ssl->conf = conf; |
/* |
* Prepare base structures |
*/ |
/* Set to NULL in case of an error condition */ |
ssl->out_buf = NULL; |
ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN ); |
if( ssl->in_buf == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) ); |
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; |
goto error; |
} |
ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN ); |
if( ssl->out_buf == NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) ); |
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; |
goto error; |
} |
ssl_reset_in_out_pointers( ssl ); |
if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) |
goto error; |
return( 0 ); |
error: |
mbedtls_free( ssl->in_buf ); |
mbedtls_free( ssl->out_buf ); |
ssl->conf = NULL; |
ssl->in_buf = NULL; |
ssl->out_buf = NULL; |
ssl->in_hdr = NULL; |
ssl->in_ctr = NULL; |
ssl->in_len = NULL; |
ssl->in_iv = NULL; |
ssl->in_msg = NULL; |
ssl->out_hdr = NULL; |
ssl->out_ctr = NULL; |
ssl->out_len = NULL; |
ssl->out_iv = NULL; |
ssl->out_msg = NULL; |
return( ret ); |
} |
/* |
* Reset an initialized and used SSL context for re-use while retaining |
* all application-set variables, function pointers and data. |
* |
* If partial is non-zero, keep data in the input buffer and client ID. |
* (Use when a DTLS client reconnects from the same port.) |
*/ |
static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) |
{ |
int ret; |
#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \ |
!defined(MBEDTLS_SSL_SRV_C) |
((void) partial); |
#endif |
ssl->state = MBEDTLS_SSL_HELLO_REQUEST; |
/* Cancel any possibly running timer */ |
ssl_set_timer( ssl, 0 ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE; |
ssl->renego_records_seen = 0; |
ssl->verify_data_len = 0; |
memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); |
memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); |
#endif |
ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; |
ssl->in_offt = NULL; |
ssl_reset_in_out_pointers( ssl ); |
ssl->in_msgtype = 0; |
ssl->in_msglen = 0; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
ssl->next_record_offset = 0; |
ssl->in_epoch = 0; |
#endif |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
ssl_dtls_replay_reset( ssl ); |
#endif |
ssl->in_hslen = 0; |
ssl->nb_zero = 0; |
ssl->keep_current_message = 0; |
ssl->out_msgtype = 0; |
ssl->out_msglen = 0; |
ssl->out_left = 0; |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ) |
ssl->split_done = 0; |
#endif |
memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) ); |
ssl->transform_in = NULL; |
ssl->transform_out = NULL; |
ssl->session_in = NULL; |
ssl->session_out = NULL; |
memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN ); |
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) |
if( partial == 0 ) |
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ |
{ |
ssl->in_left = 0; |
memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN ); |
} |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_reset != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) ); |
if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret ); |
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); |
} |
} |
#endif |
if( ssl->transform ) |
{ |
mbedtls_ssl_transform_free( ssl->transform ); |
mbedtls_free( ssl->transform ); |
ssl->transform = NULL; |
} |
if( ssl->session ) |
{ |
mbedtls_ssl_session_free( ssl->session ); |
mbedtls_free( ssl->session ); |
ssl->session = NULL; |
} |
#if defined(MBEDTLS_SSL_ALPN) |
ssl->alpn_chosen = NULL; |
#endif |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) |
if( partial == 0 ) |
#endif |
{ |
mbedtls_free( ssl->cli_id ); |
ssl->cli_id = NULL; |
ssl->cli_id_len = 0; |
} |
#endif |
if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
/* |
* Reset an initialized and used SSL context for re-use while retaining |
* all application-set variables, function pointers and data. |
*/ |
int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) |
{ |
return( ssl_session_reset_int( ssl, 0 ) ); |
} |
/* |
* SSL set accessors |
*/ |
void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ) |
{ |
conf->endpoint = endpoint; |
} |
void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) |
{ |
conf->transport = transport; |
} |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) |
{ |
conf->anti_replay = mode; |
} |
#endif |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) |
void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) |
{ |
conf->badmac_limit = limit; |
} |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, |
unsigned allow_packing ) |
{ |
ssl->disable_datagram_packing = !allow_packing; |
} |
void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, |
uint32_t min, uint32_t max ) |
{ |
conf->hs_timeout_min = min; |
conf->hs_timeout_max = max; |
} |
#endif |
void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) |
{ |
conf->authmode = authmode; |
} |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ) |
{ |
conf->f_vrfy = f_vrfy; |
conf->p_vrfy = p_vrfy; |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
conf->f_rng = f_rng; |
conf->p_rng = p_rng; |
} |
void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, |
void (*f_dbg)(void *, int, const char *, int, const char *), |
void *p_dbg ) |
{ |
conf->f_dbg = f_dbg; |
conf->p_dbg = p_dbg; |
} |
void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, |
void *p_bio, |
mbedtls_ssl_send_t *f_send, |
mbedtls_ssl_recv_t *f_recv, |
mbedtls_ssl_recv_timeout_t *f_recv_timeout ) |
{ |
ssl->p_bio = p_bio; |
ssl->f_send = f_send; |
ssl->f_recv = f_recv; |
ssl->f_recv_timeout = f_recv_timeout; |
} |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ) |
{ |
ssl->mtu = mtu; |
} |
#endif |
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) |
{ |
conf->read_timeout = timeout; |
} |
void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, |
void *p_timer, |
mbedtls_ssl_set_timer_t *f_set_timer, |
mbedtls_ssl_get_timer_t *f_get_timer ) |
{ |
ssl->p_timer = p_timer; |
ssl->f_set_timer = f_set_timer; |
ssl->f_get_timer = f_get_timer; |
/* Make sure we start with no timer running */ |
ssl_set_timer( ssl, 0 ); |
} |
#if defined(MBEDTLS_SSL_SRV_C) |
void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, |
void *p_cache, |
int (*f_get_cache)(void *, mbedtls_ssl_session *), |
int (*f_set_cache)(void *, const mbedtls_ssl_session *) ) |
{ |
conf->p_cache = p_cache; |
conf->f_get_cache = f_get_cache; |
conf->f_set_cache = f_set_cache; |
} |
#endif /* MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_CLI_C) |
int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ) |
{ |
int ret; |
if( ssl == NULL || |
session == NULL || |
ssl->session_negotiate == NULL || |
ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) |
{ |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 ) |
return( ret ); |
ssl->handshake->resume = 1; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, |
const int *ciphersuites ) |
{ |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites; |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites; |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites; |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites; |
} |
void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, |
const int *ciphersuites, |
int major, int minor ) |
{ |
if( major != MBEDTLS_SSL_MAJOR_VERSION_3 ) |
return; |
if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 ) |
return; |
conf->ciphersuite_list[minor] = ciphersuites; |
} |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, |
const mbedtls_x509_crt_profile *profile ) |
{ |
conf->cert_profile = profile; |
} |
/* Append a new keycert entry to a (possibly empty) list */ |
static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, |
mbedtls_x509_crt *cert, |
mbedtls_pk_context *key ) |
{ |
mbedtls_ssl_key_cert *new_cert; |
new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); |
if( new_cert == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
new_cert->cert = cert; |
new_cert->key = key; |
new_cert->next = NULL; |
/* Update head is the list was null, else add to the end */ |
if( *head == NULL ) |
{ |
*head = new_cert; |
} |
else |
{ |
mbedtls_ssl_key_cert *cur = *head; |
while( cur->next != NULL ) |
cur = cur->next; |
cur->next = new_cert; |
} |
return( 0 ); |
} |
int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, |
mbedtls_x509_crt *own_cert, |
mbedtls_pk_context *pk_key ) |
{ |
return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) ); |
} |
void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, |
mbedtls_x509_crt *ca_chain, |
mbedtls_x509_crl *ca_crl ) |
{ |
conf->ca_chain = ca_chain; |
conf->ca_crl = ca_crl; |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, |
mbedtls_x509_crt *own_cert, |
mbedtls_pk_context *pk_key ) |
{ |
return( ssl_append_key_cert( &ssl->handshake->sni_key_cert, |
own_cert, pk_key ) ); |
} |
void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, |
mbedtls_x509_crt *ca_chain, |
mbedtls_x509_crl *ca_crl ) |
{ |
ssl->handshake->sni_ca_chain = ca_chain; |
ssl->handshake->sni_ca_crl = ca_crl; |
} |
void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, |
int authmode ) |
{ |
ssl->handshake->sni_authmode = authmode; |
} |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
/* |
* Set EC J-PAKE password for current handshake |
*/ |
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, |
const unsigned char *pw, |
size_t pw_len ) |
{ |
mbedtls_ecjpake_role role; |
if( ssl->handshake == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
role = MBEDTLS_ECJPAKE_SERVER; |
else |
role = MBEDTLS_ECJPAKE_CLIENT; |
return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx, |
role, |
MBEDTLS_MD_SHA256, |
MBEDTLS_ECP_DP_SECP256R1, |
pw, pw_len ) ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, |
const unsigned char *psk, size_t psk_len, |
const unsigned char *psk_identity, size_t psk_identity_len ) |
{ |
if( psk == NULL || psk_identity == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( psk_len > MBEDTLS_PSK_MAX_LEN ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
/* Identity len will be encoded on two bytes */ |
if( ( psk_identity_len >> 16 ) != 0 || |
psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) |
{ |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
if( conf->psk != NULL ) |
{ |
mbedtls_platform_zeroize( conf->psk, conf->psk_len ); |
mbedtls_free( conf->psk ); |
conf->psk = NULL; |
conf->psk_len = 0; |
} |
if( conf->psk_identity != NULL ) |
{ |
mbedtls_free( conf->psk_identity ); |
conf->psk_identity = NULL; |
conf->psk_identity_len = 0; |
} |
if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL || |
( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL ) |
{ |
mbedtls_free( conf->psk ); |
mbedtls_free( conf->psk_identity ); |
conf->psk = NULL; |
conf->psk_identity = NULL; |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
} |
conf->psk_len = psk_len; |
conf->psk_identity_len = psk_identity_len; |
memcpy( conf->psk, psk, conf->psk_len ); |
memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); |
return( 0 ); |
} |
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, |
const unsigned char *psk, size_t psk_len ) |
{ |
if( psk == NULL || ssl->handshake == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( psk_len > MBEDTLS_PSK_MAX_LEN ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( ssl->handshake->psk != NULL ) |
{ |
mbedtls_platform_zeroize( ssl->handshake->psk, |
ssl->handshake->psk_len ); |
mbedtls_free( ssl->handshake->psk ); |
ssl->handshake->psk_len = 0; |
} |
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
ssl->handshake->psk_len = psk_len; |
memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); |
return( 0 ); |
} |
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, |
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, |
size_t), |
void *p_psk ) |
{ |
conf->f_psk = f_psk; |
conf->p_psk = p_psk; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) |
#if !defined(MBEDTLS_DEPRECATED_REMOVED) |
int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G ) |
{ |
int ret; |
if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 || |
( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 ) |
{ |
mbedtls_mpi_free( &conf->dhm_P ); |
mbedtls_mpi_free( &conf->dhm_G ); |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, |
const unsigned char *dhm_P, size_t P_len, |
const unsigned char *dhm_G, size_t G_len ) |
{ |
int ret; |
if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 || |
( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 ) |
{ |
mbedtls_mpi_free( &conf->dhm_P ); |
mbedtls_mpi_free( &conf->dhm_G ); |
return( ret ); |
} |
return( 0 ); |
} |
int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ) |
{ |
int ret; |
if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 || |
( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 ) |
{ |
mbedtls_mpi_free( &conf->dhm_P ); |
mbedtls_mpi_free( &conf->dhm_G ); |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) |
/* |
* Set the minimum length for Diffie-Hellman parameters |
*/ |
void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, |
unsigned int bitlen ) |
{ |
conf->dhm_min_bitlen = bitlen; |
} |
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* |
* Set allowed/preferred hashes for handshake signatures |
*/ |
void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, |
const int *hashes ) |
{ |
conf->sig_hashes = hashes; |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_ECP_C) |
/* |
* Set the allowed elliptic curves |
*/ |
void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, |
const mbedtls_ecp_group_id *curve_list ) |
{ |
conf->curve_list = curve_list; |
} |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) |
{ |
/* Initialize to suppress unnecessary compiler warning */ |
size_t hostname_len = 0; |
/* Check if new hostname is valid before |
* making any change to current one */ |
if( hostname != NULL ) |
{ |
hostname_len = strlen( hostname ); |
if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
/* Now it's clear that we will overwrite the old hostname, |
* so we can free it safely */ |
if( ssl->hostname != NULL ) |
{ |
mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); |
mbedtls_free( ssl->hostname ); |
} |
/* Passing NULL as hostname shall clear the old one */ |
if( hostname == NULL ) |
{ |
ssl->hostname = NULL; |
} |
else |
{ |
ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); |
if( ssl->hostname == NULL ) |
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); |
memcpy( ssl->hostname, hostname, hostname_len ); |
ssl->hostname[hostname_len] = '\0'; |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, |
int (*f_sni)(void *, mbedtls_ssl_context *, |
const unsigned char *, size_t), |
void *p_sni ) |
{ |
conf->f_sni = f_sni; |
conf->p_sni = p_sni; |
} |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#if defined(MBEDTLS_SSL_ALPN) |
int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ) |
{ |
size_t cur_len, tot_len; |
const char **p; |
/* |
* RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings |
* MUST NOT be truncated." |
* We check lengths now rather than later. |
*/ |
tot_len = 0; |
for( p = protos; *p != NULL; p++ ) |
{ |
cur_len = strlen( *p ); |
tot_len += cur_len; |
if( cur_len == 0 || cur_len > 255 || tot_len > 65535 ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
conf->alpn_list = protos; |
return( 0 ); |
} |
const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) |
{ |
return( ssl->alpn_chosen ); |
} |
#endif /* MBEDTLS_SSL_ALPN */ |
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) |
{ |
conf->max_major_ver = major; |
conf->max_minor_ver = minor; |
} |
void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ) |
{ |
conf->min_major_ver = major; |
conf->min_minor_ver = minor; |
} |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) |
void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) |
{ |
conf->fallback = fallback; |
} |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, |
char cert_req_ca_list ) |
{ |
conf->cert_req_ca_list = cert_req_ca_list; |
} |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ) |
{ |
conf->encrypt_then_mac = etm; |
} |
#endif |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ) |
{ |
conf->extended_ms = ems; |
} |
#endif |
#if defined(MBEDTLS_ARC4_C) |
void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) |
{ |
conf->arc4_disabled = arc4; |
} |
#endif |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ) |
{ |
if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || |
ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ) |
{ |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
conf->mfl_code = mfl_code; |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ) |
{ |
conf->trunc_hmac = truncate; |
} |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ) |
{ |
conf->cbc_record_splitting = split; |
} |
#endif |
void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ) |
{ |
conf->allow_legacy_renegotiation = allow_legacy; |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ) |
{ |
conf->disable_renegotiation = renegotiation; |
} |
void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ) |
{ |
conf->renego_max_records = max_records; |
} |
void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, |
const unsigned char period[8] ) |
{ |
memcpy( conf->renego_period, period, 8 ); |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
#if defined(MBEDTLS_SSL_CLI_C) |
void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ) |
{ |
conf->session_tickets = use_tickets; |
} |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, |
mbedtls_ssl_ticket_write_t *f_ticket_write, |
mbedtls_ssl_ticket_parse_t *f_ticket_parse, |
void *p_ticket ) |
{ |
conf->f_ticket_write = f_ticket_write; |
conf->f_ticket_parse = f_ticket_parse; |
conf->p_ticket = p_ticket; |
} |
#endif |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_SSL_EXPORT_KEYS) |
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, |
mbedtls_ssl_export_keys_t *f_export_keys, |
void *p_export_keys ) |
{ |
conf->f_export_keys = f_export_keys; |
conf->p_export_keys = p_export_keys; |
} |
#endif |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
void mbedtls_ssl_conf_async_private_cb( |
mbedtls_ssl_config *conf, |
mbedtls_ssl_async_sign_t *f_async_sign, |
mbedtls_ssl_async_decrypt_t *f_async_decrypt, |
mbedtls_ssl_async_resume_t *f_async_resume, |
mbedtls_ssl_async_cancel_t *f_async_cancel, |
void *async_config_data ) |
{ |
conf->f_async_sign_start = f_async_sign; |
conf->f_async_decrypt_start = f_async_decrypt; |
conf->f_async_resume = f_async_resume; |
conf->f_async_cancel = f_async_cancel; |
conf->p_async_config_data = async_config_data; |
} |
void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ) |
{ |
return( conf->p_async_config_data ); |
} |
void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ) |
{ |
if( ssl->handshake == NULL ) |
return( NULL ); |
else |
return( ssl->handshake->user_async_ctx ); |
} |
void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, |
void *ctx ) |
{ |
if( ssl->handshake != NULL ) |
ssl->handshake->user_async_ctx = ctx; |
} |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
/* |
* SSL get accessors |
*/ |
size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) |
{ |
return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); |
} |
int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ) |
{ |
/* |
* Case A: We're currently holding back |
* a message for further processing. |
*/ |
if( ssl->keep_current_message == 1 ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) ); |
return( 1 ); |
} |
/* |
* Case B: Further records are pending in the current datagram. |
*/ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->in_left > ssl->next_record_offset ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) ); |
return( 1 ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
/* |
* Case C: A handshake message is being processed. |
*/ |
if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) ); |
return( 1 ); |
} |
/* |
* Case D: An application data message is being processed |
*/ |
if( ssl->in_offt != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) ); |
return( 1 ); |
} |
/* |
* In all other cases, the rest of the message can be dropped. |
* As in ssl_get_next_record, this needs to be adapted if |
* we implement support for multiple alerts in single records. |
*/ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) ); |
return( 0 ); |
} |
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ) |
{ |
if( ssl->session != NULL ) |
return( ssl->session->verify_result ); |
if( ssl->session_negotiate != NULL ) |
return( ssl->session_negotiate->verify_result ); |
return( 0xFFFFFFFF ); |
} |
const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ) |
{ |
if( ssl == NULL || ssl->session == NULL ) |
return( NULL ); |
return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite ); |
} |
const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
switch( ssl->minor_ver ) |
{ |
case MBEDTLS_SSL_MINOR_VERSION_2: |
return( "DTLSv1.0" ); |
case MBEDTLS_SSL_MINOR_VERSION_3: |
return( "DTLSv1.2" ); |
default: |
return( "unknown (DTLS)" ); |
} |
} |
#endif |
switch( ssl->minor_ver ) |
{ |
case MBEDTLS_SSL_MINOR_VERSION_0: |
return( "SSLv3.0" ); |
case MBEDTLS_SSL_MINOR_VERSION_1: |
return( "TLSv1.0" ); |
case MBEDTLS_SSL_MINOR_VERSION_2: |
return( "TLSv1.1" ); |
case MBEDTLS_SSL_MINOR_VERSION_3: |
return( "TLSv1.2" ); |
default: |
return( "unknown" ); |
} |
} |
int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) |
{ |
size_t transform_expansion = 0; |
const mbedtls_ssl_transform *transform = ssl->transform_out; |
unsigned block_size; |
if( transform == NULL ) |
return( (int) mbedtls_ssl_hdr_len( ssl ) ); |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
#endif |
switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) |
{ |
case MBEDTLS_MODE_GCM: |
case MBEDTLS_MODE_CCM: |
case MBEDTLS_MODE_CHACHAPOLY: |
case MBEDTLS_MODE_STREAM: |
transform_expansion = transform->minlen; |
break; |
case MBEDTLS_MODE_CBC: |
block_size = mbedtls_cipher_get_block_size( |
&transform->cipher_ctx_enc ); |
/* Expansion due to the addition of the MAC. */ |
transform_expansion += transform->maclen; |
/* Expansion due to the addition of CBC padding; |
* Theoretically up to 256 bytes, but we never use |
* more than the block size of the underlying cipher. */ |
transform_expansion += block_size; |
/* For TLS 1.1 or higher, an explicit IV is added |
* after the record header. */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) |
transform_expansion += block_size; |
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ |
break; |
default: |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) ); |
} |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) |
{ |
size_t max_len; |
/* |
* Assume mfl_code is correct since it was checked when set |
*/ |
max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code ); |
/* Check if a smaller max length was negotiated */ |
if( ssl->session_out != NULL && |
ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len ) |
{ |
max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code ); |
} |
/* During a handshake, use the value being negotiated */ |
if( ssl->session_negotiate != NULL && |
ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len ) |
{ |
max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ); |
} |
return( max_len ); |
} |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ) |
{ |
/* Return unlimited mtu for client hello messages to avoid fragmentation. */ |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && |
( ssl->state == MBEDTLS_SSL_CLIENT_HELLO || |
ssl->state == MBEDTLS_SSL_SERVER_HELLO ) ) |
return ( 0 ); |
if( ssl->handshake == NULL || ssl->handshake->mtu == 0 ) |
return( ssl->mtu ); |
if( ssl->mtu == 0 ) |
return( ssl->handshake->mtu ); |
return( ssl->mtu < ssl->handshake->mtu ? |
ssl->mtu : ssl->handshake->mtu ); |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ) |
{ |
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; |
#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ |
!defined(MBEDTLS_SSL_PROTO_DTLS) |
(void) ssl; |
#endif |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); |
if( max_len > mfl ) |
max_len = mfl; |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl_get_current_mtu( ssl ) != 0 ) |
{ |
const size_t mtu = ssl_get_current_mtu( ssl ); |
const int ret = mbedtls_ssl_get_record_expansion( ssl ); |
const size_t overhead = (size_t) ret; |
if( ret < 0 ) |
return( ret ); |
if( mtu <= overhead ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "MTU too low for record expansion" ) ); |
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
} |
if( max_len > mtu - overhead ) |
max_len = mtu - overhead; |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ |
!defined(MBEDTLS_SSL_PROTO_DTLS) |
((void) ssl); |
#endif |
return( (int) max_len ); |
} |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ) |
{ |
if( ssl == NULL || ssl->session == NULL ) |
return( NULL ); |
return( ssl->session->peer_cert ); |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_CLI_C) |
int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst ) |
{ |
if( ssl == NULL || |
dst == NULL || |
ssl->session == NULL || |
ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) |
{ |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
return( ssl_session_copy( dst, ssl->session ) ); |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
/* |
* Perform a single step of the SSL handshake |
*/ |
int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
ret = mbedtls_ssl_handshake_client_step( ssl ); |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
ret = mbedtls_ssl_handshake_server_step( ssl ); |
#endif |
return( ret ); |
} |
/* |
* Perform the SSL handshake |
*/ |
int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) |
{ |
int ret = 0; |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); |
while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
{ |
ret = mbedtls_ssl_handshake_step( ssl ); |
if( ret != 0 ) |
break; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) ); |
return( ret ); |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
#if defined(MBEDTLS_SSL_SRV_C) |
/* |
* Write HelloRequest to request renegotiation on server |
*/ |
static int ssl_write_hello_request( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) ); |
ssl->out_msglen = 4; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; |
ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST; |
if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SSL_SRV_C */ |
/* |
* Actually renegotiate current connection, triggered by either: |
* - any side: calling mbedtls_ssl_renegotiate(), |
* - client: receiving a HelloRequest during mbedtls_ssl_read(), |
* - server: receiving any handshake message on server during mbedtls_ssl_read() after |
* the initial handshake is completed. |
* If the handshake doesn't complete due to waiting for I/O, it will continue |
* during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively. |
*/ |
static int ssl_start_renegotiation( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) ); |
if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) |
return( ret ); |
/* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and |
* the ServerHello will have message_seq = 1" */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) |
{ |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
ssl->handshake->out_msg_seq = 1; |
else |
ssl->handshake->in_msg_seq = 1; |
} |
#endif |
ssl->state = MBEDTLS_SSL_HELLO_REQUEST; |
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS; |
if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); |
return( ret ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) ); |
return( 0 ); |
} |
/* |
* Renegotiate current connection on client, |
* or request renegotiation on server |
*/ |
int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) |
{ |
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_SSL_SRV_C) |
/* On server, just send the request */ |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) |
{ |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; |
/* Did we already try/start sending HelloRequest? */ |
if( ssl->out_left != 0 ) |
return( mbedtls_ssl_flush_output( ssl ) ); |
return( ssl_write_hello_request( ssl ) ); |
} |
#endif /* MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_CLI_C) |
/* |
* On client, either start the renegotiation process or, |
* if already in progress, continue the handshake |
*/ |
if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) |
{ |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); |
return( ret ); |
} |
} |
else |
{ |
if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
return( ret ); |
} |
/* |
* Check record counters and renegotiate if they're above the limit. |
*/ |
static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) |
{ |
size_t ep_len = ssl_ep_len( ssl ); |
int in_ctr_cmp; |
int out_ctr_cmp; |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || |
ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || |
ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) |
{ |
return( 0 ); |
} |
in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, |
ssl->conf->renego_period + ep_len, 8 - ep_len ); |
out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len, |
ssl->conf->renego_period + ep_len, 8 - ep_len ); |
if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) |
{ |
return( 0 ); |
} |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) ); |
return( mbedtls_ssl_renegotiate( ssl ) ); |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/* |
* Receive application data decrypted from the SSL layer |
*/ |
int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) |
{ |
int ret; |
size_t n; |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
return( ret ); |
if( ssl->handshake != NULL && |
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) |
{ |
if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) |
return( ret ); |
} |
} |
#endif |
/* |
* Check if renegotiation is necessary and/or handshake is |
* in process. If yes, perform/continue, and fall through |
* if an unexpected packet is received while the client |
* is waiting for the ServerHello. |
* |
* (There is no equivalent to the last condition on |
* the server-side as it is not treated as within |
* a handshake while waiting for the ClientHello |
* after a renegotiation request.) |
*/ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
ret = ssl_check_ctr_renegotiate( ssl ); |
if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && |
ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); |
return( ret ); |
} |
#endif |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
{ |
ret = mbedtls_ssl_handshake( ssl ); |
if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && |
ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); |
return( ret ); |
} |
} |
/* Loop as long as no application data record is available */ |
while( ssl->in_offt == NULL ) |
{ |
/* Start timer if not already running */ |
if( ssl->f_get_timer != NULL && |
ssl->f_get_timer( ssl->p_timer ) == -1 ) |
{ |
ssl_set_timer( ssl, ssl->conf->read_timeout ); |
} |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) |
return( 0 ); |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
if( ssl->in_msglen == 0 && |
ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA ) |
{ |
/* |
* OpenSSL sends empty messages to randomize the IV |
*/ |
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) |
return( 0 ); |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); |
return( ret ); |
} |
} |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); |
/* |
* - For client-side, expect SERVER_HELLO_REQUEST. |
* - For server-side, expect CLIENT_HELLO. |
* - Fail (TLS) or silently drop record (DTLS) in other cases. |
*/ |
#if defined(MBEDTLS_SSL_CLI_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && |
( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || |
ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); |
/* With DTLS, drop the packet (probably from last handshake) */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
continue; |
} |
#endif |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
#endif /* MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_SRV_C) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); |
/* With DTLS, drop the packet (probably from last handshake) */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
continue; |
} |
#endif |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
#endif /* MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
/* Determine whether renegotiation attempt should be accepted */ |
if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || |
( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && |
ssl->conf->allow_legacy_renegotiation == |
MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) |
{ |
/* |
* Accept renegotiation request |
*/ |
/* DTLS clients need to know renego is server-initiated */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && |
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) |
{ |
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; |
} |
#endif |
ret = ssl_start_renegotiation( ssl ); |
if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && |
ret != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
{ |
/* |
* Refuse renegotiation |
*/ |
MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) |
{ |
/* SSLv3 does not have a "no_renegotiation" warning, so |
we send a fatal alert and abort the connection. */ |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) |
{ |
if( ( ret = mbedtls_ssl_send_alert_message( ssl, |
MBEDTLS_SSL_ALERT_LEVEL_WARNING, |
MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) |
{ |
return( ret ); |
} |
} |
else |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); |
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); |
} |
} |
/* At this point, we don't know whether the renegotiation has been |
* completed or not. The cases to consider are the following: |
* 1) The renegotiation is complete. In this case, no new record |
* has been read yet. |
* 2) The renegotiation is incomplete because the client received |
* an application data record while awaiting the ServerHello. |
* 3) The renegotiation is incomplete because the client received |
* a non-handshake, non-application data message while awaiting |
* the ServerHello. |
* In each of these case, looping will be the proper action: |
* - For 1), the next iteration will read a new record and check |
* if it's application data. |
* - For 2), the loop condition isn't satisfied as application data |
* is present, hence continue is the same as break |
* - For 3), the loop condition is satisfied and read_record |
* will re-deliver the message that was held back by the client |
* when expecting the ServerHello. |
*/ |
continue; |
} |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) |
{ |
if( ssl->conf->renego_max_records >= 0 ) |
{ |
if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " |
"but not honored by client" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
} |
} |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
/* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ |
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) ); |
return( MBEDTLS_ERR_SSL_WANT_READ ); |
} |
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); |
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); |
} |
ssl->in_offt = ssl->in_msg; |
/* We're going to return something now, cancel timer, |
* except if handshake (renegotiation) is in progress */ |
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) |
ssl_set_timer( ssl, 0 ); |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
/* If we requested renego but received AppData, resend HelloRequest. |
* Do it now, after setting in_offt, to avoid taking this branch |
* again if ssl_write_hello_request() returns WANT_WRITE */ |
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && |
ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) |
{ |
if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); |
return( ret ); |
} |
} |
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
} |
n = ( len < ssl->in_msglen ) |
? len : ssl->in_msglen; |
memcpy( buf, ssl->in_offt, n ); |
ssl->in_msglen -= n; |
if( ssl->in_msglen == 0 ) |
{ |
/* all bytes consumed */ |
ssl->in_offt = NULL; |
ssl->keep_current_message = 0; |
} |
else |
{ |
/* more data available */ |
ssl->in_offt += n; |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); |
return( (int) n ); |
} |
/* |
* Send application data to be encrypted by the SSL layer, taking care of max |
* fragment length and buffer size. |
* |
* According to RFC 5246 Section 6.2.1: |
* |
* Zero-length fragments of Application data MAY be sent as they are |
* potentially useful as a traffic analysis countermeasure. |
* |
* Therefore, it is possible that the input message length is 0 and the |
* corresponding return code is 0 on success. |
*/ |
static int ssl_write_real( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); |
const size_t max_len = (size_t) ret; |
if( ret < 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret ); |
return( ret ); |
} |
if( len > max_len ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " |
"maximum fragment length: %d > %d", |
len, max_len ) ); |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
} |
else |
#endif |
len = max_len; |
} |
if( ssl->out_left != 0 ) |
{ |
/* |
* The user has previously tried to send the data and |
* MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially |
* written. In this case, we expect the high-level write function |
* (e.g. mbedtls_ssl_write()) to be called with the same parameters |
*/ |
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); |
return( ret ); |
} |
} |
else |
{ |
/* |
* The user is trying to send a message the first time, so we need to |
* copy the data into the internal buffers and setup the data structure |
* to keep track of partial writes |
*/ |
ssl->out_msglen = len; |
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; |
memcpy( ssl->out_msg, buf, len ); |
if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); |
return( ret ); |
} |
} |
return( (int) len ); |
} |
/* |
* Write application data, doing 1/n-1 splitting if necessary. |
* |
* With non-blocking I/O, ssl_write_real() may return WANT_WRITE, |
* then the caller will call us again with the same arguments, so |
* remember whether we already did the split or not. |
*/ |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
static int ssl_write_split( mbedtls_ssl_context *ssl, |
const unsigned char *buf, size_t len ) |
{ |
int ret; |
if( ssl->conf->cbc_record_splitting == |
MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || |
len <= 1 || |
ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || |
mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) |
!= MBEDTLS_MODE_CBC ) |
{ |
return( ssl_write_real( ssl, buf, len ) ); |
} |
if( ssl->split_done == 0 ) |
{ |
if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 ) |
return( ret ); |
ssl->split_done = 1; |
} |
if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 ) |
return( ret ); |
ssl->split_done = 0; |
return( ret + 1 ); |
} |
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ |
/* |
* Write application data (public-facing wrapper) |
*/ |
int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) |
{ |
int ret; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); |
return( ret ); |
} |
#endif |
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) |
{ |
if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); |
return( ret ); |
} |
} |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
ret = ssl_write_split( ssl, buf, len ); |
#else |
ret = ssl_write_real( ssl, buf, len ); |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); |
return( ret ); |
} |
/* |
* Notify the peer that the connection is being closed |
*/ |
int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) |
{ |
int ret; |
if( ssl == NULL || ssl->conf == NULL ) |
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); |
if( ssl->out_left != 0 ) |
return( mbedtls_ssl_flush_output( ssl ) ); |
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) |
{ |
if( ( ret = mbedtls_ssl_send_alert_message( ssl, |
MBEDTLS_SSL_ALERT_LEVEL_WARNING, |
MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret ); |
return( ret ); |
} |
} |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); |
return( 0 ); |
} |
void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) |
{ |
if( transform == NULL ) |
return; |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
deflateEnd( &transform->ctx_deflate ); |
inflateEnd( &transform->ctx_inflate ); |
#endif |
mbedtls_cipher_free( &transform->cipher_ctx_enc ); |
mbedtls_cipher_free( &transform->cipher_ctx_dec ); |
mbedtls_md_free( &transform->md_ctx_enc ); |
mbedtls_md_free( &transform->md_ctx_dec ); |
mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); |
} |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) |
{ |
mbedtls_ssl_key_cert *cur = key_cert, *next; |
while( cur != NULL ) |
{ |
next = cur->next; |
mbedtls_free( cur ); |
cur = next; |
} |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
static void ssl_buffering_free( mbedtls_ssl_context *ssl ) |
{ |
unsigned offset; |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
if( hs == NULL ) |
return; |
ssl_free_buffered_record( ssl ); |
for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) |
ssl_buffering_free_slot( ssl, offset ); |
} |
static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, |
uint8_t slot ) |
{ |
mbedtls_ssl_handshake_params * const hs = ssl->handshake; |
mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; |
if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS ) |
return; |
if( hs_buf->is_valid == 1 ) |
{ |
hs->buffering.total_bytes_buffered -= hs_buf->data_len; |
mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len ); |
mbedtls_free( hs_buf->data ); |
memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); |
} |
} |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) |
{ |
mbedtls_ssl_handshake_params *handshake = ssl->handshake; |
if( handshake == NULL ) |
return; |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 ) |
{ |
ssl->conf->f_async_cancel( ssl ); |
handshake->async_in_progress = 0; |
} |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
mbedtls_md5_free( &handshake->fin_md5 ); |
mbedtls_sha1_free( &handshake->fin_sha1 ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
#if defined(MBEDTLS_SHA256_C) |
mbedtls_sha256_free( &handshake->fin_sha256 ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
mbedtls_sha512_free( &handshake->fin_sha512 ); |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_DHM_C) |
mbedtls_dhm_free( &handshake->dhm_ctx ); |
#endif |
#if defined(MBEDTLS_ECDH_C) |
mbedtls_ecdh_free( &handshake->ecdh_ctx ); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); |
#if defined(MBEDTLS_SSL_CLI_C) |
mbedtls_free( handshake->ecjpake_cache ); |
handshake->ecjpake_cache = NULL; |
handshake->ecjpake_cache_len = 0; |
#endif |
#endif |
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ |
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
/* explicit void pointer cast for buggy MS compiler */ |
mbedtls_free( (void *) handshake->curves ); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
if( handshake->psk != NULL ) |
{ |
mbedtls_platform_zeroize( handshake->psk, handshake->psk_len ); |
mbedtls_free( handshake->psk ); |
} |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ |
defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
/* |
* Free only the linked list wrapper, not the keys themselves |
* since the belong to the SNI callback |
*/ |
if( handshake->sni_key_cert != NULL ) |
{ |
mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next; |
while( cur != NULL ) |
{ |
next = cur->next; |
mbedtls_free( cur ); |
cur = next; |
} |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) |
mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx ); |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
mbedtls_free( handshake->verify_cookie ); |
ssl_flight_free( handshake->flight ); |
ssl_buffering_free( ssl ); |
#endif |
mbedtls_platform_zeroize( handshake, |
sizeof( mbedtls_ssl_handshake_params ) ); |
} |
void mbedtls_ssl_session_free( mbedtls_ssl_session *session ) |
{ |
if( session == NULL ) |
return; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
if( session->peer_cert != NULL ) |
{ |
mbedtls_x509_crt_free( session->peer_cert ); |
mbedtls_free( session->peer_cert ); |
} |
#endif |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) |
mbedtls_free( session->ticket ); |
#endif |
mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) ); |
} |
/* |
* Free an SSL context |
*/ |
void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) |
{ |
if( ssl == NULL ) |
return; |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) ); |
if( ssl->out_buf != NULL ) |
{ |
mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN ); |
mbedtls_free( ssl->out_buf ); |
} |
if( ssl->in_buf != NULL ) |
{ |
mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN ); |
mbedtls_free( ssl->in_buf ); |
} |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
if( ssl->compress_buf != NULL ) |
{ |
mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); |
mbedtls_free( ssl->compress_buf ); |
} |
#endif |
if( ssl->transform ) |
{ |
mbedtls_ssl_transform_free( ssl->transform ); |
mbedtls_free( ssl->transform ); |
} |
if( ssl->handshake ) |
{ |
mbedtls_ssl_handshake_free( ssl ); |
mbedtls_ssl_transform_free( ssl->transform_negotiate ); |
mbedtls_ssl_session_free( ssl->session_negotiate ); |
mbedtls_free( ssl->handshake ); |
mbedtls_free( ssl->transform_negotiate ); |
mbedtls_free( ssl->session_negotiate ); |
} |
if( ssl->session ) |
{ |
mbedtls_ssl_session_free( ssl->session ); |
mbedtls_free( ssl->session ); |
} |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
if( ssl->hostname != NULL ) |
{ |
mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); |
mbedtls_free( ssl->hostname ); |
} |
#endif |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
if( mbedtls_ssl_hw_record_finish != NULL ) |
{ |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) ); |
mbedtls_ssl_hw_record_finish( ssl ); |
} |
#endif |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
mbedtls_free( ssl->cli_id ); |
#endif |
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) ); |
/* Actually clear after last debug message */ |
mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) ); |
} |
/* |
* Initialze mbedtls_ssl_config |
*/ |
void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) |
{ |
memset( conf, 0, sizeof( mbedtls_ssl_config ) ); |
} |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
static int ssl_preset_default_hashes[] = { |
#if defined(MBEDTLS_SHA512_C) |
MBEDTLS_MD_SHA512, |
MBEDTLS_MD_SHA384, |
#endif |
#if defined(MBEDTLS_SHA256_C) |
MBEDTLS_MD_SHA256, |
MBEDTLS_MD_SHA224, |
#endif |
#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE) |
MBEDTLS_MD_SHA1, |
#endif |
MBEDTLS_MD_NONE |
}; |
#endif |
static int ssl_preset_suiteb_ciphersuites[] = { |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
0 |
}; |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
static int ssl_preset_suiteb_hashes[] = { |
MBEDTLS_MD_SHA256, |
MBEDTLS_MD_SHA384, |
MBEDTLS_MD_NONE |
}; |
#endif |
#if defined(MBEDTLS_ECP_C) |
static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
MBEDTLS_ECP_DP_SECP256R1, |
#endif |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
MBEDTLS_ECP_DP_SECP384R1, |
#endif |
MBEDTLS_ECP_DP_NONE |
}; |
#endif |
/* |
* Load default in mbedtls_ssl_config |
*/ |
int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, |
int endpoint, int transport, int preset ) |
{ |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) |
int ret; |
#endif |
/* Use the functions here so that they are covered in tests, |
* but otherwise access member directly for efficiency */ |
mbedtls_ssl_conf_endpoint( conf, endpoint ); |
mbedtls_ssl_conf_transport( conf, transport ); |
/* |
* Things that are common to all presets |
*/ |
#if defined(MBEDTLS_SSL_CLI_C) |
if( endpoint == MBEDTLS_SSL_IS_CLIENT ) |
{ |
conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED; |
#endif |
} |
#endif |
#if defined(MBEDTLS_ARC4_C) |
conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED; |
#endif |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; |
#endif |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; |
#endif |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; |
#endif |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) |
conf->f_cookie_write = ssl_cookie_write_dummy; |
conf->f_cookie_check = ssl_cookie_check_dummy; |
#endif |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; |
#endif |
#if defined(MBEDTLS_SSL_SRV_C) |
conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; |
#endif |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; |
conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; |
#endif |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; |
memset( conf->renego_period, 0x00, 2 ); |
memset( conf->renego_period + 2, 0xFF, 6 ); |
#endif |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) |
if( endpoint == MBEDTLS_SSL_IS_SERVER ) |
{ |
const unsigned char dhm_p[] = |
MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN; |
const unsigned char dhm_g[] = |
MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; |
if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf, |
dhm_p, sizeof( dhm_p ), |
dhm_g, sizeof( dhm_g ) ) ) != 0 ) |
{ |
return( ret ); |
} |
} |
#endif |
/* |
* Preset-specific defaults |
*/ |
switch( preset ) |
{ |
/* |
* NSA Suite B |
*/ |
case MBEDTLS_SSL_PRESET_SUITEB: |
conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; |
conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ |
conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; |
conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = |
ssl_preset_suiteb_ciphersuites; |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
conf->sig_hashes = ssl_preset_suiteb_hashes; |
#endif |
#if defined(MBEDTLS_ECP_C) |
conf->curve_list = ssl_preset_suiteb_curves; |
#endif |
break; |
/* |
* Default |
*/ |
default: |
conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION > |
MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ? |
MBEDTLS_SSL_MIN_MAJOR_VERSION : |
MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION; |
conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION > |
MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ? |
MBEDTLS_SSL_MIN_MINOR_VERSION : |
MBEDTLS_SSL_MIN_VALID_MINOR_VERSION; |
conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; |
conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; |
#endif |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = |
conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = |
mbedtls_ssl_list_ciphersuites(); |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
conf->cert_profile = &mbedtls_x509_crt_profile_default; |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
conf->sig_hashes = ssl_preset_default_hashes; |
#endif |
#if defined(MBEDTLS_ECP_C) |
conf->curve_list = mbedtls_ecp_grp_id_list(); |
#endif |
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) |
conf->dhm_min_bitlen = 1024; |
#endif |
} |
return( 0 ); |
} |
/* |
* Free mbedtls_ssl_config |
*/ |
void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ) |
{ |
#if defined(MBEDTLS_DHM_C) |
mbedtls_mpi_free( &conf->dhm_P ); |
mbedtls_mpi_free( &conf->dhm_G ); |
#endif |
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) |
if( conf->psk != NULL ) |
{ |
mbedtls_platform_zeroize( conf->psk, conf->psk_len ); |
mbedtls_free( conf->psk ); |
conf->psk = NULL; |
conf->psk_len = 0; |
} |
if( conf->psk_identity != NULL ) |
{ |
mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len ); |
mbedtls_free( conf->psk_identity ); |
conf->psk_identity = NULL; |
conf->psk_identity_len = 0; |
} |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
ssl_key_cert_free( conf->key_cert ); |
#endif |
mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) ); |
} |
#if defined(MBEDTLS_PK_C) && \ |
( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) ) |
/* |
* Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX |
*/ |
unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ) |
{ |
#if defined(MBEDTLS_RSA_C) |
if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) ) |
return( MBEDTLS_SSL_SIG_RSA ); |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) ) |
return( MBEDTLS_SSL_SIG_ECDSA ); |
#endif |
return( MBEDTLS_SSL_SIG_ANON ); |
} |
unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ) |
{ |
switch( type ) { |
case MBEDTLS_PK_RSA: |
return( MBEDTLS_SSL_SIG_RSA ); |
case MBEDTLS_PK_ECDSA: |
case MBEDTLS_PK_ECKEY: |
return( MBEDTLS_SSL_SIG_ECDSA ); |
default: |
return( MBEDTLS_SSL_SIG_ANON ); |
} |
} |
mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) |
{ |
switch( sig ) |
{ |
#if defined(MBEDTLS_RSA_C) |
case MBEDTLS_SSL_SIG_RSA: |
return( MBEDTLS_PK_RSA ); |
#endif |
#if defined(MBEDTLS_ECDSA_C) |
case MBEDTLS_SSL_SIG_ECDSA: |
return( MBEDTLS_PK_ECDSA ); |
#endif |
default: |
return( MBEDTLS_PK_NONE ); |
} |
} |
#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ |
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* Find an entry in a signature-hash set matching a given hash algorithm. */ |
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, |
mbedtls_pk_type_t sig_alg ) |
{ |
switch( sig_alg ) |
{ |
case MBEDTLS_PK_RSA: |
return( set->rsa ); |
case MBEDTLS_PK_ECDSA: |
return( set->ecdsa ); |
default: |
return( MBEDTLS_MD_NONE ); |
} |
} |
/* Add a signature-hash-pair to a signature-hash set */ |
void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, |
mbedtls_pk_type_t sig_alg, |
mbedtls_md_type_t md_alg ) |
{ |
switch( sig_alg ) |
{ |
case MBEDTLS_PK_RSA: |
if( set->rsa == MBEDTLS_MD_NONE ) |
set->rsa = md_alg; |
break; |
case MBEDTLS_PK_ECDSA: |
if( set->ecdsa == MBEDTLS_MD_NONE ) |
set->ecdsa = md_alg; |
break; |
default: |
break; |
} |
} |
/* Allow exactly one hash algorithm for each signature. */ |
void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, |
mbedtls_md_type_t md_alg ) |
{ |
set->rsa = md_alg; |
set->ecdsa = md_alg; |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && |
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
/* |
* Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX |
*/ |
mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) |
{ |
switch( hash ) |
{ |
#if defined(MBEDTLS_MD5_C) |
case MBEDTLS_SSL_HASH_MD5: |
return( MBEDTLS_MD_MD5 ); |
#endif |
#if defined(MBEDTLS_SHA1_C) |
case MBEDTLS_SSL_HASH_SHA1: |
return( MBEDTLS_MD_SHA1 ); |
#endif |
#if defined(MBEDTLS_SHA256_C) |
case MBEDTLS_SSL_HASH_SHA224: |
return( MBEDTLS_MD_SHA224 ); |
case MBEDTLS_SSL_HASH_SHA256: |
return( MBEDTLS_MD_SHA256 ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
case MBEDTLS_SSL_HASH_SHA384: |
return( MBEDTLS_MD_SHA384 ); |
case MBEDTLS_SSL_HASH_SHA512: |
return( MBEDTLS_MD_SHA512 ); |
#endif |
default: |
return( MBEDTLS_MD_NONE ); |
} |
} |
/* |
* Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX |
*/ |
unsigned char mbedtls_ssl_hash_from_md_alg( int md ) |
{ |
switch( md ) |
{ |
#if defined(MBEDTLS_MD5_C) |
case MBEDTLS_MD_MD5: |
return( MBEDTLS_SSL_HASH_MD5 ); |
#endif |
#if defined(MBEDTLS_SHA1_C) |
case MBEDTLS_MD_SHA1: |
return( MBEDTLS_SSL_HASH_SHA1 ); |
#endif |
#if defined(MBEDTLS_SHA256_C) |
case MBEDTLS_MD_SHA224: |
return( MBEDTLS_SSL_HASH_SHA224 ); |
case MBEDTLS_MD_SHA256: |
return( MBEDTLS_SSL_HASH_SHA256 ); |
#endif |
#if defined(MBEDTLS_SHA512_C) |
case MBEDTLS_MD_SHA384: |
return( MBEDTLS_SSL_HASH_SHA384 ); |
case MBEDTLS_MD_SHA512: |
return( MBEDTLS_SSL_HASH_SHA512 ); |
#endif |
default: |
return( MBEDTLS_SSL_HASH_NONE ); |
} |
} |
#if defined(MBEDTLS_ECP_C) |
/* |
* Check if a curve proposed by the peer is in our list. |
* Return 0 if we're willing to use it, -1 otherwise. |
*/ |
int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) |
{ |
const mbedtls_ecp_group_id *gid; |
if( ssl->conf->curve_list == NULL ) |
return( -1 ); |
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) |
if( *gid == grp_id ) |
return( 0 ); |
return( -1 ); |
} |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) |
/* |
* Check if a hash proposed by the peer is in our list. |
* Return 0 if we're willing to use it, -1 otherwise. |
*/ |
int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, |
mbedtls_md_type_t md ) |
{ |
const int *cur; |
if( ssl->conf->sig_hashes == NULL ) |
return( -1 ); |
for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) |
if( *cur == (int) md ) |
return( 0 ); |
return( -1 ); |
} |
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, |
const mbedtls_ssl_ciphersuite_t *ciphersuite, |
int cert_endpoint, |
uint32_t *flags ) |
{ |
int ret = 0; |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
int usage = 0; |
#endif |
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) |
const char *ext_oid; |
size_t ext_len; |
#endif |
#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \ |
!defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) |
((void) cert); |
((void) cert_endpoint); |
((void) flags); |
#endif |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) |
{ |
/* Server part of the key exchange */ |
switch( ciphersuite->key_exchange ) |
{ |
case MBEDTLS_KEY_EXCHANGE_RSA: |
case MBEDTLS_KEY_EXCHANGE_RSA_PSK: |
usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT; |
break; |
case MBEDTLS_KEY_EXCHANGE_DHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: |
usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; |
break; |
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: |
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: |
usage = MBEDTLS_X509_KU_KEY_AGREEMENT; |
break; |
/* Don't use default: we want warnings when adding new values */ |
case MBEDTLS_KEY_EXCHANGE_NONE: |
case MBEDTLS_KEY_EXCHANGE_PSK: |
case MBEDTLS_KEY_EXCHANGE_DHE_PSK: |
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: |
case MBEDTLS_KEY_EXCHANGE_ECJPAKE: |
usage = 0; |
} |
} |
else |
{ |
/* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */ |
usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; |
} |
if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 ) |
{ |
*flags |= MBEDTLS_X509_BADCERT_KEY_USAGE; |
ret = -1; |
} |
#else |
((void) ciphersuite); |
#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ |
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) |
if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) |
{ |
ext_oid = MBEDTLS_OID_SERVER_AUTH; |
ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH ); |
} |
else |
{ |
ext_oid = MBEDTLS_OID_CLIENT_AUTH; |
ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH ); |
} |
if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 ) |
{ |
*flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; |
ret = -1; |
} |
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ |
return( ret ); |
} |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
/* |
* Convert version numbers to/from wire format |
* and, for DTLS, to/from TLS equivalent. |
* |
* For TLS this is the identity. |
* For DTLS, use 1's complement (v -> 255 - v, and then map as follows: |
* 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) |
* 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) |
*/ |
void mbedtls_ssl_write_version( int major, int minor, int transport, |
unsigned char ver[2] ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) |
--minor; /* DTLS 1.0 stored as TLS 1.1 internally */ |
ver[0] = (unsigned char)( 255 - ( major - 2 ) ); |
ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); |
} |
else |
#else |
((void) transport); |
#endif |
{ |
ver[0] = (unsigned char) major; |
ver[1] = (unsigned char) minor; |
} |
} |
void mbedtls_ssl_read_version( int *major, int *minor, int transport, |
const unsigned char ver[2] ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) |
{ |
*major = 255 - ver[0] + 2; |
*minor = 255 - ver[1] + 1; |
if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) |
++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ |
} |
else |
#else |
((void) transport); |
#endif |
{ |
*major = ver[0]; |
*minor = ver[1]; |
} |
} |
int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) |
return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; |
switch( md ) |
{ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) |
#if defined(MBEDTLS_MD5_C) |
case MBEDTLS_SSL_HASH_MD5: |
return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; |
#endif |
#if defined(MBEDTLS_SHA1_C) |
case MBEDTLS_SSL_HASH_SHA1: |
ssl->handshake->calc_verify = ssl_calc_verify_tls; |
break; |
#endif |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SHA512_C) |
case MBEDTLS_SSL_HASH_SHA384: |
ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; |
break; |
#endif |
#if defined(MBEDTLS_SHA256_C) |
case MBEDTLS_SSL_HASH_SHA256: |
ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; |
break; |
#endif |
default: |
return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; |
} |
return 0; |
#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ |
(void) ssl; |
(void) md; |
return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
} |
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_1) |
int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, |
unsigned char *output, |
unsigned char *data, size_t data_len ) |
{ |
int ret = 0; |
mbedtls_md5_context mbedtls_md5; |
mbedtls_sha1_context mbedtls_sha1; |
mbedtls_md5_init( &mbedtls_md5 ); |
mbedtls_sha1_init( &mbedtls_sha1 ); |
/* |
* 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); |
*/ |
if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, |
ssl->handshake->randbytes, 64 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, |
ssl->handshake->randbytes, 64 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data, |
data_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1, |
output + 16 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret ); |
goto exit; |
} |
exit: |
mbedtls_md5_free( &mbedtls_md5 ); |
mbedtls_sha1_free( &mbedtls_sha1 ); |
if( ret != 0 ) |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ |
MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ |
defined(MBEDTLS_SSL_PROTO_TLS1_2) |
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, |
unsigned char *hash, size_t *hashlen, |
unsigned char *data, size_t data_len, |
mbedtls_md_type_t md_alg ) |
{ |
int ret = 0; |
mbedtls_md_context_t ctx; |
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); |
*hashlen = mbedtls_md_get_size( md_info ); |
mbedtls_md_init( &ctx ); |
/* |
* digitally-signed struct { |
* opaque client_random[32]; |
* opaque server_random[32]; |
* ServerDHParams params; |
* }; |
*/ |
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 ) |
{ |
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret ); |
goto exit; |
} |
exit: |
mbedtls_md_free( &ctx ); |
if( ret != 0 ) |
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, |
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); |
return( ret ); |
} |
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ |
MBEDTLS_SSL_PROTO_TLS1_2 */ |
#endif /* MBEDTLS_SSL_TLS_C */ |
/programs/develop/libraries/kos_mbedtls/library/threading.c |
---|
0,0 → 1,189 |
/* |
* Threading abstraction layer |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* Ensure gmtime_r is available even with -std=c99; must be defined before |
* config.h, which pulls in glibc's features.h. Harmless on other platforms. |
*/ |
#if !defined(_POSIX_C_SOURCE) |
#define _POSIX_C_SOURCE 200112L |
#endif |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_THREADING_C) |
#include "mbedtls/threading.h" |
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) |
#if !defined(_WIN32) && (defined(unix) || \ |
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ |
defined(__MACH__))) |
#include <unistd.h> |
#endif /* !_WIN32 && (unix || __unix || __unix__ || |
* (__APPLE__ && __MACH__)) */ |
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) |
/* |
* This is a convenience shorthand macro to avoid checking the long |
* preprocessor conditions above. Ideally, we could expose this macro in |
* platform_util.h and simply use it in platform_util.c, threading.c and |
* threading.h. However, this macro is not part of the Mbed TLS public API, so |
* we keep it private by only defining it in this file |
*/ |
#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) |
#define THREADING_USE_GMTIME |
#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ |
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ |
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ |
#if defined(MBEDTLS_THREADING_PTHREAD) |
static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) |
{ |
if( mutex == NULL ) |
return; |
mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; |
} |
static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) |
{ |
if( mutex == NULL || !mutex->is_valid ) |
return; |
(void) pthread_mutex_destroy( &mutex->mutex ); |
mutex->is_valid = 0; |
} |
static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) |
{ |
if( mutex == NULL || ! mutex->is_valid ) |
return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); |
if( pthread_mutex_lock( &mutex->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
return( 0 ); |
} |
static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) |
{ |
if( mutex == NULL || ! mutex->is_valid ) |
return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); |
if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) |
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
return( 0 ); |
} |
void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; |
void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; |
int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; |
int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; |
/* |
* With phtreads we can statically initialize mutexes |
*/ |
#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } |
#endif /* MBEDTLS_THREADING_PTHREAD */ |
#if defined(MBEDTLS_THREADING_ALT) |
static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) |
{ |
((void) mutex ); |
return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); |
} |
static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) |
{ |
((void) mutex ); |
return; |
} |
void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; |
void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; |
int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; |
int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; |
/* |
* Set functions pointers and initialize global mutexes |
*/ |
void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), |
void (*mutex_free)( mbedtls_threading_mutex_t * ), |
int (*mutex_lock)( mbedtls_threading_mutex_t * ), |
int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) |
{ |
mbedtls_mutex_init = mutex_init; |
mbedtls_mutex_free = mutex_free; |
mbedtls_mutex_lock = mutex_lock; |
mbedtls_mutex_unlock = mutex_unlock; |
#if defined(MBEDTLS_FS_IO) |
mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); |
#endif |
#if defined(THREADING_USE_GMTIME) |
mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); |
#endif |
} |
/* |
* Free global mutexes |
*/ |
void mbedtls_threading_free_alt( void ) |
{ |
#if defined(MBEDTLS_FS_IO) |
mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); |
#endif |
#if defined(THREADING_USE_GMTIME) |
mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); |
#endif |
} |
#endif /* MBEDTLS_THREADING_ALT */ |
/* |
* Define global mutexes |
*/ |
#ifndef MUTEX_INIT |
#define MUTEX_INIT |
#endif |
#if defined(MBEDTLS_FS_IO) |
mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; |
#endif |
#if defined(THREADING_USE_GMTIME) |
mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; |
#endif |
#endif /* MBEDTLS_THREADING_C */ |
/programs/develop/libraries/kos_mbedtls/library/timing.c |
---|
0,0 → 1,539 |
/* |
* Portable interface to the CPU cycle counter |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif |
#if defined(MBEDTLS_TIMING_C) |
#include "mbedtls/timing.h" |
#if !defined(MBEDTLS_TIMING_ALT) |
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ |
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ |
!defined(__HAIKU__) |
//#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" |
#endif |
#ifndef asm |
#define asm __asm |
#endif |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
#include <windows.h> |
#include <process.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 /* _WIN32 && !EFIX64 && !EFI32 */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long tsc; |
__asm rdtsc |
__asm mov [tsc], eax |
return( tsc ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ |
/* some versions of mingw-64 have 32-bit longs even on x84_64 */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && ( defined(__i386__) || ( \ |
( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long lo, hi; |
asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); |
return( lo ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && __i386__ */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long lo, hi; |
asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); |
return( lo | ( hi << 32 ) ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && ( __amd64__ || __x86_64__ ) */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long tbl, tbu0, tbu1; |
do |
{ |
asm volatile( "mftbu %0" : "=r" (tbu0) ); |
asm volatile( "mftb %0" : "=r" (tbl ) ); |
asm volatile( "mftbu %0" : "=r" (tbu1) ); |
} |
while( tbu0 != tbu1 ); |
return( tbl ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && ( __powerpc__ || __ppc__ ) */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && defined(__sparc64__) |
#if defined(__OpenBSD__) |
#warning OpenBSD does not allow access to tick register using software version instead |
#else |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long tick; |
asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); |
return( tick ); |
} |
#endif /* __OpenBSD__ */ |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && __sparc64__ */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long tick; |
asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); |
asm volatile( "mov %%g1, %0" : "=r" (tick) ); |
return( tick ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && __sparc__ && !__sparc64__ */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && defined(__alpha__) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long cc; |
asm volatile( "rpcc %0" : "=r" (cc) ); |
return( cc & 0xFFFFFFFF ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && __alpha__ */ |
#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ |
defined(__GNUC__) && defined(__ia64__) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
unsigned long itc; |
asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); |
return( itc ); |
} |
#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && |
__GNUC__ && __ia64__ */ |
#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ |
!defined(EFIX64) && !defined(EFI32) |
#define HAVE_HARDCLOCK |
unsigned long mbedtls_timing_hardclock( void ) |
{ |
LARGE_INTEGER offset; |
QueryPerformanceCounter( &offset ); |
return( (unsigned long)( offset.QuadPart ) ); |
} |
#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ |
#if !defined(HAVE_HARDCLOCK) |
#define HAVE_HARDCLOCK |
static int hardclock_init = 0; |
static struct timeval tv_init; |
unsigned long mbedtls_timing_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 /* !HAVE_HARDCLOCK */ |
volatile int mbedtls_timing_alarmed = 0; |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) |
{ |
struct _hr_time *t = (struct _hr_time *) val; |
if( reset ) |
{ |
QueryPerformanceCounter( &t->start ); |
return( 0 ); |
} |
else |
{ |
unsigned long delta; |
LARGE_INTEGER now, hfreq; |
QueryPerformanceCounter( &now ); |
QueryPerformanceFrequency( &hfreq ); |
delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul |
/ hfreq.QuadPart ); |
return( delta ); |
} |
} |
/* It's OK to use a global because alarm() is supposed to be global anyway */ |
static DWORD alarmMs; |
static void TimerProc( void *TimerContext ) |
{ |
(void) TimerContext; |
Sleep( alarmMs ); |
mbedtls_timing_alarmed = 1; |
/* _endthread will be called implicitly on return |
* That ensures execution of thread funcition's epilogue */ |
} |
void mbedtls_set_alarm( int seconds ) |
{ |
if( seconds == 0 ) |
{ |
/* No need to create a thread for this simple case. |
* Also, this shorcut is more reliable at least on MinGW32 */ |
mbedtls_timing_alarmed = 1; |
return; |
} |
mbedtls_timing_alarmed = 0; |
alarmMs = seconds * 1000; |
(void) _beginthread( TimerProc, 0, NULL ); |
} |
#else /* _WIN32 && !EFIX64 && !EFI32 */ |
unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) |
{ |
struct _hr_time *t = (struct _hr_time *) val; |
if( reset ) |
{ |
gettimeofday( &t->start, NULL ); |
return( 0 ); |
} |
else |
{ |
unsigned long delta; |
struct timeval now; |
gettimeofday( &now, NULL ); |
delta = ( now.tv_sec - t->start.tv_sec ) * 1000ul |
+ ( now.tv_usec - t->start.tv_usec ) / 1000; |
return( delta ); |
} |
} |
static void sighandler( int signum ) |
{ |
mbedtls_timing_alarmed = 1; |
signal( signum, sighandler ); |
} |
void mbedtls_set_alarm( int seconds ) |
{ |
mbedtls_timing_alarmed = 0; |
signal( SIGALRM, sighandler ); |
//!!!!rgimad |
//alarm( seconds ); |
if( seconds == 0 ) |
{ |
/* alarm(0) cancelled any previous pending alarm, but the |
handler won't fire, so raise the flag straight away. */ |
mbedtls_timing_alarmed = 1; |
} |
} |
#endif /* _WIN32 && !EFIX64 && !EFI32 */ |
/* |
* Set delays to watch |
*/ |
void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ) |
{ |
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; |
ctx->int_ms = int_ms; |
ctx->fin_ms = fin_ms; |
if( fin_ms != 0 ) |
(void) mbedtls_timing_get_timer( &ctx->timer, 1 ); |
} |
/* |
* Get number of delays expired |
*/ |
int mbedtls_timing_get_delay( void *data ) |
{ |
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; |
unsigned long elapsed_ms; |
if( ctx->fin_ms == 0 ) |
return( -1 ); |
elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 ); |
if( elapsed_ms >= ctx->fin_ms ) |
return( 2 ); |
if( elapsed_ms >= ctx->int_ms ) |
return( 1 ); |
return( 0 ); |
} |
#endif /* !MBEDTLS_TIMING_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* Busy-waits for the given number of milliseconds. |
* Used for testing mbedtls_timing_hardclock. |
*/ |
static void busy_msleep( unsigned long msec ) |
{ |
struct mbedtls_timing_hr_time hires; |
unsigned long i = 0; /* for busy-waiting */ |
volatile unsigned long j; /* to prevent optimisation */ |
(void) mbedtls_timing_get_timer( &hires, 1 ); |
while( mbedtls_timing_get_timer( &hires, 0 ) < msec ) |
i++; |
j = i; |
(void) j; |
} |
#define FAIL do \ |
{ \ |
if( verbose != 0 ) \ |
{ \ |
mbedtls_printf( "failed at line %d\n", __LINE__ ); \ |
mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \ |
cycles, ratio, millisecs, secs, hardfail, \ |
(unsigned long) a, (unsigned long) b ); \ |
mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \ |
mbedtls_timing_get_timer( &hires, 0 ), \ |
mbedtls_timing_get_timer( &ctx.timer, 0 ), \ |
mbedtls_timing_get_delay( &ctx ) ); \ |
} \ |
return( 1 ); \ |
} while( 0 ) |
/* |
* Checkup routine |
* |
* Warning: this is work in progress, some tests may not be reliable enough |
* yet! False positives may happen. |
*/ |
int mbedtls_timing_self_test( int verbose ) |
{ |
unsigned long cycles = 0, ratio = 0; |
unsigned long millisecs = 0, secs = 0; |
int hardfail = 0; |
struct mbedtls_timing_hr_time hires; |
uint32_t a = 0, b = 0; |
mbedtls_timing_delay_context ctx; |
if( verbose != 0 ) |
mbedtls_printf( " TIMING tests note: will take some time!\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); |
{ |
secs = 1; |
(void) mbedtls_timing_get_timer( &hires, 1 ); |
mbedtls_set_alarm( (int) secs ); |
while( !mbedtls_timing_alarmed ) |
; |
millisecs = mbedtls_timing_get_timer( &hires, 0 ); |
/* For some reason on Windows it looks like alarm has an extra delay |
* (maybe related to creating a new thread). Allow some room here. */ |
if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) |
FAIL; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); |
{ |
a = 800; |
b = 400; |
mbedtls_timing_set_delay( &ctx, a, a + b ); /* T = 0 */ |
busy_msleep( a - a / 4 ); /* T = a - a/4 */ |
if( mbedtls_timing_get_delay( &ctx ) != 0 ) |
FAIL; |
busy_msleep( a / 4 + b / 4 ); /* T = a + b/4 */ |
if( mbedtls_timing_get_delay( &ctx ) != 1 ) |
FAIL; |
busy_msleep( b ); /* T = a + b + b/4 */ |
if( mbedtls_timing_get_delay( &ctx ) != 2 ) |
FAIL; |
} |
mbedtls_timing_set_delay( &ctx, 0, 0 ); |
busy_msleep( 200 ); |
if( mbedtls_timing_get_delay( &ctx ) != -1 ) |
FAIL; |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
if( verbose != 0 ) |
mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " ); |
/* |
* Allow one failure for possible counter wrapping. |
* On a 4Ghz 32-bit machine the cycle counter wraps about once per second; |
* since the whole test is about 10ms, it shouldn't happen twice in a row. |
*/ |
hard_test: |
if( hardfail > 1 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed (ignored)\n" ); |
goto hard_test_done; |
} |
/* Get a reference ratio cycles/ms */ |
millisecs = 1; |
cycles = mbedtls_timing_hardclock(); |
busy_msleep( millisecs ); |
cycles = mbedtls_timing_hardclock() - cycles; |
ratio = cycles / millisecs; |
/* Check that the ratio is mostly constant */ |
for( millisecs = 2; millisecs <= 4; millisecs++ ) |
{ |
cycles = mbedtls_timing_hardclock(); |
busy_msleep( millisecs ); |
cycles = mbedtls_timing_hardclock() - cycles; |
/* Allow variation up to 20% */ |
if( cycles / millisecs < ratio - ratio / 5 || |
cycles / millisecs > ratio + ratio / 5 ) |
{ |
hardfail++; |
goto hard_test; |
} |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
hard_test_done: |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
return( 0 ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_TIMING_C */ |
/programs/develop/libraries/kos_mbedtls/library/version.c |
---|
0,0 → 1,52 |
/* |
* Version information |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_VERSION_C) |
#include "mbedtls/version.h" |
#include <string.h> |
unsigned int mbedtls_version_get_number( void ) |
{ |
return( MBEDTLS_VERSION_NUMBER ); |
} |
void mbedtls_version_get_string( char *string ) |
{ |
memcpy( string, MBEDTLS_VERSION_STRING, |
sizeof( MBEDTLS_VERSION_STRING ) ); |
} |
void mbedtls_version_get_string_full( char *string ) |
{ |
memcpy( string, MBEDTLS_VERSION_STRING_FULL, |
sizeof( MBEDTLS_VERSION_STRING_FULL ) ); |
} |
#endif /* MBEDTLS_VERSION_C */ |
/programs/develop/libraries/kos_mbedtls/library/version_features.c |
---|
0,0 → 1,787 |
/* |
* Version feature information |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_VERSION_C) |
#include "mbedtls/version.h" |
#include <string.h> |
static const char *features[] = { |
#if defined(MBEDTLS_VERSION_FEATURES) |
#if defined(MBEDTLS_HAVE_ASM) |
"MBEDTLS_HAVE_ASM", |
#endif /* MBEDTLS_HAVE_ASM */ |
#if defined(MBEDTLS_NO_UDBL_DIVISION) |
"MBEDTLS_NO_UDBL_DIVISION", |
#endif /* MBEDTLS_NO_UDBL_DIVISION */ |
#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) |
"MBEDTLS_NO_64BIT_MULTIPLICATION", |
#endif /* MBEDTLS_NO_64BIT_MULTIPLICATION */ |
#if defined(MBEDTLS_HAVE_SSE2) |
"MBEDTLS_HAVE_SSE2", |
#endif /* MBEDTLS_HAVE_SSE2 */ |
#if defined(MBEDTLS_HAVE_TIME) |
"MBEDTLS_HAVE_TIME", |
#endif /* MBEDTLS_HAVE_TIME */ |
#if defined(MBEDTLS_HAVE_TIME_DATE) |
"MBEDTLS_HAVE_TIME_DATE", |
#endif /* MBEDTLS_HAVE_TIME_DATE */ |
#if defined(MBEDTLS_PLATFORM_MEMORY) |
"MBEDTLS_PLATFORM_MEMORY", |
#endif /* MBEDTLS_PLATFORM_MEMORY */ |
#if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) |
"MBEDTLS_PLATFORM_NO_STD_FUNCTIONS", |
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ |
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) |
"MBEDTLS_PLATFORM_EXIT_ALT", |
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ |
#if defined(MBEDTLS_PLATFORM_TIME_ALT) |
"MBEDTLS_PLATFORM_TIME_ALT", |
#endif /* MBEDTLS_PLATFORM_TIME_ALT */ |
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) |
"MBEDTLS_PLATFORM_FPRINTF_ALT", |
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) |
"MBEDTLS_PLATFORM_PRINTF_ALT", |
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) |
"MBEDTLS_PLATFORM_SNPRINTF_ALT", |
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ |
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) |
"MBEDTLS_PLATFORM_NV_SEED_ALT", |
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ |
#if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) |
"MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT", |
#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ |
#if defined(MBEDTLS_DEPRECATED_WARNING) |
"MBEDTLS_DEPRECATED_WARNING", |
#endif /* MBEDTLS_DEPRECATED_WARNING */ |
#if defined(MBEDTLS_DEPRECATED_REMOVED) |
"MBEDTLS_DEPRECATED_REMOVED", |
#endif /* MBEDTLS_DEPRECATED_REMOVED */ |
#if defined(MBEDTLS_CHECK_PARAMS) |
"MBEDTLS_CHECK_PARAMS", |
#endif /* MBEDTLS_CHECK_PARAMS */ |
#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) |
"MBEDTLS_CHECK_PARAMS_ASSERT", |
#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ |
#if defined(MBEDTLS_TIMING_ALT) |
"MBEDTLS_TIMING_ALT", |
#endif /* MBEDTLS_TIMING_ALT */ |
#if defined(MBEDTLS_AES_ALT) |
"MBEDTLS_AES_ALT", |
#endif /* MBEDTLS_AES_ALT */ |
#if defined(MBEDTLS_ARC4_ALT) |
"MBEDTLS_ARC4_ALT", |
#endif /* MBEDTLS_ARC4_ALT */ |
#if defined(MBEDTLS_ARIA_ALT) |
"MBEDTLS_ARIA_ALT", |
#endif /* MBEDTLS_ARIA_ALT */ |
#if defined(MBEDTLS_BLOWFISH_ALT) |
"MBEDTLS_BLOWFISH_ALT", |
#endif /* MBEDTLS_BLOWFISH_ALT */ |
#if defined(MBEDTLS_CAMELLIA_ALT) |
"MBEDTLS_CAMELLIA_ALT", |
#endif /* MBEDTLS_CAMELLIA_ALT */ |
#if defined(MBEDTLS_CCM_ALT) |
"MBEDTLS_CCM_ALT", |
#endif /* MBEDTLS_CCM_ALT */ |
#if defined(MBEDTLS_CHACHA20_ALT) |
"MBEDTLS_CHACHA20_ALT", |
#endif /* MBEDTLS_CHACHA20_ALT */ |
#if defined(MBEDTLS_CHACHAPOLY_ALT) |
"MBEDTLS_CHACHAPOLY_ALT", |
#endif /* MBEDTLS_CHACHAPOLY_ALT */ |
#if defined(MBEDTLS_CMAC_ALT) |
"MBEDTLS_CMAC_ALT", |
#endif /* MBEDTLS_CMAC_ALT */ |
#if defined(MBEDTLS_DES_ALT) |
"MBEDTLS_DES_ALT", |
#endif /* MBEDTLS_DES_ALT */ |
#if defined(MBEDTLS_DHM_ALT) |
"MBEDTLS_DHM_ALT", |
#endif /* MBEDTLS_DHM_ALT */ |
#if defined(MBEDTLS_ECJPAKE_ALT) |
"MBEDTLS_ECJPAKE_ALT", |
#endif /* MBEDTLS_ECJPAKE_ALT */ |
#if defined(MBEDTLS_GCM_ALT) |
"MBEDTLS_GCM_ALT", |
#endif /* MBEDTLS_GCM_ALT */ |
#if defined(MBEDTLS_NIST_KW_ALT) |
"MBEDTLS_NIST_KW_ALT", |
#endif /* MBEDTLS_NIST_KW_ALT */ |
#if defined(MBEDTLS_MD2_ALT) |
"MBEDTLS_MD2_ALT", |
#endif /* MBEDTLS_MD2_ALT */ |
#if defined(MBEDTLS_MD4_ALT) |
"MBEDTLS_MD4_ALT", |
#endif /* MBEDTLS_MD4_ALT */ |
#if defined(MBEDTLS_MD5_ALT) |
"MBEDTLS_MD5_ALT", |
#endif /* MBEDTLS_MD5_ALT */ |
#if defined(MBEDTLS_POLY1305_ALT) |
"MBEDTLS_POLY1305_ALT", |
#endif /* MBEDTLS_POLY1305_ALT */ |
#if defined(MBEDTLS_RIPEMD160_ALT) |
"MBEDTLS_RIPEMD160_ALT", |
#endif /* MBEDTLS_RIPEMD160_ALT */ |
#if defined(MBEDTLS_RSA_ALT) |
"MBEDTLS_RSA_ALT", |
#endif /* MBEDTLS_RSA_ALT */ |
#if defined(MBEDTLS_SHA1_ALT) |
"MBEDTLS_SHA1_ALT", |
#endif /* MBEDTLS_SHA1_ALT */ |
#if defined(MBEDTLS_SHA256_ALT) |
"MBEDTLS_SHA256_ALT", |
#endif /* MBEDTLS_SHA256_ALT */ |
#if defined(MBEDTLS_SHA512_ALT) |
"MBEDTLS_SHA512_ALT", |
#endif /* MBEDTLS_SHA512_ALT */ |
#if defined(MBEDTLS_XTEA_ALT) |
"MBEDTLS_XTEA_ALT", |
#endif /* MBEDTLS_XTEA_ALT */ |
#if defined(MBEDTLS_ECP_ALT) |
"MBEDTLS_ECP_ALT", |
#endif /* MBEDTLS_ECP_ALT */ |
#if defined(MBEDTLS_MD2_PROCESS_ALT) |
"MBEDTLS_MD2_PROCESS_ALT", |
#endif /* MBEDTLS_MD2_PROCESS_ALT */ |
#if defined(MBEDTLS_MD4_PROCESS_ALT) |
"MBEDTLS_MD4_PROCESS_ALT", |
#endif /* MBEDTLS_MD4_PROCESS_ALT */ |
#if defined(MBEDTLS_MD5_PROCESS_ALT) |
"MBEDTLS_MD5_PROCESS_ALT", |
#endif /* MBEDTLS_MD5_PROCESS_ALT */ |
#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT) |
"MBEDTLS_RIPEMD160_PROCESS_ALT", |
#endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */ |
#if defined(MBEDTLS_SHA1_PROCESS_ALT) |
"MBEDTLS_SHA1_PROCESS_ALT", |
#endif /* MBEDTLS_SHA1_PROCESS_ALT */ |
#if defined(MBEDTLS_SHA256_PROCESS_ALT) |
"MBEDTLS_SHA256_PROCESS_ALT", |
#endif /* MBEDTLS_SHA256_PROCESS_ALT */ |
#if defined(MBEDTLS_SHA512_PROCESS_ALT) |
"MBEDTLS_SHA512_PROCESS_ALT", |
#endif /* MBEDTLS_SHA512_PROCESS_ALT */ |
#if defined(MBEDTLS_DES_SETKEY_ALT) |
"MBEDTLS_DES_SETKEY_ALT", |
#endif /* MBEDTLS_DES_SETKEY_ALT */ |
#if defined(MBEDTLS_DES_CRYPT_ECB_ALT) |
"MBEDTLS_DES_CRYPT_ECB_ALT", |
#endif /* MBEDTLS_DES_CRYPT_ECB_ALT */ |
#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT) |
"MBEDTLS_DES3_CRYPT_ECB_ALT", |
#endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */ |
#if defined(MBEDTLS_AES_SETKEY_ENC_ALT) |
"MBEDTLS_AES_SETKEY_ENC_ALT", |
#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */ |
#if defined(MBEDTLS_AES_SETKEY_DEC_ALT) |
"MBEDTLS_AES_SETKEY_DEC_ALT", |
#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */ |
#if defined(MBEDTLS_AES_ENCRYPT_ALT) |
"MBEDTLS_AES_ENCRYPT_ALT", |
#endif /* MBEDTLS_AES_ENCRYPT_ALT */ |
#if defined(MBEDTLS_AES_DECRYPT_ALT) |
"MBEDTLS_AES_DECRYPT_ALT", |
#endif /* MBEDTLS_AES_DECRYPT_ALT */ |
#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) |
"MBEDTLS_ECDH_GEN_PUBLIC_ALT", |
#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */ |
#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) |
"MBEDTLS_ECDH_COMPUTE_SHARED_ALT", |
#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ |
#if defined(MBEDTLS_ECDSA_VERIFY_ALT) |
"MBEDTLS_ECDSA_VERIFY_ALT", |
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ |
#if defined(MBEDTLS_ECDSA_SIGN_ALT) |
"MBEDTLS_ECDSA_SIGN_ALT", |
#endif /* MBEDTLS_ECDSA_SIGN_ALT */ |
#if defined(MBEDTLS_ECDSA_GENKEY_ALT) |
"MBEDTLS_ECDSA_GENKEY_ALT", |
#endif /* MBEDTLS_ECDSA_GENKEY_ALT */ |
#if defined(MBEDTLS_ECP_INTERNAL_ALT) |
"MBEDTLS_ECP_INTERNAL_ALT", |
#endif /* MBEDTLS_ECP_INTERNAL_ALT */ |
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) |
"MBEDTLS_ECP_RANDOMIZE_JAC_ALT", |
#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ |
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) |
"MBEDTLS_ECP_ADD_MIXED_ALT", |
#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ |
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) |
"MBEDTLS_ECP_DOUBLE_JAC_ALT", |
#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) |
"MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", |
#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ |
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) |
"MBEDTLS_ECP_NORMALIZE_JAC_ALT", |
#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ |
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) |
"MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", |
#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ |
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) |
"MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", |
#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ |
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) |
"MBEDTLS_ECP_NORMALIZE_MXZ_ALT", |
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ |
#if defined(MBEDTLS_TEST_NULL_ENTROPY) |
"MBEDTLS_TEST_NULL_ENTROPY", |
#endif /* MBEDTLS_TEST_NULL_ENTROPY */ |
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
"MBEDTLS_ENTROPY_HARDWARE_ALT", |
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ |
#if defined(MBEDTLS_AES_ROM_TABLES) |
"MBEDTLS_AES_ROM_TABLES", |
#endif /* MBEDTLS_AES_ROM_TABLES */ |
#if defined(MBEDTLS_AES_FEWER_TABLES) |
"MBEDTLS_AES_FEWER_TABLES", |
#endif /* MBEDTLS_AES_FEWER_TABLES */ |
#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) |
"MBEDTLS_CAMELLIA_SMALL_MEMORY", |
#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
"MBEDTLS_CIPHER_MODE_CBC", |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#if defined(MBEDTLS_CIPHER_MODE_CFB) |
"MBEDTLS_CIPHER_MODE_CFB", |
#endif /* MBEDTLS_CIPHER_MODE_CFB */ |
#if defined(MBEDTLS_CIPHER_MODE_CTR) |
"MBEDTLS_CIPHER_MODE_CTR", |
#endif /* MBEDTLS_CIPHER_MODE_CTR */ |
#if defined(MBEDTLS_CIPHER_MODE_OFB) |
"MBEDTLS_CIPHER_MODE_OFB", |
#endif /* MBEDTLS_CIPHER_MODE_OFB */ |
#if defined(MBEDTLS_CIPHER_MODE_XTS) |
"MBEDTLS_CIPHER_MODE_XTS", |
#endif /* MBEDTLS_CIPHER_MODE_XTS */ |
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) |
"MBEDTLS_CIPHER_NULL_CIPHER", |
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ |
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) |
"MBEDTLS_CIPHER_PADDING_PKCS7", |
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ |
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) |
"MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS", |
#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ |
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) |
"MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN", |
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ |
#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) |
"MBEDTLS_CIPHER_PADDING_ZEROS", |
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ |
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) |
"MBEDTLS_CTR_DRBG_USE_128_BIT_KEY", |
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ |
#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) |
"MBEDTLS_ENABLE_WEAK_CIPHERSUITES", |
#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ |
#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) |
"MBEDTLS_REMOVE_ARC4_CIPHERSUITES", |
#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ |
#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) |
"MBEDTLS_REMOVE_3DES_CIPHERSUITES", |
#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ |
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) |
"MBEDTLS_ECP_DP_SECP192R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) |
"MBEDTLS_ECP_DP_SECP224R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) |
"MBEDTLS_ECP_DP_SECP256R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) |
"MBEDTLS_ECP_DP_SECP384R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) |
"MBEDTLS_ECP_DP_SECP521R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) |
"MBEDTLS_ECP_DP_SECP192K1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) |
"MBEDTLS_ECP_DP_SECP224K1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) |
"MBEDTLS_ECP_DP_SECP256K1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) |
"MBEDTLS_ECP_DP_BP256R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) |
"MBEDTLS_ECP_DP_BP384R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) |
"MBEDTLS_ECP_DP_BP512R1_ENABLED", |
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) |
"MBEDTLS_ECP_DP_CURVE25519_ENABLED", |
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ |
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) |
"MBEDTLS_ECP_DP_CURVE448_ENABLED", |
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ |
#if defined(MBEDTLS_ECP_NIST_OPTIM) |
"MBEDTLS_ECP_NIST_OPTIM", |
#endif /* MBEDTLS_ECP_NIST_OPTIM */ |
#if defined(MBEDTLS_ECP_RESTARTABLE) |
"MBEDTLS_ECP_RESTARTABLE", |
#endif /* MBEDTLS_ECP_RESTARTABLE */ |
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) |
"MBEDTLS_ECDSA_DETERMINISTIC", |
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ |
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_PSK_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ |
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) |
"MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED", |
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ |
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) |
"MBEDTLS_PK_PARSE_EC_EXTENDED", |
#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ |
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) |
"MBEDTLS_ERROR_STRERROR_DUMMY", |
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ |
#if defined(MBEDTLS_GENPRIME) |
"MBEDTLS_GENPRIME", |
#endif /* MBEDTLS_GENPRIME */ |
#if defined(MBEDTLS_FS_IO) |
"MBEDTLS_FS_IO", |
#endif /* MBEDTLS_FS_IO */ |
#if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) |
"MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES", |
#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ |
#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) |
"MBEDTLS_NO_PLATFORM_ENTROPY", |
#endif /* MBEDTLS_NO_PLATFORM_ENTROPY */ |
#if defined(MBEDTLS_ENTROPY_FORCE_SHA256) |
"MBEDTLS_ENTROPY_FORCE_SHA256", |
#endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */ |
#if defined(MBEDTLS_ENTROPY_NV_SEED) |
"MBEDTLS_ENTROPY_NV_SEED", |
#endif /* MBEDTLS_ENTROPY_NV_SEED */ |
#if defined(MBEDTLS_MEMORY_DEBUG) |
"MBEDTLS_MEMORY_DEBUG", |
#endif /* MBEDTLS_MEMORY_DEBUG */ |
#if defined(MBEDTLS_MEMORY_BACKTRACE) |
"MBEDTLS_MEMORY_BACKTRACE", |
#endif /* MBEDTLS_MEMORY_BACKTRACE */ |
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) |
"MBEDTLS_PK_RSA_ALT_SUPPORT", |
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ |
#if defined(MBEDTLS_PKCS1_V15) |
"MBEDTLS_PKCS1_V15", |
#endif /* MBEDTLS_PKCS1_V15 */ |
#if defined(MBEDTLS_PKCS1_V21) |
"MBEDTLS_PKCS1_V21", |
#endif /* MBEDTLS_PKCS1_V21 */ |
#if defined(MBEDTLS_RSA_NO_CRT) |
"MBEDTLS_RSA_NO_CRT", |
#endif /* MBEDTLS_RSA_NO_CRT */ |
#if defined(MBEDTLS_SELF_TEST) |
"MBEDTLS_SELF_TEST", |
#endif /* MBEDTLS_SELF_TEST */ |
#if defined(MBEDTLS_SHA256_SMALLER) |
"MBEDTLS_SHA256_SMALLER", |
#endif /* MBEDTLS_SHA256_SMALLER */ |
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) |
"MBEDTLS_SSL_ALL_ALERT_MESSAGES", |
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ |
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) |
"MBEDTLS_SSL_ASYNC_PRIVATE", |
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ |
#if defined(MBEDTLS_SSL_DEBUG_ALL) |
"MBEDTLS_SSL_DEBUG_ALL", |
#endif /* MBEDTLS_SSL_DEBUG_ALL */ |
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) |
"MBEDTLS_SSL_ENCRYPT_THEN_MAC", |
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ |
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) |
"MBEDTLS_SSL_EXTENDED_MASTER_SECRET", |
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ |
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) |
"MBEDTLS_SSL_FALLBACK_SCSV", |
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ |
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) |
"MBEDTLS_SSL_HW_RECORD_ACCEL", |
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ |
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) |
"MBEDTLS_SSL_CBC_RECORD_SPLITTING", |
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ |
#if defined(MBEDTLS_SSL_RENEGOTIATION) |
"MBEDTLS_SSL_RENEGOTIATION", |
#endif /* MBEDTLS_SSL_RENEGOTIATION */ |
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) |
"MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", |
#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ |
#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) |
"MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE", |
#endif /* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE */ |
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) |
"MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", |
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ |
#if defined(MBEDTLS_SSL_PROTO_SSL3) |
"MBEDTLS_SSL_PROTO_SSL3", |
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1) |
"MBEDTLS_SSL_PROTO_TLS1", |
#endif /* MBEDTLS_SSL_PROTO_TLS1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) |
"MBEDTLS_SSL_PROTO_TLS1_1", |
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ |
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) |
"MBEDTLS_SSL_PROTO_TLS1_2", |
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ |
#if defined(MBEDTLS_SSL_PROTO_DTLS) |
"MBEDTLS_SSL_PROTO_DTLS", |
#endif /* MBEDTLS_SSL_PROTO_DTLS */ |
#if defined(MBEDTLS_SSL_ALPN) |
"MBEDTLS_SSL_ALPN", |
#endif /* MBEDTLS_SSL_ALPN */ |
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) |
"MBEDTLS_SSL_DTLS_ANTI_REPLAY", |
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ |
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) |
"MBEDTLS_SSL_DTLS_HELLO_VERIFY", |
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ |
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) |
"MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", |
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ |
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) |
"MBEDTLS_SSL_DTLS_BADMAC_LIMIT", |
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ |
#if defined(MBEDTLS_SSL_SESSION_TICKETS) |
"MBEDTLS_SSL_SESSION_TICKETS", |
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ |
#if defined(MBEDTLS_SSL_EXPORT_KEYS) |
"MBEDTLS_SSL_EXPORT_KEYS", |
#endif /* MBEDTLS_SSL_EXPORT_KEYS */ |
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) |
"MBEDTLS_SSL_SERVER_NAME_INDICATION", |
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) |
"MBEDTLS_SSL_TRUNCATED_HMAC", |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ |
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) |
"MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT", |
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */ |
#if defined(MBEDTLS_THREADING_ALT) |
"MBEDTLS_THREADING_ALT", |
#endif /* MBEDTLS_THREADING_ALT */ |
#if defined(MBEDTLS_THREADING_PTHREAD) |
"MBEDTLS_THREADING_PTHREAD", |
#endif /* MBEDTLS_THREADING_PTHREAD */ |
#if defined(MBEDTLS_VERSION_FEATURES) |
"MBEDTLS_VERSION_FEATURES", |
#endif /* MBEDTLS_VERSION_FEATURES */ |
#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) |
"MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", |
#endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */ |
#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) |
"MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", |
#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
"MBEDTLS_X509_CHECK_KEY_USAGE", |
#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ |
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) |
"MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE", |
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
"MBEDTLS_X509_RSASSA_PSS_SUPPORT", |
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ |
#if defined(MBEDTLS_ZLIB_SUPPORT) |
"MBEDTLS_ZLIB_SUPPORT", |
#endif /* MBEDTLS_ZLIB_SUPPORT */ |
#if defined(MBEDTLS_AESNI_C) |
"MBEDTLS_AESNI_C", |
#endif /* MBEDTLS_AESNI_C */ |
#if defined(MBEDTLS_AES_C) |
"MBEDTLS_AES_C", |
#endif /* MBEDTLS_AES_C */ |
#if defined(MBEDTLS_ARC4_C) |
"MBEDTLS_ARC4_C", |
#endif /* MBEDTLS_ARC4_C */ |
#if defined(MBEDTLS_ASN1_PARSE_C) |
"MBEDTLS_ASN1_PARSE_C", |
#endif /* MBEDTLS_ASN1_PARSE_C */ |
#if defined(MBEDTLS_ASN1_WRITE_C) |
"MBEDTLS_ASN1_WRITE_C", |
#endif /* MBEDTLS_ASN1_WRITE_C */ |
#if defined(MBEDTLS_BASE64_C) |
"MBEDTLS_BASE64_C", |
#endif /* MBEDTLS_BASE64_C */ |
#if defined(MBEDTLS_BIGNUM_C) |
"MBEDTLS_BIGNUM_C", |
#endif /* MBEDTLS_BIGNUM_C */ |
#if defined(MBEDTLS_BLOWFISH_C) |
"MBEDTLS_BLOWFISH_C", |
#endif /* MBEDTLS_BLOWFISH_C */ |
#if defined(MBEDTLS_CAMELLIA_C) |
"MBEDTLS_CAMELLIA_C", |
#endif /* MBEDTLS_CAMELLIA_C */ |
#if defined(MBEDTLS_ARIA_C) |
"MBEDTLS_ARIA_C", |
#endif /* MBEDTLS_ARIA_C */ |
#if defined(MBEDTLS_CCM_C) |
"MBEDTLS_CCM_C", |
#endif /* MBEDTLS_CCM_C */ |
#if defined(MBEDTLS_CERTS_C) |
"MBEDTLS_CERTS_C", |
#endif /* MBEDTLS_CERTS_C */ |
#if defined(MBEDTLS_CHACHA20_C) |
"MBEDTLS_CHACHA20_C", |
#endif /* MBEDTLS_CHACHA20_C */ |
#if defined(MBEDTLS_CHACHAPOLY_C) |
"MBEDTLS_CHACHAPOLY_C", |
#endif /* MBEDTLS_CHACHAPOLY_C */ |
#if defined(MBEDTLS_CIPHER_C) |
"MBEDTLS_CIPHER_C", |
#endif /* MBEDTLS_CIPHER_C */ |
#if defined(MBEDTLS_CMAC_C) |
"MBEDTLS_CMAC_C", |
#endif /* MBEDTLS_CMAC_C */ |
#if defined(MBEDTLS_CTR_DRBG_C) |
"MBEDTLS_CTR_DRBG_C", |
#endif /* MBEDTLS_CTR_DRBG_C */ |
#if defined(MBEDTLS_DEBUG_C) |
"MBEDTLS_DEBUG_C", |
#endif /* MBEDTLS_DEBUG_C */ |
#if defined(MBEDTLS_DES_C) |
"MBEDTLS_DES_C", |
#endif /* MBEDTLS_DES_C */ |
#if defined(MBEDTLS_DHM_C) |
"MBEDTLS_DHM_C", |
#endif /* MBEDTLS_DHM_C */ |
#if defined(MBEDTLS_ECDH_C) |
"MBEDTLS_ECDH_C", |
#endif /* MBEDTLS_ECDH_C */ |
#if defined(MBEDTLS_ECDSA_C) |
"MBEDTLS_ECDSA_C", |
#endif /* MBEDTLS_ECDSA_C */ |
#if defined(MBEDTLS_ECJPAKE_C) |
"MBEDTLS_ECJPAKE_C", |
#endif /* MBEDTLS_ECJPAKE_C */ |
#if defined(MBEDTLS_ECP_C) |
"MBEDTLS_ECP_C", |
#endif /* MBEDTLS_ECP_C */ |
#if defined(MBEDTLS_ENTROPY_C) |
"MBEDTLS_ENTROPY_C", |
#endif /* MBEDTLS_ENTROPY_C */ |
#if defined(MBEDTLS_ERROR_C) |
"MBEDTLS_ERROR_C", |
#endif /* MBEDTLS_ERROR_C */ |
#if defined(MBEDTLS_GCM_C) |
"MBEDTLS_GCM_C", |
#endif /* MBEDTLS_GCM_C */ |
#if defined(MBEDTLS_HAVEGE_C) |
"MBEDTLS_HAVEGE_C", |
#endif /* MBEDTLS_HAVEGE_C */ |
#if defined(MBEDTLS_HKDF_C) |
"MBEDTLS_HKDF_C", |
#endif /* MBEDTLS_HKDF_C */ |
#if defined(MBEDTLS_HMAC_DRBG_C) |
"MBEDTLS_HMAC_DRBG_C", |
#endif /* MBEDTLS_HMAC_DRBG_C */ |
#if defined(MBEDTLS_NIST_KW_C) |
"MBEDTLS_NIST_KW_C", |
#endif /* MBEDTLS_NIST_KW_C */ |
#if defined(MBEDTLS_MD_C) |
"MBEDTLS_MD_C", |
#endif /* MBEDTLS_MD_C */ |
#if defined(MBEDTLS_MD2_C) |
"MBEDTLS_MD2_C", |
#endif /* MBEDTLS_MD2_C */ |
#if defined(MBEDTLS_MD4_C) |
"MBEDTLS_MD4_C", |
#endif /* MBEDTLS_MD4_C */ |
#if defined(MBEDTLS_MD5_C) |
"MBEDTLS_MD5_C", |
#endif /* MBEDTLS_MD5_C */ |
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) |
"MBEDTLS_MEMORY_BUFFER_ALLOC_C", |
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ |
#if defined(MBEDTLS_NET_C) |
"MBEDTLS_NET_C", |
#endif /* MBEDTLS_NET_C */ |
#if defined(MBEDTLS_OID_C) |
"MBEDTLS_OID_C", |
#endif /* MBEDTLS_OID_C */ |
#if defined(MBEDTLS_PADLOCK_C) |
"MBEDTLS_PADLOCK_C", |
#endif /* MBEDTLS_PADLOCK_C */ |
#if defined(MBEDTLS_PEM_PARSE_C) |
"MBEDTLS_PEM_PARSE_C", |
#endif /* MBEDTLS_PEM_PARSE_C */ |
#if defined(MBEDTLS_PEM_WRITE_C) |
"MBEDTLS_PEM_WRITE_C", |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#if defined(MBEDTLS_PK_C) |
"MBEDTLS_PK_C", |
#endif /* MBEDTLS_PK_C */ |
#if defined(MBEDTLS_PK_PARSE_C) |
"MBEDTLS_PK_PARSE_C", |
#endif /* MBEDTLS_PK_PARSE_C */ |
#if defined(MBEDTLS_PK_WRITE_C) |
"MBEDTLS_PK_WRITE_C", |
#endif /* MBEDTLS_PK_WRITE_C */ |
#if defined(MBEDTLS_PKCS5_C) |
"MBEDTLS_PKCS5_C", |
#endif /* MBEDTLS_PKCS5_C */ |
#if defined(MBEDTLS_PKCS11_C) |
"MBEDTLS_PKCS11_C", |
#endif /* MBEDTLS_PKCS11_C */ |
#if defined(MBEDTLS_PKCS12_C) |
"MBEDTLS_PKCS12_C", |
#endif /* MBEDTLS_PKCS12_C */ |
#if defined(MBEDTLS_PLATFORM_C) |
"MBEDTLS_PLATFORM_C", |
#endif /* MBEDTLS_PLATFORM_C */ |
#if defined(MBEDTLS_POLY1305_C) |
"MBEDTLS_POLY1305_C", |
#endif /* MBEDTLS_POLY1305_C */ |
#if defined(MBEDTLS_RIPEMD160_C) |
"MBEDTLS_RIPEMD160_C", |
#endif /* MBEDTLS_RIPEMD160_C */ |
#if defined(MBEDTLS_RSA_C) |
"MBEDTLS_RSA_C", |
#endif /* MBEDTLS_RSA_C */ |
#if defined(MBEDTLS_SHA1_C) |
"MBEDTLS_SHA1_C", |
#endif /* MBEDTLS_SHA1_C */ |
#if defined(MBEDTLS_SHA256_C) |
"MBEDTLS_SHA256_C", |
#endif /* MBEDTLS_SHA256_C */ |
#if defined(MBEDTLS_SHA512_C) |
"MBEDTLS_SHA512_C", |
#endif /* MBEDTLS_SHA512_C */ |
#if defined(MBEDTLS_SSL_CACHE_C) |
"MBEDTLS_SSL_CACHE_C", |
#endif /* MBEDTLS_SSL_CACHE_C */ |
#if defined(MBEDTLS_SSL_COOKIE_C) |
"MBEDTLS_SSL_COOKIE_C", |
#endif /* MBEDTLS_SSL_COOKIE_C */ |
#if defined(MBEDTLS_SSL_TICKET_C) |
"MBEDTLS_SSL_TICKET_C", |
#endif /* MBEDTLS_SSL_TICKET_C */ |
#if defined(MBEDTLS_SSL_CLI_C) |
"MBEDTLS_SSL_CLI_C", |
#endif /* MBEDTLS_SSL_CLI_C */ |
#if defined(MBEDTLS_SSL_SRV_C) |
"MBEDTLS_SSL_SRV_C", |
#endif /* MBEDTLS_SSL_SRV_C */ |
#if defined(MBEDTLS_SSL_TLS_C) |
"MBEDTLS_SSL_TLS_C", |
#endif /* MBEDTLS_SSL_TLS_C */ |
#if defined(MBEDTLS_THREADING_C) |
"MBEDTLS_THREADING_C", |
#endif /* MBEDTLS_THREADING_C */ |
#if defined(MBEDTLS_TIMING_C) |
"MBEDTLS_TIMING_C", |
#endif /* MBEDTLS_TIMING_C */ |
#if defined(MBEDTLS_VERSION_C) |
"MBEDTLS_VERSION_C", |
#endif /* MBEDTLS_VERSION_C */ |
#if defined(MBEDTLS_X509_USE_C) |
"MBEDTLS_X509_USE_C", |
#endif /* MBEDTLS_X509_USE_C */ |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
"MBEDTLS_X509_CRT_PARSE_C", |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
#if defined(MBEDTLS_X509_CRL_PARSE_C) |
"MBEDTLS_X509_CRL_PARSE_C", |
#endif /* MBEDTLS_X509_CRL_PARSE_C */ |
#if defined(MBEDTLS_X509_CSR_PARSE_C) |
"MBEDTLS_X509_CSR_PARSE_C", |
#endif /* MBEDTLS_X509_CSR_PARSE_C */ |
#if defined(MBEDTLS_X509_CREATE_C) |
"MBEDTLS_X509_CREATE_C", |
#endif /* MBEDTLS_X509_CREATE_C */ |
#if defined(MBEDTLS_X509_CRT_WRITE_C) |
"MBEDTLS_X509_CRT_WRITE_C", |
#endif /* MBEDTLS_X509_CRT_WRITE_C */ |
#if defined(MBEDTLS_X509_CSR_WRITE_C) |
"MBEDTLS_X509_CSR_WRITE_C", |
#endif /* MBEDTLS_X509_CSR_WRITE_C */ |
#if defined(MBEDTLS_XTEA_C) |
"MBEDTLS_XTEA_C", |
#endif /* MBEDTLS_XTEA_C */ |
#endif /* MBEDTLS_VERSION_FEATURES */ |
NULL |
}; |
int mbedtls_version_check_feature( const char *feature ) |
{ |
const char **idx = features; |
if( *idx == NULL ) |
return( -2 ); |
if( feature == NULL ) |
return( -1 ); |
while( *idx != NULL ) |
{ |
if( !strcmp( *idx, feature ) ) |
return( 0 ); |
idx++; |
} |
return( -1 ); |
} |
#endif /* MBEDTLS_VERSION_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509.c |
---|
0,0 → 1,1074 |
/* |
* X.509 common functions for parsing and verification |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The ITU-T X.509 standard defines a certificate format for PKI. |
* |
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) |
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) |
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) |
* |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_USE_C) |
#include "mbedtls/x509.h" |
#include "mbedtls/asn1.h" |
#include "mbedtls/oid.h" |
#include <stdio.h> |
#include <string.h> |
#if defined(MBEDTLS_PEM_PARSE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_free free |
#define mbedtls_calloc calloc |
#define mbedtls_printf printf |
#define mbedtls_snprintf snprintf |
#endif |
#if defined(MBEDTLS_HAVE_TIME) |
#include "mbedtls/platform_time.h" |
#endif |
#if defined(MBEDTLS_HAVE_TIME_DATE) |
#include "mbedtls/platform_util.h" |
#include <time.h> |
#endif |
#define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); } |
#define CHECK_RANGE(min, max, val) \ |
do \ |
{ \ |
if( ( val ) < ( min ) || ( val ) > ( max ) ) \ |
{ \ |
return( ret ); \ |
} \ |
} while( 0 ) |
/* |
* CertificateSerialNumber ::= INTEGER |
*/ |
int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *serial ) |
{ |
int ret; |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_SERIAL + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) && |
**p != MBEDTLS_ASN1_INTEGER ) |
return( MBEDTLS_ERR_X509_INVALID_SERIAL + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
serial->tag = *(*p)++; |
if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret ); |
serial->p = *p; |
*p += serial->len; |
return( 0 ); |
} |
/* Get an algorithm identifier without parameters (eg for signatures) |
* |
* AlgorithmIdentifier ::= SEQUENCE { |
* algorithm OBJECT IDENTIFIER, |
* parameters ANY DEFINED BY algorithm OPTIONAL } |
*/ |
int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *alg ) |
{ |
int ret; |
if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
return( 0 ); |
} |
/* |
* Parse an algorithm identifier with (optional) parameters |
*/ |
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) |
{ |
int ret; |
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
return( 0 ); |
} |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
/* |
* HashAlgorithm ::= AlgorithmIdentifier |
* |
* AlgorithmIdentifier ::= SEQUENCE { |
* algorithm OBJECT IDENTIFIER, |
* parameters ANY DEFINED BY algorithm OPTIONAL } |
* |
* For HashAlgorithm, parameters MUST be NULL or absent. |
*/ |
static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg ) |
{ |
int ret; |
unsigned char *p; |
const unsigned char *end; |
mbedtls_x509_buf md_oid; |
size_t len; |
/* Make sure we got a SEQUENCE and setup bounds */ |
if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
p = (unsigned char *) alg->p; |
end = p + alg->len; |
if( p >= end ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
/* Parse md_oid */ |
md_oid.tag = *p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
md_oid.p = p; |
p += md_oid.len; |
/* Get md_alg from md_oid */ |
if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
/* Make sure params is absent of NULL */ |
if( p == end ) |
return( 0 ); |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p != end ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* RSASSA-PSS-params ::= SEQUENCE { |
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, |
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, |
* saltLength [2] INTEGER DEFAULT 20, |
* trailerField [3] INTEGER DEFAULT 1 } |
* -- Note that the tags in this Sequence are explicit. |
* |
* RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value |
* of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other |
* option. Enfore this at parsing time. |
*/ |
int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, |
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, |
int *salt_len ) |
{ |
int ret; |
unsigned char *p; |
const unsigned char *end, *end2; |
size_t len; |
mbedtls_x509_buf alg_id, alg_params; |
/* First set everything to defaults */ |
*md_alg = MBEDTLS_MD_SHA1; |
*mgf_md = MBEDTLS_MD_SHA1; |
*salt_len = 20; |
/* Make sure params is a SEQUENCE and setup bounds */ |
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
p = (unsigned char *) params->p; |
end = p + params->len; |
if( p == end ) |
return( 0 ); |
/* |
* HashAlgorithm |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) |
{ |
end2 = p + len; |
/* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ |
if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p != end2 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p == end ) |
return( 0 ); |
/* |
* MaskGenAlgorithm |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) |
{ |
end2 = p + len; |
/* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ |
if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) |
return( ret ); |
/* Only MFG1 is recognised for now */ |
if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 ) |
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE + |
MBEDTLS_ERR_OID_NOT_FOUND ); |
/* Parse HashAlgorithm */ |
if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) |
return( ret ); |
if( p != end2 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p == end ) |
return( 0 ); |
/* |
* salt_len |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 ) |
{ |
end2 = p + len; |
if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p != end2 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p == end ) |
return( 0 ); |
/* |
* trailer_field (if present, must be 1) |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 ) |
{ |
int trailer_field; |
end2 = p + len; |
if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p != end2 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
if( trailer_field != 1 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG ); |
} |
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); |
if( p != end ) |
return( MBEDTLS_ERR_X509_INVALID_ALG + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ |
/* |
* AttributeTypeAndValue ::= SEQUENCE { |
* type AttributeType, |
* value AttributeValue } |
* |
* AttributeType ::= OBJECT IDENTIFIER |
* |
* AttributeValue ::= ANY DEFINED BY AttributeType |
*/ |
static int x509_get_attr_type_value( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_name *cur ) |
{ |
int ret; |
size_t len; |
mbedtls_x509_buf *oid; |
mbedtls_x509_buf *val; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); |
end = *p + len; |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
oid = &cur->oid; |
oid->tag = **p; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); |
oid->p = *p; |
*p += oid->len; |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && |
**p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && |
**p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && |
**p != MBEDTLS_ASN1_BIT_STRING ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
val = &cur->val; |
val->tag = *(*p)++; |
if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); |
val->p = *p; |
*p += val->len; |
if( *p != end ) |
{ |
return( MBEDTLS_ERR_X509_INVALID_NAME + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
cur->next = NULL; |
return( 0 ); |
} |
/* |
* Name ::= CHOICE { -- only one possibility for now -- |
* rdnSequence RDNSequence } |
* |
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName |
* |
* RelativeDistinguishedName ::= |
* SET OF AttributeTypeAndValue |
* |
* AttributeTypeAndValue ::= SEQUENCE { |
* type AttributeType, |
* value AttributeValue } |
* |
* AttributeType ::= OBJECT IDENTIFIER |
* |
* AttributeValue ::= ANY DEFINED BY AttributeType |
* |
* The data structure is optimized for the common case where each RDN has only |
* one element, which is represented as a list of AttributeTypeAndValue. |
* For the general case we still use a flat list, but we mark elements of the |
* same set so that they are "merged" together in the functions that consume |
* this list, eg mbedtls_x509_dn_gets(). |
*/ |
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, |
mbedtls_x509_name *cur ) |
{ |
int ret; |
size_t set_len; |
const unsigned char *end_set; |
/* don't use recursion, we'd risk stack overflow if not optimized */ |
while( 1 ) |
{ |
/* |
* parse SET |
*/ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); |
end_set = *p + set_len; |
while( 1 ) |
{ |
if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) |
return( ret ); |
if( *p == end_set ) |
break; |
/* Mark this item as being no the only one in a set */ |
cur->next_merged = 1; |
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); |
if( cur->next == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
cur = cur->next; |
} |
/* |
* continue until end of SEQUENCE is reached |
*/ |
if( *p == end ) |
return( 0 ); |
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); |
if( cur->next == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
cur = cur->next; |
} |
} |
static int x509_parse_int( unsigned char **p, size_t n, int *res ) |
{ |
*res = 0; |
for( ; n > 0; --n ) |
{ |
if( ( **p < '0') || ( **p > '9' ) ) |
return ( MBEDTLS_ERR_X509_INVALID_DATE ); |
*res *= 10; |
*res += ( *(*p)++ - '0' ); |
} |
return( 0 ); |
} |
static int x509_date_is_valid(const mbedtls_x509_time *t ) |
{ |
int ret = MBEDTLS_ERR_X509_INVALID_DATE; |
int month_len; |
CHECK_RANGE( 0, 9999, t->year ); |
CHECK_RANGE( 0, 23, t->hour ); |
CHECK_RANGE( 0, 59, t->min ); |
CHECK_RANGE( 0, 59, t->sec ); |
switch( t->mon ) |
{ |
case 1: case 3: case 5: case 7: case 8: case 10: case 12: |
month_len = 31; |
break; |
case 4: case 6: case 9: case 11: |
month_len = 30; |
break; |
case 2: |
if( ( !( t->year % 4 ) && t->year % 100 ) || |
!( t->year % 400 ) ) |
month_len = 29; |
else |
month_len = 28; |
break; |
default: |
return( ret ); |
} |
CHECK_RANGE( 1, month_len, t->day ); |
return( 0 ); |
} |
/* |
* Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) |
* field. |
*/ |
static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, |
mbedtls_x509_time *tm ) |
{ |
int ret; |
/* |
* Minimum length is 10 or 12 depending on yearlen |
*/ |
if ( len < yearlen + 8 ) |
return ( MBEDTLS_ERR_X509_INVALID_DATE ); |
len -= yearlen + 8; |
/* |
* Parse year, month, day, hour, minute |
*/ |
CHECK( x509_parse_int( p, yearlen, &tm->year ) ); |
if ( 2 == yearlen ) |
{ |
if ( tm->year < 50 ) |
tm->year += 100; |
tm->year += 1900; |
} |
CHECK( x509_parse_int( p, 2, &tm->mon ) ); |
CHECK( x509_parse_int( p, 2, &tm->day ) ); |
CHECK( x509_parse_int( p, 2, &tm->hour ) ); |
CHECK( x509_parse_int( p, 2, &tm->min ) ); |
/* |
* Parse seconds if present |
*/ |
if ( len >= 2 ) |
{ |
CHECK( x509_parse_int( p, 2, &tm->sec ) ); |
len -= 2; |
} |
else |
return ( MBEDTLS_ERR_X509_INVALID_DATE ); |
/* |
* Parse trailing 'Z' if present |
*/ |
if ( 1 == len && 'Z' == **p ) |
{ |
(*p)++; |
len--; |
} |
/* |
* We should have parsed all characters at this point |
*/ |
if ( 0 != len ) |
return ( MBEDTLS_ERR_X509_INVALID_DATE ); |
CHECK( x509_date_is_valid( tm ) ); |
return ( 0 ); |
} |
/* |
* Time ::= CHOICE { |
* utcTime UTCTime, |
* generalTime GeneralizedTime } |
*/ |
int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, |
mbedtls_x509_time *tm ) |
{ |
int ret; |
size_t len, year_len; |
unsigned char tag; |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_DATE + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
tag = **p; |
if( tag == MBEDTLS_ASN1_UTC_TIME ) |
year_len = 2; |
else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) |
year_len = 4; |
else |
return( MBEDTLS_ERR_X509_INVALID_DATE + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
(*p)++; |
ret = mbedtls_asn1_get_len( p, end, &len ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); |
return x509_parse_time( p, len, year_len, tm ); |
} |
int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) |
{ |
int ret; |
size_t len; |
int tag_type; |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
tag_type = **p; |
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); |
sig->tag = tag_type; |
sig->len = len; |
sig->p = *p; |
*p += len; |
return( 0 ); |
} |
/* |
* Get signature algorithm from alg OID and optional parameters |
*/ |
int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, |
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, |
void **sig_opts ) |
{ |
int ret; |
if( *sig_opts != NULL ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) |
return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) |
{ |
mbedtls_pk_rsassa_pss_options *pss_opts; |
pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); |
if( pss_opts == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
ret = mbedtls_x509_get_rsassa_pss_params( sig_params, |
md_alg, |
&pss_opts->mgf1_hash_id, |
&pss_opts->expected_salt_len ); |
if( ret != 0 ) |
{ |
mbedtls_free( pss_opts ); |
return( ret ); |
} |
*sig_opts = (void *) pss_opts; |
} |
else |
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ |
{ |
/* Make sure parameters are absent or NULL */ |
if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || |
sig_params->len != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_ALG ); |
} |
return( 0 ); |
} |
/* |
* X.509 Extensions (No parsing of extensions, pointer should |
* be either manually updated or extensions should be parsed!) |
*/ |
int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, |
mbedtls_x509_buf *ext, int tag ) |
{ |
int ret; |
size_t len; |
/* Extension structure use EXPLICIT tagging. That is, the actual |
* `Extensions` structure is wrapped by a tag-length pair using |
* the respective context-specific tag. */ |
ret = mbedtls_asn1_get_tag( p, end, &ext->len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag; |
ext->p = *p; |
end = *p + ext->len; |
/* |
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension |
*/ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( end != *p + len ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* Store the name in printable form into buf; no more |
* than size characters will be written |
*/ |
int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) |
{ |
int ret; |
size_t i, n; |
unsigned char c, merge = 0; |
const mbedtls_x509_name *name; |
const char *short_name = NULL; |
char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; |
memset( s, 0, sizeof( s ) ); |
name = dn; |
p = buf; |
n = size; |
while( name != NULL ) |
{ |
if( !name->oid.p ) |
{ |
name = name->next; |
continue; |
} |
if( name != dn ) |
{ |
ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
} |
ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); |
if( ret == 0 ) |
ret = mbedtls_snprintf( p, n, "%s=", short_name ); |
else |
ret = mbedtls_snprintf( p, n, "\?\?=" ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
for( i = 0; i < name->val.len; i++ ) |
{ |
if( i >= sizeof( s ) - 1 ) |
break; |
c = name->val.p[i]; |
if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) |
s[i] = '?'; |
else s[i] = c; |
} |
s[i] = '\0'; |
ret = mbedtls_snprintf( p, n, "%s", s ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
merge = name->next_merged; |
name = name->next; |
} |
return( (int) ( size - n ) ); |
} |
/* |
* Store the serial in printable form into buf; no more |
* than size characters will be written |
*/ |
int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) |
{ |
int ret; |
size_t i, n, nr; |
char *p; |
p = buf; |
n = size; |
nr = ( serial->len <= 32 ) |
? serial->len : 28; |
for( i = 0; i < nr; i++ ) |
{ |
if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) |
continue; |
ret = mbedtls_snprintf( p, n, "%02X%s", |
serial->p[i], ( i < nr - 1 ) ? ":" : "" ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
} |
if( nr != serial->len ) |
{ |
ret = mbedtls_snprintf( p, n, "...." ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
} |
return( (int) ( size - n ) ); |
} |
/* |
* Helper for writing signature algorithms |
*/ |
int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, |
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, |
const void *sig_opts ) |
{ |
int ret; |
char *p = buf; |
size_t n = size; |
const char *desc = NULL; |
ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); |
if( ret != 0 ) |
ret = mbedtls_snprintf( p, n, "???" ); |
else |
ret = mbedtls_snprintf( p, n, "%s", desc ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) |
{ |
const mbedtls_pk_rsassa_pss_options *pss_opts; |
const mbedtls_md_info_t *md_info, *mgf_md_info; |
pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; |
md_info = mbedtls_md_info_from_type( md_alg ); |
mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); |
ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", |
md_info ? mbedtls_md_get_name( md_info ) : "???", |
mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", |
pss_opts->expected_salt_len ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
} |
#else |
((void) pk_alg); |
((void) md_alg); |
((void) sig_opts); |
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ |
return( (int)( size - n ) ); |
} |
/* |
* Helper for writing "RSA key size", "EC key size", etc |
*/ |
int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) |
{ |
char *p = buf; |
size_t n = buf_size; |
int ret; |
ret = mbedtls_snprintf( p, n, "%s key size", name ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
return( 0 ); |
} |
#if defined(MBEDTLS_HAVE_TIME_DATE) |
/* |
* Set the time structure to the current time. |
* Return 0 on success, non-zero on failure. |
*/ |
static int x509_get_current_time( mbedtls_x509_time *now ) |
{ |
struct tm *lt, tm_buf; |
mbedtls_time_t tt; |
int ret = 0; |
tt = mbedtls_time( NULL ); |
lt = mbedtls_platform_gmtime_r( &tt, &tm_buf ); |
if( lt == NULL ) |
ret = -1; |
else |
{ |
now->year = lt->tm_year + 1900; |
now->mon = lt->tm_mon + 1; |
now->day = lt->tm_mday; |
now->hour = lt->tm_hour; |
now->min = lt->tm_min; |
now->sec = lt->tm_sec; |
} |
return( ret ); |
} |
/* |
* Return 0 if before <= after, 1 otherwise |
*/ |
static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) |
{ |
if( before->year > after->year ) |
return( 1 ); |
if( before->year == after->year && |
before->mon > after->mon ) |
return( 1 ); |
if( before->year == after->year && |
before->mon == after->mon && |
before->day > after->day ) |
return( 1 ); |
if( before->year == after->year && |
before->mon == after->mon && |
before->day == after->day && |
before->hour > after->hour ) |
return( 1 ); |
if( before->year == after->year && |
before->mon == after->mon && |
before->day == after->day && |
before->hour == after->hour && |
before->min > after->min ) |
return( 1 ); |
if( before->year == after->year && |
before->mon == after->mon && |
before->day == after->day && |
before->hour == after->hour && |
before->min == after->min && |
before->sec > after->sec ) |
return( 1 ); |
return( 0 ); |
} |
int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) |
{ |
mbedtls_x509_time now; |
if( x509_get_current_time( &now ) != 0 ) |
return( 1 ); |
return( x509_check_time( &now, to ) ); |
} |
int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) |
{ |
mbedtls_x509_time now; |
if( x509_get_current_time( &now ) != 0 ) |
return( 1 ); |
return( x509_check_time( from, &now ) ); |
} |
#else /* MBEDTLS_HAVE_TIME_DATE */ |
int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) |
{ |
((void) to); |
return( 0 ); |
} |
int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) |
{ |
((void) from); |
return( 0 ); |
} |
#endif /* MBEDTLS_HAVE_TIME_DATE */ |
#if defined(MBEDTLS_SELF_TEST) |
#include "mbedtls/x509_crt.h" |
#include "mbedtls/certs.h" |
/* |
* Checkup routine |
*/ |
int mbedtls_x509_self_test( int verbose ) |
{ |
int ret = 0; |
#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) |
uint32_t flags; |
mbedtls_x509_crt cacert; |
mbedtls_x509_crt clicert; |
if( verbose != 0 ) |
mbedtls_printf( " X.509 certificate load: " ); |
mbedtls_x509_crt_init( &cacert ); |
mbedtls_x509_crt_init( &clicert ); |
ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, |
mbedtls_test_cli_crt_len ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto cleanup; |
} |
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, |
mbedtls_test_ca_crt_len ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n X.509 signature verify: "); |
ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); |
if( ret != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
goto cleanup; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n\n"); |
cleanup: |
mbedtls_x509_crt_free( &cacert ); |
mbedtls_x509_crt_free( &clicert ); |
#else |
((void) verbose); |
#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */ |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_X509_USE_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509_create.c |
---|
0,0 → 1,381 |
/* |
* X.509 base functions for creating certificates / CSRs |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_CREATE_C) |
#include "mbedtls/x509.h" |
#include "mbedtls/asn1write.h" |
#include "mbedtls/oid.h" |
#include <string.h> |
/* Structure linking OIDs for X.509 DN AttributeTypes to their |
* string representations and default string encodings used by Mbed TLS. */ |
typedef struct { |
const char *name; /* String representation of AttributeType, e.g. |
* "CN" or "emailAddress". */ |
size_t name_len; /* Length of 'name', without trailing 0 byte. */ |
const char *oid; /* String representation of OID of AttributeType, |
* as per RFC 5280, Appendix A.1. */ |
int default_tag; /* The default character encoding used for the |
* given attribute type, e.g. |
* MBEDTLS_ASN1_UTF8_STRING for UTF-8. */ |
} x509_attr_descriptor_t; |
#define ADD_STRLEN( s ) s, sizeof( s ) - 1 |
/* X.509 DN attributes from RFC 5280, Appendix A.1. */ |
static const x509_attr_descriptor_t x509_attrs[] = |
{ |
{ ADD_STRLEN( "CN" ), |
MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "commonName" ), |
MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "C" ), |
MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, |
{ ADD_STRLEN( "countryName" ), |
MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, |
{ ADD_STRLEN( "O" ), |
MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "organizationName" ), |
MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "L" ), |
MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "locality" ), |
MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "R" ), |
MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, |
{ ADD_STRLEN( "OU" ), |
MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "organizationalUnitName" ), |
MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "ST" ), |
MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "stateOrProvinceName" ), |
MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "emailAddress" ), |
MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, |
{ ADD_STRLEN( "serialNumber" ), |
MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING }, |
{ ADD_STRLEN( "postalAddress" ), |
MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING }, |
{ ADD_STRLEN( "postalCode" ), |
MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING }, |
{ ADD_STRLEN( "dnQualifier" ), |
MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING }, |
{ ADD_STRLEN( "title" ), |
MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "surName" ), |
MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "SN" ), |
MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "givenName" ), |
MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "GN" ), |
MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "initials" ), |
MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "pseudonym" ), |
MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "generationQualifier" ), |
MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING }, |
{ ADD_STRLEN( "domainComponent" ), |
MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, |
{ ADD_STRLEN( "DC" ), |
MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, |
{ NULL, 0, NULL, MBEDTLS_ASN1_NULL } |
}; |
static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name, size_t name_len ) |
{ |
const x509_attr_descriptor_t *cur; |
for( cur = x509_attrs; cur->name != NULL; cur++ ) |
if( cur->name_len == name_len && |
strncmp( cur->name, name, name_len ) == 0 ) |
break; |
if ( cur->name == NULL ) |
return( NULL ); |
return( cur ); |
} |
int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) |
{ |
int ret = 0; |
const char *s = name, *c = s; |
const char *end = s + strlen( s ); |
const char *oid = NULL; |
const x509_attr_descriptor_t* attr_descr = NULL; |
int in_tag = 1; |
char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; |
char *d = data; |
/* Clear existing chain if present */ |
mbedtls_asn1_free_named_data_list( head ); |
while( c <= end ) |
{ |
if( in_tag && *c == '=' ) |
{ |
if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL ) |
{ |
ret = MBEDTLS_ERR_X509_UNKNOWN_OID; |
goto exit; |
} |
oid = attr_descr->oid; |
s = c + 1; |
in_tag = 0; |
d = data; |
} |
if( !in_tag && *c == '\\' && c != end ) |
{ |
c++; |
/* Check for valid escaped characters */ |
if( c == end || *c != ',' ) |
{ |
ret = MBEDTLS_ERR_X509_INVALID_NAME; |
goto exit; |
} |
} |
else if( !in_tag && ( *c == ',' || c == end ) ) |
{ |
mbedtls_asn1_named_data* cur = |
mbedtls_asn1_store_named_data( head, oid, strlen( oid ), |
(unsigned char *) data, |
d - data ); |
if(cur == NULL ) |
{ |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
} |
// set tagType |
cur->val.tag = attr_descr->default_tag; |
while( c < end && *(c + 1) == ' ' ) |
c++; |
s = c + 1; |
in_tag = 1; |
} |
if( !in_tag && s != c + 1 ) |
{ |
*(d++) = *c; |
if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE ) |
{ |
ret = MBEDTLS_ERR_X509_INVALID_NAME; |
goto exit; |
} |
} |
c++; |
} |
exit: |
return( ret ); |
} |
/* The first byte of the value in the mbedtls_asn1_named_data structure is reserved |
* to store the critical boolean for us |
*/ |
int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, |
int critical, const unsigned char *val, size_t val_len ) |
{ |
mbedtls_asn1_named_data *cur; |
if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len, |
NULL, val_len + 1 ) ) == NULL ) |
{ |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
} |
cur->val.p[0] = critical; |
memcpy( cur->val.p + 1, val, val_len ); |
return( 0 ); |
} |
/* |
* RelativeDistinguishedName ::= |
* SET OF AttributeTypeAndValue |
* |
* AttributeTypeAndValue ::= SEQUENCE { |
* type AttributeType, |
* value AttributeValue } |
* |
* AttributeType ::= OBJECT IDENTIFIER |
* |
* AttributeValue ::= ANY DEFINED BY AttributeType |
*/ |
static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name) |
{ |
int ret; |
size_t len = 0; |
const char *oid = (const char*)cur_name->oid.p; |
size_t oid_len = cur_name->oid.len; |
const unsigned char *name = cur_name->val.p; |
size_t name_len = cur_name->val.len; |
// Write correct string tag and value |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tagged_string( p, start, |
cur_name->val.tag, |
(const char *) name, |
name_len ) ); |
// Write OID |
// |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, |
oid_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, |
MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, |
MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SET ) ); |
return( (int) len ); |
} |
int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, |
mbedtls_asn1_named_data *first ) |
{ |
int ret; |
size_t len = 0; |
mbedtls_asn1_named_data *cur = first; |
while( cur != NULL ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, cur ) ); |
cur = cur->next; |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, |
const char *oid, size_t oid_len, |
unsigned char *sig, size_t size ) |
{ |
int ret; |
size_t len = 0; |
if( *p < start || (size_t)( *p - start ) < size ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
len = size; |
(*p) -= len; |
memcpy( *p, sig, len ); |
if( *p - start < 1 ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
*--(*p) = 0; |
len += 1; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); |
// Write OID |
// |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid, |
oid_len, 0 ) ); |
return( (int) len ); |
} |
static int x509_write_extension( unsigned char **p, unsigned char *start, |
mbedtls_asn1_named_data *ext ) |
{ |
int ret; |
size_t len = 0; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1, |
ext->val.len - 1 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); |
if( ext->val.p[0] != 0 ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) ); |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p, |
ext->oid.len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
/* |
* Extension ::= SEQUENCE { |
* extnID OBJECT IDENTIFIER, |
* critical BOOLEAN DEFAULT FALSE, |
* extnValue OCTET STRING |
* -- contains the DER encoding of an ASN.1 value |
* -- corresponding to the extension type identified |
* -- by extnID |
* } |
*/ |
int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, |
mbedtls_asn1_named_data *first ) |
{ |
int ret; |
size_t len = 0; |
mbedtls_asn1_named_data *cur_ext = first; |
while( cur_ext != NULL ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) ); |
cur_ext = cur_ext->next; |
} |
return( (int) len ); |
} |
#endif /* MBEDTLS_X509_CREATE_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509_crl.c |
---|
0,0 → 1,775 |
/* |
* X.509 Certidicate Revocation List (CRL) parsing |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The ITU-T X.509 standard defines a certificate format for PKI. |
* |
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) |
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) |
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) |
* |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_CRL_PARSE_C) |
#include "mbedtls/x509_crl.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PEM_PARSE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#include <stdio.h> |
#define mbedtls_free free |
#define mbedtls_calloc calloc |
#define mbedtls_snprintf snprintf |
#endif |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
#include <windows.h> |
#else |
#include <time.h> |
#endif |
#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) |
#include <stdio.h> |
#endif |
/* |
* Version ::= INTEGER { v1(0), v2(1) } |
*/ |
static int x509_crl_get_version( unsigned char **p, |
const unsigned char *end, |
int *ver ) |
{ |
int ret; |
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
{ |
*ver = 0; |
return( 0 ); |
} |
return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); |
} |
return( 0 ); |
} |
/* |
* X.509 CRL v2 extensions |
* |
* We currently don't parse any extension's content, but we do check that the |
* list of extensions is well-formed and abort on critical extensions (that |
* are unsupported as we don't support any extension so far) |
*/ |
static int x509_get_crl_ext( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_buf *ext ) |
{ |
int ret; |
if( *p == end ) |
return( 0 ); |
/* |
* crlExtensions [0] EXPLICIT Extensions OPTIONAL |
* -- if present, version MUST be v2 |
*/ |
if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 ) |
return( ret ); |
end = ext->p + ext->len; |
while( *p < end ) |
{ |
/* |
* Extension ::= SEQUENCE { |
* extnID OBJECT IDENTIFIER, |
* critical BOOLEAN DEFAULT FALSE, |
* extnValue OCTET STRING } |
*/ |
int is_critical = 0; |
const unsigned char *end_ext_data; |
size_t len; |
/* Get enclosing sequence tag */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
end_ext_data = *p + len; |
/* Get OID (currently ignored) */ |
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, |
MBEDTLS_ASN1_OID ) ) != 0 ) |
{ |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
} |
*p += len; |
/* Get optional critical */ |
if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, |
&is_critical ) ) != 0 && |
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) |
{ |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
} |
/* Data should be octet string type */ |
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, |
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
/* Ignore data so far and just check its length */ |
*p += len; |
if( *p != end_ext_data ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
/* Abort on (unsupported) critical extensions */ |
if( is_critical ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
} |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* X.509 CRL v2 entry extensions (no extensions parsed yet.) |
*/ |
static int x509_get_crl_entry_ext( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_buf *ext ) |
{ |
int ret; |
size_t len = 0; |
/* OPTIONAL */ |
if( end <= *p ) |
return( 0 ); |
ext->tag = **p; |
ext->p = *p; |
/* |
* Get CRL-entry extension sequence header |
* crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2 |
*/ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
{ |
ext->p = NULL; |
return( 0 ); |
} |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
} |
end = *p + ext->len; |
if( end != *p + ext->len ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
while( *p < end ) |
{ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
*p += len; |
} |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* X.509 CRL Entries |
*/ |
static int x509_get_entries( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_crl_entry *entry ) |
{ |
int ret; |
size_t entry_len; |
mbedtls_x509_crl_entry *cur_entry = entry; |
if( *p == end ) |
return( 0 ); |
if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len, |
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( 0 ); |
return( ret ); |
} |
end = *p + entry_len; |
while( *p < end ) |
{ |
size_t len2; |
const unsigned char *end2; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len2, |
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) |
{ |
return( ret ); |
} |
cur_entry->raw.tag = **p; |
cur_entry->raw.p = *p; |
cur_entry->raw.len = len2; |
end2 = *p + len2; |
if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_x509_get_time( p, end2, |
&cur_entry->revocation_date ) ) != 0 ) |
return( ret ); |
if( ( ret = x509_get_crl_entry_ext( p, end2, |
&cur_entry->entry_ext ) ) != 0 ) |
return( ret ); |
if( *p < end ) |
{ |
cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) ); |
if( cur_entry->next == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
cur_entry = cur_entry->next; |
} |
} |
return( 0 ); |
} |
/* |
* Parse one CRLs in DER format and append it to the chained list |
*/ |
int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, |
const unsigned char *buf, size_t buflen ) |
{ |
int ret; |
size_t len; |
unsigned char *p = NULL, *end = NULL; |
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; |
mbedtls_x509_crl *crl = chain; |
/* |
* Check for valid input |
*/ |
if( crl == NULL || buf == NULL ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); |
memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); |
memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); |
/* |
* Add new CRL on the end of the chain if needed. |
*/ |
while( crl->version != 0 && crl->next != NULL ) |
crl = crl->next; |
if( crl->version != 0 && crl->next == NULL ) |
{ |
crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) ); |
if( crl->next == NULL ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
} |
mbedtls_x509_crl_init( crl->next ); |
crl = crl->next; |
} |
/* |
* Copy raw DER-encoded CRL |
*/ |
if( buflen == 0 ) |
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); |
p = mbedtls_calloc( 1, buflen ); |
if( p == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
memcpy( p, buf, buflen ); |
crl->raw.p = p; |
crl->raw.len = buflen; |
end = p + buflen; |
/* |
* CertificateList ::= SEQUENCE { |
* tbsCertList TBSCertList, |
* signatureAlgorithm AlgorithmIdentifier, |
* signatureValue BIT STRING } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); |
} |
if( len != (size_t) ( end - p ) ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
/* |
* TBSCertList ::= SEQUENCE { |
*/ |
crl->tbs.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
end = p + len; |
crl->tbs.len = end - crl->tbs.p; |
/* |
* Version ::= INTEGER OPTIONAL { v1(0), v2(1) } |
* -- if present, MUST be v2 |
* |
* signature AlgorithmIdentifier |
*/ |
if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 || |
( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
if( crl->version < 0 || crl->version > 1 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); |
} |
crl->version++; |
if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1, |
&crl->sig_md, &crl->sig_pk, |
&crl->sig_opts ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); |
} |
/* |
* issuer Name |
*/ |
crl->issuer_raw.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
crl->issuer_raw.len = p - crl->issuer_raw.p; |
/* |
* thisUpdate Time |
* nextUpdate Time OPTIONAL |
*/ |
if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 ) |
{ |
if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) && |
ret != ( MBEDTLS_ERR_X509_INVALID_DATE + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
} |
/* |
* revokedCertificates SEQUENCE OF SEQUENCE { |
* userCertificate CertificateSerialNumber, |
* revocationDate Time, |
* crlEntryExtensions Extensions OPTIONAL |
* -- if present, MUST be v2 |
* } OPTIONAL |
*/ |
if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
/* |
* crlExtensions EXPLICIT Extensions OPTIONAL |
* -- if present, MUST be v2 |
*/ |
if( crl->version == 2 ) |
{ |
ret = x509_get_crl_ext( &p, end, &crl->crl_ext ); |
if( ret != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
} |
if( p != end ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
end = crl->raw.p + crl->raw.len; |
/* |
* signatureAlgorithm AlgorithmIdentifier, |
* signatureValue BIT STRING |
*/ |
if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
if( crl->sig_oid.len != sig_oid2.len || |
memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 || |
sig_params1.len != sig_params2.len || |
( sig_params1.len != 0 && |
memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_SIG_MISMATCH ); |
} |
if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( ret ); |
} |
if( p != end ) |
{ |
mbedtls_x509_crl_free( crl ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
return( 0 ); |
} |
/* |
* Parse one or more CRLs and add them to the chained list |
*/ |
int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ) |
{ |
#if defined(MBEDTLS_PEM_PARSE_C) |
int ret; |
size_t use_len; |
mbedtls_pem_context pem; |
int is_pem = 0; |
if( chain == NULL || buf == NULL ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
do |
{ |
mbedtls_pem_init( &pem ); |
// Avoid calling mbedtls_pem_read_buffer() on non-null-terminated |
// string |
if( buflen == 0 || buf[buflen - 1] != '\0' ) |
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; |
else |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN X509 CRL-----", |
"-----END X509 CRL-----", |
buf, NULL, 0, &use_len ); |
if( ret == 0 ) |
{ |
/* |
* Was PEM encoded |
*/ |
is_pem = 1; |
buflen -= use_len; |
buf += use_len; |
if( ( ret = mbedtls_x509_crl_parse_der( chain, |
pem.buf, pem.buflen ) ) != 0 ) |
{ |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
} |
else if( is_pem ) |
{ |
mbedtls_pem_free( &pem ); |
return( ret ); |
} |
mbedtls_pem_free( &pem ); |
} |
/* In the PEM case, buflen is 1 at the end, for the terminated NULL byte. |
* And a valid CRL cannot be less than 1 byte anyway. */ |
while( is_pem && buflen > 1 ); |
if( is_pem ) |
return( 0 ); |
else |
#endif /* MBEDTLS_PEM_PARSE_C */ |
return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) ); |
} |
#if defined(MBEDTLS_FS_IO) |
/* |
* Load one or more CRLs and add them to the chained list |
*/ |
int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ) |
{ |
int ret; |
size_t n; |
unsigned char *buf; |
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) |
return( ret ); |
ret = mbedtls_x509_crl_parse( chain, buf, n ); |
mbedtls_platform_zeroize( buf, n ); |
mbedtls_free( buf ); |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
/* |
* Return an informational string about the certificate. |
*/ |
#define BEFORE_COLON 14 |
#define BC "14" |
/* |
* Return an informational string about the CRL. |
*/ |
int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, |
const mbedtls_x509_crl *crl ) |
{ |
int ret; |
size_t n; |
char *p; |
const mbedtls_x509_crl_entry *entry; |
p = buf; |
n = size; |
ret = mbedtls_snprintf( p, n, "%sCRL version : %d", |
prefix, crl->version ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_dn_gets( p, n, &crl->issuer ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%sthis update : " \ |
"%04d-%02d-%02d %02d:%02d:%02d", prefix, |
crl->this_update.year, crl->this_update.mon, |
crl->this_update.day, crl->this_update.hour, |
crl->this_update.min, crl->this_update.sec ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%snext update : " \ |
"%04d-%02d-%02d %02d:%02d:%02d", prefix, |
crl->next_update.year, crl->next_update.mon, |
crl->next_update.day, crl->next_update.hour, |
crl->next_update.min, crl->next_update.sec ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
entry = &crl->entry; |
ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:", |
prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
while( entry != NULL && entry->raw.len != 0 ) |
{ |
ret = mbedtls_snprintf( p, n, "\n%sserial number: ", |
prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_serial_gets( p, n, &entry->serial ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, " revocation date: " \ |
"%04d-%02d-%02d %02d:%02d:%02d", |
entry->revocation_date.year, entry->revocation_date.mon, |
entry->revocation_date.day, entry->revocation_date.hour, |
entry->revocation_date.min, entry->revocation_date.sec ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
entry = entry->next; |
} |
ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md, |
crl->sig_opts ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n" ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
return( (int) ( size - n ) ); |
} |
/* |
* Initialize a CRL chain |
*/ |
void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ) |
{ |
memset( crl, 0, sizeof(mbedtls_x509_crl) ); |
} |
/* |
* Unallocate all CRL data |
*/ |
void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ) |
{ |
mbedtls_x509_crl *crl_cur = crl; |
mbedtls_x509_crl *crl_prv; |
mbedtls_x509_name *name_cur; |
mbedtls_x509_name *name_prv; |
mbedtls_x509_crl_entry *entry_cur; |
mbedtls_x509_crl_entry *entry_prv; |
if( crl == NULL ) |
return; |
do |
{ |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
mbedtls_free( crl_cur->sig_opts ); |
#endif |
name_cur = crl_cur->issuer.next; |
while( name_cur != NULL ) |
{ |
name_prv = name_cur; |
name_cur = name_cur->next; |
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); |
mbedtls_free( name_prv ); |
} |
entry_cur = crl_cur->entry.next; |
while( entry_cur != NULL ) |
{ |
entry_prv = entry_cur; |
entry_cur = entry_cur->next; |
mbedtls_platform_zeroize( entry_prv, |
sizeof( mbedtls_x509_crl_entry ) ); |
mbedtls_free( entry_prv ); |
} |
if( crl_cur->raw.p != NULL ) |
{ |
mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len ); |
mbedtls_free( crl_cur->raw.p ); |
} |
crl_cur = crl_cur->next; |
} |
while( crl_cur != NULL ); |
crl_cur = crl; |
do |
{ |
crl_prv = crl_cur; |
crl_cur = crl_cur->next; |
mbedtls_platform_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) ); |
if( crl_prv != crl ) |
mbedtls_free( crl_prv ); |
} |
while( crl_cur != NULL ); |
} |
#endif /* MBEDTLS_X509_CRL_PARSE_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509_crt.c |
---|
0,0 → 1,2732 |
/* |
* X.509 certificate parsing and verification |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The ITU-T X.509 standard defines a certificate format for PKI. |
* |
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) |
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) |
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) |
* |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf |
* |
* [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_CRT_PARSE_C) |
#include "mbedtls/x509_crt.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PEM_PARSE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_free free |
#define mbedtls_calloc calloc |
#define mbedtls_snprintf snprintf |
#endif |
#if defined(MBEDTLS_THREADING_C) |
#include "mbedtls/threading.h" |
#endif |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
#include <windows.h> |
#else |
#include <time.h> |
#endif |
#if defined(MBEDTLS_FS_IO) |
#include <stdio.h> |
#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <dirent.h> |
#endif /* !_WIN32 || EFIX64 || EFI32 */ |
#endif |
/* |
* Item in a verification chain: cert and flags for it |
*/ |
typedef struct { |
mbedtls_x509_crt *crt; |
uint32_t flags; |
} x509_crt_verify_chain_item; |
/* |
* Max size of verification chain: end-entity + intermediates + trusted root |
*/ |
#define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) |
/* |
* Default profile |
*/ |
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = |
{ |
#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) |
/* Allow SHA-1 (weak, but still safe in controlled environments) */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | |
#endif |
/* Only SHA-2 hashes */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), |
0xFFFFFFF, /* Any PK alg */ |
0xFFFFFFF, /* Any curve */ |
2048, |
}; |
/* |
* Next-default profile |
*/ |
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = |
{ |
/* Hashes from SHA-256 and above */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), |
0xFFFFFFF, /* Any PK alg */ |
#if defined(MBEDTLS_ECP_C) |
/* Curves at or above 128-bit security level */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ), |
#else |
0, |
#endif |
2048, |
}; |
/* |
* NSA Suite B Profile |
*/ |
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = |
{ |
/* Only SHA-256 and 384 */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), |
/* Only ECDSA */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), |
#if defined(MBEDTLS_ECP_C) |
/* Only NIST P-256 and P-384 */ |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | |
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), |
#else |
0, |
#endif |
0, |
}; |
/* |
* Check md_alg against profile |
* Return 0 if md_alg is acceptable for this profile, -1 otherwise |
*/ |
static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, |
mbedtls_md_type_t md_alg ) |
{ |
if( md_alg == MBEDTLS_MD_NONE ) |
return( -1 ); |
if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) |
return( 0 ); |
return( -1 ); |
} |
/* |
* Check pk_alg against profile |
* Return 0 if pk_alg is acceptable for this profile, -1 otherwise |
*/ |
static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, |
mbedtls_pk_type_t pk_alg ) |
{ |
if( pk_alg == MBEDTLS_PK_NONE ) |
return( -1 ); |
if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) |
return( 0 ); |
return( -1 ); |
} |
/* |
* Check key against profile |
* Return 0 if pk is acceptable for this profile, -1 otherwise |
*/ |
static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, |
const mbedtls_pk_context *pk ) |
{ |
const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk ); |
#if defined(MBEDTLS_RSA_C) |
if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) |
{ |
if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen ) |
return( 0 ); |
return( -1 ); |
} |
#endif |
#if defined(MBEDTLS_ECP_C) |
if( pk_alg == MBEDTLS_PK_ECDSA || |
pk_alg == MBEDTLS_PK_ECKEY || |
pk_alg == MBEDTLS_PK_ECKEY_DH ) |
{ |
const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; |
if( gid == MBEDTLS_ECP_DP_NONE ) |
return( -1 ); |
if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) |
return( 0 ); |
return( -1 ); |
} |
#endif |
return( -1 ); |
} |
/* |
* Like memcmp, but case-insensitive and always returns -1 if different |
*/ |
static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) |
{ |
size_t i; |
unsigned char diff; |
const unsigned char *n1 = s1, *n2 = s2; |
for( i = 0; i < len; i++ ) |
{ |
diff = n1[i] ^ n2[i]; |
if( diff == 0 ) |
continue; |
if( diff == 32 && |
( ( n1[i] >= 'a' && n1[i] <= 'z' ) || |
( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) |
{ |
continue; |
} |
return( -1 ); |
} |
return( 0 ); |
} |
/* |
* Return 0 if name matches wildcard, -1 otherwise |
*/ |
static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) |
{ |
size_t i; |
size_t cn_idx = 0, cn_len = strlen( cn ); |
/* We can't have a match if there is no wildcard to match */ |
if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) |
return( -1 ); |
for( i = 0; i < cn_len; ++i ) |
{ |
if( cn[i] == '.' ) |
{ |
cn_idx = i; |
break; |
} |
} |
if( cn_idx == 0 ) |
return( -1 ); |
if( cn_len - cn_idx == name->len - 1 && |
x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) |
{ |
return( 0 ); |
} |
return( -1 ); |
} |
/* |
* Compare two X.509 strings, case-insensitive, and allowing for some encoding |
* variations (but not all). |
* |
* Return 0 if equal, -1 otherwise. |
*/ |
static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) |
{ |
if( a->tag == b->tag && |
a->len == b->len && |
memcmp( a->p, b->p, b->len ) == 0 ) |
{ |
return( 0 ); |
} |
if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && |
( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && |
a->len == b->len && |
x509_memcasecmp( a->p, b->p, b->len ) == 0 ) |
{ |
return( 0 ); |
} |
return( -1 ); |
} |
/* |
* Compare two X.509 Names (aka rdnSequence). |
* |
* See RFC 5280 section 7.1, though we don't implement the whole algorithm: |
* we sometimes return unequal when the full algorithm would return equal, |
* but never the other way. (In particular, we don't do Unicode normalisation |
* or space folding.) |
* |
* Return 0 if equal, -1 otherwise. |
*/ |
static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) |
{ |
/* Avoid recursion, it might not be optimised by the compiler */ |
while( a != NULL || b != NULL ) |
{ |
if( a == NULL || b == NULL ) |
return( -1 ); |
/* type */ |
if( a->oid.tag != b->oid.tag || |
a->oid.len != b->oid.len || |
memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) |
{ |
return( -1 ); |
} |
/* value */ |
if( x509_string_cmp( &a->val, &b->val ) != 0 ) |
return( -1 ); |
/* structure of the list of sets */ |
if( a->next_merged != b->next_merged ) |
return( -1 ); |
a = a->next; |
b = b->next; |
} |
/* a == NULL == b */ |
return( 0 ); |
} |
/* |
* Reset (init or clear) a verify_chain |
*/ |
static void x509_crt_verify_chain_reset( |
mbedtls_x509_crt_verify_chain *ver_chain ) |
{ |
size_t i; |
for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ ) |
{ |
ver_chain->items[i].crt = NULL; |
ver_chain->items[i].flags = (uint32_t) -1; |
} |
ver_chain->len = 0; |
} |
/* |
* Version ::= INTEGER { v1(0), v2(1), v3(2) } |
*/ |
static int x509_get_version( unsigned char **p, |
const unsigned char *end, |
int *ver ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
{ |
*ver = 0; |
return( 0 ); |
} |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
end = *p + len; |
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_VERSION + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* Validity ::= SEQUENCE { |
* notBefore Time, |
* notAfter Time } |
*/ |
static int x509_get_dates( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_time *from, |
mbedtls_x509_time *to ) |
{ |
int ret; |
size_t len; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); |
end = *p + len; |
if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 ) |
return( ret ); |
if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 ) |
return( ret ); |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_DATE + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* X.509 v2/v3 unique identifier (not parsed) |
*/ |
static int x509_get_uid( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_buf *uid, int n ) |
{ |
int ret; |
if( *p == end ) |
return( 0 ); |
uid->tag = **p; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
return( 0 ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
uid->p = *p; |
*p += uid->len; |
return( 0 ); |
} |
static int x509_get_basic_constraints( unsigned char **p, |
const unsigned char *end, |
int *ca_istrue, |
int *max_pathlen ) |
{ |
int ret; |
size_t len; |
/* |
* BasicConstraints ::= SEQUENCE { |
* cA BOOLEAN DEFAULT FALSE, |
* pathLenConstraint INTEGER (0..MAX) OPTIONAL } |
*/ |
*ca_istrue = 0; /* DEFAULT FALSE */ |
*max_pathlen = 0; /* endless */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( *p == end ) |
return( 0 ); |
if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
ret = mbedtls_asn1_get_int( p, end, ca_istrue ); |
if( ret != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( *ca_istrue != 0 ) |
*ca_istrue = 1; |
} |
if( *p == end ) |
return( 0 ); |
if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
(*max_pathlen)++; |
return( 0 ); |
} |
static int x509_get_ns_cert_type( unsigned char **p, |
const unsigned char *end, |
unsigned char *ns_cert_type) |
{ |
int ret; |
mbedtls_x509_bitstring bs = { 0, 0, NULL }; |
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( bs.len != 1 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
/* Get actual bitstring */ |
*ns_cert_type = *bs.p; |
return( 0 ); |
} |
static int x509_get_key_usage( unsigned char **p, |
const unsigned char *end, |
unsigned int *key_usage) |
{ |
int ret; |
size_t i; |
mbedtls_x509_bitstring bs = { 0, 0, NULL }; |
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( bs.len < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
/* Get actual bitstring */ |
*key_usage = 0; |
for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) |
{ |
*key_usage |= (unsigned int) bs.p[i] << (8*i); |
} |
return( 0 ); |
} |
/* |
* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId |
* |
* KeyPurposeId ::= OBJECT IDENTIFIER |
*/ |
static int x509_get_ext_key_usage( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_sequence *ext_key_usage) |
{ |
int ret; |
if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
/* Sequence length must be >= 1 */ |
if( ext_key_usage->buf.p == NULL ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_INVALID_LENGTH ); |
return( 0 ); |
} |
/* |
* SubjectAltName ::= GeneralNames |
* |
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName |
* |
* GeneralName ::= CHOICE { |
* otherName [0] OtherName, |
* rfc822Name [1] IA5String, |
* dNSName [2] IA5String, |
* x400Address [3] ORAddress, |
* directoryName [4] Name, |
* ediPartyName [5] EDIPartyName, |
* uniformResourceIdentifier [6] IA5String, |
* iPAddress [7] OCTET STRING, |
* registeredID [8] OBJECT IDENTIFIER } |
* |
* OtherName ::= SEQUENCE { |
* type-id OBJECT IDENTIFIER, |
* value [0] EXPLICIT ANY DEFINED BY type-id } |
* |
* EDIPartyName ::= SEQUENCE { |
* nameAssigner [0] DirectoryString OPTIONAL, |
* partyName [1] DirectoryString } |
* |
* NOTE: we only parse and use dNSName at this point. |
*/ |
static int x509_get_subject_alt_name( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_sequence *subject_alt_name ) |
{ |
int ret; |
size_t len, tag_len; |
mbedtls_asn1_buf *buf; |
unsigned char tag; |
mbedtls_asn1_sequence *cur = subject_alt_name; |
/* Get main sequence tag */ |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( *p + len != end ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
while( *p < end ) |
{ |
if( ( end - *p ) < 1 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); |
tag = **p; |
(*p)++; |
if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != |
MBEDTLS_ASN1_CONTEXT_SPECIFIC ) |
{ |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
} |
/* Skip everything but DNS name */ |
if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) |
{ |
*p += tag_len; |
continue; |
} |
/* Allocate and assign next pointer */ |
if( cur->buf.p != NULL ) |
{ |
if( cur->next != NULL ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); |
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); |
if( cur->next == NULL ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_ALLOC_FAILED ); |
cur = cur->next; |
} |
buf = &(cur->buf); |
buf->tag = tag; |
buf->p = *p; |
buf->len = tag_len; |
*p += buf->len; |
} |
/* Set final sequence entry's next pointer to NULL */ |
cur->next = NULL; |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* X.509 v3 extensions |
* |
*/ |
static int x509_get_crt_ext( unsigned char **p, |
const unsigned char *end, |
mbedtls_x509_crt *crt ) |
{ |
int ret; |
size_t len; |
unsigned char *end_ext_data, *end_ext_octet; |
if( *p == end ) |
return( 0 ); |
if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) |
return( ret ); |
end = crt->v3_ext.p + crt->v3_ext.len; |
while( *p < end ) |
{ |
/* |
* Extension ::= SEQUENCE { |
* extnID OBJECT IDENTIFIER, |
* critical BOOLEAN DEFAULT FALSE, |
* extnValue OCTET STRING } |
*/ |
mbedtls_x509_buf extn_oid = {0, 0, NULL}; |
int is_critical = 0; /* DEFAULT FALSE */ |
int ext_type = 0; |
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
end_ext_data = *p + len; |
/* Get extension ID */ |
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len, |
MBEDTLS_ASN1_OID ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
extn_oid.tag = MBEDTLS_ASN1_OID; |
extn_oid.p = *p; |
*p += extn_oid.len; |
/* Get optional critical */ |
if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && |
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
/* Data should be octet string type */ |
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, |
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); |
end_ext_octet = *p + len; |
if( end_ext_octet != end_ext_data ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
/* |
* Detect supported extensions |
*/ |
ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); |
if( ret != 0 ) |
{ |
/* No parser found, skip extension */ |
*p = end_ext_octet; |
#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) |
if( is_critical ) |
{ |
/* Data is marked as critical: fail */ |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); |
} |
#endif |
continue; |
} |
/* Forbid repeated extensions */ |
if( ( crt->ext_types & ext_type ) != 0 ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); |
crt->ext_types |= ext_type; |
switch( ext_type ) |
{ |
case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: |
/* Parse basic constraints */ |
if( ( ret = x509_get_basic_constraints( p, end_ext_octet, |
&crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) |
return( ret ); |
break; |
case MBEDTLS_X509_EXT_KEY_USAGE: |
/* Parse key usage */ |
if( ( ret = x509_get_key_usage( p, end_ext_octet, |
&crt->key_usage ) ) != 0 ) |
return( ret ); |
break; |
case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: |
/* Parse extended key usage */ |
if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, |
&crt->ext_key_usage ) ) != 0 ) |
return( ret ); |
break; |
case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: |
/* Parse subject alt name */ |
if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, |
&crt->subject_alt_names ) ) != 0 ) |
return( ret ); |
break; |
case MBEDTLS_X509_EXT_NS_CERT_TYPE: |
/* Parse netscape certificate type */ |
if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, |
&crt->ns_cert_type ) ) != 0 ) |
return( ret ); |
break; |
default: |
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); |
} |
} |
if( *p != end ) |
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
return( 0 ); |
} |
/* |
* Parse and fill a single X.509 certificate in DER format |
*/ |
static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf, |
size_t buflen ) |
{ |
int ret; |
size_t len; |
unsigned char *p, *end, *crt_end; |
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; |
memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); |
memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); |
memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); |
/* |
* Check for valid input |
*/ |
if( crt == NULL || buf == NULL ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
// Use the original buffer until we figure out actual length |
p = (unsigned char*) buf; |
len = buflen; |
end = p + len; |
/* |
* Certificate ::= SEQUENCE { |
* tbsCertificate TBSCertificate, |
* signatureAlgorithm AlgorithmIdentifier, |
* signatureValue BIT STRING } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); |
} |
if( len > (size_t) ( end - p ) ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
crt_end = p + len; |
// Create and populate a new buffer for the raw field |
crt->raw.len = crt_end - buf; |
crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); |
if( p == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
memcpy( p, buf, crt->raw.len ); |
// Direct pointers to the new buffer |
p += crt->raw.len - len; |
end = crt_end = p + len; |
/* |
* TBSCertificate ::= SEQUENCE { |
*/ |
crt->tbs.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
end = p + len; |
crt->tbs.len = end - crt->tbs.p; |
/* |
* Version ::= INTEGER { v1(0), v2(1), v3(2) } |
* |
* CertificateSerialNumber ::= INTEGER |
* |
* signature AlgorithmIdentifier |
*/ |
if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || |
( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || |
( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, |
&sig_params1 ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
if( crt->version < 0 || crt->version > 2 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); |
} |
crt->version++; |
if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, |
&crt->sig_md, &crt->sig_pk, |
&crt->sig_opts ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
/* |
* issuer Name |
*/ |
crt->issuer_raw.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
crt->issuer_raw.len = p - crt->issuer_raw.p; |
/* |
* Validity ::= SEQUENCE { |
* notBefore Time, |
* notAfter Time } |
* |
*/ |
if( ( ret = x509_get_dates( &p, end, &crt->valid_from, |
&crt->valid_to ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
/* |
* subject Name |
*/ |
crt->subject_raw.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
crt->subject_raw.len = p - crt->subject_raw.p; |
/* |
* SubjectPublicKeyInfo |
*/ |
if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
/* |
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, |
* -- If present, version shall be v2 or v3 |
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, |
* -- If present, version shall be v2 or v3 |
* extensions [3] EXPLICIT Extensions OPTIONAL |
* -- If present, version shall be v3 |
*/ |
if( crt->version == 2 || crt->version == 3 ) |
{ |
ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); |
if( ret != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
} |
if( crt->version == 2 || crt->version == 3 ) |
{ |
ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); |
if( ret != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
} |
#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) |
if( crt->version == 3 ) |
#endif |
{ |
ret = x509_get_crt_ext( &p, end, crt ); |
if( ret != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
} |
if( p != end ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
end = crt_end; |
/* |
* } |
* -- end of TBSCertificate |
* |
* signatureAlgorithm AlgorithmIdentifier, |
* signatureValue BIT STRING |
*/ |
if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
if( crt->sig_oid.len != sig_oid2.len || |
memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || |
sig_params1.len != sig_params2.len || |
( sig_params1.len != 0 && |
memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_SIG_MISMATCH ); |
} |
if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( ret ); |
} |
if( p != end ) |
{ |
mbedtls_x509_crt_free( crt ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
return( 0 ); |
} |
/* |
* Parse one X.509 certificate in DER format from a buffer and add them to a |
* chained list |
*/ |
int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, |
size_t buflen ) |
{ |
int ret; |
mbedtls_x509_crt *crt = chain, *prev = NULL; |
/* |
* Check for valid input |
*/ |
if( crt == NULL || buf == NULL ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
while( crt->version != 0 && crt->next != NULL ) |
{ |
prev = crt; |
crt = crt->next; |
} |
/* |
* Add new certificate on the end of the chain if needed. |
*/ |
if( crt->version != 0 && crt->next == NULL ) |
{ |
crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); |
if( crt->next == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
prev = crt; |
mbedtls_x509_crt_init( crt->next ); |
crt = crt->next; |
} |
if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) |
{ |
if( prev ) |
prev->next = NULL; |
if( crt != chain ) |
mbedtls_free( crt ); |
return( ret ); |
} |
return( 0 ); |
} |
/* |
* Parse one or more PEM certificates from a buffer and add them to the chained |
* list |
*/ |
int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) |
{ |
#if defined(MBEDTLS_PEM_PARSE_C) |
int success = 0, first_error = 0, total_failed = 0; |
int buf_format = MBEDTLS_X509_FORMAT_DER; |
#endif |
/* |
* Check for valid input |
*/ |
if( chain == NULL || buf == NULL ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
/* |
* Determine buffer content. Buffer contains either one DER certificate or |
* one or more PEM certificates. |
*/ |
#if defined(MBEDTLS_PEM_PARSE_C) |
if( buflen != 0 && buf[buflen - 1] == '\0' && |
strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) |
{ |
buf_format = MBEDTLS_X509_FORMAT_PEM; |
} |
if( buf_format == MBEDTLS_X509_FORMAT_DER ) |
return mbedtls_x509_crt_parse_der( chain, buf, buflen ); |
#else |
return mbedtls_x509_crt_parse_der( chain, buf, buflen ); |
#endif |
#if defined(MBEDTLS_PEM_PARSE_C) |
if( buf_format == MBEDTLS_X509_FORMAT_PEM ) |
{ |
int ret; |
mbedtls_pem_context pem; |
/* 1 rather than 0 since the terminating NULL byte is counted in */ |
while( buflen > 1 ) |
{ |
size_t use_len; |
mbedtls_pem_init( &pem ); |
/* If we get there, we know the string is null-terminated */ |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN CERTIFICATE-----", |
"-----END CERTIFICATE-----", |
buf, NULL, 0, &use_len ); |
if( ret == 0 ) |
{ |
/* |
* Was PEM encoded |
*/ |
buflen -= use_len; |
buf += use_len; |
} |
else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA ) |
{ |
return( ret ); |
} |
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
{ |
mbedtls_pem_free( &pem ); |
/* |
* PEM header and footer were found |
*/ |
buflen -= use_len; |
buf += use_len; |
if( first_error == 0 ) |
first_error = ret; |
total_failed++; |
continue; |
} |
else |
break; |
ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen ); |
mbedtls_pem_free( &pem ); |
if( ret != 0 ) |
{ |
/* |
* Quit parsing on a memory error |
*/ |
if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED ) |
return( ret ); |
if( first_error == 0 ) |
first_error = ret; |
total_failed++; |
continue; |
} |
success = 1; |
} |
} |
if( success ) |
return( total_failed ); |
else if( first_error ) |
return( first_error ); |
else |
return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); |
#endif /* MBEDTLS_PEM_PARSE_C */ |
} |
#if defined(MBEDTLS_FS_IO) |
/* |
* Load one or more certificates and add them to the chained list |
*/ |
int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) |
{ |
int ret; |
size_t n; |
unsigned char *buf; |
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) |
return( ret ); |
ret = mbedtls_x509_crt_parse( chain, buf, n ); |
mbedtls_platform_zeroize( buf, n ); |
mbedtls_free( buf ); |
return( ret ); |
} |
int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) |
{ |
int ret = 0; |
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
int w_ret; |
WCHAR szDir[MAX_PATH]; |
char filename[MAX_PATH]; |
char *p; |
size_t len = strlen( path ); |
WIN32_FIND_DATAW file_data; |
HANDLE hFind; |
if( len > MAX_PATH - 3 ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
memset( szDir, 0, sizeof(szDir) ); |
memset( filename, 0, MAX_PATH ); |
memcpy( filename, path, len ); |
filename[len++] = '\\'; |
p = filename + len; |
filename[len++] = '*'; |
w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, |
MAX_PATH - 3 ); |
if( w_ret == 0 ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
hFind = FindFirstFileW( szDir, &file_data ); |
if( hFind == INVALID_HANDLE_VALUE ) |
return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); |
len = MAX_PATH - len; |
do |
{ |
memset( p, 0, len ); |
if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) |
continue; |
w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, |
lstrlenW( file_data.cFileName ), |
p, (int) len - 1, |
NULL, NULL ); |
if( w_ret == 0 ) |
{ |
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; |
goto cleanup; |
} |
w_ret = mbedtls_x509_crt_parse_file( chain, filename ); |
if( w_ret < 0 ) |
ret++; |
else |
ret += w_ret; |
} |
while( FindNextFileW( hFind, &file_data ) != 0 ); |
if( GetLastError() != ERROR_NO_MORE_FILES ) |
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; |
cleanup: |
FindClose( hFind ); |
#else /* _WIN32 */ |
int t_ret; |
int snp_ret; |
struct stat sb; |
struct dirent *entry; |
char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; |
DIR *dir = opendir( path ); |
if( dir == NULL ) |
return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); |
#if defined(MBEDTLS_THREADING_C) |
if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 ) |
{ |
closedir( dir ); |
return( ret ); |
} |
#endif /* MBEDTLS_THREADING_C */ |
while( ( entry = readdir( dir ) ) != NULL ) |
{ |
snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, |
"%s/%s", path, entry->d_name ); |
if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) |
{ |
ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; |
goto cleanup; |
} |
else if( stat( entry_name, &sb ) == -1 ) |
{ |
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; |
goto cleanup; |
} |
if( !S_ISREG( sb.st_mode ) ) |
continue; |
// Ignore parse errors |
// |
t_ret = mbedtls_x509_crt_parse_file( chain, entry_name ); |
if( t_ret < 0 ) |
ret++; |
else |
ret += t_ret; |
} |
cleanup: |
closedir( dir ); |
#if defined(MBEDTLS_THREADING_C) |
if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) |
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; |
#endif /* MBEDTLS_THREADING_C */ |
#endif /* _WIN32 */ |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
static int x509_info_subject_alt_name( char **buf, size_t *size, |
const mbedtls_x509_sequence *subject_alt_name ) |
{ |
size_t i; |
size_t n = *size; |
char *p = *buf; |
const mbedtls_x509_sequence *cur = subject_alt_name; |
const char *sep = ""; |
size_t sep_len = 0; |
while( cur != NULL ) |
{ |
if( cur->buf.len + sep_len >= n ) |
{ |
*p = '\0'; |
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); |
} |
n -= cur->buf.len + sep_len; |
for( i = 0; i < sep_len; i++ ) |
*p++ = sep[i]; |
for( i = 0; i < cur->buf.len; i++ ) |
*p++ = cur->buf.p[i]; |
sep = ", "; |
sep_len = 2; |
cur = cur->next; |
} |
*p = '\0'; |
*size = n; |
*buf = p; |
return( 0 ); |
} |
#define PRINT_ITEM(i) \ |
{ \ |
ret = mbedtls_snprintf( p, n, "%s" i, sep ); \ |
MBEDTLS_X509_SAFE_SNPRINTF; \ |
sep = ", "; \ |
} |
#define CERT_TYPE(type,name) \ |
if( ns_cert_type & (type) ) \ |
PRINT_ITEM( name ); |
static int x509_info_cert_type( char **buf, size_t *size, |
unsigned char ns_cert_type ) |
{ |
int ret; |
size_t n = *size; |
char *p = *buf; |
const char *sep = ""; |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" ); |
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); |
*size = n; |
*buf = p; |
return( 0 ); |
} |
#define KEY_USAGE(code,name) \ |
if( key_usage & (code) ) \ |
PRINT_ITEM( name ); |
static int x509_info_key_usage( char **buf, size_t *size, |
unsigned int key_usage ) |
{ |
int ret; |
size_t n = *size; |
char *p = *buf; |
const char *sep = ""; |
KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" ); |
KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" ); |
KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" ); |
KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" ); |
KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" ); |
KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" ); |
KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" ); |
KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" ); |
KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" ); |
*size = n; |
*buf = p; |
return( 0 ); |
} |
static int x509_info_ext_key_usage( char **buf, size_t *size, |
const mbedtls_x509_sequence *extended_key_usage ) |
{ |
int ret; |
const char *desc; |
size_t n = *size; |
char *p = *buf; |
const mbedtls_x509_sequence *cur = extended_key_usage; |
const char *sep = ""; |
while( cur != NULL ) |
{ |
if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) |
desc = "???"; |
ret = mbedtls_snprintf( p, n, "%s%s", sep, desc ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
sep = ", "; |
cur = cur->next; |
} |
*size = n; |
*buf = p; |
return( 0 ); |
} |
/* |
* Return an informational string about the certificate. |
*/ |
#define BEFORE_COLON 18 |
#define BC "18" |
int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, |
const mbedtls_x509_crt *crt ) |
{ |
int ret; |
size_t n; |
char *p; |
char key_size_str[BEFORE_COLON]; |
p = buf; |
n = size; |
if( NULL == crt ) |
{ |
ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
return( (int) ( size - n ) ); |
} |
ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", |
prefix, crt->version ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "%sserial number : ", |
prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ |
"%04d-%02d-%02d %02d:%02d:%02d", prefix, |
crt->valid_from.year, crt->valid_from.mon, |
crt->valid_from.day, crt->valid_from.hour, |
crt->valid_from.min, crt->valid_from.sec ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ |
"%04d-%02d-%02d %02d:%02d:%02d", prefix, |
crt->valid_to.year, crt->valid_to.mon, |
crt->valid_to.day, crt->valid_to.hour, |
crt->valid_to.min, crt->valid_to.sec ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk, |
crt->sig_md, crt->sig_opts ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
/* Key size */ |
if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, |
mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) |
{ |
return( ret ); |
} |
ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, |
(int) mbedtls_pk_get_bitlen( &crt->pk ) ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
/* |
* Optional extensions |
*/ |
if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) |
{ |
ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, |
crt->ca_istrue ? "true" : "false" ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
if( crt->max_pathlen > 0 ) |
{ |
ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
} |
} |
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) |
{ |
ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
if( ( ret = x509_info_subject_alt_name( &p, &n, |
&crt->subject_alt_names ) ) != 0 ) |
return( ret ); |
} |
if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) |
{ |
ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) |
return( ret ); |
} |
if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) |
{ |
ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) |
return( ret ); |
} |
if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) |
{ |
ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
if( ( ret = x509_info_ext_key_usage( &p, &n, |
&crt->ext_key_usage ) ) != 0 ) |
return( ret ); |
} |
ret = mbedtls_snprintf( p, n, "\n" ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
return( (int) ( size - n ) ); |
} |
struct x509_crt_verify_string { |
int code; |
const char *string; |
}; |
static const struct x509_crt_verify_string x509_crt_verify_strings[] = { |
{ MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, |
{ MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, |
{ MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, |
{ MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" }, |
{ MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" }, |
{ MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" }, |
{ MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" }, |
{ MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" }, |
{ MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" }, |
{ MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" }, |
{ MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" }, |
{ MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, |
{ MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, |
{ MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, |
{ MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." }, |
{ MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, |
{ MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." }, |
{ MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." }, |
{ MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, |
{ MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, |
{ 0, NULL } |
}; |
int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, |
uint32_t flags ) |
{ |
int ret; |
const struct x509_crt_verify_string *cur; |
char *p = buf; |
size_t n = size; |
for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) |
{ |
if( ( flags & cur->code ) == 0 ) |
continue; |
ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
flags ^= cur->code; |
} |
if( flags != 0 ) |
{ |
ret = mbedtls_snprintf( p, n, "%sUnknown reason " |
"(this should not happen)\n", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
} |
return( (int) ( size - n ) ); |
} |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, |
unsigned int usage ) |
{ |
unsigned int usage_must, usage_may; |
unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY |
| MBEDTLS_X509_KU_DECIPHER_ONLY; |
if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 ) |
return( 0 ); |
usage_must = usage & ~may_mask; |
if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
usage_may = usage & may_mask; |
if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
return( 0 ); |
} |
#endif |
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) |
int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, |
const char *usage_oid, |
size_t usage_len ) |
{ |
const mbedtls_x509_sequence *cur; |
/* Extension is not mandatory, absent means no restriction */ |
if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) |
return( 0 ); |
/* |
* Look for the requested usage (or wildcard ANY) in our list |
*/ |
for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) |
{ |
const mbedtls_x509_buf *cur_oid = &cur->buf; |
if( cur_oid->len == usage_len && |
memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) |
{ |
return( 0 ); |
} |
if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) |
return( 0 ); |
} |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
} |
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ |
#if defined(MBEDTLS_X509_CRL_PARSE_C) |
/* |
* Return 1 if the certificate is revoked, or 0 otherwise. |
*/ |
int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) |
{ |
const mbedtls_x509_crl_entry *cur = &crl->entry; |
while( cur != NULL && cur->serial.len != 0 ) |
{ |
if( crt->serial.len == cur->serial.len && |
memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) |
{ |
if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) |
return( 1 ); |
} |
cur = cur->next; |
} |
return( 0 ); |
} |
/* |
* Check that the given certificate is not revoked according to the CRL. |
* Skip validation if no CRL for the given CA is present. |
*/ |
static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, |
mbedtls_x509_crl *crl_list, |
const mbedtls_x509_crt_profile *profile ) |
{ |
int flags = 0; |
unsigned char hash[MBEDTLS_MD_MAX_SIZE]; |
const mbedtls_md_info_t *md_info; |
if( ca == NULL ) |
return( flags ); |
while( crl_list != NULL ) |
{ |
if( crl_list->version == 0 || |
x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 ) |
{ |
crl_list = crl_list->next; |
continue; |
} |
/* |
* Check if the CA is configured to sign CRLs |
*/ |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
if( mbedtls_x509_crt_check_key_usage( ca, |
MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) |
{ |
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; |
break; |
} |
#endif |
/* |
* Check if CRL is correctly signed by the trusted CA |
*/ |
if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 ) |
flags |= MBEDTLS_X509_BADCRL_BAD_MD; |
if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 ) |
flags |= MBEDTLS_X509_BADCRL_BAD_PK; |
md_info = mbedtls_md_info_from_type( crl_list->sig_md ); |
if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 ) |
{ |
/* Note: this can't happen except after an internal error */ |
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; |
break; |
} |
if( x509_profile_check_key( profile, &ca->pk ) != 0 ) |
flags |= MBEDTLS_X509_BADCERT_BAD_KEY; |
if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, |
crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), |
crl_list->sig.p, crl_list->sig.len ) != 0 ) |
{ |
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; |
break; |
} |
/* |
* Check for validity of CRL (Do not drop out) |
*/ |
if( mbedtls_x509_time_is_past( &crl_list->next_update ) ) |
flags |= MBEDTLS_X509_BADCRL_EXPIRED; |
if( mbedtls_x509_time_is_future( &crl_list->this_update ) ) |
flags |= MBEDTLS_X509_BADCRL_FUTURE; |
/* |
* Check if certificate is revoked |
*/ |
if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) |
{ |
flags |= MBEDTLS_X509_BADCERT_REVOKED; |
break; |
} |
crl_list = crl_list->next; |
} |
return( flags ); |
} |
#endif /* MBEDTLS_X509_CRL_PARSE_C */ |
/* |
* Check the signature of a certificate by its parent |
*/ |
static int x509_crt_check_signature( const mbedtls_x509_crt *child, |
mbedtls_x509_crt *parent, |
mbedtls_x509_crt_restart_ctx *rs_ctx ) |
{ |
const mbedtls_md_info_t *md_info; |
unsigned char hash[MBEDTLS_MD_MAX_SIZE]; |
md_info = mbedtls_md_info_from_type( child->sig_md ); |
if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) |
{ |
/* Note: this can't happen except after an internal error */ |
return( -1 ); |
} |
/* Skip expensive computation on obvious mismatch */ |
if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) ) |
return( -1 ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA ) |
{ |
return( mbedtls_pk_verify_restartable( &parent->pk, |
child->sig_md, hash, mbedtls_md_get_size( md_info ), |
child->sig.p, child->sig.len, &rs_ctx->pk ) ); |
} |
#else |
(void) rs_ctx; |
#endif |
return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, |
child->sig_md, hash, mbedtls_md_get_size( md_info ), |
child->sig.p, child->sig.len ) ); |
} |
/* |
* Check if 'parent' is a suitable parent (signing CA) for 'child'. |
* Return 0 if yes, -1 if not. |
* |
* top means parent is a locally-trusted certificate |
*/ |
static int x509_crt_check_parent( const mbedtls_x509_crt *child, |
const mbedtls_x509_crt *parent, |
int top ) |
{ |
int need_ca_bit; |
/* Parent must be the issuer */ |
if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) |
return( -1 ); |
/* Parent must have the basicConstraints CA bit set as a general rule */ |
need_ca_bit = 1; |
/* Exception: v1/v2 certificates that are locally trusted. */ |
if( top && parent->version < 3 ) |
need_ca_bit = 0; |
if( need_ca_bit && ! parent->ca_istrue ) |
return( -1 ); |
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) |
if( need_ca_bit && |
mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) |
{ |
return( -1 ); |
} |
#endif |
return( 0 ); |
} |
/* |
* Find a suitable parent for child in candidates, or return NULL. |
* |
* Here suitable is defined as: |
* 1. subject name matches child's issuer |
* 2. if necessary, the CA bit is set and key usage allows signing certs |
* 3. for trusted roots, the signature is correct |
* (for intermediates, the signature is checked and the result reported) |
* 4. pathlen constraints are satisfied |
* |
* If there's a suitable candidate which is also time-valid, return the first |
* such. Otherwise, return the first suitable candidate (or NULL if there is |
* none). |
* |
* The rationale for this rule is that someone could have a list of trusted |
* roots with two versions on the same root with different validity periods. |
* (At least one user reported having such a list and wanted it to just work.) |
* The reason we don't just require time-validity is that generally there is |
* only one version, and if it's expired we want the flags to state that |
* rather than NOT_TRUSTED, as would be the case if we required it here. |
* |
* The rationale for rule 3 (signature for trusted roots) is that users might |
* have two versions of the same CA with different keys in their list, and the |
* way we select the correct one is by checking the signature (as we don't |
* rely on key identifier extensions). (This is one way users might choose to |
* handle key rollover, another relies on self-issued certs, see [SIRO].) |
* |
* Arguments: |
* - [in] child: certificate for which we're looking for a parent |
* - [in] candidates: chained list of potential parents |
* - [out] r_parent: parent found (or NULL) |
* - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0 |
* - [in] top: 1 if candidates consists of trusted roots, ie we're at the top |
* of the chain, 0 otherwise |
* - [in] path_cnt: number of intermediates seen so far |
* - [in] self_cnt: number of self-signed intermediates seen so far |
* (will never be greater than path_cnt) |
* - [in-out] rs_ctx: context for restarting operations |
* |
* Return value: |
* - 0 on success |
* - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise |
*/ |
static int x509_crt_find_parent_in( |
mbedtls_x509_crt *child, |
mbedtls_x509_crt *candidates, |
mbedtls_x509_crt **r_parent, |
int *r_signature_is_good, |
int top, |
unsigned path_cnt, |
unsigned self_cnt, |
mbedtls_x509_crt_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_x509_crt *parent, *fallback_parent; |
int signature_is_good, fallback_signature_is_good; |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* did we have something in progress? */ |
if( rs_ctx != NULL && rs_ctx->parent != NULL ) |
{ |
/* restore saved state */ |
parent = rs_ctx->parent; |
fallback_parent = rs_ctx->fallback_parent; |
fallback_signature_is_good = rs_ctx->fallback_signature_is_good; |
/* clear saved state */ |
rs_ctx->parent = NULL; |
rs_ctx->fallback_parent = NULL; |
rs_ctx->fallback_signature_is_good = 0; |
/* resume where we left */ |
goto check_signature; |
} |
#endif |
fallback_parent = NULL; |
fallback_signature_is_good = 0; |
for( parent = candidates; parent != NULL; parent = parent->next ) |
{ |
/* basic parenting skills (name, CA bit, key usage) */ |
if( x509_crt_check_parent( child, parent, top ) != 0 ) |
continue; |
/* +1 because stored max_pathlen is 1 higher that the actual value */ |
if( parent->max_pathlen > 0 && |
(size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) |
{ |
continue; |
} |
/* Signature */ |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
check_signature: |
#endif |
ret = x509_crt_check_signature( child, parent, rs_ctx ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
{ |
/* save state */ |
rs_ctx->parent = parent; |
rs_ctx->fallback_parent = fallback_parent; |
rs_ctx->fallback_signature_is_good = fallback_signature_is_good; |
return( ret ); |
} |
#else |
(void) ret; |
#endif |
signature_is_good = ret == 0; |
if( top && ! signature_is_good ) |
continue; |
/* optional time check */ |
if( mbedtls_x509_time_is_past( &parent->valid_to ) || |
mbedtls_x509_time_is_future( &parent->valid_from ) ) |
{ |
if( fallback_parent == NULL ) |
{ |
fallback_parent = parent; |
fallback_signature_is_good = signature_is_good; |
} |
continue; |
} |
*r_parent = parent; |
*r_signature_is_good = signature_is_good; |
break; |
} |
if( parent == NULL ) |
{ |
*r_parent = fallback_parent; |
*r_signature_is_good = fallback_signature_is_good; |
} |
return( 0 ); |
} |
/* |
* Find a parent in trusted CAs or the provided chain, or return NULL. |
* |
* Searches in trusted CAs first, and return the first suitable parent found |
* (see find_parent_in() for definition of suitable). |
* |
* Arguments: |
* - [in] child: certificate for which we're looking for a parent, followed |
* by a chain of possible intermediates |
* - [in] trust_ca: list of locally trusted certificates |
* - [out] parent: parent found (or NULL) |
* - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0 |
* - [out] signature_is_good: 1 if child signature by parent is valid, or 0 |
* - [in] path_cnt: number of links in the chain so far (EE -> ... -> child) |
* - [in] self_cnt: number of self-signed certs in the chain so far |
* (will always be no greater than path_cnt) |
* - [in-out] rs_ctx: context for restarting operations |
* |
* Return value: |
* - 0 on success |
* - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise |
*/ |
static int x509_crt_find_parent( |
mbedtls_x509_crt *child, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crt **parent, |
int *parent_is_trusted, |
int *signature_is_good, |
unsigned path_cnt, |
unsigned self_cnt, |
mbedtls_x509_crt_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_x509_crt *search_list; |
*parent_is_trusted = 1; |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* restore then clear saved state if we have some stored */ |
if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 ) |
{ |
*parent_is_trusted = rs_ctx->parent_is_trusted; |
rs_ctx->parent_is_trusted = -1; |
} |
#endif |
while( 1 ) { |
search_list = *parent_is_trusted ? trust_ca : child->next; |
ret = x509_crt_find_parent_in( child, search_list, |
parent, signature_is_good, |
*parent_is_trusted, |
path_cnt, self_cnt, rs_ctx ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
{ |
/* save state */ |
rs_ctx->parent_is_trusted = *parent_is_trusted; |
return( ret ); |
} |
#else |
(void) ret; |
#endif |
/* stop here if found or already in second iteration */ |
if( *parent != NULL || *parent_is_trusted == 0 ) |
break; |
/* prepare second iteration */ |
*parent_is_trusted = 0; |
} |
/* extra precaution against mistakes in the caller */ |
if( *parent == NULL ) |
{ |
*parent_is_trusted = 0; |
*signature_is_good = 0; |
} |
return( 0 ); |
} |
/* |
* Check if an end-entity certificate is locally trusted |
* |
* Currently we require such certificates to be self-signed (actually only |
* check for self-issued as self-signatures are not checked) |
*/ |
static int x509_crt_check_ee_locally_trusted( |
mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca ) |
{ |
mbedtls_x509_crt *cur; |
/* must be self-issued */ |
if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 ) |
return( -1 ); |
/* look for an exact match with trusted cert */ |
for( cur = trust_ca; cur != NULL; cur = cur->next ) |
{ |
if( crt->raw.len == cur->raw.len && |
memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 ) |
{ |
return( 0 ); |
} |
} |
/* too bad */ |
return( -1 ); |
} |
/* |
* Build and verify a certificate chain |
* |
* Given a peer-provided list of certificates EE, C1, ..., Cn and |
* a list of trusted certs R1, ... Rp, try to build and verify a chain |
* EE, Ci1, ... Ciq [, Rj] |
* such that every cert in the chain is a child of the next one, |
* jumping to a trusted root as early as possible. |
* |
* Verify that chain and return it with flags for all issues found. |
* |
* Special cases: |
* - EE == Rj -> return a one-element list containing it |
* - EE, Ci1, ..., Ciq cannot be continued with a trusted root |
* -> return that chain with NOT_TRUSTED set on Ciq |
* |
* Tests for (aspects of) this function should include at least: |
* - trusted EE |
* - EE -> trusted root |
* - EE -> intermediate CA -> trusted root |
* - if relevant: EE untrusted |
* - if relevant: EE -> intermediate, untrusted |
* with the aspect under test checked at each relevant level (EE, int, root). |
* For some aspects longer chains are required, but usually length 2 is |
* enough (but length 1 is not in general). |
* |
* Arguments: |
* - [in] crt: the cert list EE, C1, ..., Cn |
* - [in] trust_ca: the trusted list R1, ..., Rp |
* - [in] ca_crl, profile: as in verify_with_profile() |
* - [out] ver_chain: the built and verified chain |
* Only valid when return value is 0, may contain garbage otherwise! |
* Restart note: need not be the same when calling again to resume. |
* - [in-out] rs_ctx: context for restarting operations |
* |
* Return value: |
* - non-zero if the chain could not be fully built and examined |
* - 0 is the chain was successfully built and examined, |
* even if it was found to be invalid |
*/ |
static int x509_crt_verify_chain( |
mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const mbedtls_x509_crt_profile *profile, |
mbedtls_x509_crt_verify_chain *ver_chain, |
mbedtls_x509_crt_restart_ctx *rs_ctx ) |
{ |
/* Don't initialize any of those variables here, so that the compiler can |
* catch potential issues with jumping ahead when restarting */ |
int ret; |
uint32_t *flags; |
mbedtls_x509_crt_verify_chain_item *cur; |
mbedtls_x509_crt *child; |
mbedtls_x509_crt *parent; |
int parent_is_trusted; |
int child_is_trusted; |
int signature_is_good; |
unsigned self_cnt; |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* resume if we had an operation in progress */ |
if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent ) |
{ |
/* restore saved state */ |
*ver_chain = rs_ctx->ver_chain; /* struct copy */ |
self_cnt = rs_ctx->self_cnt; |
/* restore derived state */ |
cur = &ver_chain->items[ver_chain->len - 1]; |
child = cur->crt; |
flags = &cur->flags; |
goto find_parent; |
} |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
child = crt; |
self_cnt = 0; |
parent_is_trusted = 0; |
child_is_trusted = 0; |
while( 1 ) { |
/* Add certificate to the verification chain */ |
cur = &ver_chain->items[ver_chain->len]; |
cur->crt = child; |
cur->flags = 0; |
ver_chain->len++; |
flags = &cur->flags; |
/* Check time-validity (all certificates) */ |
if( mbedtls_x509_time_is_past( &child->valid_to ) ) |
*flags |= MBEDTLS_X509_BADCERT_EXPIRED; |
if( mbedtls_x509_time_is_future( &child->valid_from ) ) |
*flags |= MBEDTLS_X509_BADCERT_FUTURE; |
/* Stop here for trusted roots (but not for trusted EE certs) */ |
if( child_is_trusted ) |
return( 0 ); |
/* Check signature algorithm: MD & PK algs */ |
if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) |
*flags |= MBEDTLS_X509_BADCERT_BAD_MD; |
if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) |
*flags |= MBEDTLS_X509_BADCERT_BAD_PK; |
/* Special case: EE certs that are locally trusted */ |
if( ver_chain->len == 1 && |
x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) |
{ |
return( 0 ); |
} |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
find_parent: |
#endif |
/* Look for a parent in trusted CAs or up the chain */ |
ret = x509_crt_find_parent( child, trust_ca, &parent, |
&parent_is_trusted, &signature_is_good, |
ver_chain->len - 1, self_cnt, rs_ctx ); |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) |
{ |
/* save state */ |
rs_ctx->in_progress = x509_crt_rs_find_parent; |
rs_ctx->self_cnt = self_cnt; |
rs_ctx->ver_chain = *ver_chain; /* struct copy */ |
return( ret ); |
} |
#else |
(void) ret; |
#endif |
/* No parent? We're done here */ |
if( parent == NULL ) |
{ |
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; |
return( 0 ); |
} |
/* Count intermediate self-issued (not necessarily self-signed) certs. |
* These can occur with some strategies for key rollover, see [SIRO], |
* and should be excluded from max_pathlen checks. */ |
if( ver_chain->len != 1 && |
x509_name_cmp( &child->issuer, &child->subject ) == 0 ) |
{ |
self_cnt++; |
} |
/* path_cnt is 0 for the first intermediate CA, |
* and if parent is trusted it's not an intermediate CA */ |
if( ! parent_is_trusted && |
ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) |
{ |
/* return immediately to avoid overflow the chain array */ |
return( MBEDTLS_ERR_X509_FATAL_ERROR ); |
} |
/* signature was checked while searching parent */ |
if( ! signature_is_good ) |
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; |
/* check size of signing key */ |
if( x509_profile_check_key( profile, &parent->pk ) != 0 ) |
*flags |= MBEDTLS_X509_BADCERT_BAD_KEY; |
#if defined(MBEDTLS_X509_CRL_PARSE_C) |
/* Check trusted CA's CRL for the given crt */ |
*flags |= x509_crt_verifycrl( child, parent, ca_crl, profile ); |
#else |
(void) ca_crl; |
#endif |
/* prepare for next iteration */ |
child = parent; |
parent = NULL; |
child_is_trusted = parent_is_trusted; |
signature_is_good = 0; |
} |
} |
/* |
* Check for CN match |
*/ |
static int x509_crt_check_cn( const mbedtls_x509_buf *name, |
const char *cn, size_t cn_len ) |
{ |
/* try exact match */ |
if( name->len == cn_len && |
x509_memcasecmp( cn, name->p, cn_len ) == 0 ) |
{ |
return( 0 ); |
} |
/* try wildcard match */ |
if( x509_check_wildcard( cn, name ) == 0 ) |
{ |
return( 0 ); |
} |
return( -1 ); |
} |
/* |
* Verify the requested CN - only call this if cn is not NULL! |
*/ |
static void x509_crt_verify_name( const mbedtls_x509_crt *crt, |
const char *cn, |
uint32_t *flags ) |
{ |
const mbedtls_x509_name *name; |
const mbedtls_x509_sequence *cur; |
size_t cn_len = strlen( cn ); |
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) |
{ |
for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next ) |
{ |
if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 ) |
break; |
} |
if( cur == NULL ) |
*flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
} |
else |
{ |
for( name = &crt->subject; name != NULL; name = name->next ) |
{ |
if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 && |
x509_crt_check_cn( &name->val, cn, cn_len ) == 0 ) |
{ |
break; |
} |
} |
if( name == NULL ) |
*flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; |
} |
} |
/* |
* Merge the flags for all certs in the chain, after calling callback |
*/ |
static int x509_crt_merge_flags_with_cb( |
uint32_t *flags, |
const mbedtls_x509_crt_verify_chain *ver_chain, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ) |
{ |
int ret; |
unsigned i; |
uint32_t cur_flags; |
const mbedtls_x509_crt_verify_chain_item *cur; |
for( i = ver_chain->len; i != 0; --i ) |
{ |
cur = &ver_chain->items[i-1]; |
cur_flags = cur->flags; |
if( NULL != f_vrfy ) |
if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 ) |
return( ret ); |
*flags |= cur_flags; |
} |
return( 0 ); |
} |
/* |
* Verify the certificate validity (default profile, not restartable) |
*/ |
int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const char *cn, uint32_t *flags, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ) |
{ |
return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl, |
&mbedtls_x509_crt_profile_default, cn, flags, |
f_vrfy, p_vrfy, NULL ) ); |
} |
/* |
* Verify the certificate validity (user-chosen profile, not restartable) |
*/ |
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const mbedtls_x509_crt_profile *profile, |
const char *cn, uint32_t *flags, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy ) |
{ |
return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl, |
profile, cn, flags, f_vrfy, p_vrfy, NULL ) ); |
} |
/* |
* Verify the certificate validity, with profile, restartable version |
* |
* This function: |
* - checks the requested CN (if any) |
* - checks the type and size of the EE cert's key, |
* as that isn't done as part of chain building/verification currently |
* - builds and verifies the chain |
* - then calls the callback and merges the flags |
*/ |
int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, |
mbedtls_x509_crt *trust_ca, |
mbedtls_x509_crl *ca_crl, |
const mbedtls_x509_crt_profile *profile, |
const char *cn, uint32_t *flags, |
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), |
void *p_vrfy, |
mbedtls_x509_crt_restart_ctx *rs_ctx ) |
{ |
int ret; |
mbedtls_pk_type_t pk_type; |
mbedtls_x509_crt_verify_chain ver_chain; |
uint32_t ee_flags; |
*flags = 0; |
ee_flags = 0; |
x509_crt_verify_chain_reset( &ver_chain ); |
if( profile == NULL ) |
{ |
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; |
goto exit; |
} |
/* check name if requested */ |
if( cn != NULL ) |
x509_crt_verify_name( crt, cn, &ee_flags ); |
/* Check the type and size of the key */ |
pk_type = mbedtls_pk_get_type( &crt->pk ); |
if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) |
ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; |
if( x509_profile_check_key( profile, &crt->pk ) != 0 ) |
ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; |
/* Check the chain */ |
ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile, |
&ver_chain, rs_ctx ); |
if( ret != 0 ) |
goto exit; |
/* Merge end-entity flags */ |
ver_chain.items[0].flags |= ee_flags; |
/* Build final flags, calling callback on the way if any */ |
ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy ); |
exit: |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) |
mbedtls_x509_crt_restart_free( rs_ctx ); |
#endif |
/* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by |
* the SSL module for authmode optional, but non-zero return from the |
* callback means a fatal error so it shouldn't be ignored */ |
if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) |
ret = MBEDTLS_ERR_X509_FATAL_ERROR; |
if( ret != 0 ) |
{ |
*flags = (uint32_t) -1; |
return( ret ); |
} |
if( *flags != 0 ) |
return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); |
return( 0 ); |
} |
/* |
* Initialize a certificate chain |
*/ |
void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) |
{ |
memset( crt, 0, sizeof(mbedtls_x509_crt) ); |
} |
/* |
* Unallocate all certificate data |
*/ |
void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) |
{ |
mbedtls_x509_crt *cert_cur = crt; |
mbedtls_x509_crt *cert_prv; |
mbedtls_x509_name *name_cur; |
mbedtls_x509_name *name_prv; |
mbedtls_x509_sequence *seq_cur; |
mbedtls_x509_sequence *seq_prv; |
if( crt == NULL ) |
return; |
do |
{ |
mbedtls_pk_free( &cert_cur->pk ); |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
mbedtls_free( cert_cur->sig_opts ); |
#endif |
name_cur = cert_cur->issuer.next; |
while( name_cur != NULL ) |
{ |
name_prv = name_cur; |
name_cur = name_cur->next; |
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); |
mbedtls_free( name_prv ); |
} |
name_cur = cert_cur->subject.next; |
while( name_cur != NULL ) |
{ |
name_prv = name_cur; |
name_cur = name_cur->next; |
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); |
mbedtls_free( name_prv ); |
} |
seq_cur = cert_cur->ext_key_usage.next; |
while( seq_cur != NULL ) |
{ |
seq_prv = seq_cur; |
seq_cur = seq_cur->next; |
mbedtls_platform_zeroize( seq_prv, |
sizeof( mbedtls_x509_sequence ) ); |
mbedtls_free( seq_prv ); |
} |
seq_cur = cert_cur->subject_alt_names.next; |
while( seq_cur != NULL ) |
{ |
seq_prv = seq_cur; |
seq_cur = seq_cur->next; |
mbedtls_platform_zeroize( seq_prv, |
sizeof( mbedtls_x509_sequence ) ); |
mbedtls_free( seq_prv ); |
} |
if( cert_cur->raw.p != NULL ) |
{ |
mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len ); |
mbedtls_free( cert_cur->raw.p ); |
} |
cert_cur = cert_cur->next; |
} |
while( cert_cur != NULL ); |
cert_cur = crt; |
do |
{ |
cert_prv = cert_cur; |
cert_cur = cert_cur->next; |
mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); |
if( cert_prv != crt ) |
mbedtls_free( cert_prv ); |
} |
while( cert_cur != NULL ); |
} |
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) |
/* |
* Initialize a restart context |
*/ |
void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ) |
{ |
mbedtls_pk_restart_init( &ctx->pk ); |
ctx->parent = NULL; |
ctx->fallback_parent = NULL; |
ctx->fallback_signature_is_good = 0; |
ctx->parent_is_trusted = -1; |
ctx->in_progress = x509_crt_rs_none; |
ctx->self_cnt = 0; |
x509_crt_verify_chain_reset( &ctx->ver_chain ); |
} |
/* |
* Free the components of a restart context |
*/ |
void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_pk_restart_free( &ctx->pk ); |
mbedtls_x509_crt_restart_init( ctx ); |
} |
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ |
#endif /* MBEDTLS_X509_CRT_PARSE_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509_csr.c |
---|
0,0 → 1,421 |
/* |
* X.509 Certificate Signing Request (CSR) parsing |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* The ITU-T X.509 standard defines a certificate format for PKI. |
* |
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) |
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) |
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) |
* |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf |
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_CSR_PARSE_C) |
#include "mbedtls/x509_csr.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PEM_PARSE_C) |
#include "mbedtls/pem.h" |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdlib.h> |
#include <stdio.h> |
#define mbedtls_free free |
#define mbedtls_calloc calloc |
#define mbedtls_snprintf snprintf |
#endif |
#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) |
#include <stdio.h> |
#endif |
/* |
* Version ::= INTEGER { v1(0) } |
*/ |
static int x509_csr_get_version( unsigned char **p, |
const unsigned char *end, |
int *ver ) |
{ |
int ret; |
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) |
{ |
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) |
{ |
*ver = 0; |
return( 0 ); |
} |
return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); |
} |
return( 0 ); |
} |
/* |
* Parse a CSR in DER format |
*/ |
int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, |
const unsigned char *buf, size_t buflen ) |
{ |
int ret; |
size_t len; |
unsigned char *p, *end; |
mbedtls_x509_buf sig_params; |
memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); |
/* |
* Check for valid input |
*/ |
if( csr == NULL || buf == NULL || buflen == 0 ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
mbedtls_x509_csr_init( csr ); |
/* |
* first copy the raw DER data |
*/ |
p = mbedtls_calloc( 1, len = buflen ); |
if( p == NULL ) |
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); |
memcpy( p, buf, buflen ); |
csr->raw.p = p; |
csr->raw.len = len; |
end = p + len; |
/* |
* CertificationRequest ::= SEQUENCE { |
* certificationRequestInfo CertificationRequestInfo, |
* signatureAlgorithm AlgorithmIdentifier, |
* signature BIT STRING |
* } |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); |
} |
if( len != (size_t) ( end - p ) ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
/* |
* CertificationRequestInfo ::= SEQUENCE { |
*/ |
csr->cri.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
end = p + len; |
csr->cri.len = end - csr->cri.p; |
/* |
* Version ::= INTEGER { v1(0) } |
*/ |
if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( ret ); |
} |
if( csr->version != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); |
} |
csr->version++; |
/* |
* subject Name |
*/ |
csr->subject_raw.p = p; |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( ret ); |
} |
csr->subject_raw.len = p - csr->subject_raw.p; |
/* |
* subjectPKInfo SubjectPublicKeyInfo |
*/ |
if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( ret ); |
} |
/* |
* attributes [0] Attributes |
* |
* The list of possible attributes is open-ended, though RFC 2985 |
* (PKCS#9) defines a few in section 5.4. We currently don't support any, |
* so we just ignore them. This is a safe thing to do as the worst thing |
* that could happen is that we issue a certificate that does not match |
* the requester's expectations - this cannot cause a violation of our |
* signature policies. |
*/ |
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, |
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); |
} |
p += len; |
end = csr->raw.p + csr->raw.len; |
/* |
* signatureAlgorithm AlgorithmIdentifier, |
* signature BIT STRING |
*/ |
if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( ret ); |
} |
if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params, |
&csr->sig_md, &csr->sig_pk, |
&csr->sig_opts ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); |
} |
if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( ret ); |
} |
if( p != end ) |
{ |
mbedtls_x509_csr_free( csr ); |
return( MBEDTLS_ERR_X509_INVALID_FORMAT + |
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); |
} |
return( 0 ); |
} |
/* |
* Parse a CSR, allowing for PEM or raw DER encoding |
*/ |
int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) |
{ |
#if defined(MBEDTLS_PEM_PARSE_C) |
int ret; |
size_t use_len; |
mbedtls_pem_context pem; |
#endif |
/* |
* Check for valid input |
*/ |
if( csr == NULL || buf == NULL || buflen == 0 ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
#if defined(MBEDTLS_PEM_PARSE_C) |
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ |
if( buf[buflen - 1] == '\0' ) |
{ |
mbedtls_pem_init( &pem ); |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN CERTIFICATE REQUEST-----", |
"-----END CERTIFICATE REQUEST-----", |
buf, NULL, 0, &use_len ); |
if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
{ |
ret = mbedtls_pem_read_buffer( &pem, |
"-----BEGIN NEW CERTIFICATE REQUEST-----", |
"-----END NEW CERTIFICATE REQUEST-----", |
buf, NULL, 0, &use_len ); |
} |
if( ret == 0 ) |
{ |
/* |
* Was PEM encoded, parse the result |
*/ |
ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ); |
} |
mbedtls_pem_free( &pem ); |
if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) |
return( ret ); |
} |
#endif /* MBEDTLS_PEM_PARSE_C */ |
return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); |
} |
#if defined(MBEDTLS_FS_IO) |
/* |
* Load a CSR into the structure |
*/ |
int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) |
{ |
int ret; |
size_t n; |
unsigned char *buf; |
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) |
return( ret ); |
ret = mbedtls_x509_csr_parse( csr, buf, n ); |
mbedtls_platform_zeroize( buf, n ); |
mbedtls_free( buf ); |
return( ret ); |
} |
#endif /* MBEDTLS_FS_IO */ |
#define BEFORE_COLON 14 |
#define BC "14" |
/* |
* Return an informational string about the CSR. |
*/ |
int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, |
const mbedtls_x509_csr *csr ) |
{ |
int ret; |
size_t n; |
char *p; |
char key_size_str[BEFORE_COLON]; |
p = buf; |
n = size; |
ret = mbedtls_snprintf( p, n, "%sCSR version : %d", |
prefix, csr->version ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_dn_gets( p, n, &csr->subject ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, |
csr->sig_opts ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, |
mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) |
{ |
return( ret ); |
} |
ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, |
(int) mbedtls_pk_get_bitlen( &csr->pk ) ); |
MBEDTLS_X509_SAFE_SNPRINTF; |
return( (int) ( size - n ) ); |
} |
/* |
* Initialize a CSR |
*/ |
void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) |
{ |
memset( csr, 0, sizeof(mbedtls_x509_csr) ); |
} |
/* |
* Unallocate all CSR data |
*/ |
void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) |
{ |
mbedtls_x509_name *name_cur; |
mbedtls_x509_name *name_prv; |
if( csr == NULL ) |
return; |
mbedtls_pk_free( &csr->pk ); |
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) |
mbedtls_free( csr->sig_opts ); |
#endif |
name_cur = csr->subject.next; |
while( name_cur != NULL ) |
{ |
name_prv = name_cur; |
name_cur = name_cur->next; |
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); |
mbedtls_free( name_prv ); |
} |
if( csr->raw.p != NULL ) |
{ |
mbedtls_platform_zeroize( csr->raw.p, csr->raw.len ); |
mbedtls_free( csr->raw.p ); |
} |
mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) ); |
} |
#endif /* MBEDTLS_X509_CSR_PARSE_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509write_crt.c |
---|
0,0 → 1,524 |
/* |
* X.509 certificate writing |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* - certificates: RFC 5280, updated by RFC 6818 |
* - CSRs: PKCS#10 v1.7 aka RFC 2986 |
* - attributes: PKCS#9 v2.0 aka RFC 2985 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_CRT_WRITE_C) |
#include "mbedtls/x509_crt.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/asn1write.h" |
#include "mbedtls/sha1.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_PEM_WRITE_C) |
#include "mbedtls/pem.h" |
#endif /* MBEDTLS_PEM_WRITE_C */ |
/* |
* For the currently used signature algorithms the buffer to store any signature |
* must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) |
*/ |
#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE |
#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN |
#else |
#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE |
#endif |
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); |
mbedtls_mpi_init( &ctx->serial ); |
ctx->version = MBEDTLS_X509_CRT_VERSION_3; |
} |
void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) |
{ |
mbedtls_mpi_free( &ctx->serial ); |
mbedtls_asn1_free_named_data_list( &ctx->subject ); |
mbedtls_asn1_free_named_data_list( &ctx->issuer ); |
mbedtls_asn1_free_named_data_list( &ctx->extensions ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) ); |
} |
void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ) |
{ |
ctx->version = version; |
} |
void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ) |
{ |
ctx->md_alg = md_alg; |
} |
void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ) |
{ |
ctx->subject_key = key; |
} |
void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ) |
{ |
ctx->issuer_key = key; |
} |
int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, |
const char *subject_name ) |
{ |
return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); |
} |
int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, |
const char *issuer_name ) |
{ |
return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); |
} |
int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ) |
{ |
int ret; |
if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 ) |
return( ret ); |
return( 0 ); |
} |
int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, |
const char *not_after ) |
{ |
if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || |
strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ) |
{ |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
} |
strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); |
strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); |
ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; |
ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; |
return( 0 ); |
} |
int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, |
const char *oid, size_t oid_len, |
int critical, |
const unsigned char *val, size_t val_len ) |
{ |
return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, |
critical, val, val_len ); |
} |
int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, |
int is_ca, int max_pathlen ) |
{ |
int ret; |
unsigned char buf[9]; |
unsigned char *c = buf + sizeof(buf); |
size_t len = 0; |
memset( buf, 0, sizeof(buf) ); |
if( is_ca && max_pathlen > 127 ) |
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); |
if( is_ca ) |
{ |
if( max_pathlen >= 0 ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) ); |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), |
0, buf + sizeof(buf) - len, len ); |
} |
#if defined(MBEDTLS_SHA1_C) |
int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) |
{ |
int ret; |
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ |
unsigned char *c = buf + sizeof(buf); |
size_t len = 0; |
memset( buf, 0, sizeof(buf) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); |
ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, |
buf + sizeof( buf ) - 20 ); |
if( ret != 0 ) |
return( ret ); |
c = buf + sizeof( buf ) - 20; |
len = 20; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); |
return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), |
0, buf + sizeof(buf) - len, len ); |
} |
int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) |
{ |
int ret; |
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ |
unsigned char *c = buf + sizeof( buf ); |
size_t len = 0; |
memset( buf, 0, sizeof(buf) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); |
ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, |
buf + sizeof( buf ) - 20 ); |
if( ret != 0 ) |
return( ret ); |
c = buf + sizeof( buf ) - 20; |
len = 20; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), |
0, buf + sizeof( buf ) - len, len ); |
} |
#endif /* MBEDTLS_SHA1_C */ |
static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring, |
size_t bit_offset ) |
{ |
size_t unused_bits; |
/* Count the unused bits removing trailing 0s */ |
for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) |
if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) |
break; |
return( unused_bits ); |
} |
int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, |
unsigned int key_usage ) |
{ |
unsigned char buf[4], ku; |
unsigned char *c; |
int ret; |
size_t unused_bits; |
const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | |
MBEDTLS_X509_KU_NON_REPUDIATION | |
MBEDTLS_X509_KU_KEY_ENCIPHERMENT | |
MBEDTLS_X509_KU_DATA_ENCIPHERMENT | |
MBEDTLS_X509_KU_KEY_AGREEMENT | |
MBEDTLS_X509_KU_KEY_CERT_SIGN | |
MBEDTLS_X509_KU_CRL_SIGN; |
/* Check that nothing other than the allowed flags is set */ |
if( ( key_usage & ~allowed_bits ) != 0 ) |
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); |
c = buf + 4; |
ku = (unsigned char)key_usage; |
unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 ); |
ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits ); |
if( ret < 0 ) |
return( ret ); |
else if( ret < 3 || ret > 4 ) |
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); |
ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), |
1, c, (size_t)ret ); |
if( ret != 0 ) |
return( ret ); |
return( 0 ); |
} |
int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, |
unsigned char ns_cert_type ) |
{ |
unsigned char buf[4]; |
unsigned char *c; |
size_t unused_bits; |
int ret; |
c = buf + 4; |
unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); |
ret = mbedtls_asn1_write_bitstring( &c, |
buf, |
&ns_cert_type, |
8 - unused_bits ); |
if( ret < 3 || ret > 4 ) |
return( ret ); |
ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), |
0, c, (size_t)ret ); |
if( ret != 0 ) |
return( ret ); |
return( 0 ); |
} |
static int x509_write_time( unsigned char **p, unsigned char *start, |
const char *t, size_t size ) |
{ |
int ret; |
size_t len = 0; |
/* |
* write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) |
*/ |
if( t[0] == '2' && t[1] == '0' && t[2] < '5' ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, |
(const unsigned char *) t + 2, |
size - 2 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) ); |
} |
else |
{ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, |
(const unsigned char *) t, |
size ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) ); |
} |
return( (int) len ); |
} |
int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
const char *sig_oid; |
size_t sig_oid_len = 0; |
unsigned char *c, *c2; |
unsigned char hash[64]; |
unsigned char sig[SIGNATURE_MAX_SIZE]; |
unsigned char tmp_buf[2048]; |
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; |
size_t len = 0; |
mbedtls_pk_type_t pk_alg; |
/* |
* Prepare data to be signed in tmp_buf |
*/ |
c = tmp_buf + sizeof( tmp_buf ); |
/* Signature algorithm needed in TBS, and later for actual signature */ |
/* There's no direct way of extracting a signature algorithm |
* (represented as an element of mbedtls_pk_type_t) from a PK instance. */ |
if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) ) |
pk_alg = MBEDTLS_PK_RSA; |
else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) ) |
pk_alg = MBEDTLS_PK_ECDSA; |
else |
return( MBEDTLS_ERR_X509_INVALID_ALG ); |
if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, |
&sig_oid, &sig_oid_len ) ) != 0 ) |
{ |
return( ret ); |
} |
/* |
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension |
*/ |
/* Only for v3 */ |
if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | |
MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); |
} |
/* |
* SubjectPublicKeyInfo |
*/ |
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key, |
tmp_buf, c - tmp_buf ) ); |
c -= pub_len; |
len += pub_len; |
/* |
* Subject ::= Name |
*/ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); |
/* |
* Validity ::= SEQUENCE { |
* notBefore Time, |
* notAfter Time } |
*/ |
sub_len = 0; |
MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, |
MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); |
MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, |
MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); |
len += sub_len; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
/* |
* Issuer ::= Name |
*/ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) ); |
/* |
* Signature ::= AlgorithmIdentifier |
*/ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf, |
sig_oid, strlen( sig_oid ), 0 ) ); |
/* |
* Serial ::= INTEGER |
*/ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); |
/* |
* Version ::= INTEGER { v1(0), v2(1), v3(2) } |
*/ |
/* Can be omitted for v1 */ |
if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 ) |
{ |
sub_len = 0; |
MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) ); |
len += sub_len; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | |
MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
/* |
* Make signature |
*/ |
if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, |
len, hash ) ) != 0 ) |
{ |
return( ret ); |
} |
if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, |
f_rng, p_rng ) ) != 0 ) |
{ |
return( ret ); |
} |
/* |
* Write data to output buffer |
*/ |
c2 = buf + size; |
MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, |
sig_oid, sig_oid_len, sig, sig_len ) ); |
if( len > (size_t)( c2 - buf ) ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
c2 -= len; |
memcpy( c2, c, len ); |
len += sig_and_oid_len; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" |
#define PEM_END_CRT "-----END CERTIFICATE-----\n" |
#if defined(MBEDTLS_PEM_WRITE_C) |
int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
unsigned char output_buf[4096]; |
size_t olen = 0; |
if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf), |
f_rng, p_rng ) ) < 0 ) |
{ |
return( ret ); |
} |
if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, |
output_buf + sizeof(output_buf) - ret, |
ret, buf, size, &olen ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_X509_CRT_WRITE_C */ |
/programs/develop/libraries/kos_mbedtls/library/x509write_csr.c |
---|
0,0 → 1,304 |
/* |
* X.509 Certificate Signing Request writing |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
/* |
* References: |
* - CSRs: PKCS#10 v1.7 aka RFC 2986 |
* - attributes: PKCS#9 v2.0 aka RFC 2985 |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_X509_CSR_WRITE_C) |
#include "mbedtls/x509_csr.h" |
#include "mbedtls/oid.h" |
#include "mbedtls/asn1write.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#include <stdlib.h> |
#if defined(MBEDTLS_PEM_WRITE_C) |
#include "mbedtls/pem.h" |
#endif |
/* |
* For the currently used signature algorithms the buffer to store any signature |
* must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) |
*/ |
#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE |
#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN |
#else |
#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE |
#endif |
void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); |
} |
void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) |
{ |
mbedtls_asn1_free_named_data_list( &ctx->subject ); |
mbedtls_asn1_free_named_data_list( &ctx->extensions ); |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) ); |
} |
void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ) |
{ |
ctx->md_alg = md_alg; |
} |
void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ) |
{ |
ctx->key = key; |
} |
int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, |
const char *subject_name ) |
{ |
return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); |
} |
int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, |
const char *oid, size_t oid_len, |
const unsigned char *val, size_t val_len ) |
{ |
return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, |
0, val, val_len ); |
} |
static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring, |
size_t bit_offset ) |
{ |
size_t unused_bits; |
/* Count the unused bits removing trailing 0s */ |
for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) |
if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) |
break; |
return( unused_bits ); |
} |
int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) |
{ |
unsigned char buf[4]; |
unsigned char *c; |
size_t unused_bits; |
int ret; |
c = buf + 4; |
unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 ); |
ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits ); |
if( ret < 0 ) |
return( ret ); |
else if( ret < 3 || ret > 4 ) |
return( MBEDTLS_ERR_X509_INVALID_FORMAT ); |
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), |
c, (size_t)ret ); |
if( ret != 0 ) |
return( ret ); |
return( 0 ); |
} |
int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, |
unsigned char ns_cert_type ) |
{ |
unsigned char buf[4]; |
unsigned char *c; |
size_t unused_bits; |
int ret; |
c = buf + 4; |
unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); |
ret = mbedtls_asn1_write_bitstring( &c, |
buf, |
&ns_cert_type, |
8 - unused_bits ); |
if( ret < 0 ) |
return( ret ); |
else if( ret < 3 || ret > 4 ) |
return( ret ); |
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), |
c, (size_t)ret ); |
if( ret != 0 ) |
return( ret ); |
return( 0 ); |
} |
int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
const char *sig_oid; |
size_t sig_oid_len = 0; |
unsigned char *c, *c2; |
unsigned char hash[64]; |
unsigned char sig[SIGNATURE_MAX_SIZE]; |
unsigned char tmp_buf[2048]; |
size_t pub_len = 0, sig_and_oid_len = 0, sig_len; |
size_t len = 0; |
mbedtls_pk_type_t pk_alg; |
/* |
* Prepare data to be signed in tmp_buf |
*/ |
c = tmp_buf + sizeof( tmp_buf ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); |
if( len ) |
{ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SET ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, |
MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
} |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); |
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, |
tmp_buf, c - tmp_buf ) ); |
c -= pub_len; |
len += pub_len; |
/* |
* Subject ::= Name |
*/ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); |
/* |
* Version ::= INTEGER { v1(0), v2(1), v3(2) } |
*/ |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
/* |
* Prepare signature |
*/ |
ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); |
if( ret != 0 ) |
return( ret ); |
if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, |
f_rng, p_rng ) ) != 0 ) |
{ |
return( ret ); |
} |
if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) ) |
pk_alg = MBEDTLS_PK_RSA; |
else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) ) |
pk_alg = MBEDTLS_PK_ECDSA; |
else |
return( MBEDTLS_ERR_X509_INVALID_ALG ); |
if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, |
&sig_oid, &sig_oid_len ) ) != 0 ) |
{ |
return( ret ); |
} |
/* |
* Write data to output buffer |
*/ |
c2 = buf + size; |
MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, |
sig_oid, sig_oid_len, sig, sig_len ) ); |
if( len > (size_t)( c2 - buf ) ) |
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); |
c2 -= len; |
memcpy( c2, c, len ); |
len += sig_and_oid_len; |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); |
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | |
MBEDTLS_ASN1_SEQUENCE ) ); |
return( (int) len ); |
} |
#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" |
#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" |
#if defined(MBEDTLS_PEM_WRITE_C) |
int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, |
int (*f_rng)(void *, unsigned char *, size_t), |
void *p_rng ) |
{ |
int ret; |
unsigned char output_buf[4096]; |
size_t olen = 0; |
if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf), |
f_rng, p_rng ) ) < 0 ) |
{ |
return( ret ); |
} |
if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, |
output_buf + sizeof(output_buf) - ret, |
ret, buf, size, &olen ) ) != 0 ) |
{ |
return( ret ); |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_PEM_WRITE_C */ |
#endif /* MBEDTLS_X509_CSR_WRITE_C */ |
/programs/develop/libraries/kos_mbedtls/library/xtea.c |
---|
0,0 → 1,279 |
/* |
* An 32-bit implementation of the XTEA algorithm |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_XTEA_C) |
#include "mbedtls/xtea.h" |
#include "mbedtls/platform_util.h" |
#include <string.h> |
#if defined(MBEDTLS_SELF_TEST) |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#define mbedtls_printf printf |
#endif /* MBEDTLS_PLATFORM_C */ |
#endif /* MBEDTLS_SELF_TEST */ |
#if !defined(MBEDTLS_XTEA_ALT) |
/* |
* 32-bit integer manipulation macros (big endian) |
*/ |
#ifndef GET_UINT32_BE |
#define GET_UINT32_BE(n,b,i) \ |
{ \ |
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \ |
| ( (uint32_t) (b)[(i) + 1] << 16 ) \ |
| ( (uint32_t) (b)[(i) + 2] << 8 ) \ |
| ( (uint32_t) (b)[(i) + 3] ); \ |
} |
#endif |
#ifndef PUT_UINT32_BE |
#define PUT_UINT32_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 |
void mbedtls_xtea_init( mbedtls_xtea_context *ctx ) |
{ |
memset( ctx, 0, sizeof( mbedtls_xtea_context ) ); |
} |
void mbedtls_xtea_free( mbedtls_xtea_context *ctx ) |
{ |
if( ctx == NULL ) |
return; |
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) ); |
} |
/* |
* XTEA key schedule |
*/ |
void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ) |
{ |
int i; |
memset( ctx, 0, sizeof(mbedtls_xtea_context) ); |
for( i = 0; i < 4; i++ ) |
{ |
GET_UINT32_BE( ctx->k[i], key, i << 2 ); |
} |
} |
/* |
* XTEA encrypt function |
*/ |
int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode, |
const unsigned char input[8], unsigned char output[8]) |
{ |
uint32_t *k, v0, v1, i; |
k = ctx->k; |
GET_UINT32_BE( v0, input, 0 ); |
GET_UINT32_BE( v1, input, 4 ); |
if( mode == MBEDTLS_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 /* MBEDTLS_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_UINT32_BE( v0, output, 0 ); |
PUT_UINT32_BE( v1, output, 4 ); |
return( 0 ); |
} |
#if defined(MBEDTLS_CIPHER_MODE_CBC) |
/* |
* XTEA-CBC buffer encryption/decryption |
*/ |
int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length, |
unsigned char iv[8], const unsigned char *input, |
unsigned char *output) |
{ |
int i; |
unsigned char temp[8]; |
if( length % 8 ) |
return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH ); |
if( mode == MBEDTLS_XTEA_DECRYPT ) |
{ |
while( length > 0 ) |
{ |
memcpy( temp, input, 8 ); |
mbedtls_xtea_crypt_ecb( ctx, mode, 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; |
} |
} |
else |
{ |
while( length > 0 ) |
{ |
for( i = 0; i < 8; i++ ) |
output[i] = (unsigned char)( input[i] ^ iv[i] ); |
mbedtls_xtea_crypt_ecb( ctx, mode, output, output ); |
memcpy( iv, output, 8 ); |
input += 8; |
output += 8; |
length -= 8; |
} |
} |
return( 0 ); |
} |
#endif /* MBEDTLS_CIPHER_MODE_CBC */ |
#endif /* !MBEDTLS_XTEA_ALT */ |
#if defined(MBEDTLS_SELF_TEST) |
/* |
* 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 mbedtls_xtea_self_test( int verbose ) |
{ |
int i, ret = 0; |
unsigned char buf[8]; |
mbedtls_xtea_context ctx; |
mbedtls_xtea_init( &ctx ); |
for( i = 0; i < 6; i++ ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( " XTEA test #%d: ", i + 1 ); |
memcpy( buf, xtea_test_pt[i], 8 ); |
mbedtls_xtea_setup( &ctx, xtea_test_key[i] ); |
mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf ); |
if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) |
{ |
if( verbose != 0 ) |
mbedtls_printf( "failed\n" ); |
ret = 1; |
goto exit; |
} |
if( verbose != 0 ) |
mbedtls_printf( "passed\n" ); |
} |
if( verbose != 0 ) |
mbedtls_printf( "\n" ); |
exit: |
mbedtls_xtea_free( &ctx ); |
return( ret ); |
} |
#endif /* MBEDTLS_SELF_TEST */ |
#endif /* MBEDTLS_XTEA_C */ |
/programs/develop/libraries/kos_mbedtls/notes.md |
---|
0,0 → 1,22 |
##### Notes |
- in include/mbedtls/config.h |
- uncommented:\ |
MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES\ |
MBEDTLS_NO_PLATFORM_ENTROPY |
- commented out:\ |
MBEDTLS_TIMING_C\ |
MBEDTLS_FS_IO |
- following functions deleted because they are NOT neccesary for programs/ssl_client1.c |
- mbedtls_net_bind |
- mbedtls_net_accept |
- mbedtls_net_poll |
- mbedtls_net_set_block |
- mbedtls_net_set_nonblock |
- mbedtls_net_usleep |
- mbedtls_net_recv_timeout |
##### Other: |
- Order in which you list libs in ldflags matter ! |
/programs/develop/libraries/kos_mbedtls/programs/random/Makefile |
---|
0,0 → 1,33 |
NEWLIB_INCLUDES=D:\KOSSDK\newlib\libc\include |
APP_DYNAMIC_LDS=D:\KOSSDK\newlib/app-dynamic.lds |
LIBDIR=D:\KOSSDK\kos32-msys-5.4.0\win32\lib |
TARGET_1=gen_entropy |
TARGET_2=gen_random_ctr_drbg |
CC=kos32-gcc |
LD=kos32-ld |
OBJCOPY=kos32-objcopy |
CCFLAGS=-c -fomit-frame-pointer -I $(NEWLIB_INCLUDES) -I../../include -Wall -Wextra |
LDFLAGS=-call_shared -nostdlib --subsystem console -T $(APP_DYNAMIC_LDS) --image-base 0 -L $(LIBDIR) -L ../../library -lmbedtls -lmbedx509 -lmbedcrypto -lgcc -lapp -lc.dll |
all: gen_entropy gen_random_ctr_drbg |
gen_entropy: gen_entropy.o |
$(LD) gen_entropy.o -o $(TARGET_1) $(LDFLAGS) |
$(OBJCOPY) $(TARGET_1) -O binary |
gen_entropy.o: gen_entropy.c |
$(CC) $(CCFLAGS) gen_entropy.c -o gen_entropy.o |
gen_random_ctr_drbg: gen_random_ctr_drbg.o |
$(LD) gen_random_ctr_drbg.o -o $(TARGET_2) $(LDFLAGS) |
$(OBJCOPY) $(TARGET_2) -O binary |
gen_random_ctr_drbg.o: gen_random_ctr_drbg.c |
$(CC) $(CCFLAGS) gen_random_ctr_drbg.c -o gen_random_ctr_drbg.o |
clean: |
del *.o |
del $(TARGET_1) |
del $(TARGET_2) |
/programs/develop/libraries/kos_mbedtls/programs/random/gen_entropy |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/programs/develop/libraries/kos_mbedtls/programs/random/gen_entropy.c |
---|
0,0 → 1,107 |
/** |
* \brief Use and generate multiple entropies calls into a file |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_fprintf fprintf |
#define mbedtls_printf printf |
#define mbedtls_exit exit |
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS |
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE |
#endif /* MBEDTLS_PLATFORM_C */ |
#if defined(MBEDTLS_ENTROPY_C)/* && defined(MBEDTLS_FS_IO)*/ |
#include "mbedtls/entropy.h" |
#include <stdio.h> |
#endif |
#if !defined(MBEDTLS_ENTROPY_C)/* || !defined(MBEDTLS_FS_IO)*/ |
int main( void ) |
{ |
mbedtls_printf("MBEDTLS_ENTROPY_C and/or MBEDTLS_FS_IO not defined.\n"); |
return( 0 ); |
} |
#else |
int main( int argc, char *argv[] ) |
{ |
FILE *f; |
int i, k, ret = 1; |
int exit_code = MBEDTLS_EXIT_FAILURE; |
mbedtls_entropy_context entropy; |
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; |
if( argc < 2 ) |
{ |
//mbedtls_fprintf( stderr, "usage: %s <output filename>\n", argv[0] ); |
mbedtls_printf( "usage: %s <output filename>\n", argv[0] ); |
return( exit_code ); |
} |
if( ( f = fopen( argv[1], "wb+" ) ) == NULL ) |
{ |
mbedtls_printf( "failed to open '%s' for writing.\n", argv[1] ); |
return( exit_code ); |
} |
mbedtls_entropy_init( &entropy ); |
for( i = 0, k = 768; i < k; i++ ) |
{ |
ret = mbedtls_entropy_func( &entropy, buf, sizeof( buf ) ); |
if( ret != 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_entropy_func returned -%04X\n", |
ret ); |
goto cleanup; |
} |
fwrite( buf, 1, sizeof( buf ), f ); |
mbedtls_printf( "Generating %ldkb of data in file '%s'... %04.1f" \ |
"%% done\r", (long)(sizeof(buf) * k / 1024), argv[1], (100 * (float) (i + 1)) / k ); |
fflush( stdout ); |
} |
exit_code = MBEDTLS_EXIT_SUCCESS; |
cleanup: |
mbedtls_printf( "\n" ); |
fclose( f ); |
mbedtls_entropy_free( &entropy ); |
return( exit_code ); |
} |
#endif /* MBEDTLS_ENTROPY_C */ |
/programs/develop/libraries/kos_mbedtls/programs/random/gen_random_ctr_drbg |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/programs/develop/libraries/kos_mbedtls/programs/random/gen_random_ctr_drbg.c |
---|
0,0 → 1,140 |
/** |
* \brief Use and generate random data into a file via the CTR_DBRG based on AES |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_fprintf fprintf |
#define mbedtls_printf printf |
#define mbedtls_exit exit |
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS |
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE |
#endif /* MBEDTLS_PLATFORM_C */ |
#if defined(MBEDTLS_CTR_DRBG_C) && defined(MBEDTLS_ENTROPY_C)/* && \ |
defined(MBEDTLS_FS_IO)*/ |
#include "mbedtls/entropy.h" |
#include "mbedtls/ctr_drbg.h" |
#include <stdio.h> |
#endif |
#if !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_ENTROPY_C)/* || \ |
!defined(MBEDTLS_FS_IO)*/ |
int main( void ) |
{ |
mbedtls_printf("MBEDTLS_CTR_DRBG_C and/or MBEDTLS_ENTROPY_C and/or MBEDTLS_FS_IO not defined.\n"); |
return( 0 ); |
} |
#else |
int main( int argc, char *argv[] ) |
{ |
FILE *f; |
int i, k, ret = 1; |
int exit_code = MBEDTLS_EXIT_FAILURE; |
mbedtls_ctr_drbg_context ctr_drbg; |
mbedtls_entropy_context entropy; |
unsigned char buf[1024]; |
mbedtls_ctr_drbg_init( &ctr_drbg ); |
if( argc < 2 ) |
{ |
//mbedtls_fprintf( stderr, "usage: %s <output filename>\n", argv[0] ); |
mbedtls_printf( "usage: %s <output filename>\n", argv[0] ); |
return( exit_code ); |
} |
if( ( f = fopen( argv[1], "wb+" ) ) == NULL ) |
{ |
mbedtls_printf( "failed to open '%s' for writing.\n", argv[1] ); |
return( exit_code ); |
} |
mbedtls_entropy_init( &entropy ); |
ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) "RANDOM_GEN", 10 ); |
if( ret != 0 ) |
{ |
mbedtls_printf( "failed in mbedtls_ctr_drbg_seed: %d\n", ret ); |
goto cleanup; |
} |
mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF ); |
/*#if defined(MBEDTLS_FS_IO) |
ret = mbedtls_ctr_drbg_update_seed_file( &ctr_drbg, "seedfile" ); |
if( ret == MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ) |
{ |
mbedtls_printf( "Failed to open seedfile. Generating one.\n" ); |
ret = mbedtls_ctr_drbg_write_seed_file( &ctr_drbg, "seedfile" ); |
if( ret != 0 ) |
{ |
mbedtls_printf( "failed in mbedtls_ctr_drbg_write_seed_file: %d\n", ret ); |
goto cleanup; |
} |
} |
else if( ret != 0 ) |
{ |
mbedtls_printf( "failed in mbedtls_ctr_drbg_update_seed_file: %d\n", ret ); |
goto cleanup; |
} |
#endif*/ |
for( i = 0, k = 768; i < k; i++ ) |
{ |
ret = mbedtls_ctr_drbg_random( &ctr_drbg, buf, sizeof( buf ) ); |
if( ret != 0 ) |
{ |
mbedtls_printf("failed!\n"); |
goto cleanup; |
} |
fwrite( buf, 1, sizeof( buf ), f ); |
mbedtls_printf( "Generating %ldkb of data in file '%s'... %04.1f" \ |
"%% done\r", (long)(sizeof(buf) * k / 1024), argv[1], (100 * (float) (i + 1)) / k ); |
fflush( stdout ); |
} |
exit_code = MBEDTLS_EXIT_SUCCESS; |
cleanup: |
mbedtls_printf("\n"); |
fclose( f ); |
mbedtls_ctr_drbg_free( &ctr_drbg ); |
mbedtls_entropy_free( &entropy ); |
return( exit_code ); |
} |
#endif /* MBEDTLS_CTR_DRBG_C && MBEDTLS_ENTROPY_C */ |
/programs/develop/libraries/kos_mbedtls/programs/random/run_img.bat |
---|
0,0 → 1,0 |
qemu-system-i386 -m 256 -fda ../../test_kos_images/kolibri.img -boot a -vga vmware -net nic,model=rtl8139 -net user -soundhw ac97 -usb -usbdevice tablet -drive file=fat:rw:. |
/programs/develop/libraries/kos_mbedtls/programs/ssl/Makefile |
---|
0,0 → 1,24 |
NEWLIB_INCLUDES=D:\KOSSDK\newlib\libc\include |
APP_DYNAMIC_LDS=D:\KOSSDK\newlib/app-dynamic.lds |
LIBDIR=D:\KOSSDK\kos32-msys-5.4.0\win32\lib |
MAIN_TARGET=ssl_client1 |
CC=kos32-gcc |
LD=kos32-ld |
OBJCOPY=kos32-objcopy |
CCFLAGS=-c -fomit-frame-pointer -I $(NEWLIB_INCLUDES) -I../../include -I../../kosnet/include -Wall -Wextra |
LDFLAGS=-call_shared -nostdlib --subsystem console -T $(APP_DYNAMIC_LDS) --image-base 0 -L $(LIBDIR) -L ../../kosnet -L ../../library -lmbedtls -lmbedx509 -lmbedcrypto -lkosnet -lgcc -lapp -lc.dll |
all: ssl_client1 |
ssl_client1: ssl_client1.o |
$(LD) ssl_client1.o -o $(MAIN_TARGET) $(LDFLAGS) |
$(OBJCOPY) $(MAIN_TARGET) -O binary |
ssl_client1.o: ssl_client1.c |
$(CC) $(CCFLAGS) ssl_client1.c -o ssl_client1.o |
clean: |
del *.o |
del $(MAIN_TARGET) |
/programs/develop/libraries/kos_mbedtls/programs/ssl/run_img.bat |
---|
0,0 → 1,0 |
qemu-system-i386 -m 256 -fda ../../test_kos_images/kolibri.img -boot a -vga vmware -net nic,model=rtl8139 -net user -soundhw ac97 -usb -usbdevice tablet -drive file=fat:rw:. |
/programs/develop/libraries/kos_mbedtls/programs/ssl/ssl_client1 |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/programs/develop/libraries/kos_mbedtls/programs/ssl/ssl_client1.c |
---|
0,0 → 1,328 |
/* |
* SSL client demonstration program |
* |
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
* SPDX-License-Identifier: GPL-2.0 |
* |
* 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 file is part of mbed TLS (https://tls.mbed.org) |
*/ |
#if !defined(MBEDTLS_CONFIG_FILE) |
#include "mbedtls/config.h" |
#else |
#include MBEDTLS_CONFIG_FILE |
#endif |
#if defined(MBEDTLS_PLATFORM_C) |
#include "mbedtls/platform.h" |
#else |
#include <stdio.h> |
#include <stdlib.h> |
#define mbedtls_time time |
#define mbedtls_time_t time_t |
#define mbedtls_fprintf fprintf |
#define mbedtls_printf printf |
#define mbedtls_exit exit |
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS |
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE |
#endif /* MBEDTLS_PLATFORM_C */ |
#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \ |
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \ |
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \ |
!defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \ |
!defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) |
int main( void ) |
{ |
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or " |
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or " |
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " |
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C " |
"not defined.\n"); |
return( 0 ); |
} |
#else |
#include "mbedtls/net_sockets.h" |
#include "mbedtls/debug.h" |
#include "mbedtls/ssl.h" |
#include "mbedtls/entropy.h" |
#include "mbedtls/ctr_drbg.h" |
#include "mbedtls/error.h" |
#include "mbedtls/certs.h" |
#include <string.h> |
//#define SERVER_PORT "443" |
//#define SERVER_NAME "wikipedia.org" |
//#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n" |
char SERVER_PORT[16]; |
char SERVER_NAME[128]; |
char GET_REQUEST[512]; |
#define DEBUG_LEVEL 1 |
static void my_debug( void *ctx, int level, |
const char *file, int line, |
const char *str ) |
{ |
((void) level); |
//mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str ); |
//fflush( (FILE *) ctx ); |
printf("%s:%04d: %s", file, line, str ); |
} |
int main( void ) |
{ |
puts("Enter SERVER_NAME : "); |
gets(SERVER_NAME); |
puts("Enter SERVER_PORT : "); |
gets(SERVER_PORT); |
sprintf(GET_REQUEST, "GET / HTTP/1.1\r\nHost: %s\r\n\r\n", SERVER_NAME); |
int ret = 1, len; |
int exit_code = MBEDTLS_EXIT_FAILURE; |
mbedtls_net_context server_fd; |
uint32_t flags; |
unsigned char buf[1024]; |
const char *pers = "ssl_client1"; |
mbedtls_entropy_context entropy; |
mbedtls_ctr_drbg_context ctr_drbg; |
mbedtls_ssl_context ssl; |
mbedtls_ssl_config conf; |
mbedtls_x509_crt cacert; |
#if defined(MBEDTLS_DEBUG_C) |
mbedtls_debug_set_threshold( DEBUG_LEVEL ); |
#endif |
/* |
* 0. Initialize the RNG and the session data |
*/ |
mbedtls_net_init( &server_fd ); |
mbedtls_ssl_init( &ssl ); |
mbedtls_ssl_config_init( &conf ); |
mbedtls_x509_crt_init( &cacert ); |
mbedtls_ctr_drbg_init( &ctr_drbg ); |
mbedtls_printf( "\n . Seeding the random number generator..." ); |
//fflush( stdout ); |
mbedtls_entropy_init( &entropy ); |
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, |
(const unsigned char *) pers, |
strlen( pers ) ) ) != 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); |
goto exit; |
} |
mbedtls_printf( " ok\n" ); |
/* |
* 0. Initialize certificates |
*/ |
mbedtls_printf( " . Loading the CA root certificate ..." ); |
//fflush( stdout ); |
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, |
mbedtls_test_cas_pem_len ); |
if( ret < 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret ); |
goto exit; |
} |
mbedtls_printf( " ok (%d skipped)\n", ret ); |
/* |
* 1. Start the connection |
*/ |
mbedtls_printf( " . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT ); |
//fflush( stdout ); |
if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME, |
SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret ); |
goto exit; |
} |
mbedtls_printf( " ok\n" ); |
/* |
* 2. Setup stuff |
*/ |
mbedtls_printf( " . Setting up the SSL/TLS structure..." ); |
//fflush( stdout ); |
if( ( ret = mbedtls_ssl_config_defaults( &conf, |
MBEDTLS_SSL_IS_CLIENT, |
MBEDTLS_SSL_TRANSPORT_STREAM, |
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); |
goto exit; |
} |
mbedtls_printf( " ok\n" ); |
/* OPTIONAL is not optimal for security, |
* but makes interop easier in this simplified example */ |
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL ); |
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); |
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); |
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); |
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); |
goto exit; |
} |
if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); |
goto exit; |
} |
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL ); |
/* |
* 4. Handshake |
*/ |
mbedtls_printf( " . Performing the SSL/TLS handshake..." ); |
//fflush( stdout ); |
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) |
{ |
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); |
goto exit; |
} |
} |
mbedtls_printf( " ok\n" ); |
/* |
* 5. Verify the server certificate |
*/ |
mbedtls_printf( " . Verifying peer X.509 certificate..." ); |
/* In real life, we probably want to bail out when ret != 0 */ |
if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 ) |
{ |
char vrfy_buf[512]; |
mbedtls_printf( " failed\n" ); |
mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); |
mbedtls_printf( "%s\n", vrfy_buf ); |
} |
else |
mbedtls_printf( " ok\n" ); |
/* |
* 3. Write the GET request |
*/ |
mbedtls_printf( " > Write to server:" ); |
//fflush( stdout ); |
len = sprintf( (char *) buf, GET_REQUEST ); |
while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 ) |
{ |
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) |
{ |
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret ); |
goto exit; |
} |
} |
len = ret; |
mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf ); |
/* |
* 7. Read the HTTP response |
*/ |
mbedtls_printf( " < Read from server:" ); |
//fflush( stdout ); |
do |
{ |
len = sizeof( buf ) - 1; |
memset( buf, 0, sizeof( buf ) ); |
ret = mbedtls_ssl_read( &ssl, buf, len ); |
if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) |
continue; |
if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ) |
break; |
if( ret < 0 ) |
{ |
mbedtls_printf( "failed\n ! mbedtls_ssl_read returned %d\n\n", ret ); |
break; |
} |
if( ret == 0 ) |
{ |
mbedtls_printf( "\n\nEOF\n\n" ); |
break; |
} |
len = ret; |
mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf ); |
} |
while( 1 ); |
mbedtls_ssl_close_notify( &ssl ); |
exit_code = MBEDTLS_EXIT_SUCCESS; |
exit: |
#ifdef MBEDTLS_ERROR_C |
if( exit_code != MBEDTLS_EXIT_SUCCESS ) |
{ |
char error_buf[100]; |
mbedtls_strerror( ret, error_buf, 100 ); |
mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf ); |
} |
#endif |
mbedtls_net_free( &server_fd ); |
mbedtls_x509_crt_free( &cacert ); |
mbedtls_ssl_free( &ssl ); |
mbedtls_ssl_config_free( &conf ); |
mbedtls_ctr_drbg_free( &ctr_drbg ); |
mbedtls_entropy_free( &entropy ); |
return( exit_code ); |
} |
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C && |
MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C && |
MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C && |
MBEDTLS_X509_CRT_PARSE_C */ |
/programs/develop/libraries/kos_mbedtls/test_kos_images/about_image.md |
---|
0,0 → 1,6 |
Test KOS image features: |
- rev 8498 |
- kernel unpacked (to run faster in qemu for windows) |
- kolibrios/ directory with lib/libc.dll (newlib) inside automatically mounts on start |
- DOCKY removed from autorun.dat (cuz its very annoying :D ) |
- removed 3d, demos, games, fnav, kfm, animage, iconedit, etc. to get free space for things above |
/programs/develop/libraries/kos_mbedtls/test_kos_images/kolibri.img |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |