Merge commit '01b34fb316a5' into development
Merge a development version of Mbed TLS 2.16.0 that doesn't have
parameter validation into development.
The following conflicts were resolved:
- Update ChangeLog to include release notes merged from development so
far, with a version of "2.14.0+01b34fb316a5" and release date of
"xxxx-xx-xx" to show this is not a released version, but instead a
snapshot of the development branch equivalent to version of the 2.14.0
with additional commits from the mbedtls/development branch up through
01b34fb316
included. Entries added for unreleased versions of Mbed
Crypto remain at the top of the file for Mbed TLS 2.xx.x.
- Replace the Mbed Crypto version of
mbedtls_rsa_rsaes_pkcs1_v15_decrypt() with the version from Mbed TLS
which fixes timing variations and memory access variations that could
lead to a Bleichenbacher-style padding oracle attack. This will
prevent using psa_asymmetric_decrypt() with zero-length output buffers
until a follow up commit is made to restore this capability.
- In ssl_srv.c, include changes for both the new ECDH interface and
opaque PSK as already added to development previously.
This commit is contained in:
commit
68933640f5
@ -4,6 +4,13 @@ compiler:
|
||||
- gcc
|
||||
sudo: false
|
||||
cache: ccache
|
||||
|
||||
# blocklist
|
||||
branches:
|
||||
except:
|
||||
- development-psa
|
||||
- coverity_scan
|
||||
|
||||
script:
|
||||
- tests/scripts/recursion.pl library/*.c
|
||||
- tests/scripts/check-generated-files.sh
|
||||
@ -34,7 +41,7 @@ addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "ARMmbed/mbedtls"
|
||||
notification_email: p.j.bakker@polarssl.org
|
||||
notification_email: simon.butcher@arm.com
|
||||
build_command_prepend:
|
||||
build_command: make
|
||||
branch_pattern: coverity_scan
|
||||
|
52
ChangeLog
52
ChangeLog
@ -6,6 +6,58 @@ Changes
|
||||
* Add unit tests for AES-GCM when called through mbedtls_cipher_auth_xxx()
|
||||
from the cipher abstraction layer. Fixes #2198.
|
||||
|
||||
= mbed TLS 2.14.0+01b34fb316a5 branch released xxxx-xx-xx
|
||||
|
||||
Security
|
||||
* Fix timing variations and memory access variations in RSA PKCS#1 v1.5
|
||||
decryption that could lead to a Bleichenbacher-style padding oracle
|
||||
attack. In TLS, this affects servers that accept ciphersuites based on
|
||||
RSA decryption (i.e. ciphersuites whose name contains RSA but not
|
||||
(EC)DH(E)). Discovered by Eyal Ronen (Weizmann Institute), Robert Gillham
|
||||
(University of Adelaide), Daniel Genkin (University of Michigan),
|
||||
Adi Shamir (Weizmann Institute), David Wong (NCC Group), and Yuval Yarom
|
||||
(University of Adelaide, Data61). The attack is described in more detail
|
||||
in the paper available here: http://cat.eyalro.net/cat.pdf CVE-2018-19608
|
||||
* In mbedtls_mpi_write_binary(), don't leak the exact size of the number
|
||||
via branching and memory access patterns. An attacker who could submit
|
||||
a plaintext for RSA PKCS#1 v1.5 decryption but only observe the timing
|
||||
of the decryption and not its result could nonetheless decrypt RSA
|
||||
plaintexts and forge RSA signatures. Other asymmetric algorithms may
|
||||
have been similarly vulnerable. Reported by Eyal Ronen, Robert Gillham,
|
||||
Daniel Genkin, Adi Shamir, David Wong and Yuval Yarom.
|
||||
* Wipe sensitive buffers on the stack in the CTR_DRBG and HMAC_DRBG
|
||||
modules.
|
||||
|
||||
API Changes
|
||||
* The following functions in the random generator modules have been
|
||||
deprecated and replaced as shown below. The new functions change
|
||||
the return type from void to int to allow returning error codes when
|
||||
using MBEDTLS_<MODULE>_ALT for the underlying AES or message digest
|
||||
primitive. Fixes #1798.
|
||||
mbedtls_ctr_drbg_update() -> mbedtls_ctr_drbg_update_ret()
|
||||
mbedtls_hmac_drbg_update() -> mbedtls_hmac_drbg_update_ret()
|
||||
* Extend ECDH interface to enable alternative implementations.
|
||||
|
||||
New deprecations
|
||||
* Deprecate mbedtls_ctr_drbg_update and mbedtls_hmac_drbg_update
|
||||
in favor of functions that can return an error code.
|
||||
|
||||
Bugfix
|
||||
* Fix for Clang, which was reporting a warning for the bignum.c inline
|
||||
assembly for AMD64 targets creating string literals greater than those
|
||||
permitted by the ISO C99 standard. Found by Aaron Jones. Fixes #482.
|
||||
* Fix runtime error in `mbedtls_platform_entropy_poll()` when run
|
||||
through qemu user emulation. Reported and fix suggested by randombit
|
||||
in #1212. Fixes #1212.
|
||||
* Fix an unsafe bounds check when restoring an SSL session from a ticket.
|
||||
This could lead to a buffer overflow, but only in case ticket authentication
|
||||
was broken. Reported and fix suggested by Guido Vranken in #659.
|
||||
* Add explicit integer to enumeration type casts to example program
|
||||
programs/pkey/gen_key which previously led to compilation failure
|
||||
on some toolchains. Reported by phoenixmcallister. Fixes #2170.
|
||||
* Fix double initialization of ECC hardware that made some accelerators
|
||||
hang.
|
||||
|
||||
= mbed TLS 2.14.0 branch released 2018-11-19
|
||||
|
||||
Security
|
||||
|
@ -170,19 +170,19 @@
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( \
|
||||
"xorq %%r8, %%r8 \n\t"
|
||||
"xorq %%r8, %%r8\n"
|
||||
|
||||
#define MULADDC_CORE \
|
||||
"movq (%%rsi), %%rax \n\t" \
|
||||
"mulq %%rbx \n\t" \
|
||||
"addq $8, %%rsi \n\t" \
|
||||
"addq %%rcx, %%rax \n\t" \
|
||||
"movq %%r8, %%rcx \n\t" \
|
||||
"adcq $0, %%rdx \n\t" \
|
||||
"nop \n\t" \
|
||||
"addq %%rax, (%%rdi) \n\t" \
|
||||
"adcq %%rdx, %%rcx \n\t" \
|
||||
"addq $8, %%rdi \n\t"
|
||||
"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) \
|
||||
|
@ -114,6 +114,7 @@
|
||||
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
|
||||
@ -137,6 +138,10 @@
|
||||
#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"
|
||||
|
@ -414,11 +414,11 @@
|
||||
* 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_deinit( 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_deinit are
|
||||
* 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.
|
||||
*
|
||||
|
@ -239,18 +239,20 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
/**
|
||||
* \brief This function updates the state of the CTR_DRBG context.
|
||||
*
|
||||
* \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.
|
||||
* \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.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
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
|
||||
@ -290,6 +292,35 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
||||
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.
|
||||
|
@ -65,6 +65,11 @@
|
||||
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 )
|
||||
@ -73,6 +78,7 @@
|
||||
#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 */
|
||||
|
||||
@ -221,6 +227,36 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
|
||||
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
|
||||
|
@ -36,6 +36,18 @@
|
||||
|
||||
#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
|
||||
@ -49,6 +61,39 @@ typedef enum
|
||||
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
|
||||
@ -58,6 +103,7 @@ typedef enum
|
||||
*/
|
||||
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. */
|
||||
@ -70,7 +116,26 @@ typedef struct mbedtls_ecdh_context
|
||||
#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
|
||||
#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;
|
||||
|
||||
@ -134,6 +199,24 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
|
||||
*/
|
||||
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.
|
||||
* \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.
|
||||
*
|
||||
@ -145,8 +228,8 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
|
||||
* \brief This function generates a public key and a TLS
|
||||
* ServerKeyExchange payload.
|
||||
*
|
||||
* This is the first function used by a TLS server for ECDHE
|
||||
* ciphersuites.
|
||||
* This is the second function used by a TLS server for ECDHE
|
||||
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
|
||||
*
|
||||
* \note This function assumes that the ECP group (grp) of the
|
||||
* \p ctx context has already been properly set,
|
||||
@ -242,8 +325,9 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
* \brief This function parses and processes a TLS ClientKeyExchange
|
||||
* payload.
|
||||
*
|
||||
* This is the second function used by a TLS server for ECDH(E)
|
||||
* ciphersuites.
|
||||
* 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
|
||||
*
|
||||
|
@ -159,6 +159,10 @@ mbedtls_ecp_point;
|
||||
* 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
|
||||
{
|
||||
@ -632,7 +636,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_poi
|
||||
/**
|
||||
* \brief This function imports a point from a TLS ECPoint record.
|
||||
*
|
||||
* \note On function return, \p buf is updated to point to immediately
|
||||
* \note On function return, \p *buf is updated to point immediately
|
||||
* after the ECPoint record.
|
||||
*
|
||||
* \param grp The ECP group used.
|
||||
@ -641,7 +645,8 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_poi
|
||||
* \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 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,
|
||||
@ -687,19 +692,39 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id );
|
||||
/**
|
||||
* \brief This function sets a group from a TLS ECParameters record.
|
||||
*
|
||||
* \note \p buf is updated to point right after the ECParameters record
|
||||
* on exit.
|
||||
* \note \p buf is updated to point right after the ECParameters
|
||||
* record on exit.
|
||||
*
|
||||
* \param grp The destination group.
|
||||
* \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 An \c MBEDTLS_ERR_MPI_XXX error code on initialization
|
||||
* failure.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
|
||||
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
|
||||
* recognised.
|
||||
*/
|
||||
int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len );
|
||||
|
||||
/**
|
||||
* \brief This function reads a group from a TLS ECParameters record.
|
||||
*
|
||||
* \note \p buf is updated to point right after the ECParameters
|
||||
* record on exit.
|
||||
*
|
||||
* \param grp Output parameter to hold the group id.
|
||||
* \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 #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
|
||||
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
|
||||
* recognised.
|
||||
*/
|
||||
int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp,
|
||||
const unsigned char **buf, size_t len );
|
||||
/**
|
||||
* \brief This function writes the TLS ECParameters record for a group.
|
||||
*
|
||||
|
@ -195,10 +195,13 @@ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
|
||||
* \param additional Additional data to update state with, or NULL
|
||||
* \param add_len Length of additional data, or 0
|
||||
*
|
||||
* \return \c 0 on success, or an error from the underlying
|
||||
* hash calculation.
|
||||
*
|
||||
* \note Additional data is optional, pass NULL and 0 as second
|
||||
* third argument if no additional data is being used.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
|
||||
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
|
||||
/**
|
||||
@ -257,6 +260,31 @@ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len
|
||||
*/
|
||||
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 HMAC_DRBG update state
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_hmac_drbg_update_ret()
|
||||
* in 2.16.0.
|
||||
*
|
||||
* \param ctx HMAC_DRBG context
|
||||
* \param additional Additional data to update state with, or NULL
|
||||
* \param add_len Length of additional data, or 0
|
||||
*
|
||||
* \note Additional data is optional, pass NULL and 0 as second
|
||||
* third argument if no additional data is being used.
|
||||
*/
|
||||
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 Write a seed file
|
||||
|
@ -46,6 +46,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
|
||||
/**
|
||||
* \brief PKCS12 Password Based function (encryption / decryption)
|
||||
* for pbeWithSHAAnd128BitRC4
|
||||
@ -87,6 +89,8 @@ int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
|
||||
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".
|
||||
|
@ -44,6 +44,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBES2 function
|
||||
*
|
||||
@ -62,6 +64,8 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *data, size_t datalen,
|
||||
unsigned char *output );
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBKDF2 using HMAC
|
||||
*
|
||||
|
@ -232,19 +232,34 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
|
||||
size_t buflen );
|
||||
|
||||
/**
|
||||
* \brief Parse 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.
|
||||
* \brief Parse one DER-encoded or one or more concatenated PEM-encoded
|
||||
* certificates and add them to the chained list.
|
||||
*
|
||||
* \param chain points to the start of the chain
|
||||
* \param buf buffer holding the certificate data in PEM or DER format
|
||||
* \param buflen size of the buffer
|
||||
* (including the terminating null byte for PEM data)
|
||||
* 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.
|
||||
*
|
||||
* \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( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );
|
||||
|
||||
|
@ -331,14 +331,36 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
|
||||
return( (int) len );
|
||||
}
|
||||
|
||||
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head,
|
||||
|
||||
/* 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 = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
|
||||
if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
|
||||
{
|
||||
// Add new entry if not present yet based on OID
|
||||
//
|
||||
|
@ -321,6 +321,10 @@ int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
|
||||
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
|
||||
*/
|
||||
@ -704,19 +708,40 @@ cleanup:
|
||||
/*
|
||||
* Export X into unsigned binary data, big endian
|
||||
*/
|
||||
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen )
|
||||
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
|
||||
unsigned char *buf, size_t buflen )
|
||||
{
|
||||
size_t i, j, n;
|
||||
size_t stored_bytes = X->n * ciL;
|
||||
size_t bytes_to_copy;
|
||||
unsigned char *p;
|
||||
size_t i;
|
||||
|
||||
n = mbedtls_mpi_size( X );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
if( buflen < n )
|
||||
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
|
||||
|
||||
memset( buf, 0, buflen );
|
||||
|
||||
for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
|
||||
buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
|
||||
for( i = 0; i < bytes_to_copy; i++ )
|
||||
p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -299,9 +299,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
|
||||
* Crypt counter block
|
||||
*/
|
||||
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
@ -313,12 +311,12 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
|
||||
* Update key and counter
|
||||
*/
|
||||
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
|
||||
|
||||
return( 0 );
|
||||
exit:
|
||||
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
|
||||
@ -333,23 +331,39 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
|
||||
* and with outputs
|
||||
* ctx = initial_working_state
|
||||
*/
|
||||
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len )
|
||||
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 )
|
||||
{
|
||||
/* 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;
|
||||
if( add_len == 0 )
|
||||
return( 0 );
|
||||
|
||||
block_cipher_df( add_input, additional, add_len );
|
||||
ctr_drbg_update_internal( ctx, add_input );
|
||||
}
|
||||
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
|
||||
@ -399,20 +413,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
* Reduce to 384 bits
|
||||
*/
|
||||
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
/*
|
||||
* Update state
|
||||
*/
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
ctx->reseed_counter = 1;
|
||||
|
||||
return( 0 );
|
||||
exit:
|
||||
mbedtls_platform_zeroize( seed, sizeof( seed ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
|
||||
@ -467,13 +479,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
||||
if( add_len > 0 )
|
||||
{
|
||||
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while( output_len > 0 )
|
||||
@ -489,9 +497,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
||||
* Crypt counter block
|
||||
*/
|
||||
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
|
||||
output_len;
|
||||
@ -504,12 +510,13 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
||||
}
|
||||
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
ctx->reseed_counter++;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
|
||||
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -561,35 +568,36 @@ exit:
|
||||
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *f;
|
||||
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 );
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
n = (size_t) ftell( f );
|
||||
fseek( f, 0, SEEK_SET );
|
||||
|
||||
if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
|
||||
n = fread( buf, 1, sizeof( buf ), f );
|
||||
if( fread( &c, 1, 1, f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( fread( buf, 1, n, f ) != n )
|
||||
if( n == 0 || ferror( f ) )
|
||||
{
|
||||
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
|
||||
else
|
||||
mbedtls_ctr_drbg_update( ctx, buf, n );
|
||||
|
||||
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 */
|
||||
|
@ -365,4 +365,54 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
|
||||
}
|
||||
#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 */
|
||||
|
388
library/ecdh.c
388
library/ecdh.c
@ -38,6 +38,10 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
|
||||
/*
|
||||
* Generate public key (restartable version)
|
||||
@ -124,43 +128,84 @@ int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
|
||||
}
|
||||
#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
|
||||
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
|
||||
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 );
|
||||
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
|
||||
mbedtls_ecp_point_init( &ctx->Vi );
|
||||
mbedtls_ecp_point_init( &ctx->Vf );
|
||||
mbedtls_mpi_init( &ctx->_d );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
ctx->restart_enabled = 0;
|
||||
mbedtls_ecp_restart_init( &ctx->rs );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Free context
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
|
||||
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
|
||||
{
|
||||
#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 )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#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 );
|
||||
mbedtls_ecp_point_free( &ctx->Vi );
|
||||
mbedtls_ecp_point_free( &ctx->Vf );
|
||||
mbedtls_mpi_free( &ctx->_d );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
mbedtls_ecp_restart_free( &ctx->rs );
|
||||
@ -173,21 +218,50 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
|
||||
*/
|
||||
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
ctx->restart_enabled = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup and write the ServerKeyExhange parameters (RFC 4492)
|
||||
* struct {
|
||||
* ECParameters curve_params;
|
||||
* ECPoint public;
|
||||
* } ServerECDHParams;
|
||||
* Free context
|
||||
*/
|
||||
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 )
|
||||
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;
|
||||
@ -195,12 +269,14 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
|
||||
#endif
|
||||
|
||||
if( ctx == NULL || ctx->grp.pbits == 0 )
|
||||
if( ctx->grp.pbits == 0 )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( ctx->restart_enabled )
|
||||
if( restart_enabled )
|
||||
rs_ctx = &ctx->rs;
|
||||
#else
|
||||
(void) restart_enabled;
|
||||
#endif
|
||||
|
||||
|
||||
@ -214,14 +290,14 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
|
||||
!= 0 )
|
||||
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, ctx->point_format,
|
||||
if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format,
|
||||
&pt_len, buf, blen ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
@ -229,6 +305,54 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
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;
|
||||
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#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 {
|
||||
@ -237,31 +361,42 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
* } ServerECDHParams;
|
||||
*/
|
||||
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
|
||||
const unsigned char **buf, const unsigned char *end )
|
||||
const unsigned char **buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
|
||||
if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
|
||||
!= 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
|
||||
!= 0 )
|
||||
if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
#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
|
||||
}
|
||||
|
||||
/*
|
||||
* Get parameters from a keypair
|
||||
*/
|
||||
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
|
||||
mbedtls_ecdh_side side )
|
||||
static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||
const mbedtls_ecp_keypair *key,
|
||||
mbedtls_ecdh_side side )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
|
||||
return( 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 ) );
|
||||
@ -278,29 +413,61 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypai
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup and export the client public value
|
||||
* Get parameters from a keypair
|
||||
*/
|
||||
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 mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
|
||||
const mbedtls_ecp_keypair *key,
|
||||
mbedtls_ecdh_side side )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
#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 == NULL || ctx->grp.pbits == 0 )
|
||||
if( ctx->grp.pbits == 0 )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( ctx->restart_enabled )
|
||||
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 )
|
||||
f_rng, p_rng, rs_ctx ) ) != 0 )
|
||||
return( ret );
|
||||
#else
|
||||
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
|
||||
@ -308,23 +475,52 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
|
||||
olen, buf, blen );
|
||||
return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen,
|
||||
buf, blen );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and import the client's public value
|
||||
* Setup and export the client public value
|
||||
*/
|
||||
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
|
||||
const unsigned char *buf, size_t blen )
|
||||
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 ret;
|
||||
const unsigned char *p = buf;
|
||||
int restart_enabled = 0;
|
||||
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
|
||||
#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 )
|
||||
@ -334,12 +530,36 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
|
||||
}
|
||||
|
||||
/*
|
||||
* Derive and export the shared secret
|
||||
* Parse and import the client's public value
|
||||
*/
|
||||
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 mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
|
||||
const unsigned char *buf, size_t blen )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#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)
|
||||
@ -350,13 +570,16 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( ctx->restart_enabled )
|
||||
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 )
|
||||
if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp,
|
||||
&ctx->d, f_rng, p_rng,
|
||||
rs_ctx ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
@ -375,4 +598,37 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
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;
|
||||
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
#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 */
|
||||
|
@ -47,6 +47,35 @@
|
||||
#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"
|
||||
@ -645,7 +674,7 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two points lazyly
|
||||
* Compare two points lazily
|
||||
*/
|
||||
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
|
||||
const mbedtls_ecp_point *Q )
|
||||
@ -833,7 +862,24 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp
|
||||
/*
|
||||
* 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 mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
|
||||
const unsigned char **buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
|
||||
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;
|
||||
@ -860,7 +906,9 @@ int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **bu
|
||||
if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL )
|
||||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||
|
||||
return mbedtls_ecp_group_load( grp, curve_info->grp_id );
|
||||
*grp = curve_info->grp_id;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2393,11 +2441,6 @@ int mbedtls_ecp_muladd_restartable(
|
||||
|
||||
mbedtls_ecp_point_init( &mP );
|
||||
|
||||
#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 */
|
||||
|
||||
ECP_RS_ENTER( ma );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
@ -2425,6 +2468,12 @@ int mbedtls_ecp_muladd_restartable(
|
||||
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;
|
||||
|
@ -99,6 +99,7 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len
|
||||
#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 )
|
||||
{
|
||||
@ -108,47 +109,8 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
|
||||
memset( buf, 0, buflen );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return( syscall( SYS_getrandom, buf, buflen, flags ) );
|
||||
}
|
||||
|
||||
#include <sys/utsname.h>
|
||||
/* Check if version is at least 3.17.0 */
|
||||
static int check_version_3_17_plus( void )
|
||||
{
|
||||
int minor;
|
||||
struct utsname un;
|
||||
const char *ver;
|
||||
|
||||
/* Get version information */
|
||||
uname(&un);
|
||||
ver = un.release;
|
||||
|
||||
/* Check major version; assume a single digit */
|
||||
if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
|
||||
return( -1 );
|
||||
|
||||
if( ver[0] - '0' > 3 )
|
||||
return( 0 );
|
||||
|
||||
/* Ok, so now we know major == 3, check minor.
|
||||
* Assume 1 or 2 digits. */
|
||||
if( ver[2] < '0' || ver[2] > '9' )
|
||||
return( -1 );
|
||||
|
||||
minor = ver[2] - '0';
|
||||
|
||||
if( ver[3] >= '0' && ver[3] <= '9' )
|
||||
minor = 10 * minor + ver[3] - '0';
|
||||
else if( ver [3] != '.' )
|
||||
return( -1 );
|
||||
|
||||
if( minor < 17 )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
static int has_getrandom = -1;
|
||||
#endif /* SYS_getrandom */
|
||||
#endif /* __linux__ */
|
||||
|
||||
@ -159,22 +121,21 @@ int mbedtls_platform_entropy_poll( void *data,
|
||||
{
|
||||
FILE *file;
|
||||
size_t read_len;
|
||||
int ret;
|
||||
((void) data);
|
||||
|
||||
#if defined(HAVE_GETRANDOM)
|
||||
if( has_getrandom == -1 )
|
||||
has_getrandom = ( check_version_3_17_plus() == 0 );
|
||||
|
||||
if( has_getrandom )
|
||||
ret = getrandom_wrapper( output, len, 0 );
|
||||
if( ret >= 0 )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
|
||||
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
||||
|
||||
*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;
|
||||
|
@ -66,31 +66,60 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
|
||||
/*
|
||||
* HMAC_DRBG update, using optional additional data (10.1.2.2)
|
||||
*/
|
||||
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len )
|
||||
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 */
|
||||
mbedtls_md_hmac_reset( &ctx->md_ctx );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
|
||||
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 )
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
|
||||
mbedtls_md_hmac_finish( &ctx->md_ctx, K );
|
||||
{
|
||||
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 */
|
||||
mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
|
||||
mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
|
||||
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)
|
||||
*/
|
||||
@ -108,10 +137,13 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
|
||||
* 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.
|
||||
*/
|
||||
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) );
|
||||
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 ) );
|
||||
|
||||
mbedtls_hmac_drbg_update( ctx, data, data_len );
|
||||
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -124,6 +156,7 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
{
|
||||
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
|
||||
size_t seedlen;
|
||||
int ret;
|
||||
|
||||
/* III. Check input length */
|
||||
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
|
||||
@ -135,7 +168,8 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
|
||||
|
||||
/* IV. Gather entropy_len bytes of entropy for the seed */
|
||||
if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
|
||||
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;
|
||||
@ -148,13 +182,16 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
}
|
||||
|
||||
/* 2. Update state */
|
||||
mbedtls_hmac_drbg_update( ctx, seed, seedlen );
|
||||
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
/* 3. Reset reseed_counter */
|
||||
ctx->reseed_counter = 1;
|
||||
|
||||
exit:
|
||||
/* 4. Done */
|
||||
return( 0 );
|
||||
mbedtls_platform_zeroize( seed, seedlen );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -180,7 +217,8 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
||||
* 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.
|
||||
*/
|
||||
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size );
|
||||
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;
|
||||
@ -273,16 +311,24 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
|
||||
|
||||
/* 2. Use additional data if any */
|
||||
if( additional != NULL && add_len != 0 )
|
||||
mbedtls_hmac_drbg_update( ctx, additional, add_len );
|
||||
{
|
||||
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;
|
||||
|
||||
mbedtls_md_hmac_reset( &ctx->md_ctx );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
|
||||
mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
|
||||
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;
|
||||
@ -290,13 +336,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
|
||||
}
|
||||
|
||||
/* 6. Update */
|
||||
mbedtls_hmac_drbg_update( ctx, additional, add_len );
|
||||
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( 0 );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -368,35 +417,36 @@ exit:
|
||||
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *f;
|
||||
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 );
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
n = (size_t) ftell( f );
|
||||
fseek( f, 0, SEEK_SET );
|
||||
|
||||
if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
|
||||
n = fread( buf, 1, sizeof( buf ), f );
|
||||
if( fread( &c, 1, 1, f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( fread( buf, 1, n, f ) != n )
|
||||
if( n == 0 || ferror( f ) )
|
||||
{
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||
else
|
||||
mbedtls_hmac_drbg_update( ctx, buf, n );
|
||||
|
||||
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 */
|
||||
|
@ -48,6 +48,8 @@
|
||||
#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 )
|
||||
{
|
||||
@ -226,6 +228,8 @@ exit:
|
||||
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 )
|
||||
{
|
||||
|
@ -54,22 +54,7 @@
|
||||
#define mbedtls_printf printf
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ASN1_PARSE_C)
|
||||
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 )
|
||||
{
|
||||
((void) pbe_params);
|
||||
((void) mode);
|
||||
((void) pwd);
|
||||
((void) pwdlen);
|
||||
((void) data);
|
||||
((void) datalen);
|
||||
((void) output);
|
||||
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
#else
|
||||
#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 )
|
||||
|
242
library/rsa.c
242
library/rsa.c
@ -1392,6 +1392,97 @@ cleanup:
|
||||
#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
|
||||
*/
|
||||
@ -1401,18 +1492,34 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len)
|
||||
size_t output_max_len )
|
||||
{
|
||||
int ret;
|
||||
size_t ilen, pad_count = 0, i;
|
||||
unsigned char *p, bad, pad_done = 0;
|
||||
size_t ilen = ctx->len;
|
||||
size_t i;
|
||||
size_t plaintext_max_size = ( output_max_len > ilen - 11 ?
|
||||
ilen - 11 :
|
||||
output_max_len );
|
||||
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;
|
||||
|
||||
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ilen = ctx->len;
|
||||
|
||||
if( ilen < 16 || ilen > sizeof( buf ) )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
@ -1423,64 +1530,109 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
|
||||
if( ret != 0 )
|
||||
goto cleanup;
|
||||
|
||||
p = buf;
|
||||
bad = 0;
|
||||
/* Check and get padding length in constant time and constant
|
||||
* memory trace. The first byte must be 0. */
|
||||
bad |= buf[0];
|
||||
|
||||
/*
|
||||
* Check and get padding len in "constant-time"
|
||||
*/
|
||||
bad |= *p++; /* First byte must be 0 */
|
||||
|
||||
/* This test does not depend on secret data */
|
||||
if( mode == MBEDTLS_RSA_PRIVATE )
|
||||
{
|
||||
bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
|
||||
/* 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;
|
||||
|
||||
/* Get padding len, but always read till end of buffer
|
||||
* (minus one, for the 00 byte) */
|
||||
for( i = 0; i < ilen - 3; i++ )
|
||||
/* 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 |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
|
||||
pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
|
||||
pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
|
||||
}
|
||||
|
||||
p += pad_count;
|
||||
bad |= *p++; /* Must be zero */
|
||||
}
|
||||
else
|
||||
{
|
||||
bad |= *p++ ^ MBEDTLS_RSA_SIGN;
|
||||
/* 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;
|
||||
|
||||
/* Get padding len, but always read till end of buffer
|
||||
* (minus one, for the 00 byte) */
|
||||
for( i = 0; i < ilen - 3; i++ )
|
||||
/* 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 |= ( p[i] != 0xFF );
|
||||
pad_count += ( pad_done == 0 );
|
||||
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 );
|
||||
}
|
||||
|
||||
p += pad_count;
|
||||
bad |= *p++; /* Must be zero */
|
||||
}
|
||||
|
||||
bad |= ( pad_count < 8 );
|
||||
/* If pad_done is still zero, there's no data, only unfinished padding. */
|
||||
bad |= if_int( pad_done, 0, 1 );
|
||||
|
||||
if( bad )
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
goto cleanup;
|
||||
}
|
||||
/* There must be at least 8 bytes of padding. */
|
||||
bad |= size_greater_than( 8, pad_count );
|
||||
|
||||
if( ilen - ( p - buf ) > output_max_len )
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
|
||||
goto cleanup;
|
||||
}
|
||||
/* 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 ) );
|
||||
|
||||
*olen = ilen - (p - buf);
|
||||
if( *olen != 0 )
|
||||
memcpy( output, p, *olen );
|
||||
ret = 0;
|
||||
/* 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 ) );
|
||||
|
@ -2074,8 +2074,14 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
|
||||
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( ssl->handshake->ecdh_ctx.grp.id );
|
||||
curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
|
||||
if( curve_info == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||
@ -2085,14 +2091,15 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 )
|
||||
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_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_QP );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -3014,7 +3021,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_Q );
|
||||
|
||||
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
|
||||
if( ssl->handshake->ecrs_enabled )
|
||||
@ -3041,7 +3049,8 @@ ecdh_calc_secret:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_Z );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
|
||||
@ -3156,7 +3165,8 @@ ecdh_calc_secret:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_Q );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
|
@ -3088,8 +3088,8 @@ curve_matching_done:
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
|
||||
|
||||
if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp,
|
||||
(*curve)->grp_id ) ) != 0 )
|
||||
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 );
|
||||
@ -3111,7 +3111,8 @@ curve_matching_done:
|
||||
|
||||
ssl->out_msglen += len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_Q );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
|
||||
|
||||
@ -3832,7 +3833,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
|
||||
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,
|
||||
@ -3844,7 +3846,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_Z );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
|
||||
@ -3982,7 +3985,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
|
||||
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 )
|
||||
|
@ -217,9 +217,9 @@ static int ssl_save_session( const mbedtls_ssl_session *session,
|
||||
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 );
|
||||
*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 );
|
||||
@ -244,14 +244,14 @@ static int ssl_load_session( mbedtls_ssl_session *session,
|
||||
size_t cert_len;
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
if( p + sizeof( mbedtls_ssl_session ) > end )
|
||||
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( p + 3 > end )
|
||||
if( 3 > (size_t)( end - p ) )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
|
||||
@ -265,7 +265,7 @@ static int ssl_load_session( mbedtls_ssl_session *session,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( p + cert_len > end )
|
||||
if( cert_len > (size_t)( end - p ) )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
|
||||
@ -276,7 +276,7 @@ static int ssl_load_session( mbedtls_ssl_session *session,
|
||||
mbedtls_x509_crt_init( session->peer_cert );
|
||||
|
||||
if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
|
||||
p, cert_len ) ) != 0 )
|
||||
p, cert_len ) ) != 0 )
|
||||
{
|
||||
mbedtls_x509_crt_free( session->peer_cert );
|
||||
mbedtls_free( session->peer_cert );
|
||||
|
@ -1499,7 +1499,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
|
||||
*(p++) = (unsigned char)( zlen );
|
||||
p += zlen;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
|
||||
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
|
||||
MBEDTLS_DEBUG_ECDH_Z );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
@ -3366,8 +3367,10 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
|
||||
}
|
||||
}
|
||||
|
||||
if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
|
||||
hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST &&
|
||||
/* 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" ) );
|
||||
@ -3461,8 +3464,8 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
|
||||
/* 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 ) )
|
||||
! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
|
||||
hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
|
||||
{
|
||||
if( ( ret = ssl_flight_append( ssl ) ) != 0 )
|
||||
{
|
||||
|
@ -2203,7 +2203,7 @@ static int x509_crt_find_parent(
|
||||
}
|
||||
|
||||
/* extra precaution against mistakes in the caller */
|
||||
if( parent == NULL )
|
||||
if( *parent == NULL )
|
||||
{
|
||||
*parent_is_trusted = 0;
|
||||
*signature_is_good = 0;
|
||||
|
@ -35,12 +35,12 @@
|
||||
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
|
||||
#if !defined(MBEDTLS_ECDH_C) || \
|
||||
#if !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) || \
|
||||
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
|
||||
!defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
|
||||
int main( void )
|
||||
{
|
||||
mbedtls_printf( "MBEDTLS_ECDH_C and/or "
|
||||
mbedtls_printf( "MBEDTLS_ECDH_C and/or MBEDTLS_ECDH_LEGACY_CONTEXT and/or "
|
||||
"MBEDTLS_ECP_DP_CURVE25519_ENABLED and/or "
|
||||
"MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
|
||||
"not defined\n" );
|
||||
|
@ -322,7 +322,8 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_printf( "\n . Generating the private key ..." );
|
||||
fflush( stdout );
|
||||
|
||||
if( ( ret = mbedtls_pk_setup( &key, mbedtls_pk_info_from_type( opt.type ) ) ) != 0 )
|
||||
if( ( ret = mbedtls_pk_setup( &key,
|
||||
mbedtls_pk_info_from_type( (mbedtls_pk_type_t) opt.type ) ) ) != 0 )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! mbedtls_pk_setup returned -0x%04x", -ret );
|
||||
goto exit;
|
||||
@ -344,7 +345,8 @@ int main( int argc, char *argv[] )
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
if( opt.type == MBEDTLS_PK_ECKEY )
|
||||
{
|
||||
ret = mbedtls_ecp_gen_key( opt.ec_curve, mbedtls_pk_ec( key ),
|
||||
ret = mbedtls_ecp_gen_key( (mbedtls_ecp_group_id) opt.ec_curve,
|
||||
mbedtls_pk_ec( key ),
|
||||
mbedtls_ctr_drbg_random, &ctr_drbg );
|
||||
if( ret != 0 )
|
||||
{
|
||||
|
@ -87,10 +87,12 @@
|
||||
USAGE_OUT \
|
||||
"\n"
|
||||
|
||||
#if !defined(MBEDTLS_PK_WRITE_C) || !defined(MBEDTLS_FS_IO)
|
||||
#if !defined(MBEDTLS_PK_PARSE_C) || \
|
||||
!defined(MBEDTLS_PK_WRITE_C) || \
|
||||
!defined(MBEDTLS_FS_IO)
|
||||
int main( void )
|
||||
{
|
||||
mbedtls_printf( "MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
|
||||
mbedtls_printf( "MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
@ -433,4 +435,4 @@ exit:
|
||||
|
||||
return( exit_code );
|
||||
}
|
||||
#endif /* MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
|
||||
#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
|
||||
|
@ -862,7 +862,7 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_C)
|
||||
#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
if( todo.ecdh )
|
||||
{
|
||||
mbedtls_ecdh_context ecdh;
|
||||
|
@ -46,3 +46,4 @@ run_test ./tests/scripts/check-doxy-blocks.pl
|
||||
run_test ./tests/scripts/check-names.sh
|
||||
run_test ./tests/scripts/check-generated-files.sh
|
||||
run_test ./tests/scripts/check-files.py
|
||||
run_test ./tests/scripts/doxygen.sh
|
||||
|
@ -76,7 +76,7 @@ TEST_OUTPUT=out_${PPID}
|
||||
cd tests
|
||||
|
||||
# Step 2a - Unit Tests
|
||||
perl scripts/run-test-suites.pl -v |tee unit-test-$TEST_OUTPUT
|
||||
perl scripts/run-test-suites.pl -v 2 |tee unit-test-$TEST_OUTPUT
|
||||
echo
|
||||
|
||||
# Step 2b - System Tests
|
||||
|
@ -43,11 +43,14 @@ class IssueTracker(object):
|
||||
for i, line in enumerate(iter(f.readline, b"")):
|
||||
self.check_file_line(filepath, line, i + 1)
|
||||
|
||||
def record_issue(self, filepath, line_number):
|
||||
if filepath not in self.files_with_issues.keys():
|
||||
self.files_with_issues[filepath] = []
|
||||
self.files_with_issues[filepath].append(line_number)
|
||||
|
||||
def check_file_line(self, filepath, line, line_number):
|
||||
if self.issue_with_line(line):
|
||||
if filepath not in self.files_with_issues.keys():
|
||||
self.files_with_issues[filepath] = []
|
||||
self.files_with_issues[filepath].append(line_number)
|
||||
self.record_issue(filepath, line_number)
|
||||
|
||||
def output_file_issues(self, logger):
|
||||
if self.files_with_issues.values():
|
||||
@ -132,13 +135,36 @@ class TabIssueTracker(IssueTracker):
|
||||
return b"\t" in line
|
||||
|
||||
|
||||
class MergeArtifactIssueTracker(IssueTracker):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.heading = "Merge artifact:"
|
||||
|
||||
def issue_with_line(self, filepath, line):
|
||||
# Detect leftover git conflict markers.
|
||||
if line.startswith(b'<<<<<<< ') or line.startswith(b'>>>>>>> '):
|
||||
return True
|
||||
if line.startswith(b'||||||| '): # from merge.conflictStyle=diff3
|
||||
return True
|
||||
if line.rstrip(b'\r\n') == b'=======' and \
|
||||
not filepath.endswith('.md'):
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_file_line(self, filepath, line, line_number):
|
||||
if self.issue_with_line(filepath, line):
|
||||
self.record_issue(filepath, line_number)
|
||||
|
||||
class TodoIssueTracker(IssueTracker):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.heading = "TODO present:"
|
||||
self.files_exemptions = [
|
||||
__file__, "benchmark.c", "pull_request_template.md"
|
||||
os.path.basename(__file__),
|
||||
"benchmark.c",
|
||||
"pull_request_template.md",
|
||||
]
|
||||
|
||||
def issue_with_line(self, line):
|
||||
@ -167,6 +193,7 @@ class IntegrityChecker(object):
|
||||
LineEndingIssueTracker(),
|
||||
TrailingWhitespaceIssueTracker(),
|
||||
TabIssueTracker(),
|
||||
MergeArtifactIssueTracker(),
|
||||
TodoIssueTracker(),
|
||||
]
|
||||
|
||||
|
@ -185,7 +185,7 @@ class MbedTlsTest(BaseHostTest):
|
||||
binary_path = self.get_config_item('image_path')
|
||||
script_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
suite_name = os.path.splitext(os.path.basename(binary_path))[0]
|
||||
data_file = ".".join((suite_name, 'data'))
|
||||
data_file = ".".join((suite_name, 'datax'))
|
||||
data_file = os.path.join(script_dir, '..', 'mbedtls',
|
||||
suite_name, data_file)
|
||||
if os.path.exists(data_file):
|
||||
|
@ -24,14 +24,10 @@ use strict;
|
||||
use utf8;
|
||||
use open qw(:std utf8);
|
||||
|
||||
use constant FALSE => 0;
|
||||
use constant TRUE => 1;
|
||||
use Getopt::Long;
|
||||
|
||||
my $verbose;
|
||||
my $switch = shift;
|
||||
if ( defined($switch) && ( $switch eq "-v" || $switch eq "--verbose" ) ) {
|
||||
$verbose = TRUE;
|
||||
}
|
||||
my $verbose = 0;
|
||||
GetOptions( "verbose|v:1" => \$verbose );
|
||||
|
||||
# All test suites = executable files, excluding source files, debug
|
||||
# and profiling information, etc. We can't just grep {! /\./} because
|
||||
@ -50,10 +46,20 @@ my ($failed_suites, $total_tests_run, $failed, $suite_cases_passed,
|
||||
$suite_cases_failed, $suite_cases_skipped, $total_cases_passed,
|
||||
$total_cases_failed, $total_cases_skipped );
|
||||
|
||||
sub pad_print_center {
|
||||
my( $width, $padchar, $string ) = @_;
|
||||
my $padlen = ( $width - length( $string ) - 2 ) / 2;
|
||||
print $padchar x( $padlen ), " $string ", $padchar x( $padlen ), "\n";
|
||||
}
|
||||
|
||||
for my $suite (@suites)
|
||||
{
|
||||
print "$suite ", "." x ( 72 - length($suite) - 2 - 4 ), " ";
|
||||
my $result = `$prefix$suite`;
|
||||
my $command = "$prefix$suite";
|
||||
if( $verbose ) {
|
||||
$command .= ' -v';
|
||||
}
|
||||
my $result = `$command`;
|
||||
|
||||
$suite_cases_passed = () = $result =~ /.. PASS/g;
|
||||
$suite_cases_failed = () = $result =~ /.. FAILED/g;
|
||||
@ -61,15 +67,25 @@ for my $suite (@suites)
|
||||
|
||||
if( $result =~ /PASSED/ ) {
|
||||
print "PASS\n";
|
||||
if( $verbose > 2 ) {
|
||||
pad_print_center( 72, '-', "Begin $suite" );
|
||||
print $result;
|
||||
pad_print_center( 72, '-', "End $suite" );
|
||||
}
|
||||
} else {
|
||||
$failed_suites++;
|
||||
print "FAIL\n";
|
||||
if( $verbose ) {
|
||||
pad_print_center( 72, '-', "Begin $suite" );
|
||||
print $result;
|
||||
pad_print_center( 72, '-', "End $suite" );
|
||||
}
|
||||
}
|
||||
|
||||
my ($passed, $tests, $skipped) = $result =~ /([0-9]*) \/ ([0-9]*) tests.*?([0-9]*) skipped/;
|
||||
$total_tests_run += $tests - $skipped;
|
||||
|
||||
if ( $verbose ) {
|
||||
if( $verbose > 1 ) {
|
||||
print "(test cases passed:", $suite_cases_passed,
|
||||
" failed:", $suite_cases_failed,
|
||||
" skipped:", $suite_cases_skipped,
|
||||
@ -87,7 +103,7 @@ print "-" x 72, "\n";
|
||||
print $failed_suites ? "FAILED" : "PASSED";
|
||||
printf " (%d suites, %d tests run)\n", scalar @suites, $total_tests_run;
|
||||
|
||||
if ( $verbose ) {
|
||||
if( $verbose > 1 ) {
|
||||
print " test cases passed :", $total_cases_passed, "\n";
|
||||
print " failed :", $total_cases_failed, "\n";
|
||||
print " skipped :", $total_cases_skipped, "\n";
|
||||
|
@ -78,7 +78,7 @@ void mbedtls_asn1_write_ia5_string( char * str, data_t * asn1,
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_C */
|
||||
void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
|
||||
int result )
|
||||
{
|
||||
|
@ -244,9 +244,11 @@ void ctr_drbg_entropy_usage( )
|
||||
}
|
||||
TEST_ASSERT( last_idx == test_offset_idx );
|
||||
|
||||
/* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
|
||||
* (just make sure it doesn't cause memory corruption) */
|
||||
mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) );
|
||||
/* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
|
||||
* Make sure it's detected as an error and doesn't cause memory
|
||||
* corruption. */
|
||||
TEST_ASSERT( mbedtls_ctr_drbg_update_ret(
|
||||
&ctx, entropy, sizeof( entropy ) ) != 0 );
|
||||
|
||||
/* Now enable PR, so the next few calls should all reseed */
|
||||
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
|
||||
|
@ -69,3 +69,7 @@ ecdh_restart:MBEDTLS_ECP_DP_SECP256R1:"C88F01F510D9AC3F70A292DAA2316DE544E9AAB8A
|
||||
ECDH restartable rfc 5903 p256 restart disabled max_ops=250
|
||||
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
ecdh_restart:MBEDTLS_ECP_DP_SECP256R1:"C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433":"C6EF9C5D78AE012A011164ACB397CE2088685D8F06BF9BE0B283AB46476BEE53":"D6840F6B42F6EDAFD13116E0E12565202FEF8E9ECE7DCE03812464D04B9442DE":0:250:0:0
|
||||
|
||||
ECDH exchange legacy context
|
||||
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
ecdh_exchange_legacy:MBEDTLS_ECP_DP_SECP192R1
|
||||
|
@ -129,27 +129,31 @@ void ecdh_exchange( int id )
|
||||
const unsigned char *vbuf;
|
||||
size_t len;
|
||||
rnd_pseudo_info rnd_info;
|
||||
unsigned char res_buf[1000];
|
||||
size_t res_len;
|
||||
|
||||
mbedtls_ecdh_init( &srv );
|
||||
mbedtls_ecdh_init( &cli );
|
||||
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
||||
|
||||
TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 );
|
||||
|
||||
memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
|
||||
TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000,
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
|
||||
|
||||
memset( buf, 0x00, sizeof( buf ) );
|
||||
TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000,
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
|
||||
|
||||
TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000,
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &len, buf, 1000, NULL, NULL ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &res_len, res_buf, 1000,
|
||||
NULL, NULL ) == 0 );
|
||||
TEST_ASSERT( len == res_len );
|
||||
TEST_ASSERT( memcmp( buf, res_buf, len ) == 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_ecdh_free( &srv );
|
||||
@ -172,7 +176,9 @@ void ecdh_restart( int id, char *dA_str, char *dB_str, char *z_str,
|
||||
unsigned char rnd_buf_B[MBEDTLS_ECP_MAX_BYTES];
|
||||
rnd_buf_info rnd_info_A, rnd_info_B;
|
||||
int cnt_restart;
|
||||
mbedtls_ecp_group grp;
|
||||
|
||||
mbedtls_ecp_group_init( &grp );
|
||||
mbedtls_ecdh_init( &srv );
|
||||
mbedtls_ecdh_init( &cli );
|
||||
|
||||
@ -184,16 +190,20 @@ void ecdh_restart( int id, char *dA_str, char *dB_str, char *z_str,
|
||||
rnd_info_B.buf = rnd_buf_B;
|
||||
rnd_info_B.length = unhexify( rnd_buf_B, dB_str );
|
||||
|
||||
TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
|
||||
/* The ECDH context is not guaranteed ot have an mbedtls_ecp_group structure
|
||||
* in every configuration, therefore we load it separately. */
|
||||
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
|
||||
|
||||
/* otherwise we would have to fix the random buffer,
|
||||
* as in ecdh_primitive_test_vec */
|
||||
TEST_ASSERT( srv.grp.nbits % 8 == 0 );
|
||||
/* Otherwise we would have to fix the random buffer,
|
||||
* as in ecdh_primitive_testvec. */
|
||||
TEST_ASSERT( grp.nbits % 8 == 0 );
|
||||
|
||||
TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 );
|
||||
|
||||
/* set up restart parameters */
|
||||
mbedtls_ecp_set_max_ops( max_ops );
|
||||
|
||||
if( enable)
|
||||
if( enable )
|
||||
{
|
||||
mbedtls_ecdh_enable_restart( &srv );
|
||||
mbedtls_ecdh_enable_restart( &cli );
|
||||
@ -268,6 +278,45 @@ void ecdh_restart( int id, char *dA_str, char *dB_str, char *z_str,
|
||||
TEST_ASSERT( len == z_len );
|
||||
TEST_ASSERT( memcmp( buf, z, len ) == 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_ecp_group_free( &grp );
|
||||
mbedtls_ecdh_free( &srv );
|
||||
mbedtls_ecdh_free( &cli );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ECDH_LEGACY_CONTEXT */
|
||||
void ecdh_exchange_legacy( int id )
|
||||
{
|
||||
mbedtls_ecdh_context srv, cli;
|
||||
unsigned char buf[1000];
|
||||
const unsigned char *vbuf;
|
||||
size_t len;
|
||||
|
||||
rnd_pseudo_info rnd_info;
|
||||
|
||||
mbedtls_ecdh_init( &srv );
|
||||
mbedtls_ecdh_init( &cli );
|
||||
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
||||
|
||||
TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
|
||||
|
||||
memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
|
||||
TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000,
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
|
||||
|
||||
memset( buf, 0x00, sizeof( buf ) );
|
||||
TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000,
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
|
||||
|
||||
TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000,
|
||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &len, buf, 1000, NULL,
|
||||
NULL ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_ecdh_free( &srv );
|
||||
mbedtls_ecdh_free( &cli );
|
||||
|
@ -14,7 +14,7 @@ void ecdsa_prim_random( int id )
|
||||
mbedtls_ecp_point Q;
|
||||
mbedtls_mpi d, r, s;
|
||||
rnd_pseudo_info rnd_info;
|
||||
unsigned char buf[66];
|
||||
unsigned char buf[MBEDTLS_MD_MAX_SIZE];
|
||||
|
||||
mbedtls_ecp_group_init( &grp );
|
||||
mbedtls_ecp_point_init( &Q );
|
||||
|
@ -33,3 +33,93 @@ pkcs1_rsassa_v15_sign:1024:16:"d17f655bf27c8b16d35462c905cc04a26f37e2a67fa9c0ce0
|
||||
|
||||
RSASSA-V15 Verification Test Vector Int
|
||||
pkcs1_rsassa_v15_verify:1024:16:"a2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5":16:"010001":MBEDTLS_MD_SHA1:MBEDTLS_MD_SHA1:"859eef2fd78aca00308bdc471193bf55bf9d78db8f8a672b484634f3c9c26e6478ae10260fe0dd8c082e53a5293af2173cd50c6d5d354febf78b26021c25c02712e78cd4694c9f469777e451e7f8e9e04cd3739c6bbfedae487fb55644e9ca74ff77a53cb729802f6ed4a5ffa8ba159890fc":"e3b5d5d002c1bce50c2b65ef88a188d83bce7e61":"2154f928615e5101fcdeb57bc08fc2f35c3d5996403861ae3efb1d0712f8bb05cc21f7f5f11f62e5b6ea9f0f2b62180e5cbe7ba535032d6ac8068fff7f362f73d2c3bf5eca6062a1723d7cfd5abb6dcf7e405f2dc560ffe6fc37d38bee4dc9e24fe2bece3e3b4a3f032701d3f0947b42930083dd4ad241b3309b514595482d42":0
|
||||
|
||||
RSAES-V15 decoding: good, payload=max, tight output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505152535455565700":117:117:0
|
||||
|
||||
RSAES-V15 decoding: good, payload=max, larger output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505152535455565700":117:128:0
|
||||
|
||||
RSAES-V15 decoding: good, payload=max-1, tight output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000250515253545556575800":116:116:0
|
||||
|
||||
RSAES-V15 decoding: good, payload=max-1, larger output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000250515253545556575800":116:117:0
|
||||
|
||||
RSAES-V15 decoding: good, payload=1
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"00025050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505000":1:1:0
|
||||
|
||||
RSAES-V15 decoding: good, empty payload
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505000":0:0:0
|
||||
|
||||
RSAES-V15 decoding: payload=max, output too large
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505152535455565700":117:116:MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
|
||||
|
||||
RSAES-V15 decoding: payload=max-1, output too large
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000250515253545556575800":116:115:MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
|
||||
|
||||
RSAES-V15 decoding: bad first byte
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0102505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
RSAES-V15 decoding: bad second byte (0 instead of 2)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0000505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
RSAES-V15 decoding: bad second byte (1 instead of 2)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0001505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
RSAES-V15 decoding: padding too short (0)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"000200":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
RSAES-V15 decoding: padding too short (7)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505050505050500000ffffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
RSAES-V15 decoding: unfinished padding
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PRIVATE:"0002505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: good, payload=max, tight output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffff00":117:117:0
|
||||
|
||||
EMSA-V15 decoding: good, payload=max, larger output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffff00":117:128:0
|
||||
|
||||
EMSA-V15 decoding: good, payload=max-1, tight output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffff00":116:116:0
|
||||
|
||||
EMSA-V15 decoding: good, payload=max-1, larger output buffer
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffff00":116:117:0
|
||||
|
||||
EMSA-V15 decoding: good, payload=1
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00":1:1:0
|
||||
|
||||
EMSA-V15 decoding: good, empty payload
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00":0:0:0
|
||||
|
||||
EMSA-V15 decoding: bad first byte
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0101ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: bad second byte (0 instead of 1)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0000ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: bad second byte (2 instead of 1)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0002ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: padding too short (0)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"000100":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: padding too short (7)
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffff0000ffffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: invalid padding at first byte
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001fffffffffffffffe00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: invalid padding at last byte
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001feffffffffffffff00":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: unfinished padding
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: unfinished padding with invalid first byte
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
||||
EMSA-V15 decoding: unfinished padding with invalid last byte
|
||||
pkcs1_v15_decode:MBEDTLS_RSA_PUBLIC:"0001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe":0:42:MBEDTLS_ERR_RSA_INVALID_PADDING
|
||||
|
@ -93,6 +93,154 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void pkcs1_v15_decode( int mode,
|
||||
data_t *input,
|
||||
int expected_plaintext_length_arg,
|
||||
int output_size_arg,
|
||||
int expected_result )
|
||||
{
|
||||
size_t expected_plaintext_length = expected_plaintext_length_arg;
|
||||
size_t output_size = output_size_arg;
|
||||
rnd_pseudo_info rnd_info;
|
||||
mbedtls_mpi Nmpi, Empi, Pmpi, Qmpi;
|
||||
mbedtls_rsa_context ctx;
|
||||
static unsigned char N[128] = {
|
||||
0xc4, 0x79, 0x4c, 0x6d, 0xb2, 0xe9, 0xdf, 0xc5,
|
||||
0xe5, 0xd7, 0x55, 0x4b, 0xfb, 0x6c, 0x2e, 0xec,
|
||||
0x84, 0xd0, 0x88, 0x12, 0xaf, 0xbf, 0xb4, 0xf5,
|
||||
0x47, 0x3c, 0x7e, 0x92, 0x4c, 0x58, 0xc8, 0x73,
|
||||
0xfe, 0x8f, 0x2b, 0x8f, 0x8e, 0xc8, 0x5c, 0xf5,
|
||||
0x05, 0xeb, 0xfb, 0x0d, 0x7b, 0x2a, 0x93, 0xde,
|
||||
0x15, 0x0d, 0xc8, 0x13, 0xcf, 0xd2, 0x6f, 0x0d,
|
||||
0x9d, 0xad, 0x30, 0xe5, 0x70, 0x20, 0x92, 0x9e,
|
||||
0xb3, 0x6b, 0xba, 0x5c, 0x50, 0x0f, 0xc3, 0xb2,
|
||||
0x7e, 0x64, 0x07, 0x94, 0x7e, 0xc9, 0x4e, 0xc1,
|
||||
0x65, 0x04, 0xaf, 0xb3, 0x9f, 0xde, 0xa8, 0x46,
|
||||
0xfa, 0x6c, 0xf3, 0x03, 0xaf, 0x1c, 0x1b, 0xec,
|
||||
0x75, 0x44, 0x66, 0x77, 0xc9, 0xde, 0x51, 0x33,
|
||||
0x64, 0x27, 0xb0, 0xd4, 0x8d, 0x31, 0x6a, 0x11,
|
||||
0x27, 0x3c, 0x99, 0xd4, 0x22, 0xc0, 0x9d, 0x12,
|
||||
0x01, 0xc7, 0x4a, 0x73, 0xac, 0xbf, 0xc2, 0xbb
|
||||
};
|
||||
static unsigned char E[1] = { 0x03 };
|
||||
static unsigned char P[64] = {
|
||||
0xe5, 0x53, 0x1f, 0x88, 0x51, 0xee, 0x59, 0xf8,
|
||||
0xc1, 0xe4, 0xcc, 0x5b, 0xb3, 0x75, 0x8d, 0xc8,
|
||||
0xe8, 0x95, 0x2f, 0xd0, 0xef, 0x37, 0xb4, 0xcd,
|
||||
0xd3, 0x9e, 0x48, 0x8b, 0x81, 0x58, 0x60, 0xb9,
|
||||
0x27, 0x1d, 0xb6, 0x28, 0x92, 0x64, 0xa3, 0xa5,
|
||||
0x64, 0xbd, 0xcc, 0x53, 0x68, 0xdd, 0x3e, 0x55,
|
||||
0xea, 0x9d, 0x5e, 0xcd, 0x1f, 0x96, 0x87, 0xf1,
|
||||
0x29, 0x75, 0x92, 0x70, 0x8f, 0x28, 0xfb, 0x2b
|
||||
};
|
||||
static unsigned char Q[64] = {
|
||||
0xdb, 0x53, 0xef, 0x74, 0x61, 0xb4, 0x20, 0x3b,
|
||||
0x3b, 0x87, 0x76, 0x75, 0x81, 0x56, 0x11, 0x03,
|
||||
0x59, 0x31, 0xe3, 0x38, 0x4b, 0x8c, 0x7a, 0x9c,
|
||||
0x05, 0xd6, 0x7f, 0x1e, 0x5e, 0x60, 0xf0, 0x4e,
|
||||
0x0b, 0xdc, 0x34, 0x54, 0x1c, 0x2e, 0x90, 0x83,
|
||||
0x14, 0xef, 0xc0, 0x96, 0x5c, 0x30, 0x10, 0xcc,
|
||||
0xc1, 0xba, 0xa0, 0x54, 0x3f, 0x96, 0x24, 0xca,
|
||||
0xa3, 0xfb, 0x55, 0xbc, 0x71, 0x29, 0x4e, 0xb1
|
||||
};
|
||||
unsigned char original[128];
|
||||
unsigned char intermediate[128];
|
||||
static unsigned char default_content[128] = {
|
||||
/* A randomly generated pattern. */
|
||||
0x4c, 0x27, 0x54, 0xa0, 0xce, 0x0d, 0x09, 0x4a,
|
||||
0x1c, 0x38, 0x8e, 0x2d, 0xa3, 0xc4, 0xe0, 0x19,
|
||||
0x4c, 0x99, 0xb2, 0xbf, 0xe6, 0x65, 0x7e, 0x58,
|
||||
0xd7, 0xb6, 0x8a, 0x05, 0x2f, 0xa5, 0xec, 0xa4,
|
||||
0x35, 0xad, 0x10, 0x36, 0xff, 0x0d, 0x08, 0x50,
|
||||
0x74, 0x47, 0xc9, 0x9c, 0x4a, 0xe7, 0xfd, 0xfa,
|
||||
0x83, 0x5f, 0x14, 0x5a, 0x1e, 0xe7, 0x35, 0x08,
|
||||
0xad, 0xf7, 0x0d, 0x86, 0xdf, 0xb8, 0xd4, 0xcf,
|
||||
0x32, 0xb9, 0x5c, 0xbe, 0xa3, 0xd2, 0x89, 0x70,
|
||||
0x7b, 0xc6, 0x48, 0x7e, 0x58, 0x4d, 0xf3, 0xef,
|
||||
0x34, 0xb7, 0x57, 0x54, 0x79, 0xc5, 0x8e, 0x0a,
|
||||
0xa3, 0xbf, 0x6d, 0x42, 0x83, 0x25, 0x13, 0xa2,
|
||||
0x95, 0xc0, 0x0d, 0x32, 0xec, 0x77, 0x91, 0x2b,
|
||||
0x68, 0xb6, 0x8c, 0x79, 0x15, 0xfb, 0x94, 0xde,
|
||||
0xb9, 0x2b, 0x94, 0xb3, 0x28, 0x23, 0x86, 0x3d,
|
||||
0x37, 0x00, 0xe6, 0xf1, 0x1f, 0x4e, 0xd4, 0x42
|
||||
};
|
||||
unsigned char final[128];
|
||||
size_t output_length = 0x7EA0;
|
||||
|
||||
memset( &rnd_info, 0, sizeof( rnd_pseudo_info ) );
|
||||
mbedtls_mpi_init( &Nmpi ); mbedtls_mpi_init( &Empi );
|
||||
mbedtls_mpi_init( &Pmpi ); mbedtls_mpi_init( &Qmpi );
|
||||
mbedtls_rsa_init( &ctx, MBEDTLS_RSA_PKCS_V15, 0 );
|
||||
|
||||
TEST_ASSERT( mbedtls_mpi_read_binary( &Nmpi, N, sizeof( N ) ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_read_binary( &Empi, E, sizeof( E ) ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_read_binary( &Pmpi, P, sizeof( P ) ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_read_binary( &Qmpi, Q, sizeof( Q ) ) == 0 );
|
||||
|
||||
TEST_ASSERT( mbedtls_rsa_import( &ctx, &Nmpi, &Pmpi, &Qmpi,
|
||||
NULL, &Empi ) == 0 );
|
||||
TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
|
||||
|
||||
TEST_ASSERT( input->len <= sizeof( N ) );
|
||||
memcpy( original, input->x, input->len );
|
||||
memset( original + input->len, 'd', sizeof( original ) - input->len );
|
||||
if( mode == MBEDTLS_RSA_PRIVATE )
|
||||
TEST_ASSERT( mbedtls_rsa_public( &ctx, original, intermediate ) == 0 );
|
||||
else
|
||||
TEST_ASSERT( mbedtls_rsa_private( &ctx, &rnd_pseudo_rand, &rnd_info,
|
||||
original, intermediate ) == 0 );
|
||||
|
||||
memcpy( final, default_content, sizeof( final ) );
|
||||
TEST_ASSERT( mbedtls_rsa_pkcs1_decrypt( &ctx,
|
||||
&rnd_pseudo_rand, &rnd_info,
|
||||
mode,
|
||||
&output_length,
|
||||
intermediate,
|
||||
final,
|
||||
output_size ) == expected_result );
|
||||
if( expected_result == 0 )
|
||||
{
|
||||
TEST_ASSERT( output_length == expected_plaintext_length );
|
||||
TEST_ASSERT( memcmp( original + sizeof( N ) - output_length,
|
||||
final,
|
||||
output_length ) == 0 );
|
||||
}
|
||||
else if( expected_result == MBEDTLS_ERR_RSA_INVALID_PADDING ||
|
||||
expected_result == MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE )
|
||||
{
|
||||
size_t max_payload_length =
|
||||
output_size > sizeof( N ) - 11 ? sizeof( N ) - 11 : output_size;
|
||||
size_t i;
|
||||
size_t count = 0;
|
||||
|
||||
#if !defined(MBEDTLS_RSA_ALT)
|
||||
/* Check that the output in invalid cases is what the default
|
||||
* implementation currently does. Alternative implementations
|
||||
* may produce different output, so we only perform these precise
|
||||
* checks when using the default implementation. */
|
||||
TEST_ASSERT( output_length == max_payload_length );
|
||||
for( i = 0; i < max_payload_length; i++ )
|
||||
TEST_ASSERT( final[i] == 0 );
|
||||
#endif
|
||||
/* Even in alternative implementations, the outputs must have
|
||||
* changed, otherwise it indicates at least a timing vulnerability
|
||||
* because no write to the outputs is performed in the bad case. */
|
||||
TEST_ASSERT( output_length != 0x7EA0 );
|
||||
for( i = 0; i < max_payload_length; i++ )
|
||||
count += ( final[i] == default_content[i] );
|
||||
/* If more than 16 bytes are unchanged in final, that's evidence
|
||||
* that final wasn't overwritten. */
|
||||
TEST_ASSERT( count < 16 );
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_mpi_free( &Nmpi ); mbedtls_mpi_free( &Empi );
|
||||
mbedtls_mpi_free( &Pmpi ); mbedtls_mpi_free( &Qmpi );
|
||||
mbedtls_rsa_free( &ctx );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void pkcs1_rsassa_v15_sign( int mod, int radix_P, char * input_P, int radix_Q,
|
||||
char * input_Q, int radix_N, char * input_N,
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:MBEDTLS_PK_WRITE_C:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO
|
||||
* depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user